UPF/Assets/Game/Scripts/Minigame/MinigameManager.cs
2022-10-06 23:45:04 +05:30

339 lines
10 KiB
C#

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 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;
public int maxMoons, maxStars = 100;
public Transform pickupItemsParent;
private List<PickupItem> ActiveMoons = new List<PickupItem>();
private List<PickupItem> ActiveStars = new List<PickupItem>();
List<PickupItem> MoonPool = new List<PickupItem>();
List<PickupItem> StarsPool = new List<PickupItem>();
public GameObject moon;
public GameObject star;
private void Awake()
{
// if(!DBmanager.LoggedIn){SceneManager.LoadScene(0);}
SceneData.GameManager = this;
instance = this;
DBmanager.OnStateChanged.AddListener(UpdateMaterialValues);
UpdateMaterialValues();
safeZoneShrinkSpeed = mapRadius / safeZoneShrinkTime;
}
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<SpaceshipController>();
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<SpaceshipController>();
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<SpaceshipController>();
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<SpaceshipController>();
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");
}
}
}
}
void HandlePickupSpawn()
{
foreach(PickupItem moon in ActiveMoons){
if(Vector2.Distance(Vector2.zero, moon.transform.position) > mapRadius){
moon.Deactivate();
}
}
int moonsNeed = maxMoons - ActiveMoons.Count;
int starsNeed = maxStars - ActiveStars.Count;
if (moonsNeed > 0)
{ // <-- We need more moons!
SpawnMoons(moonsNeed);
}
if (starsNeed > 0)
{ // <-- We need more moons!
SpawnStars(starsNeed);
}
}
public void SpawnLeftoverPickups(Vector3 position, int amount)
{
SpawnStars(amount, focusedPosition: position);
}
void SpawnStars(int amount, Vector3? focusedPosition = null)
{
for (int i = 0; i < amount; i++)
{
Vector3 newPosition = (focusedPosition == null) ? getRandomPositionOnMap() : getRandomPointInCirlce((Vector3)focusedPosition, 10);
if (StarsPool.Count > 0)
{ // <-- Got some in the pool, no need to spawn new
PickupItem pickedStar = StarsPool[0];
pickedStar.Reposition(newPosition);
ActiveStars.Add(pickedStar);
StarsPool.RemoveAt(0);
}
else
{
GameObject newStar = Instantiate(star, pickupItemsParent);
NetworkServer.Spawn(newStar);
newStar.GetComponent<PickupItem>().Reposition(newPosition);
ActiveStars.Add(newStar.GetComponent<PickupItem>());
}
}
}
void SpawnMoons(int amount)
{
for (int i = 0; i < amount; i++)
{
if (MoonPool.Count > 0)
{ // <-- Got some in the pool, no need to spawn new
PickupItem pickedMoon = MoonPool[0];
pickedMoon.Reposition(getRandomPositionOnMap());
ActiveMoons.Add(pickedMoon);
MoonPool.RemoveAt(0);
}
else
{
GameObject newMoon = Instantiate(moon, pickupItemsParent);
NetworkServer.Spawn(newMoon);
newMoon.GetComponent<PickupItem>().Reposition(getRandomPositionOnMap());
ActiveMoons.Add(newMoon.GetComponent<PickupItem>());
}
}
}
public void DeactivatePickupItem(PickupItem item)
{
if (item.type == PickupItem.PickupType.Moon)
{
ActiveMoons.Remove(item);
MoonPool.Add(item);
}
else if (item.type == PickupItem.PickupType.Star)
{
ActiveStars.Remove(item);
StarsPool.Add(item);
}
}
public void SetRespawn(GameObject player)
{
StartCoroutine(setRespawn(player));
}
public void Restart(){
if(SceneData.localPlayer.GetComponent<SpaceshipController>().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<SpaceshipController>().Respawn(RespawnPoint);
// }
// else
// {
yield return new WaitForSeconds(1);
// }
}
Vector3 getRandomPositionOnMap()
{
return getRandomPointInCirlce(Vector3.zero, mapRadius);
}
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();
// 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();
}
}