@@ -3,12 +3,7 @@ import { Block, Facing } from "./constants.ts";
33import { printCells } from "./grid.ts" ;
44import { createSnapshot } from "./history.ts" ;
55import * as History from "./history.ts" ;
6- import type {
7- AbilityInit ,
8- Context ,
9- Coords ,
10- MovableObject ,
11- } from "./public-types.ts" ;
6+ import type { AbilityInit , Context , Coords , MovableObject } from "./public-types.ts" ;
127
138export function init ( cx : Context , options ?: AbilityInit ) {
149 cx . state . update ( ( prev ) => ( {
@@ -65,8 +60,7 @@ export function copy(cx: Context) {
6560 const x = focus . x ;
6661 const y = focus . y ;
6762 const target = cx . grid . getBlock ( cx , x , y ) ;
68- if ( ! target || ( target !== Block . movable && target !== Block . fallable ) )
69- return ;
63+ if ( ! target || ( target !== Block . movable && target !== Block . fallable ) ) return ;
7064 const movableObject = cx . grid . getMovableObject ( cx , x , y ) ;
7165 if ( ! movableObject ) return ;
7266
@@ -83,35 +77,19 @@ export function copy(cx: Context) {
8377}
8478export function paste ( cx : Context ) {
8579 const state = get ( cx . state ) ;
86- const { focus } = cx . dynamic ;
80+ const { focus, player } = cx . dynamic ;
8781 const { inventory } = state ;
8882 if ( ! focus ) return ;
8983 if ( ! inventory ) return ;
9084 if ( state . usage . paste <= 0 ) return ;
9185
92- // 左向きのときにブロックを配置する位置を変更するのに使用
93- const width =
94- inventory . relativePositions . reduce ( ( acc , i ) => Math . max ( acc , i . x ) , 0 ) -
95- inventory . relativePositions . reduce ( ( acc , i ) => Math . min ( acc , i . x ) , 1000 ) +
96- 1 ;
97-
98- const facing = cx . dynamic . player . facing ;
99- const x = focus . x - ( facing === Facing . left ? width - 1 : 0 ) ;
100- const y = focus . y ;
101-
102- for ( const i of inventory . relativePositions ) {
103- const positionX = x + i . x ;
104- const positionY = y + i . y ;
105- const target = cx . grid . getBlock ( cx , positionX , positionY ) ;
106- if ( target !== Block . air && target !== Block . switch ) {
107- // すでに何かある場合は、ペーストできない
108- return ;
109- }
86+ const { x, y } = findSafeObjectPlace ( player . facing , focus . x , focus . y , inventory ) ;
87+ if ( ! canPlaceMovableObject ( cx , x , y , inventory ) ) {
88+ return ;
11089 }
111-
11290 History . record ( cx ) ;
11391 placeMovableObject ( cx , x , y , inventory ) ;
114- if ( ! get ( cx . state ) . inventoryIsInfinite ) {
92+ if ( ! state . inventoryIsInfinite ) {
11593 cx . state . update ( ( prev ) => {
11694 prev . inventory = null ;
11795 return prev ;
@@ -129,8 +107,7 @@ export function cut(cx: Context) {
129107 const y = focus . y ;
130108 const target = cx . grid . getBlock ( cx , x , y ) ;
131109 // removable 以外はカットできない
132- if ( ! target || ( target !== Block . movable && target !== Block . fallable ) )
133- return ;
110+ if ( ! target || ( target !== Block . movable && target !== Block . fallable ) ) return ;
134111 const movableObject = cx . grid . getMovableObject ( cx , x , y ) ;
135112 if ( ! movableObject ) return ;
136113
@@ -142,35 +119,47 @@ export function cut(cx: Context) {
142119 } ) ;
143120 cx . grid . update ( cx , ( prev ) => {
144121 if ( prev . objectId !== movableObject . objectId ) return prev ;
145- if (
146- ( prev . block === Block . movable || prev . block === Block . fallable ) &&
147- prev . switchId !== undefined
148- )
122+ if ( ( prev . block === Block . movable || prev . block === Block . fallable ) && prev . switchId !== undefined )
149123 return { block : Block . switch , switchId : prev . switchId } ;
150- return { block : Block . air } ;
124+ return { block : null } ;
151125 } ) ;
152126
153127 printCells ( createSnapshot ( cx ) . game . cells , "cut" ) ;
154128 History . record ( cx ) ;
155129}
156130
157- export function placeMovableObject (
158- cx : Context ,
159- x : number ,
160- y : number ,
161- object : MovableObject ,
162- ) {
163- const grid = cx . grid ;
131+ // 左向きのときにブロックを配置する位置を変更するのに使用
132+ function findSafeObjectPlace ( facing : Facing , x : number , y : number , obj : MovableObject ) {
133+ const width =
134+ obj . relativePositions . reduce ( ( acc , i ) => Math . max ( acc , i . x ) , 0 ) -
135+ obj . relativePositions . reduce ( ( acc , i ) => Math . min ( acc , i . x ) , 1000 ) +
136+ 1 ;
164137
138+ return {
139+ x : x - ( facing === Facing . left ? width - 1 : 0 ) ,
140+ y : y ,
141+ } ;
142+ }
143+ export function canPlaceMovableObject ( cx : Context , x : number , y : number , object : MovableObject ) {
144+ const grid = cx . grid ;
165145 for ( const i of object . relativePositions ) {
166146 const positionX = x + i . x ;
167147 const positionY = y + i . y ;
168148 const target = grid . getBlock ( cx , positionX , positionY ) ;
169- if ( target !== Block . air && target !== Block . switch ) {
149+ if ( target && target !== Block . switch ) {
170150 // すでに何かある場合は、ペーストできない
171- return ;
151+ return false ;
172152 }
173153 }
154+ return true ;
155+ }
156+ export function placeMovableObject ( cx : Context , x : number , y : number , object : MovableObject ) {
157+ const grid = cx . grid ;
158+
159+ if ( ! canPlaceMovableObject ( cx , x , y , object ) ) {
160+ console . error ( "[placeMovableObject] cannot place object" ) ;
161+ return ;
162+ }
174163 for ( const rel of object . relativePositions ) {
175164 const positionX = x + rel . x ;
176165 const positionY = y + rel . y ;
@@ -181,20 +170,3 @@ export function placeMovableObject(
181170 } ) ;
182171 }
183172}
184-
185- export function removeMovableObject (
186- cx : Context ,
187- x : number ,
188- y : number ,
189- ) : MovableObject | undefined {
190- const grid = cx . grid ;
191- const obj = grid . getMovableObject ( cx , x , y ) ;
192- if ( ! obj ) return undefined ;
193-
194- for ( const i of obj . relativePositions ) {
195- const positionX = x + i . x ;
196- const positionY = y + i . y ;
197- grid . setBlock ( cx , positionX , positionY , { block : Block . air } ) ;
198- }
199- return obj ;
200- }
0 commit comments