Update Healer Man server
This commit is contained in:
1 parent
9c5fb4c614
commit
bd073fb00f
113 files changed
+4902
-273
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { selectedCharacter, useShellStore } from "../app/shellStore";
|
||||
import { installDungeonShellRuntime } from "../app/dungeonShellRuntime";
|
||||
import { useOnlineGroupStore } from "../app/onlineGroupStore";
|
||||
@@ -10,7 +10,9 @@ import {
|
||||
RANDOMIZED_BITE_SIZED_STOCKADES_DUNGEON_ID,
|
||||
dungeonContentPackId,
|
||||
} from "../game/dungeonContentSource";
|
||||
import { dungeonById } from "../game/dungeonCatalog";
|
||||
import { dungeonById, randomRandomizedBiteSizedDungeon } from "../game/dungeonCatalog";
|
||||
import { dungeonEnabledForQueue } from "../game/dungeonQueuePolicy";
|
||||
import { loadDungeonQueuePolicy, useDungeonQueuePolicyStore } from "../app/dungeonQueuePolicyStore";
|
||||
import { RANDOMIZED_BITE_SIZED_CREATURE_CATALOG, requireDungeonDefinition } from "../game/dungeonRegistry";
|
||||
import { BrandMark, FrontSurface } from "./FrontSurface";
|
||||
import { DungeonDifficultySlider } from "./DungeonDifficultySlider";
|
||||
@@ -38,6 +40,9 @@ export function RandomizedBiteSizedScreen({ onClose }: { readonly onClose: () =>
|
||||
const [downloading, setDownloading] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const [readinessOpen, setReadinessOpen] = useState(false);
|
||||
const queuePolicy = useDungeonQueuePolicyStore((state) => state.config);
|
||||
const refreshQueuePolicy = useDungeonQueuePolicyStore((state) => state.refresh);
|
||||
useEffect(() => { void refreshQueuePolicy(session); }, [refreshQueuePolicy, session]);
|
||||
const character = activeCharacter ?? rosterCharacter;
|
||||
const specialization = specializationById(character?.specializationId);
|
||||
const roles = character
|
||||
@@ -46,16 +51,24 @@ export function RandomizedBiteSizedScreen({ onClose }: { readonly onClose: () =>
|
||||
const installed = dungeonContentIsUsable(RANDOMIZED_BITE_SIZED_STOCKADES_DUNGEON_ID);
|
||||
const mobCount = CANDIDATES.filter((candidate) => candidate.kind === "mob").length;
|
||||
const bossCount = CANDIDATES.filter((candidate) => candidate.kind === "boss").length;
|
||||
const queueEnabled = Boolean(DUNGEON && dungeonEnabledForQueue(queuePolicy, DUNGEON));
|
||||
|
||||
const launch = async (role: PartyRole) => {
|
||||
if (!character || !DUNGEON?.available) return;
|
||||
const policy = await loadDungeonQueuePolicy();
|
||||
const selectedDungeon = randomRandomizedBiteSizedDungeon(undefined, Math.random,
|
||||
(candidate) => dungeonEnabledForQueue(policy, candidate));
|
||||
if (!selectedDungeon) {
|
||||
setError("No Randomized Bite-Sized location is enabled for this queue.");
|
||||
return;
|
||||
}
|
||||
if (!onlineGroup || !session || session.kind !== "account") {
|
||||
const runId = globalThis.crypto.randomUUID();
|
||||
setDownloading(true); setError("");
|
||||
try {
|
||||
await ensureRandomizedBiteSizedRunContent(runId);
|
||||
enterDungeon(RANDOMIZED_BITE_SIZED_STOCKADES_DUNGEON_ID, role, {
|
||||
difficultyId: requireDungeonDefinition(RANDOMIZED_BITE_SIZED_STOCKADES_DUNGEON_ID).defaultDifficultyId,
|
||||
enterDungeon(selectedDungeon.id, role, {
|
||||
difficultyId: requireDungeonDefinition(selectedDungeon.id).defaultDifficultyId,
|
||||
bossDifficulty,
|
||||
freshRun: true,
|
||||
runId,
|
||||
@@ -74,8 +87,8 @@ export function RandomizedBiteSizedScreen({ onClose }: { readonly onClose: () =>
|
||||
}
|
||||
await startOnlineActivity(session, {
|
||||
type: "dungeon",
|
||||
contentId: RANDOMIZED_BITE_SIZED_STOCKADES_DUNGEON_ID,
|
||||
difficultyId: requireDungeonDefinition(RANDOMIZED_BITE_SIZED_STOCKADES_DUNGEON_ID).defaultDifficultyId,
|
||||
contentId: selectedDungeon.id,
|
||||
difficultyId: requireDungeonDefinition(selectedDungeon.id).defaultDifficultyId,
|
||||
bossDifficulty,
|
||||
partySize: 5,
|
||||
fillWithAi: true,
|
||||
@@ -122,17 +135,18 @@ export function RandomizedBiteSizedScreen({ onClose }: { readonly onClose: () =>
|
||||
</section>
|
||||
<section className="randomized-bite-sized-screen__launch">
|
||||
<p className="front-kicker">Run setup</p>
|
||||
<h2>{DUNGEON?.title ?? "Cellblock Shuffle"}</h2>
|
||||
<h2>{queueEnabled ? DUNGEON?.title ?? "Cellblock Shuffle" : "No enabled location"}</h2>
|
||||
<DungeonDifficultySlider value={bossDifficulty} onChange={setBossDifficulty} selectedId="" select={() => undefined} />
|
||||
{!installed ? (
|
||||
{!queueEnabled ? null : !installed ? (
|
||||
<button className="front-button front-button--primary" type="button" disabled={downloading} onClick={() => void install()}>{downloading ? "Installing…" : "Install randomized dungeon content"}</button>
|
||||
) : roles.length ? (
|
||||
<div className="randomized-bite-sized-screen__roles">
|
||||
<strong>Enter as</strong>
|
||||
{roles.map((role) => <button className="front-button front-button--primary" key={role} type="button" disabled={!DUNGEON?.available || downloading} onClick={() => void launch(role)}>{downloading ? "Preparing run…" : PARTY_ROLE_LABELS[role]}</button>)}
|
||||
{roles.map((role) => <button className="front-button front-button--primary" key={role} type="button" disabled={!DUNGEON?.available || !queueEnabled || downloading} onClick={() => void launch(role)}>{downloading ? "Preparing run…" : PARTY_ROLE_LABELS[role]}</button>)}
|
||||
</div>
|
||||
) : <p className="front-notice">Choose a specialization in your Class Hall before entering.</p>}
|
||||
{!DUNGEON?.available && <p className="front-notice">This randomized route is not enterable in the current content build.</p>}
|
||||
{!queueEnabled && <p className="front-notice">No Randomized Bite-Sized location is enabled in GM queue settings.</p>}
|
||||
{(error || notice) && <p className="front-notice" role="status">{error || notice}</p>}
|
||||
</section>
|
||||
</main>
|
||||
|
||||
Reference in new issue
Block a user