Update Healer Man server
This commit is contained in:
1 parent
daa417ec17
commit
8b9c95b24f
3 files changed
+48
-5
No files matched your search
@@ -34,8 +34,9 @@ describe("bite-sized Stormwind Stockades", () => {
|
|||||||
expect(biteSized.objectiveOrder).toEqual(biteSized.bosses);
|
expect(biteSized.objectiveOrder).toEqual(biteSized.bosses);
|
||||||
expect(biteSized.staticSpawns.filter((spawn) => spawn.id === bossId)).toHaveLength(1);
|
expect(biteSized.staticSpawns.filter((spawn) => spawn.id === bossId)).toHaveLength(1);
|
||||||
expect(biteSized.staticSpawns.every((spawn) => Math.abs(spawn.position[2]) <= 15)).toBe(true);
|
expect(biteSized.staticSpawns.every((spawn) => Math.abs(spawn.position[2]) <= 15)).toBe(true);
|
||||||
expect(biteSized.navigationLinks.map((link) => link.id)).toEqual(["entrance-to-central-stairs"]);
|
expect(biteSized.navigationLinks).toEqual(source.navigationLinks);
|
||||||
expect(biteSized.traversalRamps?.map((ramp) => ramp.id)).toEqual(["entrance-stair-ramp"]);
|
expect(biteSized.traversalRamps).toEqual(source.traversalRamps);
|
||||||
|
expect(biteSized.roamingPacks).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("seals both side wings with visible movement and sight blockers", () => {
|
it("seals both side wings with visible movement and sight blockers", () => {
|
||||||
|
|||||||
@@ -133,8 +133,10 @@ export function createBiteSizedStockadesDefinition(
|
|||||||
roamingPacks: [],
|
roamingPacks: [],
|
||||||
bosses: [boss],
|
bosses: [boss],
|
||||||
objectiveOrder: [boss],
|
objectiveOrder: [boss],
|
||||||
navigationLinks: source.navigationLinks.filter((link) => link.id === "entrance-to-central-stairs"),
|
// Keep the complete reviewed Stockades navigation graph connected. The
|
||||||
traversalRamps: source.traversalRamps?.filter((ramp) => ramp.id === "entrance-stair-ramp"),
|
// physical branch walls, not navmesh pruning, close the unused wings.
|
||||||
|
navigationLinks: source.navigationLinks,
|
||||||
|
traversalRamps: source.traversalRamps,
|
||||||
encounters: [{
|
encounters: [{
|
||||||
id: `${BITE_SIZED_STOCKADES_DUNGEON_ID}:boss-progression`,
|
id: `${BITE_SIZED_STOCKADES_DUNGEON_ID}:boss-progression`,
|
||||||
dungeonId: BITE_SIZED_STOCKADES_DUNGEON_ID,
|
dungeonId: BITE_SIZED_STOCKADES_DUNGEON_ID,
|
||||||
@@ -148,7 +150,7 @@ export function createBiteSizedStockadesDefinition(
|
|||||||
reviewedBehavior: "A single seeded Stockades boss completes the bite-sized run in the first boss room.",
|
reviewedBehavior: "A single seeded Stockades boss completes the bite-sized run in the first boss room.",
|
||||||
adaptations: [
|
adaptations: [
|
||||||
"Each seeded run retains the selected source boss objective ID so saves, loot, guides, and leaderboards report the correct variant.",
|
"Each seeded run retains the selected source boss objective ID so saves, loot, guides, and leaderboards report the correct variant.",
|
||||||
"The two side-wing stairs are permanently sealed and omitted from party navigation.",
|
"The side-wing stairs retain their navigation bridges so the central route stays on the retained navmesh component; physical walls seal both unused wings.",
|
||||||
],
|
],
|
||||||
remainingGaps: [],
|
remainingGaps: [],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ const STOCKADES_NAVIGATION = "public/assets/game/manastorm/34-stormwindjail/navi
|
|||||||
const TANK_RANGE = Object.freeze({ minimum: 0, preferred: 2.9, maximum: 3.15 });
|
const TANK_RANGE = Object.freeze({ minimum: 0, preferred: 2.9, maximum: 3.15 });
|
||||||
|
|
||||||
const stockades = requireDungeonDefinition("stormwind-stockade");
|
const stockades = requireDungeonDefinition("stormwind-stockade");
|
||||||
|
const biteSizedStockades = requireDungeonDefinition("bite-sized-stormwind-stockade");
|
||||||
let graph: PartyNavigationGraph;
|
let graph: PartyNavigationGraph;
|
||||||
|
let biteSizedGraph: PartyNavigationGraph;
|
||||||
let sourceCollision: Group;
|
let sourceCollision: Group;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
@@ -64,6 +66,10 @@ beforeAll(async () => {
|
|||||||
graph = preparePartyNavigationGraph(
|
graph = preparePartyNavigationGraph(
|
||||||
"/test/stockades-navigation.glb", scene, stockades.navigationLinks, stockades.traversalRamps,
|
"/test/stockades-navigation.glb", scene, stockades.navigationLinks, stockades.traversalRamps,
|
||||||
);
|
);
|
||||||
|
biteSizedGraph = preparePartyNavigationGraph(
|
||||||
|
"/test/bite-sized-stockades-navigation.glb", scene,
|
||||||
|
biteSizedStockades.navigationLinks, biteSizedStockades.traversalRamps,
|
||||||
|
);
|
||||||
geometry.dispose();
|
geometry.dispose();
|
||||||
|
|
||||||
const collisionDocument = await new NodeIO()
|
const collisionDocument = await new NodeIO()
|
||||||
@@ -256,6 +262,40 @@ describe("Stormwind Stockade party navigation", () => {
|
|||||||
expect(graph.triangleNodes?.length).toBe(graph.triangles?.length);
|
expect(graph.triangleNodes?.length).toBe(graph.triangles?.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("keeps the bite-sized entrance and boss room on the retained navigation surface", () => {
|
||||||
|
const world = collisionWorld();
|
||||||
|
try {
|
||||||
|
for (const wall of biteSizedStockades.serverGameObjects.filter((object) => object.id.startsWith("bite-sized-"))) {
|
||||||
|
world.createCollider(RAPIER.ColliderDesc.cuboid(...wall.halfExtents)
|
||||||
|
.setTranslation(...wall.position)
|
||||||
|
.setCollisionGroups(DUNGEON_PHYSICAL_COLLISION_GROUPS));
|
||||||
|
}
|
||||||
|
world.step();
|
||||||
|
const entrance = findNearestPartyNavigationSurface(
|
||||||
|
biteSizedGraph,
|
||||||
|
biteSizedStockades.entrance.footPosition,
|
||||||
|
6,
|
||||||
|
);
|
||||||
|
const boss = findNearestPartyNavigationSurface(
|
||||||
|
biteSizedGraph,
|
||||||
|
biteSizedStockades.bosses[0].position,
|
||||||
|
15,
|
||||||
|
);
|
||||||
|
expect(entrance).not.toBeNull();
|
||||||
|
expect(boss).not.toBeNull();
|
||||||
|
expect(findPartyNavigationPath(
|
||||||
|
biteSizedGraph,
|
||||||
|
entrance!.position,
|
||||||
|
boss!.position,
|
||||||
|
{
|
||||||
|
maxStartSnapDistance: 0.1,
|
||||||
|
maxEndSnapDistance: 0.1,
|
||||||
|
routeSegmentAllowed: createPartyRouteSegmentValidator(RAPIER, world),
|
||||||
|
},
|
||||||
|
)).not.toBeNull();
|
||||||
|
} finally { world.free(); }
|
||||||
|
});
|
||||||
|
|
||||||
it("projects every entrance formation slot onto the retained walkable surface", () => {
|
it("projects every entrance formation slot onto the retained walkable surface", () => {
|
||||||
const slots = derivePartySpawnSlots({
|
const slots = derivePartySpawnSlots({
|
||||||
footPosition: stockades.entrance.footPosition,
|
footPosition: stockades.entrance.footPosition,
|
||||||
|
|||||||
Reference in new issue
Block a user