Zabiju je

This commit is contained in:
2026-04-26 13:30:33 +02:00
parent 208696487e
commit 700e6bfbfc
143 changed files with 11027 additions and 1298 deletions

View File

@@ -4,43 +4,53 @@ using Subsystems;
using System.Collections;
using System;
using TMPro;
/*
GameManager - hlavní tøida pro správu hry
GameManager_Network - subsystém pro správu komunikace se serverem
GameManager_Game - subsystém pro správu logiky hry (sabotáže, tasky, atd.)
GameManager_Map - subsystém pro správu mapy a prostøedí
GameManager_Input - subsystém pro správu vstupu od hráèe
GameManager_UI - subsystém pro správu uživatelského rozhraní
GamaManager_Stats - subsystém pro správu statistik pro server
*/
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
[Header("Subsystems")]
protected GameManager_Network networkSubsystem;
protected GameManager_UI uiSubsystem;
protected GameManager_Map mapSubsystem;
protected GameManager_Input inputSubsystem;
// Singleton
public static GameManager Instance { get; private set; }
protected GameClient gameClient;
[Header("Subsystems")]
public GameManager_Network networkSubsystem;
public GameManager_UI uiSubsystem;
public GameManager_Map mapSubsystem;
public GameManager_Input inputSubsystem;
public GameManager_Tasks taskSubsystem;
public GameClient gameClient;
[Header("Player Info")]
public string displayName;
[Header("UI Elements")]
public Canvas JoinCreateLobby;
public Canvas InLobby;
public Canvas LoadingScreen;
public Canvas GameScreen;
[Header("Scene Management")]
[SerializeField] public string firstMenuScene = "main menu asi idk lol";
[Header("UI Elements (Client.unity)")]
// Canvas names in Client.unity — found at runtime in OnSceneLoaded
private const string CanvasNameJoinCreate = "LobbySelector";
private const string CanvasNameInLobby = "InLobby";
private const string CanvasNameLoading = "LoadingScreen";
private const string CanvasNameGame = "InGame";
[Header("Map")]
public GameObject MapCenterPoint;
// MapCenterPoint and Player are in Client.unity — wired at runtime in OnSceneLoaded.
// buildingSettings/pathwaySettings/areaSettings must be assigned in SampleScene Inspector.
public BuildingSettings buildingSettings;
public PathwaySettings pathwaySettings;
public AreaSettings areaSettings;
[Header("GPS")]
public GameObject Player;
[Header("Lobby Settings")]
public double pendingRadius = 500;
public int pendingImpostorCount = 1;
public int pendingTaskCount = 5;
[Header("Task Minigames (round-robin)")]
[SerializeField] public string[] minigameScenes = {
"MiniGame-Kabely",
"MiniGame-InsertKeys",
"MiniGame-FlappyBird",
"MiniGame-ThrowInHole"
};
[Header("Debug")]
public bool testMode = false;
@@ -49,100 +59,307 @@ public class GameManager : MonoBehaviour
private GameManager_Network _secondNetwork;
private GameManager_Network _thirdNetwork;
void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
void Start()
{
DontDestroyOnLoad(this);
if (displayName == null || displayName == "")
{
displayName = GenerateUsername();
}
if (string.IsNullOrEmpty(displayName))
displayName = PlayerPrefs.GetString("PlayerName", GenerateUsername());
gameClient = new GameClient(GenerateUUID(), displayName);
networkSubsystem = new GameManager_Network(gameClient, this);
mapSubsystem = new GameManager_Map(gameClient, null, buildingSettings, pathwaySettings, areaSettings);
uiSubsystem = new GameManager_UI(gameClient);
inputSubsystem = new GameManager_Input(gameClient, null, testMode);
taskSubsystem = new GameManager_Tasks(gameClient, minigameScenes, this);
if (testMode)
{
_secondClient = new GameClient(GenerateUUID(), GenerateUsername());
_secondNetwork = new GameManager_Network(_secondClient);
_secondNetwork = new GameManager_Network(_secondClient, null);
_thirdClient = new GameClient(GenerateUUID(), GenerateUsername());
_thirdNetwork = new GameManager_Network(_thirdClient);
_secondNetwork.OpenConection();
_thirdNetwork.OpenConection();
_thirdNetwork = new GameManager_Network(_thirdClient, null);
_secondNetwork.OpenConnection();
_thirdNetwork.OpenConnection();
}
gameClient = new GameClient(GenerateUUID(), displayName);
uiSubsystem = new GameManager_UI(gameClient, JoinCreateLobby, InLobby, LoadingScreen, GameScreen);
networkSubsystem = new GameManager_Network(gameClient);
mapSubsystem = new GameManager_Map(gameClient, MapCenterPoint, buildingSettings, pathwaySettings, areaSettings);
inputSubsystem = new GameManager_Input(gameClient, Player, testMode);
networkSubsystem.OpenConection();
networkSubsystem.OpenConnection();
// Load main menu after GameManager is ready
if (!string.IsNullOrEmpty(firstMenuScene))
SceneManager.LoadScene(firstMenuScene, LoadSceneMode.Single);
}
private void Update()
{
if (gameClient.CurrentLobbyState != null)
{
uiSubsystem.UpdateLobbyUI();
}
try
{
if (gameClient.CurrentLobbyState.MapDataReady)
{
mapSubsystem.BuildMap();
gameClient.CurrentLobbyState.MapDataReady = false;
}
}
catch (NullReferenceException ex) { }
inputSubsystem.positionCheck();
}
protected string GenerateUUID()
{
string UUID = System.Guid.NewGuid().ToString();
Debug.Log(UUID);
return UUID;
}
protected string GenerateUsername()
{
string Username = UnityEngine.Random.Range(0,10).ToString() + UnityEngine.Random.Range(0, 10).ToString() + UnityEngine.Random.Range(0, 10).ToString() + UnityEngine.Random.Range(0, 10).ToString();
Debug.Log(Username);
return Username;
}
public void CreateLobbyButton()
{
networkSubsystem.CrateLobby(50.7727264, 15.0719876);
// Tick the SDK dispatcher so callbacks fire on main thread
gameClient?.Update();
if (testMode)
{
StartCoroutine(ConnectTestClients());
_secondClient?.Update();
_thirdClient?.Update();
}
if (gameClient?.CurrentLobbyState != null)
{
uiSubsystem?.UpdateLobbyUI();
taskSubsystem?.UpdateProximity();
}
if (gameClient?.MyRole == PlayerRole.Impostor)
UpdateKillCooldown();
inputSubsystem?.positionCheck();
}
void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
/// <summary>
/// After Client.unity loads, re-bind all canvas/HUD references because
/// those GameObjects don't exist in the Art menu scenes.
/// </summary>
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (scene.name == "Client")
{
var roots = scene.GetRootGameObjects();
// Find a root or deep GameObject by name in the loaded scene
GameObject FindGO(string n) {
foreach (var go in roots) {
if (go.name == n) return go;
var found = go.transform.Find(n);
if (found != null) return found.gameObject;
}
return null;
}
Canvas FindCanvas(string n) {
var go = FindGO(n);
return go != null ? go.GetComponent<Canvas>() : null;
}
// ── Build HUD BEFORE BindClientScene so FindTMP/Find can locate new elements ──
var inGameGO = FindGO("InGame");
if (inGameGO != null)
{
var builder = inGameGO.GetComponent<InGameHUDBuilder>()
?? inGameGO.AddComponent<InGameHUDBuilder>();
builder.BuildNow();
}
// ── Wire canvases (after HUD is built) ──
uiSubsystem?.BindClientScene(
FindCanvas(CanvasNameJoinCreate),
FindCanvas(CanvasNameInLobby),
FindCanvas(CanvasNameLoading),
FindCanvas(CanvasNameGame));
// ── Wire map center point and player capsule ──
var mapCenter = FindGO("MapCenterPoint");
var player = FindGO("Capsule");
mapSubsystem?.SetMapCenterPoint(mapCenter);
inputSubsystem?.SetPlayerObject(player);
// ── Attach camera controller to Main Camera ──
var mainCamGO = FindGO("Main Camera");
if (mainCamGO != null)
{
var camCtrl = mainCamGO.GetComponent<MapCameraController>()
?? mainCamGO.AddComponent<MapCameraController>();
camCtrl.SetTarget(player);
}
// If MapDataReady arrived before Client scene finished loading,
// this will build the map now that scene references are valid.
networkSubsystem?.OnClientSceneReady();
}
else if (scene.name == "create" || scene.name == "join loading")
{
// Lobby scene just loaded — ensure LobbyDisplayUI refreshes once
// its Start() has run and registered itself (happens before Update).
uiSubsystem?.NotifyLobbyChanged();
}
}
public void JoinLobbyButton()
// ── Kill cooldown ─────────────────────────────────────────────────────────
private float _killCooldownSeconds = 0f;
private const float KillCooldownDuration = 20f;
private void UpdateKillCooldown()
{
TMP_InputField joinCode = JoinCreateLobby.transform.Find("InputCode").GetComponent<TMP_InputField>();
if (joinCode.text != null && joinCode.text != "")
if (_killCooldownSeconds > 0)
{
networkSubsystem.JoinLobby(joinCode.text);
_killCooldownSeconds -= Time.deltaTime;
uiSubsystem?.SetKillCooldownText($"Kill: {Mathf.CeilToInt(_killCooldownSeconds)}s");
}
else
{
Debug.Log("Join code is empty!");
uiSubsystem?.SetKillCooldownText("");
}
}
/// <summary>
/// Called by the ActionButton. Routes to kill / report / emergency / use-task
/// depending on current proximity state.
/// </summary>
public void PerformAction()
{
if (uiSubsystem == null || uiSubsystem.IsPlayerDead) return;
bool isImpostor = gameClient?.MyRole == PlayerRole.Impostor;
// 1. Nearby task → USE
var nearbyTask = taskSubsystem?.NearbyTask;
if (nearbyTask != null && !isImpostor)
{
taskSubsystem.TriggerNearbyTask();
return;
}
// 2. Nearby body → REPORT
if (!uiSubsystem.IsCommsBlackout)
{
var nearbyBody = gameClient?.FindNearbyBody(5.0);
if (nearbyBody != null)
{
gameClient.ReportBody(nearbyBody.BodyId);
return;
}
// 3. Near map centre → EMERGENCY
if (gameClient?.CurrentLobbyState?.MapData != null)
{
double distToCenter = gameClient.MyPosition.DistanceTo(gameClient.CurrentLobbyState.MapData.Center);
if (distToCenter <= 5.0)
{
gameClient.CallEmergencyMeeting();
return;
}
}
}
// 4. Impostor kill
if (isImpostor && _killCooldownSeconds <= 0)
{
var targetUuid = gameClient?.FindNearbyPlayer(5.0);
if (!string.IsNullOrEmpty(targetUuid))
{
gameClient.Kill(targetUuid);
_killCooldownSeconds = KillCooldownDuration;
}
}
}
/// <summary>Called by Impostor sabotage buttons.</summary>
public void StartSabotage(int typeIndex)
{
gameClient?.Send(new GeoSus.Client.StartSabotage { SabotageType = (SabotageType)typeIndex });
}
/// <summary>Called by the meeting vote buttons. Pass null to skip.</summary>
public void CastVote(string targetUuid)
{
gameClient?.Vote(targetUuid);
}
protected string GenerateUUID()
{
return System.Guid.NewGuid().ToString();
}
protected string GenerateUsername()
{
return "Player" + UnityEngine.Random.Range(1000, 9999).ToString();
}
// Called by HostLobbyUI
public void CreateLobbyButton()
{
// Use current GPS position if available, else hardcoded fallback
double lat = 50.7727264, lon = 15.0719876;
if (inputSubsystem?.LastKnownPosition != null)
{
lat = inputSubsystem.LastKnownPosition.Value.Lat;
lon = inputSubsystem.LastKnownPosition.Value.Lon;
}
networkSubsystem.CreateLobby(lat, lon, pendingRadius, pendingImpostorCount, pendingTaskCount);
if (testMode) StartCoroutine(ConnectTestClients());
}
// Called by JoinLobbyUI with the code from the input field
public void JoinLobbyButton(string code)
{
if (!string.IsNullOrEmpty(code))
networkSubsystem.JoinLobby(code);
else
Debug.LogWarning("Join code is empty!");
}
public void LeaveLobbyButton()
{
networkSubsystem.LeaveLobby();
}
public void StartGameButton()
{
networkSubsystem.StartGame();
}
void OnApplicationQuit()
{
gameClient.Disconnect();
gameClient?.Disconnect();
_secondClient?.Disconnect();
_thirdClient?.Disconnect();
_thirdClient?.Disconnect();
}
IEnumerator ConnectTestClients()
{
yield return new WaitForSeconds(2f);
_secondNetwork.JoinLobby(gameClient.CurrentLobbyState.JoinCode);
_thirdNetwork.JoinLobby(gameClient.CurrentLobbyState.JoinCode);
IEnumerator ConnectTestClients()
{
// Wait until host lobby code exists
float wait = 0f;
while ((gameClient?.CurrentLobbyState == null || string.IsNullOrEmpty(gameClient.CurrentLobbyState.JoinCode)) && wait < 20f)
{
wait += 0.25f;
yield return new WaitForSeconds(0.25f);
}
var joinCode = gameClient?.CurrentLobbyState?.JoinCode;
if (string.IsNullOrEmpty(joinCode))
{
Debug.LogWarning("[TestMode] Could not join test clients: join code not available.");
yield break;
}
// Wait until helper clients are connected and handshake-complete
wait = 0f;
while (((_secondClient == null || !_secondClient.IsReady) || (_thirdClient == null || !_thirdClient.IsReady)) && wait < 20f)
{
wait += 0.25f;
yield return new WaitForSeconds(0.25f);
}
if (_secondClient == null || _thirdClient == null || !_secondClient.IsReady || !_thirdClient.IsReady)
{
Debug.LogWarning("[TestMode] Helper clients are not ready, skipping auto-join.");
yield break;
}
_secondNetwork?.JoinLobby(joinCode);
_thirdNetwork?.JoinLobby(joinCode);
Debug.Log($"[TestMode] Helper clients joined lobby with code {joinCode}.");
}
}