metahunt/Assets/Scripts/Managers/MainMenu.cs
2024-02-11 13:53:18 +05:30

405 lines
12 KiB
C#

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using ExitGames.Client.Photon;
using ExitGames.Client.Photon.StructWrapping;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class MainMenu : MonoBehaviourPunCallbacks, IOnEventCallback
{
public const byte MatchmadeEventCode = 1;
public const byte StartMatchmakeEventCode = 2;
public const byte StopMatchmakeEventCode = 3;
#region overrides
public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
base.OnRoomListUpdate(roomList);
RoomList = roomList;
Debug.Log($"{RoomList.Count} rooms available");
}
public override void OnConnectedToMaster()
{
base.OnConnectedToMaster();
Debug.Log("Connected to photon");
PhotonNetwork.JoinLobby();
PhotonNetwork.LocalPlayer.NickName = UserDataManager.instance.Username;
}
public override void OnJoinedLobby()
{
base.OnJoinedLobby();
PhotonNetwork.LocalPlayer.NickName = UserDataManager.instance.Username;
if(queuedRoomname == "GAME_READY"){
SceneManager.LoadScene("SampleScene");
return;
}
JoinQueuedRoom();
}
public override void OnPlayerEnteredRoom(Player newPlayer)
{
base.OnPlayerEnteredRoom(newPlayer);
UpdateLobbyPlayers();
}
public override void OnPlayerLeftRoom(Player otherPlayer)
{
base.OnPlayerLeftRoom(otherPlayer);
UpdateLobbyPlayers();
}
public override void OnJoinedRoom()
{
base.OnJoinedRoom();
Debug.Log("Connected to new room : " + PhotonNetwork.CurrentRoom.Name);
loadingPanel.SetActive(false);
UpdateLobbyPlayers();
}
#endregion
public GameObject[] panels;
public TMP_Text usernameTxt;
public TMP_Text xpTxt;
public Button btnPlay;
public Button btnCancel;
public Transform InviteListParent;
public GameObject InviteListItemPrefab;
public GameObject[] LobbyPlayerObjects;
public TMP_Text[] LobbyPlayerNameTexts;
public ComboSelection GameModeSelector;
public string myRoomname;
public GameObject loadingPanel;
void Start()
{
loadingPanel.SetActive(true);
DisableLobbyPlayers();
myRoomname = UserDataManager.instance.Username +"#"+UserDataManager.instance.UserID;
queuedRoomname = myRoomname;
if(!PhotonNetwork.IsConnected){
PhotonNetwork.ConnectUsingSettings();
}else{
if(PhotonNetwork.InLobby){PhotonNetwork.LeaveLobby();}
Debug.Log("Already connected to photon, Joining lobby");
PhotonNetwork.JoinLobby();
}
GameModeSelector.OnSelectedChanged.AddListener(OnSelectedGameModeChanged);
RefreshUserdata();
UserDataManager.instance.OnInvitesUpdated = OnInvitesUpdated;
btnPlay.onClick.AddListener(PlayClicked);
btnCancel.onClick.AddListener(CancelClicked);
}
void Update(){
if(btnCancel.gameObject.activeSelf){
matchmakingTimer+=Time.deltaTime;
btnCancel.transform.GetChild(1).GetComponent<TMP_Text>().text = Helpers.secondsToTimerString(matchmakingTimer);
}
}
public string gameModeSelection => GameModeSelector.SelectedOption.ToLower();
void OnSelectedGameModeChanged(){
GameModes gameMode = GameModes.Deathmatch;
if(gameModeSelection == "dm"){gameMode = GameModes.Deathmatch;}
if(gameModeSelection== "tdm"){gameMode = GameModes.TeamDeathmatch;}
if(gameModeSelection == "br"){gameMode = GameModes.BattleRoyale;}
GameManager.desiredGameMode = gameMode.ToString();
}
void OnInvitesUpdated(){
foreach(Transform t in InviteListParent.GetComponentsInChildren<Transform>()){
if(t== InviteListParent){continue;}
Destroy(t.gameObject);
}
for(int i=0; i < UserDataManager.instance.Invites.Count; i++){
Invite invite = UserDataManager.instance.Invites[i];
GameObject newInviteItem = Instantiate(InviteListItemPrefab, InviteListParent);
newInviteItem.transform.GetChild(0).GetComponent<TMP_Text>().text = $"Lobby Invite from <color=green>{invite.host}";
newInviteItem.transform.GetChild(1).GetComponent<Button>().onClick.AddListener(()=>{ JoinFriendsLobby(invite.host, invite.host_id,invite.id); });
newInviteItem.transform.GetChild(2).GetComponent<Button>().onClick.AddListener(()=>{ StartCoroutine(CoroutineDeleteInvite(invite.id)); });
}
}
void PlayClicked(){
// StartMatchmaking();
PhotonNetwork.RaiseEvent(StartMatchmakeEventCode, "", EveryoneRaiseEventOptions, new SendOptions());
// PlayDM();
}
void CancelClicked(){
PhotonNetwork.RaiseEvent(StopMatchmakeEventCode, "", EveryoneRaiseEventOptions, new SendOptions());
}
void JoinFriendsLobby(string hostname, int hostid, int inviteid){
StartCoroutine(CoroutineDeleteInvite(inviteid));
string roomName = hostname+"#"+hostid;
JoinAnotherRoom(roomName);
}
public void JoinAnotherRoom(string roomname){
if(PhotonNetwork.InRoom){
queuedRoomname=roomname;
PhotonNetwork.LeaveRoom();
}else{
PhotonNetwork.JoinRoom(roomname);
}
}
string queuedRoomname;
void JoinQueuedRoom(){
loadingPanel.SetActive(true);
if(queuedRoomname.Length >0){
PhotonNetwork.JoinOrCreateRoom(queuedRoomname, new RoomOptions(){IsOpen=true, IsVisible=true}, TypedLobby.Default);
}
queuedRoomname="";
}
void DisableLobbyPlayers(){
foreach(GameObject player in LobbyPlayerObjects){
player.SetActive(false);
}
foreach(TMP_Text txt in LobbyPlayerNameTexts){
txt.text = "";
}
}
public bool isHost {get{return PhotonNetwork.CurrentRoom.Name == myRoomname;}}
void UpdateLobbyPlayers(){
if(PhotonNetwork.CurrentRoom.PlayerCount <= 1 && PhotonNetwork.CurrentRoom.Name != myRoomname){
Debug.Log("everyone left, Im going back home");
JoinAnotherRoom(myRoomname);
return;
}
GameManager.partyMembers = new List<string>();
for(int i=0; i < LobbyPlayerObjects.Length; i++){
bool withinRange = i < PhotonNetwork.PlayerListOthers.Length;
// bool withinRange = i < PhotonNetwork.CurrentRoom.PlayerCount -1;
LobbyPlayerObjects[i].SetActive(withinRange);
LobbyPlayerNameTexts[i].text = withinRange ? PhotonNetwork.PlayerListOthers[i].NickName : "";
if(withinRange && isHost){
GameManager.partyMembers.Add(PhotonNetwork.PlayerListOthers[i].NickName);
}
}
//Uodate cotrols
btnPlay.interactable=PhotonNetwork.IsMasterClient;
GameModeSelector.SetInteractable(PhotonNetwork.IsMasterClient);
}
IEnumerator CoroutineDeleteInvite(int inviteId){
foreach(Invite invite in UserDataManager.instance.Invites){
if(invite.id == inviteId){
UserDataManager.instance.Invites.Remove(invite);
break;
}
}
OnInvitesUpdated();
WWWForm form =new WWWForm();
form.AddField("id", inviteId);
WWW req = new WWW(UserDataManager.GetApiUrl("delete_invite"),form);
yield return req;
Debug.Log(req.text);
UserDataManager.instance.RefreshInvites();
}
void RefreshUserdata(){
usernameTxt.text = UserDataManager.instance.Username;
xpTxt.text = (UserDataManager.instance.Kills * 10f).ToString("n0") + " XP";
}
public static List<RoomInfo> RoomList;
public void ShowGameModes(){
foreach(GameObject panel in panels){
panel.SetActive(panel.name == "GameModes");
}
}
public void ShowMainMenu(){
foreach(GameObject panel in panels){
panel.SetActive(panel.name == "MainMenu");
}
}
public void ShowOptions(){
foreach(GameObject panel in panels){
panel.SetActive(panel.name == "Options");
}
}
public void ShowCrosshairOptions(){
foreach(GameObject panel in panels){
panel.SetActive(panel.name == "CrosshairOptions");
}
}
float matchmakingTimer = 0;
RaiseEventOptions EveryoneRaiseEventOptions =new RaiseEventOptions(){Receivers = ReceiverGroup.All};
RaiseEventOptions OthersRaiseEventOptions =new RaiseEventOptions(){Receivers = ReceiverGroup.All};
Coroutine MathcmakeOperation;
public void StartMatchmaking(){
btnPlay.gameObject.SetActive(false);
btnCancel.gameObject.SetActive(true);
GameModeSelector.SetInteractable(false);
matchmakingTimer = 0;
MathcmakeOperation = StartCoroutine(CoroutineMatchmake());
}
IEnumerator CoroutineMatchmake(){
GameManager.partyId = PhotonNetwork.CurrentRoom.Name;
while(true){
string roomnameBase = $"room_{gameModeSelection}";
bool foundRoom =false;
List<string> suitableRooms = new List<string>();
foreach(RoomInfo room in RoomList){
if(room.Name.Contains(roomnameBase)){
//Suitable Room
suitableRooms.Add(room.Name);
if(room.MaxPlayers - room.PlayerCount > PhotonNetwork.CurrentRoom.PlayerCount){
//Has room!
// PhotonNetwork.RaiseEvent(MatchmadeEventCode, room.Name, EveryoneRaiseEventOptions, new SendOptions());
OnMatchmade(room.Name);
foundRoom= true;
break;
}
}
}
if(!foundRoom){
string newRoomname = "";
for(int i=0;i < 100; i++){
newRoomname = roomnameBase +"#" + i;
if(!suitableRooms.Contains(newRoomname)){
break;
}
}
OnMatchmade(newRoomname);
}
yield return new WaitForSeconds(1);
}
}
void OnMatchmade(string newRoomname){
if(!PhotonNetwork.IsMasterClient){Debug.Log("Match found but im not the boss"); return;}
PhotonNetwork.RaiseEvent(MatchmadeEventCode, newRoomname, EveryoneRaiseEventOptions, new SendOptions());
}
public void CancelMatchmaking(){
btnCancel.gameObject.SetActive(false);
btnPlay.gameObject.SetActive(true);
GameModeSelector.SetInteractable(true);
StopCoroutine(MathcmakeOperation);
}
public void Play()
{
GameManager.desiredGameMode = GameModes.Deathmatch.ToString();
SceneManager.LoadScene("SampleScene");
}
public void PlayDM(){
string roomName = "";
for(int i=0; i < RoomList.Count; i++){
if(RoomList[i].IsOpen){
roomName = RoomList[i].Name;
break;
}
}
if(roomName == ""){roomName="Deathmatch#" + RoomList.Count;}
Debug.Log("Room name is " + roomName);
queuedRoomname = "GAME_READY";
PhotonNetwork.LeaveRoom();
GameManager.RoomName = roomName;
}
void LoadGame(string newRoomname){
queuedRoomname = "GAME_READY";
PhotonNetwork.LeaveRoom();
GameManager.RoomName = newRoomname;
}
private void OnEnable()
{
PhotonNetwork.AddCallbackTarget(this);
}
private void OnDisable()
{
PhotonNetwork.RemoveCallbackTarget(this);
}
public void OnEvent(EventData photonEvent)
{
byte eventCode = photonEvent.Code;
if(eventCode == MatchmadeEventCode){
string newRoomName = (string)photonEvent.CustomData;
LoadGame(newRoomName);
}else if(eventCode == StartMatchmakeEventCode){
StartMatchmaking();
}else if(eventCode == StopMatchmakeEventCode){
CancelMatchmaking();
}
}
}