170 lines
6.2 KiB
C#
170 lines
6.2 KiB
C#
using System;
|
|
using Ext.B83.Unity.Attributes;
|
|
using InterfaceOff.MainMenu;
|
|
using InterfaceOff.WorldScene;
|
|
using UnityEngine;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace InterfaceOff
|
|
{
|
|
[Serializable] public struct SpawnableWindowType
|
|
{
|
|
[field: SerializeField, MonoScript] private string Typename { get; set; }
|
|
public Type Type => Type.GetType(Typename);
|
|
|
|
[field: SerializeField] public int SpawnWeight { get; private set; }
|
|
}
|
|
|
|
public class WindowSpawner : MonoBehaviour
|
|
{
|
|
[field: SerializeField] private GameObject SampleChild { get; set; }
|
|
[field: SerializeField] private Canvas GameCanvas { get; set; }
|
|
[field: SerializeField] private GameObject DeathInfo { get; set; }
|
|
[field: SerializeField] private SpawnableWindowType[] WindowTypes { get; set; }
|
|
[field: SerializeField] private GameObject Parent { get; set; }
|
|
[field: SerializeField] private GameObject PasswordField { get; set; }
|
|
[field: SerializeField] private GameObject LeaderboardObject { get; set; }
|
|
private int TotalSpawnWeight { get; set; }
|
|
|
|
[field: SerializeField] public int SpawnedWindowCount { get; private set; }
|
|
|
|
[field: SerializeField] public bool AutoSpawn { get; private set; } = true;
|
|
private int TimeTillNextSpawn { get; set; }
|
|
|
|
private void Awake()
|
|
{
|
|
/* Logs the amount of types found and errors if there is none */
|
|
Debug.Log($"Found [{WindowTypes.Length}] different window types ");
|
|
if (WindowTypes.Length == 0)
|
|
{
|
|
Debug.LogError("Could not find any window types");
|
|
return;
|
|
}
|
|
|
|
/* Calculates the total spawn weight */
|
|
TotalSpawnWeight = 0;
|
|
foreach (SpawnableWindowType type in WindowTypes)
|
|
{
|
|
TotalSpawnWeight += type.SpawnWeight;
|
|
}
|
|
}
|
|
|
|
private Type GetRandomWindowType()
|
|
{
|
|
int currentTypeWeight = Random.Range(0, TotalSpawnWeight);
|
|
foreach (SpawnableWindowType type in WindowTypes)
|
|
{
|
|
currentTypeWeight -= type.SpawnWeight;
|
|
if (currentTypeWeight <= 0)
|
|
{
|
|
return type.Type;
|
|
}
|
|
}
|
|
|
|
return WindowTypes[0].Type;
|
|
}
|
|
|
|
private void SpawnNewRandomWindow()
|
|
{
|
|
/* Creates the gameobject with a random class */
|
|
GameObject go = Instantiate(SampleChild, Parent.transform);
|
|
go.SetActive(true);
|
|
|
|
Type type = GetRandomWindowType();
|
|
go.name = type.Name;
|
|
|
|
WindowBase windowBase = go.AddComponent(type) as WindowBase;
|
|
|
|
/* Checks it created correctly before instantiating further */
|
|
if (DebugUtils.IsNull(windowBase))
|
|
{
|
|
Debug.LogError("How did this happen");
|
|
return;
|
|
}
|
|
|
|
/* Updates the window trackers */
|
|
SpawnedWindowCount++;
|
|
|
|
/* Makes sure the WindowInteractions and WindowComponents are set up before passing to user code */
|
|
windowBase.Interactions = go.GetComponent<WindowInteractions>();
|
|
windowBase.Interactions.SetAttachedTo(windowBase);
|
|
|
|
windowBase.Components = go.GetComponent<WindowComponents>();
|
|
windowBase.InstantiateWindowBase(creator: this);
|
|
}
|
|
|
|
public void AlertOfDespawnedWindow() => SpawnedWindowCount--;
|
|
|
|
private int SpawnyThingyMajig = 900; // Sky chose dis
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
/* Spawns new windows whilst active */
|
|
if (AutoSpawn)
|
|
{
|
|
/* Has a random choice for the PasswordField to show up */
|
|
if (SpawnyThingyMajig == 0)
|
|
{
|
|
PasswordField.SetActive(true);
|
|
SpawnyThingyMajig = Random.Range(200, 1000);
|
|
}
|
|
else
|
|
{
|
|
SpawnyThingyMajig--;
|
|
}
|
|
|
|
/* Calculates the current max spawn time */
|
|
const int TICKS_PER_SECOND = 20; // Unity constant
|
|
const int MIN_SPAWN_TIME = 2 * TICKS_PER_SECOND;
|
|
const int MAX_SPAWN_TIME = 5 * TICKS_PER_SECOND;
|
|
|
|
int currentMaxSpawnTime = MAX_SPAWN_TIME - (int)(ScoreTracker.CurrentScore() * DifficultyManager.DifficultyEffect);
|
|
currentMaxSpawnTime = Math.Clamp(currentMaxSpawnTime, MIN_SPAWN_TIME + 1, MAX_SPAWN_TIME);
|
|
|
|
/* Decreases the spawn counter and spawns if at 0 */
|
|
TimeTillNextSpawn = Math.Max(0, TimeTillNextSpawn - 1);
|
|
if (TimeTillNextSpawn == 0)
|
|
{
|
|
float difficulty = DifficultyManager.DifficultyMultiplier;
|
|
TimeTillNextSpawn = Random.Range((int)(MIN_SPAWN_TIME * difficulty), (int)(currentMaxSpawnTime / difficulty));
|
|
SpawnNewRandomWindow();
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
/* Makes sure the password overlay does not interfere */
|
|
PasswordField.SetActive(false);
|
|
|
|
/* Else checks if it should change the active scene */
|
|
if (Input.GetKey(KeyCode.Space) && !LeaderboardObject.activeSelf)
|
|
{
|
|
SceneController.ReloadScene();
|
|
}
|
|
|
|
else if (Input.GetKey(KeyCode.Tab) && !LeaderboardObject.activeSelf)
|
|
{
|
|
SceneController.Load(name: "MenuScene");
|
|
}
|
|
}
|
|
}
|
|
|
|
public void StartEndSequence()
|
|
{
|
|
/* Destroys all children and stops them from spawning */
|
|
AutoSpawn = false;
|
|
foreach (Transform child in Parent.transform)
|
|
{
|
|
WindowBase window = child.GetComponent<WindowBase>();
|
|
if (DebugUtils.IsNotNull(window))
|
|
{
|
|
window.DestroyWindow();
|
|
}
|
|
}
|
|
|
|
/* Makes the death text visible to the player */
|
|
DeathInfo.SetActive(true);
|
|
}
|
|
}
|
|
}
|