402 lines
13 KiB
C#
402 lines
13 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 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;
|
|
|
|
defaultJoyPos = joystick.transform.GetChild(0).GetComponent<RectTransform>().localPosition;
|
|
SwitchUISides();
|
|
|
|
|
|
}
|
|
Vector2 defaultJoyPos;
|
|
|
|
public void SwitchUISides(){
|
|
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-150, btn_boost.position.y);
|
|
Vector2 newDef = new Vector2(defaultJoyPos.x, defaultJoyPos.y);
|
|
|
|
joystick.GetComponent<Joystick>().SetDefaultPosition(newDef);
|
|
}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(150, btn_boost.position.y);
|
|
Vector2 newDef = new Vector2(-defaultJoyPos.x, defaultJoyPos.y);
|
|
|
|
joystick.GetComponent<Joystick>().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<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");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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<PickupItem>().Reposition(newPosition);
|
|
pickup.Active.Add(newStar.GetComponent<PickupItem>());
|
|
}
|
|
|
|
pickup.Timer = 0;
|
|
}
|
|
}
|
|
}
|
|
GameObject RandomStar { get{
|
|
int i = Random.Range(0,5);
|
|
int c = 0;
|
|
GameObject selected = null;
|
|
foreach(PickupSetting pickup in PickupItems){
|
|
if(pickup.Prefab.name.ToLower().Contains("star")){
|
|
selected = pickup.Prefab;
|
|
if(c == i){
|
|
return pickup.Prefab;
|
|
break;
|
|
}
|
|
c++;
|
|
}
|
|
}
|
|
|
|
return selected;
|
|
}}
|
|
void SpawnStars(int amount, Vector3 focusedPosition){
|
|
for(int i=0; i < amount;i++){
|
|
Vector3 newPosition = getRandomPointInCirlce((Vector3)focusedPosition, 10);
|
|
GameObject newStar = Instantiate(RandomStar, pickupItemsParent);
|
|
NetworkServer.Spawn(newStar);
|
|
newStar.GetComponent<PickupItem>().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<DeathEffect>();
|
|
// 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<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);
|
|
}
|
|
|
|
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<PickupItem> Active = new List<PickupItem>();
|
|
public List<PickupItem> Pooled = new List<PickupItem>();
|
|
private PickupItem.PickupType? type = null;
|
|
public PickupItem.PickupType Type {get{
|
|
if(type == null && Prefab!=null){
|
|
type= Prefab.GetComponent<PickupItem>().type;
|
|
}
|
|
|
|
return (PickupItem.PickupType)type;
|
|
}}
|
|
} |