From 89a4e359bd98c3944d798aa6679b5ff1252d7830 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 11 Apr 2026 23:08:38 +0000 Subject: [PATCH] Expand outdoor shopping district Co-authored-by: Luke The Dev --- src/features/retro-office/core/district.ts | 26 ++++--- .../retro-office/core/furnitureDefaults.ts | 35 ++++++--- .../retro-office/core/navigation/shopRoute.ts | 76 +++++++++++++------ src/features/retro-office/core/types.ts | 2 +- .../retro-office/scene/environment.tsx | 48 ++++++++++-- 5 files changed, 135 insertions(+), 52 deletions(-) diff --git a/src/features/retro-office/core/district.ts b/src/features/retro-office/core/district.ts index f53604e..ae98964 100644 --- a/src/features/retro-office/core/district.ts +++ b/src/features/retro-office/core/district.ts @@ -19,28 +19,30 @@ export const LOCAL_OFFICE_ZONE: DistrictZone = { maxY: LOCAL_OFFICE_CANVAS_HEIGHT, }; -export const CITY_PATH_ZONE: DistrictZone = { +export const SHOPPING_ZONE: DistrictZone = { minX: 0, maxX: LOCAL_OFFICE_CANVAS_WIDTH, - minY: 760, - maxY: 980, + minY: 720, + maxY: 1080, }; +export const CITY_PATH_ZONE: DistrictZone = SHOPPING_ZONE; + export const REMOTE_OFFICE_ZONE: DistrictZone = { minX: 0, maxX: LOCAL_OFFICE_CANVAS_WIDTH, - minY: 1020, - maxY: 1020 + LOCAL_OFFICE_CANVAS_HEIGHT, + minY: SHOPPING_ZONE.maxY, + maxY: SHOPPING_ZONE.maxY + LOCAL_OFFICE_CANVAS_HEIGHT, }; export const REMOTE_ROAM_POINTS = [ - { x: 800, y: 1220 }, - { x: 850, y: 1520 }, - { x: 820, y: 1600 }, - { x: 450, y: 1440 }, - { x: 250, y: 1440 }, - { x: 650, y: 1440 }, - { x: 150, y: 1640 }, + { x: 800, y: 1280 }, + { x: 850, y: 1580 }, + { x: 820, y: 1660 }, + { x: 450, y: 1500 }, + { x: 250, y: 1500 }, + { x: 650, y: 1500 }, + { x: 150, y: 1700 }, ] as const; export const DISTRICT_CAMERA_POSITION: [number, number, number] = [14, 16, 18]; diff --git a/src/features/retro-office/core/furnitureDefaults.ts b/src/features/retro-office/core/furnitureDefaults.ts index 1be8a82..af023c1 100644 --- a/src/features/retro-office/core/furnitureDefaults.ts +++ b/src/features/retro-office/core/furnitureDefaults.ts @@ -62,8 +62,8 @@ const DEFAULT_JUKEBOX: FurnitureSeed = { const DEFAULT_SHOP: FurnitureSeed = { type: "shop", - x: 320, - y: 840, + x: 140, + y: 820, facing: 0, }; @@ -117,15 +117,28 @@ const DEFAULT_DINING_ITEMS: FurnitureSeed[] = [ ]; const DEFAULT_SHOPPING_STRIP_ITEMS: FurnitureSeed[] = [ - { type: "table_rect", x: 230, y: 820, w: 110, h: 40, facing: 0 }, - { type: "vending", x: 470, y: 790, facing: 0 }, - { type: "table_rect", x: 670, y: 870, w: 120, h: 40, facing: 0 }, - { type: "plant", x: 210, y: 930 }, - { type: "plant", x: 520, y: 930 }, - { type: "plant", x: 860, y: 930 }, - { type: "couch", x: 1010, y: 820, w: 90, h: 30, facing: 0 }, - { type: "couch", x: 1200, y: 820, w: 90, h: 30, facing: 0 }, - { type: "couch", x: 1390, y: 820, w: 90, h: 30, facing: 0 }, + { type: "table_rect", x: 120, y: 780, w: 120, h: 42, facing: 0 }, + { type: "vending", x: 120, y: 930, facing: 0 }, + { type: "bookshelf", x: 420, y: 780, w: 80, h: 120, facing: 0 }, + { type: "bookshelf", x: 420, y: 930, w: 80, h: 120, facing: 0 }, + { type: "bookshelf", x: 650, y: 780, w: 80, h: 120, facing: 0 }, + { type: "bookshelf", x: 650, y: 930, w: 80, h: 120, facing: 0 }, + { type: "bookshelf", x: 880, y: 780, w: 80, h: 120, facing: 0 }, + { type: "bookshelf", x: 880, y: 930, w: 80, h: 120, facing: 0 }, + { type: "bookshelf", x: 1110, y: 780, w: 80, h: 120, facing: 0 }, + { type: "bookshelf", x: 1110, y: 930, w: 80, h: 120, facing: 0 }, + { type: "bookshelf", x: 1340, y: 780, w: 80, h: 120, facing: 0 }, + { type: "bookshelf", x: 1340, y: 930, w: 80, h: 120, facing: 0 }, + { type: "table_rect", x: 1560, y: 790, w: 120, h: 42, facing: 0 }, + { type: "table_rect", x: 1560, y: 930, w: 120, h: 42, facing: 0 }, + { type: "couch", x: 1490, y: 1010, w: 90, h: 30, facing: 0 }, + { type: "couch", x: 1640, y: 1010, w: 90, h: 30, facing: 0 }, + { type: "plant", x: 300, y: 1030 }, + { type: "plant", x: 560, y: 1030 }, + { type: "plant", x: 790, y: 1030 }, + { type: "plant", x: 1020, y: 1030 }, + { type: "plant", x: 1250, y: 1030 }, + { type: "plant", x: 1480, y: 1030 }, ]; const DEFAULT_SERVER_ROOM_ITEMS: FurnitureSeed[] = [ diff --git a/src/features/retro-office/core/navigation/shopRoute.ts b/src/features/retro-office/core/navigation/shopRoute.ts index 0373681..c395353 100644 --- a/src/features/retro-office/core/navigation/shopRoute.ts +++ b/src/features/retro-office/core/navigation/shopRoute.ts @@ -1,3 +1,4 @@ +import { SHOPPING_ZONE } from "@/features/retro-office/core/district"; import { getItemBaseSize } from "@/features/retro-office/core/geometry"; import type { FacingPoint, @@ -5,9 +6,21 @@ import type { ShopRoute, } from "@/features/retro-office/core/types"; +export const SHOP_ENTRY_TARGET: FacingPoint = { + x: 900, + y: SHOPPING_ZONE.minY + 40, + facing: 0, +}; + +export const SHOP_AISLE_TARGET: FacingPoint = { + x: 980, + y: 910, + facing: 0, +}; + export const SHOP_TARGET: FacingPoint = { - x: 280, - y: 840, + x: 180, + y: 920, facing: 0, }; @@ -18,40 +31,57 @@ export const resolveShopRoute = ( ): ShopRoute => { if (!item) { return { - stage: "counter", + stage: "checkout", targetX: SHOP_TARGET.x, targetY: SHOP_TARGET.y, facing: SHOP_TARGET.facing, }; } const { width, height } = getItemBaseSize(item); - const centerY = item.y + height / 2; - const approachTarget = { + const checkoutTarget = { x: item.x + width / 2, - y: item.y + height + 50, + y: item.y + height + 44, facing: 0, }; - const counterTarget = { - x: item.x + width / 2, - y: centerY, - facing: 0, - }; - - const atCounter = - y <= approachTarget.y + 6 || Math.hypot(x - approachTarget.x, y - approachTarget.y) < 18; - if (atCounter) { + const closeToCheckout = + Math.hypot(x - checkoutTarget.x, y - checkoutTarget.y) < 44; + if (closeToCheckout) { return { - stage: "counter", - targetX: counterTarget.x, - targetY: counterTarget.y, - facing: counterTarget.facing, + stage: "checkout", + targetX: checkoutTarget.x, + targetY: checkoutTarget.y, + facing: checkoutTarget.facing, + }; + } + + const closeToAisle = + y >= SHOPPING_ZONE.minY + 70 && + Math.hypot(x - SHOP_AISLE_TARGET.x, y - SHOP_AISLE_TARGET.y) < 90; + if (closeToAisle) { + return { + stage: "checkout", + targetX: checkoutTarget.x, + targetY: checkoutTarget.y, + facing: checkoutTarget.facing, + }; + } + + const enteredStore = + y >= SHOP_ENTRY_TARGET.y - 10 || + Math.hypot(x - SHOP_ENTRY_TARGET.x, y - SHOP_ENTRY_TARGET.y) < 70; + if (enteredStore) { + return { + stage: "aisle", + targetX: SHOP_AISLE_TARGET.x, + targetY: SHOP_AISLE_TARGET.y, + facing: SHOP_AISLE_TARGET.facing, }; } return { - stage: "approach", - targetX: approachTarget.x, - targetY: approachTarget.y, - facing: approachTarget.facing, + stage: "entrance", + targetX: SHOP_ENTRY_TARGET.x, + targetY: SHOP_ENTRY_TARGET.y, + facing: SHOP_ENTRY_TARGET.facing, }; }; diff --git a/src/features/retro-office/core/types.ts b/src/features/retro-office/core/types.ts index 2419f7e..f993da2 100644 --- a/src/features/retro-office/core/types.ts +++ b/src/features/retro-office/core/types.ts @@ -137,7 +137,7 @@ export type SmsBoothRoute = { }; export type ShopRoute = { - stage: "approach" | "counter"; + stage: "entrance" | "aisle" | "checkout"; targetX: number; targetY: number; facing: number; diff --git a/src/features/retro-office/scene/environment.tsx b/src/features/retro-office/scene/environment.tsx index aec37ba..6900858 100644 --- a/src/features/retro-office/scene/environment.tsx +++ b/src/features/retro-office/scene/environment.tsx @@ -277,11 +277,11 @@ export const FloorAndWalls = memo(function FloorAndWalls({ > - + {Array.from({ length: 8 }).map((_, index) => { @@ -355,8 +355,8 @@ export const FloorAndWalls = memo(function FloorAndWalls({ ); })} - {Array.from({ length: 5 }).map((_, index) => { - const [wx, , wz] = toWorld(220 + index * 280, 785); + {Array.from({ length: 6 }).map((_, index) => { + const [wx, , wz] = toWorld(190 + index * 270, 770); return ( @@ -374,6 +374,44 @@ export const FloorAndWalls = memo(function FloorAndWalls({ ); })} + + {Array.from({ length: 5 }).map((_, index) => { + const [wx, , wz] = toWorld(300 + index * 280, 1010); + return ( + + + + + + + + + + + + + + + ); + })} + + {Array.from({ length: 6 }).map((_, index) => { + const [wx, , wz] = toWorld(360 + index * 230, 905); + return ( + + + + + ); + })} ) : null}