import React, { useState, useEffect, useRef } from "react"; import GameDataManager from "../../../services/GameDataManager.js"; import "./DungeonScreen.css"; import DungeonFinish from "../tabs/components/DungeonFinish.jsx"; const DungeonScreen = ({ session, socket }) => { const [roomData, setRoomData] = useState(session.room); const [roomIndex, setRoomIndex] = useState(session.roomIndex); const [battle, setBattle] = useState(session.battle || null); const [timeLeft, setTimeLeft] = useState(10); const [summary, setSummary] = useState(null); const [activeAttacker, setActiveAttacker] = useState(null); const [selectedTarget, setSelectedTarget] = useState(null); const [log, setLog] = useState([ "SYSTEM: Neural link established. Scanning sector...", ]); const logEndRef = useRef(null); const timerRef = useRef(null); const dungeonData = GameDataManager.getDungeon(session.dungeonId); useEffect(() => { logEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [log]); useEffect(() => { setSelectedTarget(null); }, [battle?.currentTurnIndex]); useEffect(() => { if (!battle || battle.isOver || activeAttacker) return; const isPlayer = battle.turnOrder[battle.currentTurnIndex] === "player"; const maxTime = isPlayer ? 10 : 4; setTimeLeft(maxTime); if (timerRef.current) clearInterval(timerRef.current); timerRef.current = setInterval(() => { setTimeLeft((prev) => { if (prev <= 1) { if (isPlayer) handleCombatAction(); return 0; } return prev - 1; }); }, 1000); return () => clearInterval(timerRef.current); }, [battle?.currentTurnIndex, battle?.isOver, activeAttacker]); useEffect(() => { socket.on("dungeon:room_update", (data) => { setRoomData(data.room); setRoomIndex(data.roomIndex); setBattle(data.battle); addLog(`--- ENTERING SECTOR ${data.roomIndex + 1} ---`); }); socket.on("dungeon:failed", (data) => { addLog(`--- TERMINAL ERROR: ${data.message} ---`); setTimeout(() => window.location.reload(), 3000); }); socket.on("dungeon:battle_update", async (data) => { const turnOrder = data.battle.turnOrder; const lastIndex = (data.battle.currentTurnIndex - 1 + turnOrder.length) % turnOrder.length; const lastActorId = turnOrder[lastIndex]; if (lastActorId !== "player" && !data.battle.isOver) { setActiveAttacker(lastActorId); await new Promise((resolve) => setTimeout(resolve, 2000)); setBattle(data.battle); if (data.log) data.log.forEach((msg) => addLog(msg)); setActiveAttacker(null); } else { setBattle(data.battle); if (data.log) data.log.forEach((msg) => addLog(msg)); setActiveAttacker(null); } if (data.status === "victory") addLog("MISSION_OBJECTIVE: Threats neutralized."); if (data.status === "defeat") { addLog("CRITICAL_ERROR: Bio-sign lost."); setTimeout(() => window.location.reload(), 3000); } }); socket.on("dungeon:completed", (data) => { setSummary(data.rewards); addLog("MISSION_SUCCESS: All objectives secured."); }); return () => { socket.off("dungeon:room_update"); socket.off("dungeon:battle_update"); socket.off("dungeon:completed"); socket.off("dungeon:failed"); }; }, [socket]); const addLog = (text) => { const time = new Date().toLocaleTimeString([], { hour12: false, hour: "2-digit", minute: "2-digit", second: "2-digit", }); setLog((prev) => [...prev, `[${time}] ${text}`]); }; const handleCombatAction = () => { const targetId = selectedTarget; if (!battle || battle.isOver || activeAttacker || !targetId) return; if (battle.turnOrder[battle.currentTurnIndex] !== "player") return; socket.emit("dungeon:combat_action", { targetInstanceId: targetId }); addLog(`Initiating strike sequence...`); setSelectedTarget(null); // Скидаємо вибір після атаки }; const handleNextRoom = () => { socket.emit("dungeon:next_room"); }; const isPlayerTurn = battle?.turnOrder[battle?.currentTurnIndex] === "player"; return (
AREA SECURE