Skip to content

Commit

Permalink
add tile replace tool
Browse files Browse the repository at this point in the history
  • Loading branch information
hlorenzi committed Sep 20, 2023
1 parent 7040410 commit c487ead
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 2 deletions.
8 changes: 7 additions & 1 deletion src/data/editors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ export interface Global
export const LAYERDEF_ID_MAP = "world"


export type Tool = "move" | "draw" | "fill" | "erase" | "select"
export type Tool =
"move" |
"draw" |
"fill" |
"replace" |
"erase" |
"select"


export type Editor =
Expand Down
13 changes: 13 additions & 0 deletions src/data/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,19 @@ export function *enumerateTileFieldCellsCentered(tileField: TileField): Generato
}


export function getTile(
layer: LayerTile,
cell: { x: number, y: number })
: Tile | undefined
{
const cellIndex = getTileFieldCellIndexForCell(layer.tileField, cell)
if (cellIndex === undefined)
return undefined

return layer.tileField.tiles[cellIndex]
}


export function setTile(
layer: LayerTile,
cell: { x: number, y: number },
Expand Down
5 changes: 5 additions & 0 deletions src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ export function useKeyboardShortcuts()
global.editors.mapEditing.tool = "fill"
global.editors.refreshToken.commit()
break

case "r":
global.editors.mapEditing.tool = "replace"
global.editors.refreshToken.commit()
break

case "e":
global.editors.mapEditing.tool = "erase"
Expand Down
84 changes: 84 additions & 0 deletions src/mapEditor/action_tileReplace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import * as MapEditor from "./index"
import * as ID from "../data/id"
import * as Defs from "../data/defs"
import * as Map from "../data/map"
import * as Editors from "../data/editors"
import { global } from "../global"


export function setupTileReplace(state: MapEditor.State)
{
const editor = (global.editors.editors[state.editorIndex] as Editors.EditorMap)
const tileStamp = global.editors.mapEditing.tileStamp
const brush = Defs.getTileBrushDef(editor.defs, global.editors.mapEditing.tileBrushDefId)


let lastPlacedTile = { x: -100000, y: -100000 }
let drawnMultiple = false

state.rectSelection = null

state.onMouseMove = () =>
{
editor.map = Map.ensureRoomLayer(
editor.defs,
editor.map,
state.roomId,
global.editors.mapEditing.layerDefId)

let layer = Map.getRoomLayer(
editor.map,
state.roomId,
global.editors.mapEditing.layerDefId)

if (!layer || layer.type !== "tile")
return

const layerDef = Defs.getLayerDef(editor.defs, layer.layerDefId)
if (!layerDef || layerDef.type !== "tile")
return


if (!brush)
{
if (state.toolMoveWithoutSnap &&
Math.abs(state.mouse.tile.x - lastPlacedTile.x) < tileStamp.width &&
Math.abs(state.mouse.tile.y - lastPlacedTile.y) < tileStamp.height)
return

for (const cell of Map.enumerateTileFieldCellsCentered(tileStamp))
{
const mouseCell = {
x: state.mouse.tile.x + cell.x,
y: state.mouse.tile.y + cell.y,
}

const originalTile = Map.getTile(layer, mouseCell)

for (const replaceCell of Map.enumerateTileFieldCells(layer.tileField))
{
const replaceTile = Map.getTile(layer, replaceCell)

const isSameTile =
(originalTile === undefined &&
replaceTile === undefined) ||
(originalTile?.tilesetDefId === replaceTile?.tilesetDefId &&
originalTile?.tileId === replaceTile?.tileId)

if (isSameTile)
layer = Map.setTile(layer, replaceCell, cell.tile)
}

layer = Map.setTile(layer, mouseCell, cell.tile)
}
}

lastPlacedTile = state.mouse.tile

editor.map = Map.setRoomLayer(
editor.map,
state.roomId,
global.editors.mapEditing.layerDefId,
layer)
}
}
1 change: 1 addition & 0 deletions src/mapEditor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from "./action_roomDraw"
export * from "./action_roomSelect"
export * from "./action_tileDraw"
export * from "./action_tileFill"
export * from "./action_tileReplace"
export * from "./action_tileErase"
export * from "./action_tileSelect"
export * from "./action_objectMove"
Expand Down
3 changes: 2 additions & 1 deletion src/mapEditor/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,8 @@ export function renderTileLayerForeground(
editingLayerDef.gridCellHeight)

if ((global.editors.mapEditing.tool === "draw" ||
global.editors.mapEditing.tool === "fill") &&
global.editors.mapEditing.tool === "fill" ||
global.editors.mapEditing.tool === "replace") &&
!state.onMouseMove)
{
state.ctx.save()
Expand Down
3 changes: 3 additions & 0 deletions src/mapEditor/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,9 @@ export function onMouseDown(state: State, ev: MouseEvent)
else if (global.editors.mapEditing.tool === "fill")
MapEditor.setupTileFill(state)

else if (global.editors.mapEditing.tool === "replace")
MapEditor.setupTileReplace(state)

else if (global.editors.mapEditing.tool === "erase")
MapEditor.setupTileErase(state)

Expand Down
6 changes: 6 additions & 0 deletions src/panels/EditorMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ export function EditorMap(props: {
onClick={ () => chooseTool("fill") }
/>

<UI.Button
label="💱 Replace (R)"
selected={ global.editors.mapEditing.tool === "replace" }
onClick={ () => chooseTool("replace") }
/>

<UI.Button
label="❌ Erase (E)"
selected={ global.editors.mapEditing.tool === "erase" }
Expand Down

0 comments on commit c487ead

Please sign in to comment.