GITADORA PlayerBoard Customization Update

This commit is contained in:
James Liu
2026-09-06 17:24:43 +08:00
parent 3621f581e8
commit 590b993493
7 changed files with 7900 additions and 32 deletions
@@ -7,19 +7,33 @@ export interface PlayerStickerResponse {
rotate: KITEM<'float'>
}
export interface PlayerBoardConfig {
index: KITEM<'s32'>;
is_active: KITEM<'bool'>;
sticker: PlayerStickerResponse[];
}
function finiteNumber(value: unknown, fallback = 0): number {
const number = typeof value === 'number' ? value : Number(value);
return Number.isFinite(number) ? number : fallback;
}
/** Convert legacy card documents and WebUI playerboard JSON to wire values. */
export function getPlayerStickerResponse(playerCard : any[]) : PlayerStickerResponse[] {
let stickers : PlayerStickerResponse[] = []
if (!_.isArray(playerCard)) {
return stickers
}
for (const item of playerCard) {
for (const item of playerCard.slice(0, 10)) {
const id = _.get(item, 'id');
const posX = _.get(item, 'position.0');
const posY = _.get(item, 'position.1');
const scaleX = _.get(item, 'scale.0');
const scaleY = _.get(item, 'scale.1');
const rotation = _.get(item, 'rotation');
// Accept both the historical card shape and the wire-shaped playerboard
// shape used by the editor.
const posX = _.get(item, 'pos_x', _.get(item, 'position.0'));
const posY = _.get(item, 'pos_y', _.get(item, 'position.1'));
const scaleX = _.get(item, 'scale_x', _.get(item, 'scale.0'));
const scaleY = _.get(item, 'scale_y', _.get(item, 'scale.1'));
const rotation = _.get(item, 'rotate', _.get(item, 'rotation'));
if (
!isFinite(id) ||
@@ -33,14 +47,35 @@ export function getPlayerStickerResponse(playerCard : any[]) : PlayerStickerResp
}
stickers.push({
id: K.ITEM('s32', id),
pos_x: K.ITEM('float', posX),
pos_y: K.ITEM('float', posY),
scale_x: K.ITEM('float', scaleX),
scale_y: K.ITEM('float', scaleY),
rotate: K.ITEM('float', rotation),
id: K.ITEM('s32', finiteNumber(id)),
pos_x: K.ITEM('float', finiteNumber(posX)),
pos_y: K.ITEM('float', finiteNumber(posY)),
scale_x: K.ITEM('float', finiteNumber(scaleX)),
scale_y: K.ITEM('float', finiteNumber(scaleY)),
rotate: K.ITEM('float', finiteNumber(rotation)),
});
}
return stickers
}
return stickers
}
/** Build the playerboard response, with a safe fallback for old playerinfo documents. */
export function getPlayerBoardResponse(playerInfo: any): PlayerBoardConfig {
const configured = playerInfo?.playerboard;
const legacyCard = playerInfo?.card;
const stickers = getPlayerStickerResponse(
_.isArray(configured?.sticker) ? configured.sticker : legacyCard
);
const index = finiteNumber(configured?.index, 0);
const activeValue = configured?.is_active;
const isActive = activeValue === undefined
? _.isArray(legacyCard)
: Boolean(activeValue === true || activeValue === 1 || activeValue === '1' || activeValue === 'true');
return {
index: K.ITEM('s32', Math.trunc(index)),
is_active: K.ITEM('bool', isActive ? 1 : 0),
sticker: stickers,
};
}
+19 -1
View File
@@ -17,7 +17,25 @@ export interface PlayerInfo {
rotation: number;
}[];
// TODO: Add Board things.
/**
* Playerboard data returned by gametop.get.
*
* `card` is kept for backwards compatibility with older documents. New
* edits should use this wire-shaped representation so every playerboard
* field can be changed from the WebUI.
*/
playerboard?: {
index: number;
is_active: boolean;
sticker: {
id: number;
pos_x: number;
pos_y: number;
scale_x: number;
scale_y: number;
rotate: number;
}[];
};
}
export function getDefaultPlayerInfo(version: string, id: number) : PlayerInfo {