fix: make replace blocks feature acknowledge selection
This commit is contained in:
parent
ee02e1ae47
commit
5e01bb4318
3 changed files with 27 additions and 14 deletions
|
|
@ -21,6 +21,7 @@ import CanvasBorder from "./CanvasBorder";
|
||||||
import CursorInformation from "./information/Cursor";
|
import CursorInformation from "./information/Cursor";
|
||||||
import CanvasInformation from "./information/Canvas";
|
import CanvasInformation from "./information/Canvas";
|
||||||
import SelectionToolbar from "./SelectionToolbar";
|
import SelectionToolbar from "./SelectionToolbar";
|
||||||
|
import { isInSelection } from "@/utils/selection";
|
||||||
|
|
||||||
// Set scale mode to NEAREST
|
// Set scale mode to NEAREST
|
||||||
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
|
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
|
||||||
|
|
@ -106,14 +107,6 @@ function Canvas() {
|
||||||
return { x, y };
|
return { x, y };
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if a block is within the selection
|
|
||||||
const isInSelection = (x: number, y: number): boolean => {
|
|
||||||
if (selectionCoords.length !== 0) {
|
|
||||||
return selectionCoords.some(([x2, y2]) => x2 === x && y2 === y);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const eraseTool = () => {
|
const eraseTool = () => {
|
||||||
// Fixes Infinity and NaN errors when no blocks are present
|
// Fixes Infinity and NaN errors when no blocks are present
|
||||||
if (blocks.length == 1) return;
|
if (blocks.length == 1) return;
|
||||||
|
|
@ -122,7 +115,7 @@ function Canvas() {
|
||||||
const updated = blocks.filter((block) => {
|
const updated = blocks.filter((block) => {
|
||||||
const withinRadius =
|
const withinRadius =
|
||||||
block.x >= radiusPosition.x && block.x < radiusPosition.x + radius && block.y >= radiusPosition.y && block.y < radiusPosition.y + radius;
|
block.x >= radiusPosition.x && block.x < radiusPosition.x + radius && block.y >= radiusPosition.y && block.y < radiusPosition.y + radius;
|
||||||
return !withinRadius || !isInSelection(block.x, block.y);
|
return !withinRadius || !isInSelection(selectionCoords, block.x, block.y);
|
||||||
});
|
});
|
||||||
|
|
||||||
setBlocks(updated);
|
setBlocks(updated);
|
||||||
|
|
@ -139,7 +132,7 @@ function Canvas() {
|
||||||
|
|
||||||
setBlocks((prev) =>
|
setBlocks((prev) =>
|
||||||
prev.filter((b) => {
|
prev.filter((b) => {
|
||||||
const isSelected = selectionCoords.some(([x, y]) => b.x === x && b.y === y);
|
const isSelected = isInSelection(selectionCoords, b.x, b.y);
|
||||||
|
|
||||||
// Add blocks in the selection coords to the selection layer
|
// Add blocks in the selection coords to the selection layer
|
||||||
if (isSelected) result.push(b);
|
if (isSelected) result.push(b);
|
||||||
|
|
@ -194,7 +187,7 @@ function Canvas() {
|
||||||
const tileY = radiusPosition.y + y;
|
const tileY = radiusPosition.y + y;
|
||||||
|
|
||||||
// Only add blocks within the selection
|
// Only add blocks within the selection
|
||||||
if (isInSelection(tileX, tileY)) {
|
if (isInSelection(selectionCoords, tileX, tileY)) {
|
||||||
radiusBlocks.push({
|
radiusBlocks.push({
|
||||||
name: selectedBlock,
|
name: selectedBlock,
|
||||||
x: tileX,
|
x: tileX,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { useContext, useEffect, useState } from "react";
|
||||||
import { Container, Sprite, Stage } from "@pixi/react";
|
import { Container, Sprite, Stage } from "@pixi/react";
|
||||||
|
|
||||||
import { CanvasContext } from "@/context/Canvas";
|
import { CanvasContext } from "@/context/Canvas";
|
||||||
|
import { SelectionContext } from "@/context/Selection";
|
||||||
import { ToolContext } from "@/context/Tool";
|
import { ToolContext } from "@/context/Tool";
|
||||||
import { TexturesContext } from "@/context/Textures";
|
import { TexturesContext } from "@/context/Textures";
|
||||||
|
|
||||||
|
|
@ -9,9 +10,11 @@ import { Label } from "@/components/ui/label";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
|
||||||
import { useTextures } from "@/hooks/useTextures";
|
import { useTextures } from "@/hooks/useTextures";
|
||||||
|
import { isInSelection } from "@/utils/selection";
|
||||||
|
|
||||||
function Replace() {
|
function Replace() {
|
||||||
const { version, setBlocks } = useContext(CanvasContext);
|
const { version, setBlocks } = useContext(CanvasContext);
|
||||||
|
const { coords: selectionCoords } = useContext(SelectionContext);
|
||||||
const { selectedBlock, tool, setTool } = useContext(ToolContext);
|
const { selectedBlock, tool, setTool } = useContext(ToolContext);
|
||||||
const { missingTexture } = useContext(TexturesContext);
|
const { missingTexture } = useContext(TexturesContext);
|
||||||
|
|
||||||
|
|
@ -30,9 +33,19 @@ function Replace() {
|
||||||
|
|
||||||
const onClickReplace = () => {
|
const onClickReplace = () => {
|
||||||
// If block2 name is air, delete the block instead.
|
// If block2 name is air, delete the block instead.
|
||||||
setBlocks((prevBlocks) =>
|
setBlocks((prev) =>
|
||||||
prevBlocks
|
prev
|
||||||
.map((block) => (block.name === block1 ? (block2 === "air" ? null : { ...block, name: block2 }) : block))
|
.map((block) => {
|
||||||
|
if (isInSelection(selectionCoords, block.x, block.y)) {
|
||||||
|
if (block.name === block1) {
|
||||||
|
// If block2 is air, return null
|
||||||
|
// If not, change the block name
|
||||||
|
return block2 === "air" ? null : { ...block, name: block2 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return block;
|
||||||
|
})
|
||||||
|
// Remove all blocks that are null
|
||||||
.filter((block) => block !== null)
|
.filter((block) => block !== null)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
7
src/utils/selection.ts
Normal file
7
src/utils/selection.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
// Check if a block is within the selection
|
||||||
|
export const isInSelection = (selection: CoordinateArray, x: number, y: number): boolean => {
|
||||||
|
if (selection.length !== 0) {
|
||||||
|
return selection.some(([x2, y2]) => x2 === x && y2 === y);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
Loading…
Reference in a new issue