386 lines
12 KiB
C#
386 lines
12 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 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;
|
|
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());
|
|
//
|
|
|
|
}
|
|
|
|
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(){
|
|
int position =0;
|
|
for(position=0; position < Leaderboard.list.Length; position++){
|
|
if(Leaderboard.list[position] == localPlayer.playerNetwork){
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(PhotonNetwork.IsMasterClient){
|
|
StartCoroutine(Coroutine_SubmitSession());
|
|
}
|
|
Cursor.lockState = CursorLockMode.None;
|
|
Cursor.visible = true;
|
|
CameraFollow.Pause();
|
|
if(desiredGameMode == GameModes.Deathmatch.ToString()){
|
|
UIManager.ShowDeathmatchFinishScreen(position, Leaderboard.list[0].username);
|
|
}
|
|
|
|
|
|
PhotonNetwork.LeaveRoom();
|
|
|
|
StartCoroutine(PlayAgain());
|
|
}
|
|
|
|
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;
|
|
|
|
//Wait for Players
|
|
if(PhotonNetwork.IsMasterClient){
|
|
while(PhotonNetwork.CurrentRoom.PlayerCount < 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){
|
|
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;
|
|
|
|
isInit=true;
|
|
}
|
|
}
|
|
|
|
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
|
|
} |