using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngineInternal; using Random = UnityEngine.Random; public class GameManager : MonoBehaviour { // interfaces public GameObject playerPrefab; public DifficultyManager difficultyManager = new DifficultyManager(); public ScoreManager scoreManager; public LearningEngine learningEngine; // trackers public int noOfHits = 0; public int health = 100; public int noOfKills = 0; public float currentTimeElapsed; public List<GameObject> friendlySpawns = new List<GameObject>(); public List<GameObject> enemySpawns = new List<GameObject>(); public List<GameObject> currentEnemies = new List<GameObject>(); // constants public float startTime; public GameResults results; public bool useKillsAsWincon; public float winConValue; public GameObject enemyToSpawn; public String logFileName = "GAMELOG.json"; // difficulty affecting values public float enemyNoticeRate = 0.6f; // speed at which enemy starts firing upon seeing you public float enemyDamage = 10; // damage of enemy bullets public float enemyFireRate = 0.6f; // minimum time between enemy shots public float enemyMaxFireRate = 1.5f; public float enemyAimModifier = 0.05f; // bullet spread of enemies public float playerHealRate = 0.05f; // amount player heals per successful shot public float enemyHealth = 100; // enemy maximum health public float enemySpawnRate = 5; // number of enemies spawning on the map at once public float enemySpeed = 1.5f; // Start is called before the first frame update void Start() { learningEngine = GetComponent<LearningEngine>(); useKillsAsWincon = true; winConValue = PlayerPrefs.GetFloat("targetKills"); results = new GameResults(); startTime = Time.time; var spawn = friendlySpawns[Random.Range(0, friendlySpawns.Count)]; Destroy(playerPrefab); var newPlayer = Instantiate(playerPrefab, spawn.transform.position, spawn.transform.rotation); newPlayer.GetComponent<PlayerInput>().enabled = true; newPlayer.GetComponent<PlayerController>().enabled = true; newPlayer.GetComponent<PlayerMovement>().enabled = true; newPlayer.GetComponent<SlidingMovement>().enabled = true; newPlayer.GetComponent<InterpolatedTransformUpdater>().enabled = true; playerPrefab = newPlayer; SetInitialPrefs(); if (!PlayerPrefs.HasKey("gameLog")) { PlayerPrefs.SetString("gameLog", JsonUtility.ToJson(new GameLog())); } if (PlayerPrefs.HasKey("levelShift") && PlayerPrefs.GetInt("levelShift") != 0 && PlayerPrefs.GetInt("difficultyAdjustmentEnabled") == 1) { var lastLevel = PlayerPrefs.GetInt("overallLevel"); // set limits after var level = PlayerPrefs.GetInt("levelShift"); PlayerPrefs.SetInt("overallLevel", lastLevel + level); enemyNoticeRate += (0.03f * level); enemyNoticeRate = Mathf.Clamp(enemyNoticeRate, 0.3f, 1f); PlayerPrefs.SetFloat("enemyNoticeRate", enemyNoticeRate); enemyDamage += (0.3f * level); enemyDamage = Mathf.Clamp(enemyDamage, 5f, 20f); PlayerPrefs.SetFloat("enemyDamage", enemyDamage); enemyFireRate -= (0.04f * level); enemyFireRate = Mathf.Clamp(enemyFireRate, 0.4f, 0.8f); PlayerPrefs.SetFloat("enemyFireRate", enemyFireRate); enemyMaxFireRate -= (0.04f * level); enemyMaxFireRate = Mathf.Clamp(enemyMaxFireRate, enemyFireRate, 2f); PlayerPrefs.SetFloat("enemyMaxFireRate", enemyMaxFireRate); enemyAimModifier -= (0.005f * level); enemyAimModifier = Mathf.Clamp(enemyAimModifier, 0.001f, 0.1f); PlayerPrefs.SetFloat("enemyAimModifier", enemyAimModifier); enemyHealth += (3f * level); enemyHealth = Mathf.Clamp(enemyHealth, 50f, 200f); PlayerPrefs.SetFloat("enemyHealth", enemyHealth); enemySpawnRate += (0.2f * level); enemySpawnRate = Mathf.Clamp(enemySpawnRate, 3, 15); PlayerPrefs.SetFloat("enemySpawnRate", enemySpawnRate); enemySpeed -= (0.05f * level); enemySpeed = Mathf.Clamp(enemySpeed, 0.25f, 2f); PlayerPrefs.SetFloat("enemySpeed", enemySpeed); } SpawnEnemy((int) Math.Round(enemySpawnRate)); // change this to be rounding } // Update is called once per frame void Update() { if (Input.GetKeyUp("escape")) { Cursor.lockState = CursorLockMode.None; Cursor.visible = true; SceneManager.LoadScene("MainMenu", LoadSceneMode.Single); } currentTimeElapsed = Time.time - startTime; if (CheckIfGameOver()) { // add retry menu Cursor.lockState = CursorLockMode.None; Cursor.visible = true; ConstructJsonToPrefs(); SceneManager.LoadScene("ResultsMenu", LoadSceneMode.Single); } } public void LogResults(GameResults result) { Logger log; if (File.Exists(Application.persistentDataPath + "/" + logFileName)) { var sr = new StreamReader(Application.persistentDataPath + "/" + logFileName); var fileContents = sr.ReadToEnd(); sr.Close(); log = JsonUtility.FromJson<Logger>(fileContents); } else { log = new Logger(); } log.resultsList.Add(result); var sr2 = new StreamWriter(Application.persistentDataPath + "/" + logFileName); var outJson = JsonUtility.ToJson(log); sr2.WriteLine(outJson); sr2.Close(); } public void StoreDifficultySettings() { results.enemyDamage = PlayerPrefs.GetFloat("enemyDamage"); results.enemyNoticeRate = PlayerPrefs.GetFloat("enemyNoticeRate"); results.enemyFireRate = PlayerPrefs.GetFloat("enemyFireRate"); results.enemyMaxFireRate = PlayerPrefs.GetFloat("enemyMaxFireRate"); results.enemyAimModifier = PlayerPrefs.GetFloat("enemyAimModifier"); results.enemyHealth = PlayerPrefs.GetFloat("enemyHealth"); results.enemySpawnRate = PlayerPrefs.GetFloat("enemySpawnRate"); results.enemySpeed = PlayerPrefs.GetFloat("enemySpeed"); results.graphicalTipsEnabled = PlayerPrefs.GetInt("graphicsEnabled"); results.textualTipsEnabled = PlayerPrefs.GetInt("textEnabled"); results.ddaEnabled = PlayerPrefs.GetInt("difficultyAdjustmentEnabled"); results.movingEnabled = PlayerPrefs.GetInt("playerTrackingEnabled"); results.headshotEnabled = PlayerPrefs.GetInt("playerHeadshotEnabled"); results.accuracyEnabled = PlayerPrefs.GetInt("playerAccuracyEnabled"); results.ttdEnabled = PlayerPrefs.GetInt("playerTtdEnabled"); results.ttkEnabled = PlayerPrefs.GetInt("playerTtkEnabled"); results.vcEnabled = PlayerPrefs.GetInt("playerVerticalCrosshairEnabled"); results.hcEnabled = PlayerPrefs.GetInt("playerHorizontalCrosshairEnabled"); results.missesEnabled = PlayerPrefs.GetInt("playerMissesEnabled"); results.dsEnabled = PlayerPrefs.GetInt("playerDamageSourcesEnabled"); } public void ConstructJsonToPrefs() { results.kills = noOfKills; results.timeElapsed = currentTimeElapsed; results.timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); results.health = health; results = scoreManager.SetResults(results); StoreDifficultySettings(); var levelShift = difficultyManager.DecideLevel(results); PlayerPrefs.SetInt("levelShift", levelShift); var lastLevel = PlayerPrefs.GetInt("overallLevel"); Debug.Log(difficultyManager.gamerScore); Debug.Log(lastLevel); results.score = difficultyManager.gamerScore * lastLevel; results.level = lastLevel; LogResults(results); var json = JsonUtility.ToJson(results); PlayerPrefs.SetString("lastGame", json); difficultyManager.LogGame(results); } public void SetInitialPrefs() { if (!PlayerPrefs.HasKey("enemyNoticeRate")) { PlayerPrefs.SetFloat("enemyNoticeRate", enemyNoticeRate); PlayerPrefs.SetFloat("enemyDamage", enemyDamage); PlayerPrefs.SetFloat("enemyFireRate", enemyFireRate); PlayerPrefs.SetFloat("enemyMaxFireRate", enemyMaxFireRate); PlayerPrefs.SetFloat("enemyAimModifier", enemyAimModifier); PlayerPrefs.SetFloat("enemyHealth", enemyHealth); PlayerPrefs.SetFloat("enemySpawnRate", enemySpawnRate); PlayerPrefs.SetFloat("enemySpeed", enemySpeed); } enemyNoticeRate = PlayerPrefs.GetFloat("enemyNoticeRate"); enemyDamage = PlayerPrefs.GetFloat("enemyDamage"); enemyFireRate = PlayerPrefs.GetFloat("enemyFireRate"); enemyMaxFireRate = PlayerPrefs.GetFloat("enemyMaxFireRate"); enemyAimModifier = PlayerPrefs.GetFloat("enemyAimModifier"); enemyHealth = PlayerPrefs.GetFloat("enemyHealth"); enemySpawnRate = PlayerPrefs.GetFloat("enemySpawnRate"); enemySpeed = PlayerPrefs.GetFloat("enemySpeed"); } public bool CheckIfGameOver() { if (health < 1) { results.won = false; return true; } if (noOfKills >= winConValue) { results.won = true; return true; } return false; } public void SpawnEnemy(int count) { for (var i = 0; i < count; i++) { GameObject finalSpawn = null; // shuffle spawn list for (int j = 0; j < enemySpawns.Count; j++) { GameObject temp = enemySpawns[j]; int randomIndex = Random.Range(j, enemySpawns.Count); enemySpawns[j] = enemySpawns[randomIndex]; enemySpawns[randomIndex] = temp; } for (var j = 0; j < enemySpawns.Count; j++) { var spawn = enemySpawns[j]; var position = spawn.transform.position; var origin = new Vector3(position.x, position.y + 4, position.z); var dir = (playerPrefab.transform.position - origin).normalized; RaycastHit hit; var cantSeePlayer = false; if (Physics.Raycast(origin, dir, out hit, Mathf.Infinity)) { if (!hit.collider.gameObject.CompareTag("Player")) { cantSeePlayer = true; } } var tooCloseToExisting = false; for (int k = 0; k < currentEnemies.Count; k++) { if (Vector3.Distance(spawn.transform.position, currentEnemies[k].transform.position) < 10f) { tooCloseToExisting = true; } } if (cantSeePlayer && !tooCloseToExisting) { finalSpawn = spawn; break; } } if (finalSpawn != null) { var enemy = Instantiate(enemyToSpawn, finalSpawn.transform.position, finalSpawn.transform.rotation); enemy.GetComponent<EnemyManager>().SetConstants(); currentEnemies.Add(enemy); } } } public void RemoveEnemy(GameObject enemy) { currentEnemies.Remove(enemy); } public float GetScore() { return scoreManager.GetScore(); } public void AddHit() { noOfHits += 1; } public void AddKill() { noOfKills += 1; } public int GetNoKills() { return noOfKills; } public int GetNoHits() { return noOfHits; } public int GetHealth() { return health; } public float GetCurrentElapsedTime() { return currentTimeElapsed; } public void DealDamage(int damage) { health -= damage; } public void ReportTimeToDamage(float time, EnemyManager enemy) { scoreManager.timesToDamage.Add(time); learningEngine.ReportTimeToDamage(time, enemy); } public void ReportHealthLoss(float health, EnemyManager enemy) { scoreManager.healthLossPerEnemy.Add(health); learningEngine.ReportHealthLoss(enemy, (int) health); } public void ReportTimeToKill(float time, EnemyManager enemy) { scoreManager.timesToKill.Add(time); learningEngine.ReportTimeToKill(time, enemy); } public void ReportHitShot(bool headshot, EnemyManager enemy) { if (headshot) { scoreManager.headshots += 1; } learningEngine.ReportHeadshot(headshot, enemy); scoreManager.hitshots += 1; } public void ReportFiredShot() { scoreManager.firedshots += 1; } public void HealPlayer(float damage) { health += (int) Math.Round(damage * playerHealRate); // round this properly } }