using System.Collections; using System.Collections.Generic; using UnityEngine; using Mirror; using UnityEngine.SceneManagement; using System.Threading.Tasks; using TMPro; public class MinigameManager : NetworkBehaviour { public static MinigameManager instance; public AudioClip[] musicClips; public RectTransform joystick; public RectTransform btn_boost; public bool isRanked; [SyncVar] public bool RankedGameStarted=false; [SyncVar(hook =nameof(OnWinnerChanged))] public int winnerId=-1; [SyncVar] public double startedTime = 0; public GameObject waitingScreen; public RankedGameSummary rankedSummary; [SyncVar(hook= nameof(OnMapRadisuChanged))] public float mapRadius; [SyncVar(hook=nameof(OnMapCenterChanged))] public Vector2 mapCenter = Vector2.zero; public Transform safeZone; public float safeZoneCoolTime = 60; public float safeZoneShrinkTime = 30; float safeZoneShrinkSpeed; [SerializeField] private PickupSetting[] PickupItems; public GameObject starPrefab; // public int maxMoons, maxStars = 100; // public int maxTweps = 2; public Transform pickupItemsParent; private void Awake() { // if(!DBmanager.LoggedIn){SceneManager.LoadScene(0);} SceneData.GameManager = this; instance = this; DBmanager.OnStateChanged.AddListener(UpdateMaterialValues); UpdateMaterialValues(); safeZoneShrinkSpeed = mapRadius / safeZoneShrinkTime; if(ControlSettings.ControlIsOnRight){ joystick.anchorMin = new Vector2(0,0); joystick.anchorMax = new Vector2(0.5f, 1); btn_boost.anchorMin = new Vector2(1,0); btn_boost.anchorMax = new Vector2(1,0); btn_boost.position = new Vector2(Screen.width-100, btn_boost.position.y); }else{ joystick.anchorMin = new Vector2(0.5f,0); joystick.anchorMax = new Vector2(1f, 1); btn_boost.anchorMin = new Vector2(0,0); btn_boost.anchorMax = new Vector2(0,0); btn_boost.position = new Vector2(100, btn_boost.position.y); Vector2 newDef = new Vector2(-joystick.transform.GetChild(0).GetComponent().localPosition.x, joystick.transform.GetChild(0).GetComponent().localPosition.y); joystick.GetComponent().SetDefaultPosition(newDef); } } void Start(){ AudioManager.instnace.SetCustomMusic(musicClips[Random.Range(0,musicClips.Length)]); } void Update() { // if(!DBmanager.LoggedIn){SceneManager.LoadScene(0);} //Signed out, no game for u if (!isServer) { return; } HandlePickupSpawn(); KillOutOfBoundsPlayers(); if(isRanked){RankedMechanics();} } public float timeElapsed => (float)(NetworkTime.time - startedTime); bool shrinkStarted =false; uint[] PlayersIds; Vector2 newMapCenter = Vector2.zero; public void StartRanked(){ startedTime=NetworkTime.time; RankedGameStarted=true; SpaceshipController[] players = FindObjectsOfType(); PlayersIds = new uint[players.Length]; for(int i=0; i < players.Length; i++){ PlayersIds[i] = players[i].netId; } } void RankedMechanics(){ mapCenter += ((newMapCenter - mapCenter) / safeZoneShrinkTime) * Time.deltaTime; SpaceshipController[] players = FindObjectsOfType(); if(players.Length >= 2 && !RankedGameStarted){ if(players[0].ready && players[1].ready){ //Both are ready StartRanked(); } } if(RankedGameStarted){ if(timeElapsed > safeZoneCoolTime){ if(!shrinkStarted){ shrinkStarted=true; newMapCenter = getRandomPointInCirlce(mapCenter, mapRadius /2f); KillfeedMgr.instance.AddNewEntry("Safe zone is shrinking!"); RpcKillfeed("Safe-zone is Shrinking!"); } if(mapRadius > 3){ mapRadius -= Time.deltaTime * safeZoneShrinkSpeed; safeZone.localScale = new Vector3(mapRadius, mapRadius,mapRadius); } } if(players[0].moonsCollected >= 30){ //player 1 has won winnerId = (int)players[0].netId; // players[0].WonRanked(); // players[1].LostRanked(); }else if(players[1].moonsCollected >= 30){ //player 2 has won winnerId = (int)players[1].netId; // players[0].WonRanked(); // players[1].LostRanked(); } } if(RankedGameStarted && players.Length < 2){ //Forfeited! winnerId = (int)players[0].netId; // players[0].WonRanked(); } } public void OnMapRadisuChanged(float oldVal, float newVal){ if(isRanked){ safeZone.localScale = new Vector3(mapRadius, mapRadius,mapRadius); } } public void OnMapCenterChanged(Vector2 oldPos, Vector2 newPos){ if(isRanked){ safeZone.position = newPos; } } void RpcKillfeed(string message){ KillfeedMgr.instance.AddNewEntry(message); } void OnWinnerChanged(int oldVal, int newVal){ if(newVal<= 0){return;} // if(!isLocalPlayer){return;} Debug.Log($"{newVal} id won!"); SpaceshipController localPlayer = SceneData.localPlayer.GetComponent(); if(newVal == localPlayer.netId){ //We won localPlayer.CmdWonRanked(); Debug.Log("Its Me!, I won!"); }else{ Debug.Log("Its not me, I lost!"); localPlayer.CmdLostRanked(); } } void KillOutOfBoundsPlayers() { SpaceshipController[] players = FindObjectsOfType(); foreach (SpaceshipController player in players) { if (Vector3.Distance(player.transform.position, mapCenter) > mapRadius) { //Out of bounds. Kill him if(isRanked){ player.DecreaseTrail(Time.deltaTime * 4); if(player.trailTime < 1){ winnerId = (int)(PlayersIds[0] == player.netId ? PlayersIds[1] : PlayersIds[0]); player.Die("Playzone"); } }else{ player.Die("Playzone"); } } } } float twepTimer = 60; void HandlePickupSpawn() { foreach(PickupSetting pickup in PickupItems){ int spawnsNeeded = pickup.MaxAmount - pickup.Active.Count; if(spawnsNeeded > 0){ SpawnPickups(pickup, spawnsNeeded); } } } public void SpawnLeftoverPickups(Vector3 position, int amount) { SpawnStars(amount, focusedPosition: position); } void SpawnPickups(PickupSetting pickup, int amount) { for (int i = 0; i < amount; i++) { if(pickup.Timer < pickup.SpawnInterval){ pickup.Timer++; }else{ Vector3 newPosition = getRandomPositionOnMap(); if (pickup.Pooled.Count > 0) { // <-- Got some in the pool, no need to spawn new PickupItem pickedStar = pickup.Pooled[0]; pickedStar.Reposition(newPosition); pickup.Active.Add(pickedStar); pickup.Pooled.RemoveAt(0); } else { GameObject newStar = Instantiate(pickup.Prefab, pickupItemsParent); NetworkServer.Spawn(newStar); newStar.GetComponent().Reposition(newPosition); pickup.Active.Add(newStar.GetComponent()); } pickup.Timer = 0; } } } void SpawnStars(int amount, Vector3 focusedPosition){ for(int i=0; i < amount;i++){ Vector3 newPosition = getRandomPointInCirlce((Vector3)focusedPosition, 10); GameObject newStar = Instantiate(starPrefab, pickupItemsParent); NetworkServer.Spawn(newStar); newStar.GetComponent().Reposition(newPosition); } } public void DeactivatePickupItem(PickupItem item) { foreach(PickupSetting pickup in PickupItems){ if(item.type == pickup.Type) pickup.Active.Remove(item); pickup.Pooled.Add(item); } } // public void ShowDeathEffect(Vector2 position){ // if(isServer){return;} // if(PooledDeathEffects.Count > 0){ // //Can use from pool [0] // DeathEffect pickedItem = PooledDeathEffects[0]; // pickedItem.Play(); // StartCoroutine(PoolDeathEffect(pickedItem)); // PooledDeathEffects.Remove(pickedItem); // }else{ // DeathEffect newEffect = Instantiate(DeathEffectPrefab, EffectsParent).GetComponent(); // newEffect.transform.position = position; // newEffect.Play(); // StartCoroutine(PoolDeathEffect(newEffect)); // } // } // IEnumerator PoolDeathEffect(DeathEffect effect){ // yield return new WaitForSeconds(1.5f); // PooledDeathEffects.Add(effect); // } public void SetRespawn(GameObject player) { StartCoroutine(setRespawn(player)); } public void Restart(){ if(SceneData.localPlayer.GetComponent().dead){ SetRespawn(SceneData.localPlayer); }else{ Debug.LogError("You aren't dead, you can't restart unless you are dead."); } } IEnumerator setRespawn(GameObject player) { // if (isServer) // { // player.SetActive(false); // yield return new WaitForSeconds(0.1f); Vector3 RespawnPoint = NetworkManager.startPositions[Random.Range(0, NetworkManager.startPositions.Count - 1)].position; player.GetComponent().Respawn(RespawnPoint); // } // else // { yield return new WaitForSeconds(1); // } } Vector3 getRandomPositionOnMap() { return getRandomPointInCirlce(Vector3.zero, mapRadius); } public static Vector3 getRandomPointInCirlce(Vector3 center, float radius) { float r = radius * Mathf.Sqrt(Random.Range(0f, 1f)); float theta = Random.Range(0f, 1f) * 2 * Mathf.PI; float x = center.x + r * Mathf.Cos(theta); float y = center.y + r * Mathf.Sin(theta); return new Vector3(x, y); } void OnDrawGizmos() { Gizmos.DrawWireSphere(transform.position, mapRadius); } public GameObject loadingScreen; public async void BackToBase(){ // loadingScreen.SetActive(true); // await Task.Delay(1000); if(isRanked){ // StartCoroutine(CloseRoomClient()); LoadingScreen.instance.DeleteRankedRooms(AutoConnect.serverPort); // Debug.Log("Deleting rooms for port " + AutoConnect.serverPort); } await Task.Delay(500); LoadingScreen.instance.LoadLevel("GameScene"); NetworkManager.singleton.StopClient(); Debug.Log("Loading back to base"); // SceneManager.LoadScene("GameScene"); } //Materials [Header("Materials")] public TMP_Text metalTxt; public void GainMetals(int amount){ int newAmount = DBmanager.Metal+amount; DBmanager.SetMetal(newAmount); } public void UpdateMaterialValues(){ metalTxt.text = DBmanager.Metal.ToString(); } } [System.Serializable] public class PickupSetting{ public GameObject Prefab; public int MaxAmount =10; [HideInInspector]public int Timer = 0; public int SpawnInterval = 0; public List Active = new List(); public List Pooled = new List(); private PickupItem.PickupType? type = null; public PickupItem.PickupType Type {get{ if(type == null && Prefab!=null){ type= Prefab.GetComponent().type; } return (PickupItem.PickupType)type; }} }