From f9d6cc960cd708e70d5200496ef472cec445d821 Mon Sep 17 00:00:00 2001 From: Florian <45694132+flo-bit@users.noreply.github.com> Date: Wed, 6 May 2026 13:18:25 +0200 Subject: [PATCH] add rpg actor card --- src/lib/cards/index.ts | 4 +- .../social/RPGActorCard/RPGActorCard.svelte | 152 ++++++++++++++++++ src/lib/cards/social/RPGActorCard/index.ts | 68 ++++++++ 3 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 src/lib/cards/social/RPGActorCard/RPGActorCard.svelte create mode 100644 src/lib/cards/social/RPGActorCard/index.ts diff --git a/src/lib/cards/index.ts b/src/lib/cards/index.ts index 15d875c..6be995c 100644 --- a/src/lib/cards/index.ts +++ b/src/lib/cards/index.ts @@ -63,6 +63,7 @@ import { KichRecipeCardDefinition } from './social/KichRecipeCard'; import { KichRecipeCollectionCardDefinition } from './social/KichRecipeCollectionCard'; import { KichCookingLogCardDefinition } from './social/KichCookingLogCard'; import { SecretImageCardDefinition } from './media/SecretImageCard'; +import { RPGActorCardDefinition } from './social/RPGActorCard'; // import { Model3DCardDefinition } from './visual/Model3DCard'; export const AllCardDefinitions = [ @@ -131,7 +132,8 @@ export const AllCardDefinitions = [ KichRecipeCardDefinition, KichRecipeCollectionCardDefinition, KichCookingLogCardDefinition, - SecretImageCardDefinition + SecretImageCardDefinition, + RPGActorCardDefinition ] as const; export const CardDefinitionsByType = AllCardDefinitions.reduce( diff --git a/src/lib/cards/social/RPGActorCard/RPGActorCard.svelte b/src/lib/cards/social/RPGActorCard/RPGActorCard.svelte new file mode 100644 index 0000000..8d6e4a8 --- /dev/null +++ b/src/lib/cards/social/RPGActorCard/RPGActorCard.svelte @@ -0,0 +1,152 @@ + + +
+ {#if loaded && actor} + + {:else if loaded && !actor && isEditing} +
+ + Create your character on rpg.actor + +
+ {:else if loaded && !actor} +
+ This person hasn't created a character yet +
+ {/if} +
diff --git a/src/lib/cards/social/RPGActorCard/index.ts b/src/lib/cards/social/RPGActorCard/index.ts new file mode 100644 index 0000000..07b8393 --- /dev/null +++ b/src/lib/cards/social/RPGActorCard/index.ts @@ -0,0 +1,68 @@ +import type { CardDefinition } from '../../types'; +import { getRecord, getBlobURL } from '$lib/atproto'; +import RPGActorCard from './RPGActorCard.svelte'; +import type { Did } from '@atcute/lexicons'; + +export type RpgSpriteRecord = { + rows: number; + columns: number; + frames: number; + width: number; + height: number; + frameWidth: number; + frameHeight: number; + isCustom?: boolean; + createdAt?: string; + spriteSheet: { + $type: 'blob'; + ref: { $link: string }; + mimeType: string; + size: number; + }; +}; + +export type RpgActorData = { + sprite: RpgSpriteRecord; + url: string; +} | null; + +export const RPGActorCardDefinition = { + type: 'rpgActor', + contentComponent: RPGActorCard, + + createNew: (item) => { + item.w = 4; + item.h = 2; + item.mobileW = 8; + item.mobileH = 2; + }, + + loadData: async (_items, { did }) => { + try { + const record = await getRecord({ + did: did as Did, + collection: 'actor.rpg.sprite', + rkey: 'self' + }); + const value = record?.value as RpgSpriteRecord | undefined; + if (!value?.spriteSheet) return null; + const url = await getBlobURL({ + did: did as Did, + blob: value.spriteSheet + }); + return { sprite: value, url } satisfies RpgActorData; + } catch { + return null; + } + }, + cacheLoadData: true, + + minW: 2, + minH: 1, + + name: 'RPG Character', + keywords: ['rpg', 'sprite', 'character', 'actor', 'avatar', 'pixel', 'game'], + groups: ['Social'], + canHaveLabel: true, + icon: `` +} as CardDefinition & { type: 'rpgActor' };