Init
This commit is contained in:
673
Assets/UnityTestClient/UnityTestClient_Game.cs
Normal file
673
Assets/UnityTestClient/UnityTestClient_Game.cs
Normal file
@@ -0,0 +1,673 @@
|
||||
/*
|
||||
╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user