Dwinzo_dev/app/src/modules/simulation/simulationUI.tsx

381 lines
16 KiB
TypeScript
Raw Normal View History

import { useMemo, useState } from 'react';
import { useSelectedActionSphere, useToggleView, useSimulationPaths, useSelectedPath, useStartSimulation } from '../../store/store';
import * as THREE from 'three';
import useModuleStore from '../../store/useModuleStore';
function SimulationUI() {
const { ToggleView } = useToggleView();
const { activeModule } = useModuleStore();
const { startSimulation, setStartSimulation } = useStartSimulation();
const { selectedActionSphere } = useSelectedActionSphere();
const { selectedPath, setSelectedPath } = useSelectedPath();
const { simulationPaths, setSimulationPaths } = useSimulationPaths();
const handleAddAction = () => {
if (!selectedActionSphere) return;
const newAction = { uuid: THREE.MathUtils.generateUUID(), type: 'Inherit', material: 'Inherit', delay: 'Inherit', spawnInterval: 'Inherit', isUsed: false };
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? { ...point, actions: [...point.actions, newAction] }
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleDeleteAction = (uuid: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? { ...point, actions: point.actions.filter(action => action.uuid !== uuid) }
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleActionSelect = (uuid: string, actionType: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
actions: point.actions.map((action) =>
action.uuid === uuid ? { ...action, type: actionType } : action
),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleMaterialSelect = (uuid: string, material: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
actions: point.actions.map((action) =>
action.uuid === uuid ? { ...action, material } : action
),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleDelayChange = (uuid: string, delay: number | string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
actions: point.actions.map((action) =>
action.uuid === uuid ? { ...action, delay } : action
),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleSpawnIntervalChange = (uuid: string, spawnInterval: number | string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
actions: point.actions.map((action) =>
action.uuid === uuid ? { ...action, spawnInterval } : action
),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleSpeedChange = (speed: number) => {
if (!selectedPath) return;
const updatedPaths = simulationPaths.map((path) =>
path.modeluuid === selectedPath.path.modeluuid ? { ...path, speed } : path
);
setSimulationPaths(updatedPaths);
setSelectedPath({ ...selectedPath, path: { ...selectedPath.path, speed } });
};
const handleAddTrigger = () => {
if (!selectedActionSphere) return;
const newTrigger = { uuid: THREE.MathUtils.generateUUID(), type: '', isUsed: false };
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? { ...point, triggers: [...point.triggers, newTrigger] }
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleDeleteTrigger = (uuid: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? { ...point, triggers: point.triggers.filter(trigger => trigger.uuid !== uuid) }
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleTriggerSelect = (uuid: string, triggerType: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
triggers: point.triggers.map((trigger) =>
trigger.uuid === uuid ? { ...trigger, type: triggerType } : trigger
),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleResetPath = () => {
if (!selectedPath) return;
};
const handleActionToggle = (uuid: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
actions: point.actions.map((action) => ({
...action,
isUsed: action.uuid === uuid ? !action.isUsed : false,
})),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const handleTriggerToggle = (uuid: string) => {
if (!selectedActionSphere) return;
const updatedPaths = simulationPaths.map((path) => ({
...path,
points: path.points.map((point) =>
point.uuid === selectedActionSphere.point.uuid
? {
...point,
triggers: point.triggers.map((trigger) => ({
...trigger,
isUsed: trigger.uuid === uuid ? !trigger.isUsed : false,
})),
}
: point
),
}));
setSimulationPaths(updatedPaths);
};
const selectedPoint = useMemo(() => {
if (!selectedActionSphere) return null;
return simulationPaths.flatMap((path) => path.points).find((point) => point.uuid === selectedActionSphere.point.uuid);
}, [selectedActionSphere, simulationPaths]);
return (
<>
{activeModule === "simulation" && (
<div style={{ zIndex: 10, position: "relative", width: '260px' }}>
{!ToggleView && (
<>
<button
onClick={() => setStartSimulation(!startSimulation)}
style={{
marginTop: "10px",
background: startSimulation ? '#ff320e' : '',
padding: "10px",
borderRadius: "5px"
}}
>
{startSimulation ? 'Stop Simulation' : 'Start Simulation'}
</button>
{selectedPath && (
<div style={{ marginTop: "10px" }}>
<label>Path Speed:</label>
<input
style={{ width: '50px' }}
type="number"
value={selectedPath.path.speed}
min="0.1"
step="0.1"
onChange={(e) => handleSpeedChange(parseFloat(e.target.value))}
/>
</div>
)}
{selectedActionSphere && (
<div style={{ marginTop: "10px" }}>
<button onClick={handleAddAction}>Add Action</button>
<button onClick={handleAddTrigger}>Add Trigger</button>
{selectedPoint?.actions.map((action) => (
<div key={action.uuid} style={{ marginTop: "10px" }}>
<select value={action.type} onChange={(e) => handleActionSelect(action.uuid, e.target.value)}>
<option value="Inherit">Inherit</option>
<option value="Spawn">Spawn Point</option>
<option value="Swap">Swap Material</option>
<option value="Despawn">Despawn Point</option>
<option value="Delay">Delay</option>
</select>
<button onClick={() => handleDeleteAction(action.uuid)}>Delete Action</button>
<label>
<input
type="checkbox"
checked={action.isUsed}
onChange={() => handleActionToggle(action.uuid)}
/>
</label>
{(action.type === 'Spawn' || action.type === 'Swap') && (
<div style={{ marginTop: "10px" }}>
<select value={action.material} onChange={(e) => handleMaterialSelect(action.uuid, e.target.value)}>
<option value="Inherit">Inherit</option>
<option value="Crate">Crate</option>
<option value="Box">Box</option>
</select>
</div>
)}
{action.type === 'Delay' && (
<div style={{ marginTop: "10px" }}>
<label>Delay Time:</label>
<input
style={{ width: '50px' }}
type="text"
value={isNaN(Number(action.delay)) || action.delay === "Inherit" ? "Inherit" : action.delay}
min="1"
onChange={(e) => handleDelayChange(action.uuid, parseInt(e.target.value) || 'Inherit')}
/>
</div>
)}
{action.type === 'Spawn' && (
<div style={{ marginTop: "10px" }}>
<label>Spawn Interval:</label>
<input
style={{ width: '50px' }}
type="text"
value={isNaN(Number(action.spawnInterval)) || action.spawnInterval === "Inherit" ? "Inherit" : action.spawnInterval}
min="1"
onChange={(e) => handleSpawnIntervalChange(action.uuid, parseInt(e.target.value) || 'Inherit')}
/>
</div>
)}
<hr style={{ margin: "10px 0", borderColor: "#ccc" }} />
</div>
))}
<hr style={{ margin: "10px 0", border: "1px solid black" }} />
{selectedPoint?.triggers.map((trigger) => (
<div key={trigger.uuid} style={{ marginTop: "10px" }}>
<select value={trigger.type} onChange={(e) => handleTriggerSelect(trigger.uuid, e.target.value)}>
<option value="">Select Trigger Type</option>
<option value="On-Hit">On Hit</option>
<option value="Buffer">Buffer</option>
</select>
<button onClick={() => handleDeleteTrigger(trigger.uuid)}>Delete Trigger</button>
<label>
<input
type="checkbox"
checked={trigger.isUsed}
onChange={() => handleTriggerToggle(trigger.uuid)}
/>
</label>
<hr style={{ margin: "10px 0", borderColor: "#ccc" }} />
</div>
))}
</div>
)}
{selectedPath && (
<div style={{ marginTop: "10px" }}>
<button
onClick={handleResetPath}
style={{ padding: "10px", borderRadius: "5px", background: "#ff0000", color: "#fff" }}
>
Reset Path
</button>
</div>
)}
</>
)}
</div>
)}
</>
);
}
export default SimulationUI;