diff --git a/src/components/BuildMenu/BuildMenu.tsx b/src/components/BuildMenu/BuildMenu.tsx index 372153c..4ae50de 100644 --- a/src/components/BuildMenu/BuildMenu.tsx +++ b/src/components/BuildMenu/BuildMenu.tsx @@ -11,14 +11,15 @@ import React, { useState } from 'react'; import './BuildMenu.css'; const BuildMenu = ({ - onToggleGridVisibility, - onToggleAxesVisibility, - showGrid, - showAxes, - onSelectAssembler, - onSelectExcavator, - onSelectConveyor, - }) => { + onToggleGridVisibility, + onToggleAxesVisibility, + showGrid, + showAxes, + onSelectAssembler, + onSelectExcavator, + onSelectConveyor, + onSelectDelete, +}) => { const [selected, setSelected] = useState(null); const [isDrawerOpen, setIsDrawerOpen] = useState(false); @@ -58,6 +59,25 @@ const BuildMenu = ({ ); + const DeleteOption = () => ( + <> + + { + setSelected('delete'); + onSelectDelete(); + }} + selected={selected === 'delete'} + > + + + + + + + + ); + const InfrastructureOptions = () => ( <> @@ -122,6 +142,7 @@ const BuildMenu = ({ const BuildingContent = () => ( + diff --git a/src/components/DeleteStructureButton/DeleteStructureButton.tsx b/src/components/DeleteStructureButton/DeleteStructureButton.tsx new file mode 100644 index 0000000..efd32df --- /dev/null +++ b/src/components/DeleteStructureButton/DeleteStructureButton.tsx @@ -0,0 +1,17 @@ +import DeleteIcon from '@mui/icons-material/Delete'; +import { Fab } from '@mui/material'; +import React from 'react'; + +interface DeleteStructureButtonProps { + onDeleteStructure: () => void; +} + +const DeleteStructureButton: React.FC = ({ onDeleteStructure }) => { + return ( + + + + ); +}; + +export { DeleteStructureButton }; diff --git a/src/components/Grid/Grid.css b/src/components/Grid/Grid.css index 2b00f55..038b8c2 100644 --- a/src/components/Grid/Grid.css +++ b/src/components/Grid/Grid.css @@ -32,4 +32,11 @@ canvas { z-index: 1000; right: 0; margin: 230px 16px 0 0 !important; +} + +.delete-structure-button { + position: absolute !important; + z-index: 1000; + right: 0; + margin: 300px 16px 0 0 !important; } \ No newline at end of file diff --git a/src/components/Grid/Grid.tsx b/src/components/Grid/Grid.tsx index 00329b1..6b097ca 100644 --- a/src/components/Grid/Grid.tsx +++ b/src/components/Grid/Grid.tsx @@ -20,13 +20,13 @@ const CELL_SIZE = GRID_SIZE / GRID_DIVISIONS; interface GridProps { size: number; - selectedZone: { type: string | null; density: string | null }; + selectedBuilding: { type: string | null }; currentSelected: { x: number; y: number } | null; setCurrentSelected: React.Dispatch>; map: string[][]; // Add map as a prop } -const Grid: React.FC = ({ selectedZone, currentSelected, map }) => { +const Grid: React.FC = ({ selectedBuilding, currentSelected, map }) => { const [cells, setCells] = useState(() => { const initialCells = []; for (let i = 0; i < GRID_DIVISIONS; i++) { @@ -35,7 +35,6 @@ const Grid: React.FC = ({ selectedZone, currentSelected, map }) => { x: j * CELL_SIZE - GRID_SIZE / 2, y: i * CELL_SIZE - GRID_SIZE / 2, type: map[i][j], - density: null, building: null, }); } @@ -50,7 +49,7 @@ const Grid: React.FC = ({ selectedZone, currentSelected, map }) => { const handleMouseDown = (x: number, y: number, event: ThreeEvent) => { if (event.nativeEvent.button !== 0) return; // Ensure it is a left-click - if (selectedZone.type === 'conveyor') { + if (selectedBuilding.type === 'conveyor') { setIsDragging(true); setDragStart({ x, y }); } else { @@ -59,7 +58,7 @@ const Grid: React.FC = ({ selectedZone, currentSelected, map }) => { }; const handleMouseEnter = (x: number, y: number) => { - if (isDragging && selectedZone.type === 'conveyor') { + if (isDragging && selectedBuilding.type === 'conveyor') { updateTempCells(x, y); } setHoveredCell({ x, y }); @@ -67,7 +66,7 @@ const Grid: React.FC = ({ selectedZone, currentSelected, map }) => { const handleMouseUp = (event: ThreeEvent) => { if (event.nativeEvent.button !== 0) return; // Ensure it is a left-click - if (isDragging && selectedZone.type === 'conveyor') { + if (isDragging && selectedBuilding.type === 'conveyor') { setCells(tempCells); } setIsDragging(false); @@ -77,13 +76,31 @@ const Grid: React.FC = ({ selectedZone, currentSelected, map }) => { const handleMouseClick = (x: number, y: number, event: ThreeEvent) => { if (event.nativeEvent.button !== 0) return; // Ensure it is a left-click - if (selectedZone.type && selectedZone.type !== 'conveyor') { + if (selectedBuilding.type === 'delete') { + handleDeleteClick(x, y); + } else if (selectedBuilding.type && selectedBuilding.type !== 'conveyor') { if (validatePlacement(x, y)) { updateCells(x, y); } } }; + const handleDeleteClick = (x: number, y: number) => { + const newCells = cells.map(cell => { + if (cell.x === x && cell.y === y && cell.building) { + return { + ...cell, + type: 'grass', // Revert to grass + building: null, + }; + } + return cell; + }); + + setCells(newCells); + setTempCells(newCells); // Ensure tempCells are updated to reflect the deletion + }; + const validatePlacement = (x: number, y: number) => { // Check if the entire 2x2 area is valid and empty for (let i = 0; i < 2; i++) { @@ -99,16 +116,13 @@ const Grid: React.FC = ({ selectedZone, currentSelected, map }) => { const updateCells = (x: number, y: number) => { const newCells = cells.map(cell => { - if (selectedZone.type !== 'conveyor') { - const within2x2 = (cell.x >= x && cell.x < x + 2 * CELL_SIZE) && (cell.y >= y && cell.y < y + 2 * CELL_SIZE); - if (within2x2) { - return { - ...cell, - type: selectedZone.type, - density: selectedZone.density, - building: selectedZone.type, - }; - } + const within2x2 = (cell.x >= x && cell.x < x + 2 * CELL_SIZE) && (cell.y >= y && cell.y < y + 2 * CELL_SIZE); + if (within2x2) { + return { + ...cell, + type: selectedBuilding.type, + building: selectedBuilding.type, + }; } return cell; }); @@ -126,16 +140,15 @@ const Grid: React.FC = ({ selectedZone, currentSelected, map }) => { const yMax = Math.max(dragStart.y, y); const newTempCells = cells.map(cell => { - if (selectedZone.type === 'conveyor') { + if (selectedBuilding.type === 'conveyor') { // Allow conveyors only in straight lines if (dragStart.x === x) { // Vertical line if (cell.x === dragStart.x && cell.y >= yMin && cell.y <= yMax) { return { ...cell, - type: selectedZone.type, - density: selectedZone.density, - building: selectedZone.type, + type: selectedBuilding.type, + building: selectedBuilding.type, }; } } else if (dragStart.y === y) { @@ -143,9 +156,8 @@ const Grid: React.FC = ({ selectedZone, currentSelected, map }) => { if (cell.y === dragStart.y && cell.x >= xMin && cell.x <= xMax) { return { ...cell, - type: selectedZone.type, - density: selectedZone.density, - building: selectedZone.type, + type: selectedBuilding.type, + building: selectedBuilding.type, }; } } @@ -208,7 +220,7 @@ const Grid: React.FC = ({ selectedZone, currentSelected, map }) => { return ( <> - {hoveredCell && selectedZone.type !== 'conveyor' && selectedZone.type && ( + {hoveredCell && selectedBuilding.type !== 'conveyor' && selectedBuilding.type !== 'delete' && selectedBuilding.type && ( >; map: string[][]; @@ -17,7 +17,7 @@ interface GridAndAxesProps { const GridAndAxes: React.FC = ({ showGrid, showAxes, - selectedZone, + selectedBuilding, currentSelected, setCurrentSelected, map, @@ -28,7 +28,7 @@ const GridAndAxes: React.FC = ({ {showAxes && } { const [showGrid, setShowGrid] = useState(true); const [showAxes, setShowAxes] = useState(false); - const [selectedZone, setSelectedZone] = useState<{ type: string | null; density: string | null }>({ + const [selectedBuilding, setSelectedBuilding] = useState<{ type: string | null }>({ type: null, - density: null, }); const [currentSelected, setCurrentSelected] = useState<{ x: number; y: number } | null>(null); const [map] = useState(generateRandomMap(GRID_DIVISIONS)); const toggleGridVisibility = () => setShowGrid(!showGrid); const toggleAxesVisibility = () => setShowAxes(!showAxes); - const handleSelectAssembler = (level: number) => setSelectedZone({ type: `assembler${level}`, density: null }); - const handleSelectExcavator = (level: number) => setSelectedZone({ type: `excavator${level}`, density: null }); - const handleSelectConveyor = () => setSelectedZone({ type: 'conveyor', density: null }); + const handleSelectAssembler = (level: number) => setSelectedBuilding({ type: `assembler${level}` }); + const handleSelectExcavator = (level: number) => setSelectedBuilding({ type: `excavator${level}` }); + const handleSelectConveyor = () => setSelectedBuilding({ type: 'conveyor' }); + const handleDeleteStructure = () => setSelectedBuilding({ type: 'delete' }); const orbitControlsRef = useRef(null); const cameraRef = useRef(null); @@ -55,6 +55,7 @@ const RenderGrid: React.FC = () => { onSelectAssembler={handleSelectAssembler} onSelectExcavator={handleSelectExcavator} onSelectConveyor={handleSelectConveyor} + onSelectDelete={handleDeleteStructure} showGrid={showGrid} showAxes={showAxes} /> @@ -70,7 +71,7 @@ const RenderGrid: React.FC = () => {