Simplify custom world result editing controls
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
import { resolveCustomWorldCampScene } from '../services/customWorldCamp';
|
||||
import {
|
||||
collectSceneBucketSignalKeywords,
|
||||
resolveSceneBucketForLandmark,
|
||||
} from '../services/customWorldReferenceSignals';
|
||||
import { detectCustomWorldThemeMode } from '../services/customWorldTheme';
|
||||
import {
|
||||
type CustomWorldLandmark,
|
||||
@@ -197,6 +201,7 @@ type CustomWorldSceneImageMatchOptions = {
|
||||
| 'settingText'
|
||||
| 'templateWorldType'
|
||||
| 'camp'
|
||||
| 'ownedSettingLayers'
|
||||
> | null;
|
||||
landmark?: Pick<CustomWorldLandmark, 'id' | 'name' | 'description' | 'dangerLevel'> | null;
|
||||
usedImageSrcs?: Iterable<string>;
|
||||
@@ -262,6 +267,36 @@ function buildSceneReferencePool(worldType: WorldTemplateType) {
|
||||
}));
|
||||
}
|
||||
|
||||
function buildOwnedSceneReferencePool(
|
||||
profile: Pick<
|
||||
CustomWorldProfile,
|
||||
'id' | 'name' | 'ownedSettingLayers'
|
||||
>,
|
||||
) {
|
||||
const sceneBuckets =
|
||||
profile.ownedSettingLayers?.referenceProfile.sceneBuckets ?? [];
|
||||
if (sceneBuckets.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const pool = getAllCustomWorldSceneImages();
|
||||
if (pool.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return sceneBuckets.map((bucket, index) => {
|
||||
const offset =
|
||||
hashText(`${profile.id || profile.name}:${bucket.id}:${bucket.label}`)
|
||||
% pool.length;
|
||||
|
||||
return {
|
||||
name: bucket.label,
|
||||
keywords: collectSceneBucketSignalKeywords(bucket),
|
||||
imageSrc: pool[(offset + index) % pool.length] ?? '',
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function buildSourceText(
|
||||
seedKey: string,
|
||||
index: number,
|
||||
@@ -369,7 +404,13 @@ export function getDefaultCustomWorldSceneImage(
|
||||
worldType: WorldTemplateType,
|
||||
options: CustomWorldSceneImageMatchOptions = {},
|
||||
) {
|
||||
const pool = collectWorldSceneImagePool(worldType);
|
||||
const ownedReferencePool = options.profile
|
||||
? buildOwnedSceneReferencePool(options.profile)
|
||||
: [];
|
||||
const pool =
|
||||
ownedReferencePool.length > 0
|
||||
? getAllCustomWorldSceneImages()
|
||||
: collectWorldSceneImagePool(worldType);
|
||||
if (pool.length === 0) {
|
||||
return worldType === WorldType.WUXIA ? '/scene_bg/45_PixelSky.png' : '/scene_bg/47_PixelSky.png';
|
||||
}
|
||||
@@ -379,12 +420,34 @@ export function getDefaultCustomWorldSceneImage(
|
||||
.map((value) => normalizeOptionalImageSrc(value))
|
||||
.filter((value): value is string => Boolean(value)),
|
||||
);
|
||||
const sourceText = buildSourceText(seedKey, index, worldType, options);
|
||||
const referencePool = buildSceneReferencePool(worldType);
|
||||
const preferredSceneBucket =
|
||||
options.profile && options.landmark
|
||||
? resolveSceneBucketForLandmark(
|
||||
options.profile as CustomWorldProfile,
|
||||
options.landmark,
|
||||
)
|
||||
: null;
|
||||
const sourceText = [
|
||||
buildSourceText(seedKey, index, worldType, options),
|
||||
preferredSceneBucket?.label ?? '',
|
||||
...(preferredSceneBucket
|
||||
? collectSceneBucketSignalKeywords(preferredSceneBucket)
|
||||
: []),
|
||||
].join(' ');
|
||||
const referencePool =
|
||||
ownedReferencePool.length > 0
|
||||
? ownedReferencePool
|
||||
: buildSceneReferencePool(worldType);
|
||||
const scoredReferences = referencePool
|
||||
.map((reference, referenceIndex) => ({
|
||||
imageSrc: reference.imageSrc,
|
||||
score: scoreSceneReference(reference, sourceText),
|
||||
score:
|
||||
scoreSceneReference(reference, sourceText)
|
||||
+ (
|
||||
preferredSceneBucket && reference.name === preferredSceneBucket.label
|
||||
? 28
|
||||
: 0
|
||||
),
|
||||
tieBreaker: hashText(`${seedKey}:${reference.name}:${referenceIndex}`),
|
||||
}))
|
||||
.sort((left, right) => {
|
||||
@@ -418,7 +481,14 @@ export function getDefaultCustomWorldSceneImage(
|
||||
export function resolveCustomWorldLandmarkImage(
|
||||
profile: Pick<
|
||||
CustomWorldProfile,
|
||||
'id' | 'name' | 'summary' | 'tone' | 'playerGoal' | 'settingText' | 'templateWorldType'
|
||||
| 'id'
|
||||
| 'name'
|
||||
| 'summary'
|
||||
| 'tone'
|
||||
| 'playerGoal'
|
||||
| 'settingText'
|
||||
| 'templateWorldType'
|
||||
| 'ownedSettingLayers'
|
||||
>,
|
||||
landmark: Pick<CustomWorldLandmark, 'id' | 'name' | 'description' | 'dangerLevel' | 'imageSrc'>,
|
||||
index: number,
|
||||
@@ -453,6 +523,7 @@ export function resolveCustomWorldLandmarkImageMap(
|
||||
| 'templateWorldType'
|
||||
| 'landmarks'
|
||||
| 'camp'
|
||||
| 'ownedSettingLayers'
|
||||
>,
|
||||
) {
|
||||
const usedImageSrcs = new Set(
|
||||
@@ -490,6 +561,7 @@ export function resolveCustomWorldCampSceneImage(
|
||||
| 'templateWorldType'
|
||||
| 'landmarks'
|
||||
| 'camp'
|
||||
| 'ownedSettingLayers'
|
||||
>,
|
||||
) {
|
||||
const campScene = resolveCustomWorldCampScene(profile);
|
||||
|
||||
Reference in New Issue
Block a user