metahunt/Assets/Scripts/Managers/GameManager.cs
2024-02-15 00:15:22 +05:30

409 lines
13 KiB
C#

using ExitGames.Client.Photon;
using Photon.Pun;
using Photon.Realtime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviourPunCallbacks, IOnEventCallback
{
public Transform SpawnPositionsParent;
private Transform[] SpawnPositions;
public LootItemScriptableObject[] loots;
public Transform LootSpawnPointsParent;
LootSpawner[] LootSpawnPoints;
[Header("Default Loots")]
public List<InventoryEntry> DeathmatchDefaultInventory;
private double m_startTime;
public int DeathmatchRoundLength = 600;
public int DeathmtachRoundCountdown = 5;
public int TDM_MinPlayers = 4;
public double StartTime{
get{
return m_startTime;
}
set{
m_startTime = value;
UIManager.instance.SetTimer(value, DeathmatchRoundLength);
}
}
bool testingMode =false;
private void Awake()
{
if(!PhotonNetwork.IsConnected){
testingMode=true;
PhotonNetwork.ConnectUsingSettings();
}
instance = this;
LootSpawnPoints = LootSpawnPointsParent.GetComponentsInChildren<LootSpawner>();
SpawnPositions = new Transform[SpawnPositionsParent.childCount];
for (int i=0; i < SpawnPositionsParent.childCount; i++)
{
SpawnPositions[i] = SpawnPositionsParent.GetChild(i);
}
}
//Statics
public static List<string> partyMembers = new List<string>();
public static string partyId;
public static string RoomName;
public static bool isInit =false;
public static string desiredGameMode = GameModes.Deathmatch.ToString();
public static GameManager instance;
public static PlayerController localPlayer;
void ResetStatics(){
isInit=false;
instance=null;
localPlayer= null;
}
void Start()
{
Photon.Realtime.RoomOptions options = new Photon.Realtime.RoomOptions() { IsOpen = true, IsVisible=true };
PhotonNetwork.JoinOrCreateRoom(RoomName, options, Photon.Realtime.TypedLobby.Default);
}
public override void OnConnectedToMaster()
{
base.OnConnectedToMaster();
if(testingMode){
PhotonNetwork.JoinOrCreateRoom("TEST",new RoomOptions(){IsOpen= true, IsVisible=true}, TypedLobby.Default);
}
}
List<GameObject> m_loots = new List<GameObject>();
public override void OnJoinedRoom()
{
base.OnJoinedRoom();
StartCoroutine(KickstartGame());
//
UIManager.instance.loadingPanel.SetActive(false);
}
void SpawnLoots(){
foreach(LootSpawner spawnPoint in LootSpawnPoints)
{
float totalLuck = 0;
Dictionary<LootGroup, float> startLuck = new Dictionary<LootGroup, float>();
foreach(LootGroup group in spawnPoint.groups)
{
startLuck.Add(group, totalLuck);
totalLuck += group.chance;
}
float luck = Random.Range(0f, totalLuck);
float a = 0;
foreach (KeyValuePair<LootGroup, float> pair in startLuck)
{
if(luck > pair.Value && luck < pair.Value + pair.Key.chance)
{
for(int i=0; i < pair.Key.loots.Count; i++)
{
a += Mathf.PI * 0.2f;
// float a = Mathf.Sin(((float)i / (float)pair.Key.loots.Count) * (Mathf.PI));
float x = Mathf.Sin(a);
float y = Mathf.Cos(a);
Vector3 point = spawnPoint.transform.position + new Vector3(x, 0, y);
m_loots.Add(PhotonNetwork.InstantiateRoomObject(pair.Key.loots[i].spawnableName, point, Quaternion.identity));
}
break;
}
}
}
}
public void SpawnPickup(string spawnableName, Vector3 point, int count =1){
if(PhotonNetwork.IsMasterClient){
_spawnPickup(spawnableName, point, count);
}else{
photonView.RPC("RpcSpawnPickup", RpcTarget.MasterClient, spawnableName, count, point);
}
}
[PunRPC]
void RpcSpawnPickup(string spawnableName, Vector3 point, int count=1){
if(PhotonNetwork.IsMasterClient){
_spawnPickup(spawnableName, point,count);
}
}
void _spawnPickup(string spawnableName, Vector3 point, int count = 1){
GameObject loot = PhotonNetwork.InstantiateRoomObject(spawnableName, point, Quaternion.identity);
loot.GetComponent<PickupItem>().SetCount(count);
m_loots.Add(loot);
}
// Update is called once per frame
float timer => DeathmatchRoundLength - (float)(PhotonNetwork.Time -StartTime);
bool isFinished =false;
void Update()
{
if(!isInit){return;}
if(PhotonNetwork.IsMasterClient){
if(timer <=0 ){
//Game Over
if(!isFinished){
isFinished=true;
FinishRound();
}
}
}
}
public void FinishRound(){
if(desiredGameMode == GameModes.Deathmatch.ToString()){
FinishDeathmatch();
}else if(desiredGameMode == GameModes.TeamDeathmatch.ToString()){
FinishTeamdeathmatch();
}
if(PhotonNetwork.IsMasterClient){
StartCoroutine(Coroutine_SubmitSession());
}
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
CameraFollow.Pause();
PhotonNetwork.LeaveRoom();
StartCoroutine(PlayAgain());
}
void FinishDeathmatch(){
int position =0;
for(position=0; position < Leaderboard.list.Length; position++){
if(Leaderboard.list[position] == localPlayer.playerNetwork){
break;
}
}
if(desiredGameMode == GameModes.Deathmatch.ToString()){
UIManager.ShowDeathmatchFinishScreen(position, Leaderboard.list[0].username);
}
}
void FinishTeamdeathmatch(){
KeyValuePair<string,int> winnerTeam = new KeyValuePair<string, int>("",0);
foreach(KeyValuePair<string,int> team in LeaderboardTDM.unsortedTeamScores){
if(team.Value > winnerTeam.Value){
winnerTeam = team;
}
}
if(desiredGameMode == GameModes.Deathmatch.ToString()){
UIManager.ShowTDMFinishScreen(winnerTeam.Key);
}
}
IEnumerator PlayAgain(){
yield return new WaitForSeconds(10f);
ResetStatics();
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
IEnumerator Coroutine_SubmitSession(){
WWWForm form = new WWWForm();
form.AddField("champion", Leaderboard.list[0].username);
form.AddField("master_client", localPlayer.playerNetwork.username);
form.AddField("match_code", PhotonNetwork.CurrentRoom.CustomProperties["uuid"].ToString());
string playerList = "";
foreach(PlayerNetwork player in Leaderboard.list){
playerList += player.username +",";
}
form.AddField("players", playerList);
WWW req= new WWW(UserDataManager.GetApiUrl("add_session"),form);
yield return req;
Debug.Log("Session record add response: " + req.text);
WWWForm form2 = new WWWForm();
form2.AddField("username", UserDataManager.instance.Username);
WWW req2 = new WWW(UserDataManager.GetApiUrl("add_match_count"),form2);
yield return req2;
}
public float minPlayerSpawnBetweenDist = 2;
public Transform GetRandomSpawnPoint()
{
Transform farthest= SpawnPositions[0];
PlayerNetwork[] players = FindObjectsOfType<PlayerNetwork>();
//Debug.Log($"DistPlayer count {SpawnPositions.Length} : {players.Length}");
for(int i =0; i < SpawnPositions.Length; i++){
bool tooClose = false;
for(int ii=0; ii < players.Length; ii++){
float dist = Vector3.Distance(SpawnPositions[i].position, players[ii].transform.position);
// Debug.Log("DistPlayer : " + dist);
if(dist < minPlayerSpawnBetweenDist){
tooClose=true;
break;
}
}
if(!tooClose){return SpawnPositions[i];}
}
return SpawnPositions[Random.Range(0, SpawnPositions.Length)];
}
ExitGames.Client.Photon.Hashtable CustomData;
public int DeathmatchMinPlayerCount = 1;
int customPlayerId=0;
IEnumerator KickstartGame(){
PlayerNetwork[] players = FindObjectsOfType<PlayerNetwork>();
// Debug.Log("Player cound :" + players.Length);
int iterations = 0;
while(players.Length <=0){
players = FindObjectsOfType<PlayerNetwork>();
// Debug.Log("Player cound :" + players.Length + ", iterations: " + iterations);
yield return new WaitForSeconds(0.1f);
iterations++;
if(iterations > 5){
break;
}
}
customPlayerId = players.Length;
localPlayer = PhotonNetwork.Instantiate("Player", GetRandomSpawnPoint().position, Quaternion.identity).GetComponentInChildren<PlayerController>();
// localPlayer.GetComponent<PlayerNetwork>().SetPartyName(partyName,partyId);
UIManager.instance.RoundLength = DeathmatchRoundLength;
localPlayer.GetComponent<PlayerNetwork>().AutoAssignParty();
//Wait for Players
if(PhotonNetwork.IsMasterClient){
while(PhotonNetwork.CurrentRoom.PlayerCount <(desiredGameMode == GameModes.TeamDeathmatch.ToString() ? TDM_MinPlayers : DeathmatchMinPlayerCount)){
yield return new WaitForSeconds(0.5f);
UIManager.WaitingForPlayers();
}
ExitGames.Client.Photon.Hashtable customData= new ExitGames.Client.Photon.Hashtable();
customData.Add("uuid", Helpers.GetRandomCode(8));
PhotonNetwork.CurrentRoom.SetCustomProperties(customData);
}else{
UIManager.WaitingForPlayers();
}
if(PhotonNetwork.IsMasterClient){
Debug.Log("Sending Timer Signal");
RaiseEventOptions raiseEventOptions = new RaiseEventOptions{Receivers = ReceiverGroup.All};
PhotonNetwork.RaiseEvent(GameStartEventCode, null, raiseEventOptions, SendOptions.SendReliable);
}
}
public static LootItemScriptableObject GetLootByName(string spawnableName)
{
foreach(LootItemScriptableObject loot in instance.loots)
{
if(loot.spawnableName == spawnableName)
{
return loot;
}
}
return null;
}
void OnEnable()
{
PhotonNetwork.AddCallbackTarget(this);
}
void OnDisable()
{
PhotonNetwork.RemoveCallbackTarget(this);
}
public const byte GameStartEventCode= 1;
public const byte BeginGameModeCode= 2;
public void OnEvent(EventData photonEvent)
{
byte eventCode = photonEvent.Code;
if(eventCode == GameStartEventCode)
{
StartCoroutine(BeginStartTimer());
}else if(eventCode == BeginGameModeCode){
isInit=true;
object[] customData = (object[])photonEvent.CustomData;
StartTime = (double)customData[0];
desiredGameMode = customData[1].ToString();
Debug.Log("Starting game");
if(PhotonNetwork.IsMasterClient){
SpawnLoots();
StartCoroutine(HideRoomIn((float)DeathmatchRoundLength /2f));
}
InventoryManager.ResetStocks();
if(desiredGameMode == GameModes.Deathmatch.ToString()){
InventoryManager.instance.GiveDefaultLoots(DeathmatchDefaultInventory);
}
localPlayer.transform.position = SpawnPositions[customPlayerId].position;
}
}
IEnumerator HideRoomIn(float length){
yield return new WaitForSeconds(length);
PhotonNetwork.CurrentRoom.IsOpen = false;
}
IEnumerator BeginStartTimer(){
int t = DeathmtachRoundCountdown;
while(t > 0){
UIManager.SetStatusText("Starting game in " + t);
yield return new WaitForSecondsRealtime(1);
t--;
}
UIManager.SetStatusText("");
if(PhotonNetwork.IsMasterClient){
RaiseEventOptions raiseEventOptions = new RaiseEventOptions{Receivers = ReceiverGroup.All};
PhotonNetwork.RaiseEvent(BeginGameModeCode, new object[]{PhotonNetwork.Time, desiredGameMode}, raiseEventOptions, SendOptions.SendReliable);
}
}
}
[System.Serializable]
public struct InventoryEntry{
public LootItemScriptableObject loot;
public int count;
}
public enum GameModes{
Deathmatch,
TeamDeathmatch,
BattleRoyale
}