using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using Networking.Server; public abstract class GameMode : ScriptableObject { [SerializeField] [Tooltip("Scene to load which contains Gamemode UI")] private string GameModeScene; [SerializeField] [Tooltip("Round Times are acessed from the top down")] private List RoundTimes; public Action GameStartEvent; public Action InputStartEvent; public Action RoundStartEvent; public Action AllPlayersMovedEvent; public Action RoundEndEvent; public Action OnGameOverEvent; private List gameTimes; /// /// Called once before any players have spawned /// protected virtual void OnPreGameStart() { } /// /// Called once after players have spawned /// /// All players in game protected virtual void OnGameStart(PlayerData[] allPlayers) { } /// /// Called every time players are moved to the input scene /// /// All players in game protected virtual void OnInputStart(PlayerData[] allPlayers) { } /// /// Called for each player when we recieve their input /// /// Player who's input we recieved protected virtual void OnRecievedPlayerInput(PlayerData player) { } /// /// Called after we have recieved all player input /// /// All players in game protected virtual void OnInputEnd(PlayerData[] allPlayers) { } /// /// Called at the beginning of a new Round /// protected virtual void OnRoundStart(PlayerData[] allPlayers) { } /// /// Called for each player after they finished one move. Even if they didn't move! /// /// Character which moved /// Client which controls character /// Block which the character finished on protected virtual void OnPlayerMoved(Character character, ClientData client, Block currentBlock) { } protected virtual void OnPlayerKilled(Character character, ClientData client) { } /// /// Called once after every player has finished one move /// /// List of all player Info protected virtual void OnAllPlayersMoved(PlayerData[] allPlayers) { } /// /// Called after all environmentblocks have taken their turn /// /// All players in scene protected virtual void OnEnvironmentTurn(PlayerData[] allPlayers) { } /// /// Called after one round has finished /// /// all players in game protected virtual void OnRoundEnd(PlayerData[] allPlayers) { } /// /// Called once at end of game /// /// All players in game protected virtual void OnGameOver(PlayerData[] allPlayers) { } /// /// Called to check if victory condition has been met /// /// All players in game /// returns true if victory condition has been met public abstract bool isGameOver(PlayerData[] allPlayers); public float GetRoundTime() { float retVal = gameTimes[0]; if (gameTimes.Count > 1) gameTimes.RemoveAt(0); return retVal; } #region Public functions public void PreGameStart() { OnPreGameStart(); } public void GameStart(PlayerData[] allPlayers) { gameTimes = new List(RoundTimes); if (!String.IsNullOrEmpty(GameModeScene)) UnityEngine.SceneManagement.SceneManager.LoadScene(GameModeScene, UnityEngine.SceneManagement.LoadSceneMode.Additive); for (int i = 0; i < allPlayers.Length; i++) { allPlayers[i].client.Lives = 3; } OnGameStart(allPlayers); GameStartEvent?.Invoke(); } public void InputStart(PlayerData[] AllPlayers) { OnInputStart(AllPlayers); InputStartEvent?.Invoke(); } public void RecievedPlayerInput(PlayerData player) { OnRecievedPlayerInput(player); } public void InputEnd(PlayerData[] AllPlayers) { } public abstract PlayerData[] getPlayerOrder(PlayerData[] AllPlayers); public void RoundStart(PlayerData[] allPlayers) { OnRoundStart(allPlayers); RoundStartEvent?.Invoke(); } public void PlayerMoved(PlayerData player) { OnPlayerMoved(player.character, player.client, player.character.CurrentBlock); } public void PlayerKilled(PlayerData player) { OnPlayerKilled(player.character, player.client); } public void AllPlayersMoved(PlayerData[] allPlayers) { OnAllPlayersMoved(allPlayers); AllPlayersMovedEvent?.Invoke(); } public void EnvironmentTurn(PlayerData[] allPlayers) { OnEnvironmentTurn(allPlayers); } public void RoundEnd(PlayerData[] allPlayers) { OnRoundEnd(allPlayers); RoundEndEvent?.Invoke(); } public void GameEnd(PlayerData[] allPlayers) { OnGameOver(allPlayers); OnGameOverEvent?.Invoke(); } } #endregion Public Functions /* --- Calls we need --- * * PreGameSetup(); - //Called once before the game actually starts * GameStart(PlayerData[] AllPlayers); //Called once after players have Spawned * * OnInputStart(PlayerData[] AllPlayers) //Called when players enter input mode * OnRecievedPlayerInput(PlayerData Player) //Called when a specific player has sent their input * OnInputEnd(PlayerData[] AllPlayers) //Called when player input mode has finished * * OnRoundStart(PlayerData[] AllPlayers) //Just before Players start moving * * ------- Start Round Loop ------- * * OnPlayerMoved(PlayerData player) //Called after each player moves * IsGameOver(PlayerData[] AllPlayers) //Called after each player moves * * AllPlayersMoved(PlayerData[] AllPlayers) //Called after all players have moved * EnvironmentTurn() //Also called after all players have moved but should be kept specialised to environment stuff * IsGameOver(PlayerData[] AllPlayers) //We need to check if the environment terminated the game * * --------- End Game Loop --------- * * OnRoundEnd(PlayerData[] AllPlayers) //Called after movements are made * IsGameOver(PlayerData[] AllPlayers) //This needs to be checked again * * GameEnd(PlayerData[] AllPlayers) * * * * * */