674 lines
31 KiB
C#
674 lines
31 KiB
C#
/*
|
|
╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
|
|
║ ║
|
|
║ HERNÍ MECHANIKY - UnityTestClient_Game.cs ║
|
|
║ ║
|
|
║ Tento soubor obsahuje veškeré herní mechaniky: ║
|
|
║ • Pohyb hráče (WASD + myš) ║
|
|
║ • Interakce (úkoly, reporty, opravy) ║
|
|
║ • Kill mechanika (pro impostory) ║
|
|
║ • Sabotáže a jejich opravy ║
|
|
║ • Emergency meeting ║
|
|
║ • Hlasování ║
|
|
║ ║
|
|
║ OVLÁDÁNÍ: ║
|
|
║ • WASD - pohyb hráče ║
|
|
║ • Myš - otáčení kamery (volitelné) ║
|
|
║ • E - interakce (úkoly, report, oprava) ║
|
|
║ • Q - kill (pouze impostor) ║
|
|
║ • Tab - mapa/statistiky ║
|
|
║ • Escape - menu ║
|
|
║ ║
|
|
║ SYSTÉM ÚKOLŮ: ║
|
|
║ • Všechny úkoly jsou INSTANT - stačí přijít na místo (do 5m) a stisknout E ║
|
|
║ • Server validuje pozici hráče - nemůžete dokončit úkol na dálku ║
|
|
║ • Duchové (mrtví crew) mohou dokončovat úkoly - pomáhají týmu vyhrát ║
|
|
║ • Impostoři NEMOHOU dokončovat úkoly ║
|
|
║ ║
|
|
║ SABOTÁŽE: ║
|
|
║ • CommsBlackout - blokuje reporty a emergency meetings ║
|
|
║ - 1 opravná stanice, libovolný hráč opraví sám ║
|
|
║ • CriticalMeltdown - časový limit na opravu! ║
|
|
║ - 2 stanice musí být opravovány SOUČASNĚ dvěma hráči ║
|
|
║ - Pokud čas vyprší, impostoři vyhrávají ║
|
|
║ ║
|
|
║ POZNÁMKA: ║
|
|
║ V reálné mobilní hře by se pozice hráče aktualizovala podle GPS (Input.location). ║
|
|
║ Tento test klient umožňuje simulovat pohyb pomocí WASD pro testování. ║
|
|
║ ║
|
|
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
|
|
*/
|
|
|
|
using UnityEngine;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using GeoSus.Client;
|
|
|
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
// LOKÁLNÍ TYPY PRO UNITY (kopie z Protocol.cs pro kompatibilitu)
|
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
/// <summary>
|
|
/// Reprezentace úkolu hráče
|
|
/// </summary>
|
|
[System.Serializable]
|
|
public class PlayerTask
|
|
{
|
|
public string Id;
|
|
public string Name;
|
|
public string Description;
|
|
public TaskType Type;
|
|
public Position Location;
|
|
public bool IsCompleted;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Opravná stanice pro sabotáže
|
|
/// </summary>
|
|
[System.Serializable]
|
|
public class RepairStation
|
|
{
|
|
public string Id;
|
|
public string Name;
|
|
public Position Position;
|
|
public bool IsActive;
|
|
}
|
|
|
|
public partial class UnityTestClient
|
|
{
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// GAME PROMĚNNÉ
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
// Pohyb
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>Rychlost pohybu hráče (Unity jednotky/s)</summary>
|
|
protected float moveSpeed = 10f;
|
|
|
|
/// <summary>Aktuální pozice hráče v Unity souřadnicích</summary>
|
|
protected Vector3 currentPlayerPosition;
|
|
|
|
/// <summary>Interval odesílání pozice na server (sekundy)</summary>
|
|
protected float positionUpdateInterval = 0.5f;
|
|
|
|
/// <summary>Čas posledního odeslání pozice</summary>
|
|
protected float lastPositionUpdate;
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
// Opravy
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>Právě opravujeme?</summary>
|
|
protected bool isRepairing = false;
|
|
|
|
/// <summary>ID aktivní opravné stanice</summary>
|
|
protected string activeRepairStation = null;
|
|
|
|
/// <summary>Progress opravy (0-1)</summary>
|
|
protected float repairProgress = 0f;
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
// Sabotáže
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>Aktuální sabotáž (null = žádná)</summary>
|
|
protected SabotageStartedPayload currentSabotage = null;
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
// Kill
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>Cooldown killu (sekundy)</summary>
|
|
protected float killCooldown = 25f;
|
|
|
|
/// <summary>Čas posledního killu</summary>
|
|
protected float lastKillTime = -100f;
|
|
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
// Konec hry
|
|
// ─────────────────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>Data o konci hry</summary>
|
|
protected GameEndedPayload gameEndData = null;
|
|
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// POHYB HRÁČE
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Zpracování vstupu hráče.
|
|
/// Volá se každý frame v Update().
|
|
///
|
|
/// POZNÁMKA PRO STUDENTY:
|
|
/// Input.GetAxis vrací hodnotu -1 až 1 pro plynulý pohyb.
|
|
/// "Horizontal" = A/D nebo šipky vlevo/vpravo
|
|
/// "Vertical" = W/S nebo šipky nahoru/dolů
|
|
/// </summary>
|
|
protected void HandlePlayerInput()
|
|
{
|
|
// Pohyb pouze během hraní
|
|
if (currentState != AppState.InGame) return;
|
|
|
|
// Kontrola, zda jsme naživu - bezpečný přístup
|
|
if (client?.PlayerPositions != null &&
|
|
client.PlayerPositions.TryGetValue(clientUuid, out var myInfo))
|
|
{
|
|
if (myInfo.State != PlayerState.Alive)
|
|
{
|
|
// Duch může létat, ale neposílá pozici
|
|
HandleGhostMovement();
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Kontrola, zda není meeting - ale během arrival fáze se můžeme hýbat
|
|
var phase = client?.CurrentLobbyState?.Phase;
|
|
if (phase == GamePhase.Meeting)
|
|
{
|
|
// Během arrival fáze (před ArrivalDeadline) se můžeme hýbat
|
|
if (currentMeeting != null && DateTime.UtcNow < currentMeeting.ArrivalDeadline)
|
|
{
|
|
// OK - můžeme se hýbat k meeting pointu
|
|
}
|
|
else
|
|
{
|
|
return; // Po arrival deadline se nehýbeme
|
|
}
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// WASD POHYB
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
float horizontal = Input.GetAxis("Horizontal"); // A/D
|
|
float vertical = Input.GetAxis("Vertical"); // W/S
|
|
|
|
if (horizontal != 0 || vertical != 0)
|
|
{
|
|
// Směr pohybu
|
|
Vector3 movement = new Vector3(horizontal, 0, vertical).normalized;
|
|
|
|
// Aplikace rychlosti a delta time
|
|
Vector3 newPosition = currentPlayerPosition + movement * moveSpeed * Time.deltaTime;
|
|
|
|
// Kontrola hranic herní oblasti
|
|
if (IsPositionInPlayArea(newPosition))
|
|
{
|
|
currentPlayerPosition = newPosition;
|
|
UpdateCameraPosition();
|
|
}
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// ODESÍLÁNÍ POZICE NA SERVER
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
if (Time.time - lastPositionUpdate >= positionUpdateInterval)
|
|
{
|
|
SendPositionToServer();
|
|
lastPositionUpdate = Time.time;
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// KLÁVESOVÉ ZKRATKY PRO AKCE
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
// E - Interakce (USE)
|
|
if (Input.GetKeyDown(KeyCode.E))
|
|
{
|
|
PerformPrimaryAction();
|
|
}
|
|
|
|
// Q - Kill (pouze impostor)
|
|
if (Input.GetKeyDown(KeyCode.Q) && client?.MyRole == PlayerRole.Impostor)
|
|
{
|
|
TryKillNearbyPlayer();
|
|
}
|
|
|
|
// R - Emergency meeting
|
|
if (Input.GetKeyDown(KeyCode.R))
|
|
{
|
|
CallEmergencyMeeting();
|
|
}
|
|
|
|
// Escape - Menu
|
|
if (Input.GetKeyDown(KeyCode.Escape))
|
|
{
|
|
// TODO: Toggle pause menu
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pohyb ducha (mrtvý hráč)
|
|
/// </summary>
|
|
private void HandleGhostMovement()
|
|
{
|
|
float horizontal = Input.GetAxis("Horizontal");
|
|
float vertical = Input.GetAxis("Vertical");
|
|
|
|
if (horizontal != 0 || vertical != 0)
|
|
{
|
|
Vector3 movement = new Vector3(horizontal, 0, vertical).normalized;
|
|
currentPlayerPosition += movement * moveSpeed * 1.5f * Time.deltaTime; // Duch je rychlejší
|
|
UpdateCameraPosition();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Kontrola, zda je pozice v hrací oblasti
|
|
/// </summary>
|
|
private bool IsPositionInPlayArea(Vector3 position)
|
|
{
|
|
// Vzdálenost od středu
|
|
float distance = Vector3.Distance(position, Vector3.zero);
|
|
return distance <= (float)mapRadius;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aktualizace pozice kamery podle hráče
|
|
/// </summary>
|
|
private void UpdateCameraPosition()
|
|
{
|
|
if (playerCamera == null) return;
|
|
|
|
// Top-down kamera následuje hráče
|
|
Vector3 cameraPos = currentPlayerPosition;
|
|
cameraPos.y = cameraHeight;
|
|
playerCamera.transform.position = cameraPos;
|
|
|
|
// Aktualizace lokálního hráče vizuálu
|
|
UpdateLocalPlayerVisual();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Inicializace pozice hráče při startu hry
|
|
/// </summary>
|
|
protected void InitializePlayerPosition()
|
|
{
|
|
// Nastavíme hráče na střed mapy
|
|
currentPlayerPosition = Vector3.zero;
|
|
UpdateCameraPosition();
|
|
Debug.Log("[GeoSus] Pozice hráče inicializována na střed mapy");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Odeslání pozice hráče na server
|
|
/// </summary>
|
|
private void SendPositionToServer()
|
|
{
|
|
if (client == null || !client.IsConnected) return;
|
|
|
|
// Převod na GPS
|
|
Position gpsPosition = UnityToGPS(currentPlayerPosition);
|
|
|
|
// Odeslání
|
|
client.UpdatePosition(gpsPosition);
|
|
}
|
|
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// INTERAKCE
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Provede primární akci (USE/REPORT/REPAIR)
|
|
/// </summary>
|
|
protected void PerformPrimaryAction()
|
|
{
|
|
if (client == null) return;
|
|
|
|
// Kontrola stavu hráče - bezpečný přístup
|
|
if (client.PlayerPositions != null && client.PlayerPositions.TryGetValue(clientUuid, out var myState))
|
|
{
|
|
if (myState.State != PlayerState.Alive)
|
|
{
|
|
ShowNotification("Jsi mrtvý!", Color.gray, 2f, "💀");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// PRIORITA 1: Report těla
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
var body = client.FindNearbyBody(5.0);
|
|
if (body != null)
|
|
{
|
|
// Použijeme přímo BodyId property
|
|
ReportBody(body.BodyId);
|
|
return;
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// PRIORITA 2: Oprava stanice
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
if (currentSabotage != null)
|
|
{
|
|
var station = FindNearbyRepairStation(5.0);
|
|
if (station != null)
|
|
{
|
|
if (!isRepairing)
|
|
{
|
|
StartRepair(station.StationId);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
// PRIORITA 3: Úkol (pouze crew)
|
|
// ═══════════════════════════════════════════════════════════════════
|
|
|
|
if (client.MyRole == PlayerRole.Crew)
|
|
{
|
|
var task = client.FindNearbyTask(5.0);
|
|
if (task != null)
|
|
{
|
|
TryCompleteTask(task);
|
|
return;
|
|
}
|
|
}
|
|
|
|
ShowNotification("Nic v dosahu!", Color.yellow, "❓");
|
|
}
|
|
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// ÚKOLY
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Pokus o dokončení úkolu - pošle CompleteTask na server.
|
|
/// Server ověří pozici a označí jako dokončený.
|
|
/// </summary>
|
|
private void TryCompleteTask(object taskObj)
|
|
{
|
|
if (client == null) return;
|
|
|
|
// Dynamicky získáme vlastnosti úkolu přes reflexi
|
|
var taskType = taskObj.GetType();
|
|
string taskId = taskType.GetField("TaskId")?.GetValue(taskObj) as string ??
|
|
taskType.GetProperty("TaskId")?.GetValue(taskObj) as string ?? "unknown";
|
|
string taskName = taskType.GetField("Name")?.GetValue(taskObj) as string ??
|
|
taskType.GetProperty("Name")?.GetValue(taskObj) as string ?? "Úkol";
|
|
|
|
// Pošleme CompleteTask na server
|
|
client.CompleteTask(taskId);
|
|
|
|
ShowNotification($"Provádím: {taskName}...", Color.cyan, "📋");
|
|
}
|
|
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// REPORT TĚLA
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Nahlášení těla
|
|
/// </summary>
|
|
/// <param name="bodyId">ID těla</param>
|
|
protected void ReportBody(string bodyId)
|
|
{
|
|
if (client == null) return;
|
|
|
|
client.ReportBody(bodyId);
|
|
|
|
ShowNotification("Tělo nahlášeno!", Color.red, "🚨");
|
|
}
|
|
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// KILL
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Pokus o zabití blízkého hráče
|
|
/// </summary>
|
|
private void TryKillNearbyPlayer()
|
|
{
|
|
if (client?.MyRole != PlayerRole.Impostor) return;
|
|
|
|
// Kontrola cooldownu
|
|
if (Time.time - lastKillTime < killCooldown)
|
|
{
|
|
float remaining = killCooldown - (Time.time - lastKillTime);
|
|
ShowNotification($"Cooldown: {remaining:F0}s", Color.yellow, "⏳");
|
|
return;
|
|
}
|
|
|
|
// Najdi blízkého hráče
|
|
string targetId = client.FindNearbyPlayer(5.0, true);
|
|
|
|
if (targetId != null)
|
|
{
|
|
AttemptKill(targetId);
|
|
}
|
|
else
|
|
{
|
|
ShowNotification("Nikdo v dosahu!", Color.yellow, "🔪");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pokus o zabití konkrétního hráče
|
|
/// </summary>
|
|
/// <param name="targetId">UUID cíle</param>
|
|
protected void AttemptKill(string targetId)
|
|
{
|
|
if (client == null) return;
|
|
|
|
client.Kill(targetId);
|
|
lastKillTime = Time.time;
|
|
|
|
string targetName = GetPlayerName(targetId);
|
|
ShowNotification($"Útočíš na {targetName}!", Color.red, "🔪");
|
|
}
|
|
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// SABOTÁŽE
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Spuštění sabotáže
|
|
/// </summary>
|
|
/// <param name="type">Typ sabotáže</param>
|
|
protected void StartSabotage(SabotageType type)
|
|
{
|
|
if (client?.MyRole != PlayerRole.Impostor) return;
|
|
if (currentSabotage != null) return; // Již běží sabotáž
|
|
|
|
client.Send(new StartSabotage { SabotageType = type });
|
|
|
|
string sabName = type == SabotageType.CommsBlackout ? "Comms Blackout" : "Critical Meltdown";
|
|
ShowNotification($"Sabotáž: {sabName}!", new Color(1f, 0.5f, 0f), "⚠");
|
|
}
|
|
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// OPRAVY
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Oprava stanice - INSTANT
|
|
/// Server opraví stanici okamžitě při přijetí ActivateRepairStation.
|
|
/// Budoucí pokročilý klient může simulovat progress bar a poslat request až po uplynutí času.
|
|
/// </summary>
|
|
/// <param name="stationId">ID opravné stanice</param>
|
|
private void StartRepair(string stationId)
|
|
{
|
|
if (currentSabotage == null) return;
|
|
|
|
// Pošleme serveru - ten opraví INSTANT
|
|
client.Send(new ActivateRepairStation { StationId = stationId });
|
|
|
|
ShowNotification("Stanice opravena!", Color.green, "✅");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aktualizace průběhu opravy - NEPOUŽÍVÁ SE (oprava je instant)
|
|
/// Ponecháno pro budoucí implementaci s progress barem.
|
|
/// </summary>
|
|
protected void UpdateRepairProgress()
|
|
{
|
|
// Oprava je nyní instant - tato metoda není potřeba
|
|
// Budoucí klient může implementovat lokální progress bar:
|
|
// if (!isRepairing) return;
|
|
// repairProgress += Time.deltaTime / 3f; // 3 sekundy
|
|
// if (repairProgress >= 1f) {
|
|
// client.Send(new ActivateRepairStation { StationId = activeRepairStation });
|
|
// isRepairing = false;
|
|
// }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ukončení opravy (úspěšné) - NEPOUŽÍVÁ SE (oprava je instant)
|
|
/// </summary>
|
|
private void StopRepair()
|
|
{
|
|
// Oprava je instant - tato metoda není potřeba
|
|
}
|
|
|
|
/// <summary>
|
|
/// Zrušení opravy - NEPOUŽÍVÁ SE (oprava je instant)
|
|
/// </summary>
|
|
private void CancelRepair()
|
|
{
|
|
// Oprava je instant - tato metoda není potřeba
|
|
}
|
|
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// EMERGENCY MEETING
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Svolání emergency meetingu
|
|
/// </summary>
|
|
protected void CallEmergencyMeeting()
|
|
{
|
|
if (client == null) return;
|
|
|
|
// Kontrola sabotáže - nelze volat během comms blackout
|
|
if (currentSabotage?.Type == SabotageType.CommsBlackout)
|
|
{
|
|
ShowNotification("Komunikace odpojeny!", Color.red, "📡");
|
|
return;
|
|
}
|
|
|
|
client.CallEmergencyMeeting();
|
|
|
|
ShowNotification("Emergency Meeting!", Color.red, "🔔");
|
|
}
|
|
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// HLASOVÁNÍ
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Odeslání hlasu
|
|
/// </summary>
|
|
/// <param name="targetId">UUID hráče nebo null pro skip</param>
|
|
protected void CastVote(string targetId)
|
|
{
|
|
if (client == null)
|
|
{
|
|
Debug.LogError("[GeoSus] CastVote: client je null!");
|
|
return;
|
|
}
|
|
|
|
if (!canVote)
|
|
{
|
|
Debug.LogWarning("[GeoSus] CastVote: canVote je false!");
|
|
return;
|
|
}
|
|
|
|
string voteText = targetId == null ? "SKIP" : GetPlayerName(targetId);
|
|
Debug.Log($"[GeoSus] Hlasování: {voteText} (targetId: {targetId ?? "null"})");
|
|
|
|
client.Vote(targetId);
|
|
myVote = targetId ?? "skip";
|
|
canVote = false;
|
|
|
|
ShowNotification($"Hlasoval jsi: {voteText}", Color.cyan, 2f, "🗳");
|
|
}
|
|
|
|
#region ═══════════════════════════════════════════════════════════════════
|
|
// POMOCNÉ METODY
|
|
// ════════════════════════════════════════════════════════════════════════
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Získání jména hráče podle UUID
|
|
/// </summary>
|
|
protected string GetPlayerName(string playerId)
|
|
{
|
|
if (client?.CurrentLobbyState?.Players == null) return playerId;
|
|
|
|
foreach (var player in client.CurrentLobbyState.Players)
|
|
{
|
|
if (player.ClientUuid == playerId)
|
|
{
|
|
return player.DisplayName;
|
|
}
|
|
}
|
|
|
|
return playerId.Substring(0, 8) + "...";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Inicializace herního stavu při startu hry
|
|
/// </summary>
|
|
protected void InitializeGameState()
|
|
{
|
|
// Reset pozice na střed
|
|
currentPlayerPosition = Vector3.zero;
|
|
|
|
// Reset úkolů
|
|
totalTasksCompleted = 0;
|
|
totalTasksRequired = client?.MyTasks?.Count ?? 0;
|
|
myCompletedTaskIds.Clear();
|
|
|
|
// Reset oprav
|
|
isRepairing = false;
|
|
activeRepairStation = null;
|
|
repairProgress = 0f;
|
|
|
|
// Reset kill cooldownu
|
|
lastKillTime = Time.time; // Cooldown na začátku
|
|
|
|
// Reset sabotáže
|
|
currentSabotage = null;
|
|
|
|
// Reset meetingu
|
|
currentMeeting = null;
|
|
meetingVotes.Clear();
|
|
myVote = null;
|
|
canVote = false;
|
|
|
|
// Reset konce hry
|
|
gameEndData = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Game loop - aktualizace herní logiky.
|
|
/// Volá se v Update().
|
|
/// </summary>
|
|
protected void UpdateGameLogic()
|
|
{
|
|
if (currentState != AppState.InGame) return;
|
|
|
|
// Aktualizace opravy
|
|
UpdateRepairProgress();
|
|
|
|
// Aktualizace mapových objektů
|
|
UpdateMapObjects();
|
|
}
|
|
}
|