Update Healer Man server
This commit is contained in:
1 parent
97ee0c13f9
commit
f864b5aea7
20 files changed
+468
-211
No files matched your search
@@ -78,6 +78,7 @@ function packLabel(packId) {
|
||||
const [category, id = category] = packId.split(":", 2);
|
||||
const name = id.split("-").map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`).join(" ");
|
||||
if (category === "dungeon") return name;
|
||||
if (category === "creatures") return `${name} Creatures`;
|
||||
if (packId === "characters:wow335a-v1") return "Extra Wrath Character Models & Skins";
|
||||
if (packId === "characters:ascension-v1") return "Ascension Character Models & Skins";
|
||||
if (packId === "characters:runewaker-v1") return "RuneWaker Character Models & Skins";
|
||||
@@ -107,12 +108,13 @@ export function contentPackForPath(logicalPath) {
|
||||
return basicWrathHuman ? "core:character-basic" : `characters:${segments[2]}`;
|
||||
}
|
||||
if (segments[1] === "creatures" && segments[2]) {
|
||||
return segments[2] === "shared" ? "shared:creatures" : `dungeon:${segments[2]}`;
|
||||
return segments[2] === "shared" ? "shared:creatures" : `creatures:${segments[2]}`;
|
||||
}
|
||||
if (segments[1] === "game" && segments[2] === "creatures" && segments[3]) {
|
||||
return segments[3] === "shared" ? "shared:creatures" : `dungeon:${segments[3]}`;
|
||||
return segments[3] === "shared" ? "shared:creatures" : `creatures:${segments[3]}`;
|
||||
}
|
||||
if (segments[1] === "game" && segments[2] === "dungeons" && segments[3]) {
|
||||
if (segments[4] === "creatures") return `creatures:${segments[3]}`;
|
||||
return `dungeon:${segments[3]}`;
|
||||
}
|
||||
if (segments[1] === "game" && segments[2] === "arenas") return "core:arenas";
|
||||
@@ -203,44 +205,58 @@ function assetPackId(url) {
|
||||
|
||||
/**
|
||||
* Builds the logical install topology for the 54-dungeon WoW campaign.
|
||||
* Environment files intentionally remain in their independently downloadable
|
||||
* Manastorm packs; a dungeon pack owns its creatures and pulls in exactly the
|
||||
* environment/shared-creature packs referenced by the generated definition.
|
||||
* Environment and creature files remain independently downloadable. A dungeon
|
||||
* pack pulls in exactly the environment and creature packs referenced by its
|
||||
* generated definition, while randomized modes can install creatures alone.
|
||||
*/
|
||||
export function campaignDungeonPackDefinitions(definitions) {
|
||||
const packs = new Map();
|
||||
for (const definition of definitions) {
|
||||
const dungeonPackId = `dungeon:${definition.id}`;
|
||||
if (definition.id === "wailing-caverns") {
|
||||
const referencedCreaturePacks = new Set([
|
||||
"creatures:wailing-caverns",
|
||||
...Object.values(definition.entities ?? {})
|
||||
.map((entity) => entity.visual?.model?.url)
|
||||
.filter(Boolean)
|
||||
.map(assetPackId),
|
||||
]);
|
||||
const unexpectedCreaturePacks = [...referencedCreaturePacks]
|
||||
.filter((id) => id !== "creatures:wailing-caverns" && id !== "shared:creatures");
|
||||
if (unexpectedCreaturePacks.length) {
|
||||
throw new Error(`${definition.id} references unexpected creature packs: ${unexpectedCreaturePacks.join(", ")}`);
|
||||
}
|
||||
packs.set(dungeonPackId, {
|
||||
id: dungeonPackId,
|
||||
label: definition.title ?? packLabel(dungeonPackId),
|
||||
bundledOnAndroid: true,
|
||||
dependencies: [],
|
||||
dependencies: [...referencedCreaturePacks],
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
const environmentUrls = [
|
||||
...(definition.assets?.visual ?? []).map((asset) => asset.url),
|
||||
...(definition.assets?.collision ?? []).map((asset) => asset.url),
|
||||
definition.assets?.navigation?.url,
|
||||
].filter(Boolean);
|
||||
const resolvedEnvironmentPacks = environmentUrls.map(assetPackId);
|
||||
if (!resolvedEnvironmentPacks.length || resolvedEnvironmentPacks.some((id) => !id?.startsWith("manastorm:"))) {
|
||||
throw new Error(`${definition.id} has an environment asset outside a Manastorm content pack.`);
|
||||
if (!resolvedEnvironmentPacks.length
|
||||
|| resolvedEnvironmentPacks.some((id) => !id?.startsWith("manastorm:"))) {
|
||||
throw new Error(`${definition.id} has an environment asset outside its expected content pack.`);
|
||||
}
|
||||
const environmentPackIds = new Set(resolvedEnvironmentPacks);
|
||||
if (environmentPackIds.size !== 1) {
|
||||
throw new Error(`${definition.id} must resolve to exactly one Manastorm environment pack.`);
|
||||
}
|
||||
const [environmentPackId] = environmentPackIds;
|
||||
packs.set(environmentPackId, {
|
||||
id: environmentPackId,
|
||||
label: packLabel(environmentPackId),
|
||||
bundledOnAndroid: false,
|
||||
dependencies: [],
|
||||
});
|
||||
if (environmentPackId !== dungeonPackId) {
|
||||
packs.set(environmentPackId, {
|
||||
id: environmentPackId,
|
||||
label: packLabel(environmentPackId),
|
||||
bundledOnAndroid: false,
|
||||
dependencies: [],
|
||||
});
|
||||
}
|
||||
|
||||
const creatureUrls = Object.values(definition.entities ?? {})
|
||||
.map((entity) => entity.visual?.model?.url)
|
||||
@@ -249,16 +265,21 @@ export function campaignDungeonPackDefinitions(definitions) {
|
||||
if (resolvedCreaturePacks.some((id) => !id)) {
|
||||
throw new Error(`${definition.id} has a creature asset outside a content pack.`);
|
||||
}
|
||||
const referencedCreaturePacks = new Set(resolvedCreaturePacks.filter((id) => id !== dungeonPackId));
|
||||
const unexpectedCreaturePacks = [...referencedCreaturePacks].filter((id) => id !== "shared:creatures");
|
||||
const referencedCreaturePacks = new Set(resolvedCreaturePacks);
|
||||
const expectedCreaturePackId = `creatures:${definition.id}`;
|
||||
const unexpectedCreaturePacks = [...referencedCreaturePacks]
|
||||
.filter((id) => id !== expectedCreaturePackId && id !== "shared:creatures");
|
||||
if (unexpectedCreaturePacks.length) {
|
||||
throw new Error(`${definition.id} references unexpected creature packs: ${unexpectedCreaturePacks.join(", ")}`);
|
||||
}
|
||||
packs.set(dungeonPackId, {
|
||||
id: dungeonPackId,
|
||||
label: definition.title ?? packLabel(dungeonPackId),
|
||||
bundledOnAndroid: false,
|
||||
dependencies: [environmentPackId, ...referencedCreaturePacks],
|
||||
bundledOnAndroid: definition.id === "wailing-caverns",
|
||||
dependencies: [
|
||||
...(environmentPackId === dungeonPackId ? [] : [environmentPackId]),
|
||||
...referencedCreaturePacks,
|
||||
],
|
||||
});
|
||||
}
|
||||
return [...packs.values()].sort((left, right) => left.id.localeCompare(right.id));
|
||||
@@ -350,6 +371,15 @@ export function createContentManifest(files, options = {}) {
|
||||
});
|
||||
}
|
||||
|
||||
// RuneWaker dungeon definitions are generated TypeScript rather than part of
|
||||
// the WoW JSON catalog. Their matching creature dependency is recoverable
|
||||
// from the stable pack namespace without importing runtime code here.
|
||||
for (const creaturePack of [...packs.values()].filter((pack) => pack.id.startsWith("creatures:"))) {
|
||||
const dungeonPack = packs.get(`dungeon:${creaturePack.id.slice("creatures:".length)}`);
|
||||
if (!dungeonPack || dungeonPack.dependencies.includes(creaturePack.id)) continue;
|
||||
dungeonPack.dependencies = [...dungeonPack.dependencies, creaturePack.id];
|
||||
}
|
||||
|
||||
const sortedPacks = [...packs.values()].sort((left, right) => left.id.localeCompare(right.id));
|
||||
for (const pack of sortedPacks) {
|
||||
const objects = new Map(files.filter((file) => file.packId === pack.id)
|
||||
|
||||
Reference in new issue
Block a user