fix: enforce decor placement surfaces
This commit is contained in:
@@ -83,11 +83,18 @@ export class RoomDecorService {
|
|||||||
if (!definition.rotation_steps.includes(rotationDegrees)) {
|
if (!definition.rotation_steps.includes(rotationDegrees)) {
|
||||||
throw new BadRequestException('该摆件不支持此旋转角度');
|
throw new BadRequestException('该摆件不支持此旋转角度');
|
||||||
}
|
}
|
||||||
|
const positionX = this.snapToGrid(placement.position_x ?? definition.default_position.x, definition.grid_size);
|
||||||
|
const positionY = this.snapToGrid(placement.position_y ?? definition.default_position.y, definition.grid_size);
|
||||||
|
if (placement.placed && !this.isWithinPlacementBounds(positionX, positionY, definition)) {
|
||||||
|
throw new BadRequestException(definition.placement_surface === 'wall'
|
||||||
|
? '墙面挂饰只能摆放在墙面网格内'
|
||||||
|
: '地面家具只能摆放在地面网格内');
|
||||||
|
}
|
||||||
const row = await this.roomDecorPlacementsService.savePlacement(userId, {
|
const row = await this.roomDecorPlacementsService.savePlacement(userId, {
|
||||||
...placement,
|
...placement,
|
||||||
decor_id: decorId,
|
decor_id: decorId,
|
||||||
position_x: this.snapToGrid(placement.position_x, definition.grid_size),
|
position_x: positionX,
|
||||||
position_y: this.snapToGrid(placement.position_y, definition.grid_size),
|
position_y: positionY,
|
||||||
scale: placement.scale ?? definition.default_scale,
|
scale: placement.scale ?? definition.default_scale,
|
||||||
rotation_degrees: rotationDegrees,
|
rotation_degrees: rotationDegrees,
|
||||||
z_index: placement.z_index ?? definition.default_z_index,
|
z_index: placement.z_index ?? definition.default_z_index,
|
||||||
@@ -145,6 +152,7 @@ export class RoomDecorService {
|
|||||||
z_index: row.z_index ?? definition?.default_z_index ?? 0,
|
z_index: row.z_index ?? definition?.default_z_index ?? 0,
|
||||||
category: definition?.category ?? 'floor',
|
category: definition?.category ?? 'floor',
|
||||||
placement_surface: definition?.placement_surface ?? 'floor',
|
placement_surface: definition?.placement_surface ?? 'floor',
|
||||||
|
placement_bounds: definition?.placement_bounds,
|
||||||
grid_size: definition?.grid_size ?? 16,
|
grid_size: definition?.grid_size ?? 16,
|
||||||
rotation_steps: definition?.rotation_steps ?? [0],
|
rotation_steps: definition?.rotation_steps ?? [0],
|
||||||
stackable: definition?.stackable ?? false,
|
stackable: definition?.stackable ?? false,
|
||||||
@@ -207,11 +215,15 @@ export class RoomDecorService {
|
|||||||
return definition?.rotation_steps.includes(rotation) ? rotation : definition?.default_rotation_degrees ?? 0;
|
return definition?.rotation_steps.includes(rotation) ? rotation : definition?.default_rotation_degrees ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private snapToGrid(value: number | undefined, gridSize: number): number | undefined {
|
private snapToGrid(value: number, gridSize: number): number {
|
||||||
if (value === undefined) return undefined;
|
|
||||||
return Math.round(value / gridSize) * gridSize;
|
return Math.round(value / gridSize) * gridSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isWithinPlacementBounds(x: number, y: number, definition: RoomDecorDefinition): boolean {
|
||||||
|
const bounds = definition.placement_bounds;
|
||||||
|
return x >= bounds.min_x && x <= bounds.max_x && y >= bounds.min_y && y <= bounds.max_y;
|
||||||
|
}
|
||||||
|
|
||||||
private usesLegacyPlacement(row: UserRoomDecorRow) {
|
private usesLegacyPlacement(row: UserRoomDecorRow) {
|
||||||
const legacy = ROOM_DECOR_LEGACY_DEFAULTS[row.decor_id];
|
const legacy = ROOM_DECOR_LEGACY_DEFAULTS[row.decor_id];
|
||||||
if (!legacy) {
|
if (!legacy) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export interface RoomDecorDefinition {
|
|||||||
item_id: string;
|
item_id: string;
|
||||||
category: 'floor' | 'rug' | 'wall';
|
category: 'floor' | 'rug' | 'wall';
|
||||||
placement_surface: 'floor' | 'wall';
|
placement_surface: 'floor' | 'wall';
|
||||||
|
placement_bounds: RoomDecorPlacementBounds;
|
||||||
grid_size: number;
|
grid_size: number;
|
||||||
rotation_steps: number[];
|
rotation_steps: number[];
|
||||||
stackable: boolean;
|
stackable: boolean;
|
||||||
@@ -33,6 +34,13 @@ export interface RoomDecorDefinition {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RoomDecorPlacementBounds {
|
||||||
|
min_x: number;
|
||||||
|
max_x: number;
|
||||||
|
min_y: number;
|
||||||
|
max_y: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface RoomDecorLegacyDefault {
|
export interface RoomDecorLegacyDefault {
|
||||||
scale: number;
|
scale: number;
|
||||||
default_position: {
|
default_position: {
|
||||||
@@ -48,6 +56,18 @@ export const ROOM_DECOR_FLOOR_RUG_DEFAULT_SCALE = 1.0;
|
|||||||
export const ROOM_DECOR_WALL_DECOR_DEFAULT_SCALE = 0.04;
|
export const ROOM_DECOR_WALL_DECOR_DEFAULT_SCALE = 0.04;
|
||||||
export const ROOM_DECOR_LEGACY_BED_MAX_SCALE = 0.35;
|
export const ROOM_DECOR_LEGACY_BED_MAX_SCALE = 0.35;
|
||||||
export const ROOM_DECOR_LEGACY_WALL_DECOR_SCALES = [0.7, 0.18];
|
export const ROOM_DECOR_LEGACY_WALL_DECOR_SCALES = [0.7, 0.18];
|
||||||
|
export const ROOM_DECOR_FLOOR_PLACEMENT_BOUNDS: RoomDecorPlacementBounds = {
|
||||||
|
min_x: -426,
|
||||||
|
max_x: 426,
|
||||||
|
min_y: -176,
|
||||||
|
max_y: 212,
|
||||||
|
};
|
||||||
|
export const ROOM_DECOR_WALL_PLACEMENT_BOUNDS: RoomDecorPlacementBounds = {
|
||||||
|
min_x: -378,
|
||||||
|
max_x: 378,
|
||||||
|
min_y: -258,
|
||||||
|
max_y: -192,
|
||||||
|
};
|
||||||
|
|
||||||
export const ROOM_DECOR_LEGACY_DEFAULTS: Record<string, RoomDecorLegacyDefault> = {
|
export const ROOM_DECOR_LEGACY_DEFAULTS: Record<string, RoomDecorLegacyDefault> = {
|
||||||
whale_floor_rug: {
|
whale_floor_rug: {
|
||||||
@@ -99,6 +119,7 @@ export const ROOM_DECOR_DEFINITIONS: RoomDecorDefinition[] = [
|
|||||||
name: '鲸浪地毯',
|
name: '鲸浪地毯',
|
||||||
category: 'rug',
|
category: 'rug',
|
||||||
placement_surface: 'floor',
|
placement_surface: 'floor',
|
||||||
|
placement_bounds: ROOM_DECOR_FLOOR_PLACEMENT_BOUNDS,
|
||||||
grid_size: 16,
|
grid_size: 16,
|
||||||
rotation_steps: [0],
|
rotation_steps: [0],
|
||||||
stackable: false,
|
stackable: false,
|
||||||
@@ -116,6 +137,7 @@ export const ROOM_DECOR_DEFINITIONS: RoomDecorDefinition[] = [
|
|||||||
name: '鲸语记忆板',
|
name: '鲸语记忆板',
|
||||||
category: 'wall',
|
category: 'wall',
|
||||||
placement_surface: 'wall',
|
placement_surface: 'wall',
|
||||||
|
placement_bounds: ROOM_DECOR_WALL_PLACEMENT_BOUNDS,
|
||||||
grid_size: 16,
|
grid_size: 16,
|
||||||
rotation_steps: [0],
|
rotation_steps: [0],
|
||||||
stackable: false,
|
stackable: false,
|
||||||
@@ -132,6 +154,7 @@ export const ROOM_DECOR_DEFINITIONS: RoomDecorDefinition[] = [
|
|||||||
name: '鲸尾暖灯',
|
name: '鲸尾暖灯',
|
||||||
category: 'floor',
|
category: 'floor',
|
||||||
placement_surface: 'floor',
|
placement_surface: 'floor',
|
||||||
|
placement_bounds: ROOM_DECOR_FLOOR_PLACEMENT_BOUNDS,
|
||||||
grid_size: 16,
|
grid_size: 16,
|
||||||
rotation_steps: [0, 90, 180, 270],
|
rotation_steps: [0, 90, 180, 270],
|
||||||
stackable: false,
|
stackable: false,
|
||||||
@@ -151,6 +174,7 @@ export const ROOM_DECOR_DEFINITIONS: RoomDecorDefinition[] = [
|
|||||||
name: '船舱小床',
|
name: '船舱小床',
|
||||||
category: 'floor',
|
category: 'floor',
|
||||||
placement_surface: 'floor',
|
placement_surface: 'floor',
|
||||||
|
placement_bounds: ROOM_DECOR_FLOOR_PLACEMENT_BOUNDS,
|
||||||
grid_size: 16,
|
grid_size: 16,
|
||||||
rotation_steps: [0, 90, 180, 270],
|
rotation_steps: [0, 90, 180, 270],
|
||||||
stackable: false,
|
stackable: false,
|
||||||
@@ -170,6 +194,7 @@ export const ROOM_DECOR_DEFINITIONS: RoomDecorDefinition[] = [
|
|||||||
name: '海浪低床',
|
name: '海浪低床',
|
||||||
category: 'floor',
|
category: 'floor',
|
||||||
placement_surface: 'floor',
|
placement_surface: 'floor',
|
||||||
|
placement_bounds: ROOM_DECOR_FLOOR_PLACEMENT_BOUNDS,
|
||||||
grid_size: 16,
|
grid_size: 16,
|
||||||
rotation_steps: [0, 90, 180, 270],
|
rotation_steps: [0, 90, 180, 270],
|
||||||
stackable: false,
|
stackable: false,
|
||||||
@@ -189,6 +214,7 @@ export const ROOM_DECOR_DEFINITIONS: RoomDecorDefinition[] = [
|
|||||||
name: '鲸尾床头床',
|
name: '鲸尾床头床',
|
||||||
category: 'floor',
|
category: 'floor',
|
||||||
placement_surface: 'floor',
|
placement_surface: 'floor',
|
||||||
|
placement_bounds: ROOM_DECOR_FLOOR_PLACEMENT_BOUNDS,
|
||||||
grid_size: 16,
|
grid_size: 16,
|
||||||
rotation_steps: [0, 90, 180, 270],
|
rotation_steps: [0, 90, 180, 270],
|
||||||
stackable: false,
|
stackable: false,
|
||||||
@@ -208,6 +234,7 @@ export const ROOM_DECOR_DEFINITIONS: RoomDecorDefinition[] = [
|
|||||||
name: '程序员鲸书架',
|
name: '程序员鲸书架',
|
||||||
category: 'floor',
|
category: 'floor',
|
||||||
placement_surface: 'floor',
|
placement_surface: 'floor',
|
||||||
|
placement_bounds: ROOM_DECOR_FLOOR_PLACEMENT_BOUNDS,
|
||||||
grid_size: 16,
|
grid_size: 16,
|
||||||
rotation_steps: [0, 90, 180, 270],
|
rotation_steps: [0, 90, 180, 270],
|
||||||
stackable: false,
|
stackable: false,
|
||||||
@@ -227,6 +254,7 @@ export const ROOM_DECOR_DEFINITIONS: RoomDecorDefinition[] = [
|
|||||||
name: 'BUG特性徽章',
|
name: 'BUG特性徽章',
|
||||||
category: 'wall',
|
category: 'wall',
|
||||||
placement_surface: 'wall',
|
placement_surface: 'wall',
|
||||||
|
placement_bounds: ROOM_DECOR_WALL_PLACEMENT_BOUNDS,
|
||||||
grid_size: 16,
|
grid_size: 16,
|
||||||
rotation_steps: [0],
|
rotation_steps: [0],
|
||||||
stackable: false,
|
stackable: false,
|
||||||
@@ -244,6 +272,7 @@ export const ROOM_DECOR_DEFINITIONS: RoomDecorDefinition[] = [
|
|||||||
name: '佛系学习徽章',
|
name: '佛系学习徽章',
|
||||||
category: 'wall',
|
category: 'wall',
|
||||||
placement_surface: 'wall',
|
placement_surface: 'wall',
|
||||||
|
placement_bounds: ROOM_DECOR_WALL_PLACEMENT_BOUNDS,
|
||||||
grid_size: 16,
|
grid_size: 16,
|
||||||
rotation_steps: [0],
|
rotation_steps: [0],
|
||||||
stackable: false,
|
stackable: false,
|
||||||
@@ -261,6 +290,7 @@ export const ROOM_DECOR_DEFINITIONS: RoomDecorDefinition[] = [
|
|||||||
name: '已经在做徽章',
|
name: '已经在做徽章',
|
||||||
category: 'wall',
|
category: 'wall',
|
||||||
placement_surface: 'wall',
|
placement_surface: 'wall',
|
||||||
|
placement_bounds: ROOM_DECOR_WALL_PLACEMENT_BOUNDS,
|
||||||
grid_size: 16,
|
grid_size: 16,
|
||||||
rotation_steps: [0],
|
rotation_steps: [0],
|
||||||
stackable: false,
|
stackable: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user