feat: add wooden fish play template

This commit is contained in:
2026-05-21 23:34:07 +08:00
parent ef09a23c35
commit 5b0f9f3763
121 changed files with 11580 additions and 159 deletions

View File

@@ -22,6 +22,10 @@ import type {
SquareHoleWorkSummary,
} from '../../../packages/shared/src/contracts/squareHoleWorks';
import type { VisualNovelWorkSummary } from '../../../packages/shared/src/contracts/visualNovel';
import type {
WoodenFishGalleryCardResponse,
WoodenFishWorkProfileResponse,
} from '../../../packages/shared/src/contracts/woodenFish';
import { buildCustomWorldPlayableCharacters } from '../../data/characterPresets';
import { resolveCustomWorldCampSceneImage } from '../../data/customWorldVisuals';
import {
@@ -32,7 +36,9 @@ import {
buildPuzzlePublicWorkCode,
buildSquareHolePublicWorkCode,
buildVisualNovelPublicWorkCode,
buildWoodenFishPublicWorkCode,
} from '../../services/publicWorkCode';
import { WOODEN_FISH_DEFAULT_HIT_OBJECT_SRC } from '../../services/wooden-fish/woodenFishDefaults';
import type { CustomWorldProfile } from '../../types';
export const PLATFORM_WORK_NAME_DISPLAY_LIMIT = 8;
@@ -48,6 +54,7 @@ export type PlatformWorldCardLike =
| PlatformSquareHoleGalleryCard
| PlatformPuzzleGalleryCard
| PlatformJumpHopGalleryCard
| PlatformWoodenFishGalleryCard
| PlatformVisualNovelGalleryCard
| PlatformEdutainmentGalleryCard;
@@ -202,6 +209,28 @@ export type PlatformJumpHopGalleryCard = {
stylePreset?: string;
};
export type PlatformWoodenFishGalleryCard = {
sourceType: 'wooden-fish';
workId: string;
profileId: string;
sourceSessionId?: string | null;
publicWorkCode: string;
ownerUserId: string;
authorDisplayName: string;
worldName: string;
subtitle: string;
summaryText: string;
coverImageSrc: string | null;
themeTags: string[];
playCount?: number;
remixCount?: number;
likeCount?: number;
recentPlayCount7d?: number;
visibility: 'published';
publishedAt: string | null;
updatedAt: string;
};
export type PlatformEdutainmentGalleryCard = {
sourceType: 'edutainment';
templateId: typeof EDUTAINMENT_BABY_OBJECT_MATCH_TEMPLATE_ID;
@@ -233,6 +262,7 @@ export type PlatformPublicGalleryCard =
| PlatformSquareHoleGalleryCard
| PlatformPuzzleGalleryCard
| PlatformJumpHopGalleryCard
| PlatformWoodenFishGalleryCard
| PlatformVisualNovelGalleryCard
| PlatformEdutainmentGalleryCard;
@@ -278,6 +308,12 @@ export function isJumpHopGalleryEntry(
return 'sourceType' in entry && entry.sourceType === 'jump-hop';
}
export function isWoodenFishGalleryEntry(
entry: PlatformWorldCardLike,
): entry is PlatformWoodenFishGalleryCard {
return 'sourceType' in entry && entry.sourceType === 'wooden-fish';
}
export function isEdutainmentGalleryEntry(
entry: PlatformWorldCardLike,
): entry is PlatformEdutainmentGalleryCard {
@@ -472,6 +508,39 @@ export function mapJumpHopWorkToPlatformGalleryCard(
};
}
export function mapWoodenFishWorkToPlatformGalleryCard(
work: WoodenFishGalleryCardResponse | WoodenFishWorkProfileResponse,
): PlatformWoodenFishGalleryCard {
const summary = 'summary' in work ? work.summary : work;
return {
sourceType: 'wooden-fish',
workId: summary.workId,
profileId: summary.profileId,
sourceSessionId:
'sourceSessionId' in summary ? (summary.sourceSessionId ?? null) : null,
publicWorkCode:
'publicWorkCode' in summary && summary.publicWorkCode.trim()
? summary.publicWorkCode
: buildWoodenFishPublicWorkCode(summary.profileId),
ownerUserId: summary.ownerUserId,
authorDisplayName:
'authorDisplayName' in summary ? summary.authorDisplayName : '玩家',
worldName: summary.workTitle,
subtitle: '敲木鱼',
summaryText: summary.workDescription,
coverImageSrc: summary.coverImageSrc ?? null,
themeTags: summary.themeTags.length > 0 ? summary.themeTags : ['敲木鱼'],
playCount: summary.playCount ?? 0,
remixCount: 0,
likeCount: 0,
recentPlayCount7d: 0,
visibility: 'published',
publishedAt: summary.publishedAt ?? null,
updatedAt: summary.updatedAt,
};
}
export function mapBabyObjectMatchDraftToPlatformGalleryCard(
draft: BabyObjectMatchDraft,
): PlatformEdutainmentGalleryCard {
@@ -553,6 +622,10 @@ export function resolvePlatformWorldFallbackCoverImage(
return '/creation-type-references/jump-hop.webp';
}
if (isWoodenFishGalleryEntry(entry)) {
return WOODEN_FISH_DEFAULT_HIT_OBJECT_SRC;
}
if (isBigFishGalleryEntry(entry)) {
return '/creation-type-references/big-fish.webp';
}
@@ -722,6 +795,12 @@ export function buildPlatformWorldTags(entry: PlatformWorldCardLike) {
: ['跳一跳'];
}
if (isWoodenFishGalleryEntry(entry)) {
return entry.themeTags.length > 0
? entry.themeTags.slice(0, 3)
: ['敲木鱼'];
}
if (isEdutainmentGalleryEntry(entry)) {
return entry.themeTags.length > 0
? entry.themeTags.slice(0, 3)
@@ -818,6 +897,10 @@ export function resolvePlatformPublicWorkCode(
return entry.publicWorkCode;
}
if (isWoodenFishGalleryEntry(entry)) {
return entry.publicWorkCode;
}
if (isEdutainmentGalleryEntry(entry)) {
return entry.publicWorkCode;
}