using System;
using UnityEngine;
using System.Collections;
using System.Linq;
using Random = UnityEngine.Random;
public class LightSourceManager : MonoBehaviour
{
//Public variables
public GameObject[] LightSourcePrefabs;
public float MinSpawnBoundMargin = 2f;
public float MaxSpawnBoundMargin = 5f;
public float LightSourceSpawnChance = 30f;
public float LightSourceSpawnTime = 3f;
public float LightSourceCapacityAdd { get; set; }
public bool ShowSpawnQuadrants = false;
//Private variables
private enum QuadrantNames
{
TopLeft = 1,
TopRight = 2,
BottomLeft = 3,
BottomRight = 4
}
private struct SpawnQuadrant
{
public QuadrantNames Name;
public Rect BoundsA;
public Rect BoundsB;
}
private GameObject _LightSourceClone;
private Bounds _CameraBounds;
private SpawnQuadrant _QuadrantTopLeft;
private SpawnQuadrant _QuadrantTopRight;
private SpawnQuadrant _QuadrantBottomLeft;
private SpawnQuadrant _QuadrantBottomRight;
private bool _SourceSpawnedIn;
private float _SpawnTimer;
private GameController _GameController;
// Use this for initialization
private void Start()
{
_SourceSpawnedIn = false;
LightSourceCapacityAdd = 0f;
_SpawnTimer = 0f;
_CameraBounds = GlobalFunctions.GetOrtographicBounds(Camera.main);
InitializeSpawnQuadrants();
if (ShowSpawnQuadrants)
DebugSpawnQuadrants();
_GameController = GameController.Instance;
}
///
/// Initialize all possible spawn quadrants
///
private void InitializeSpawnQuadrants()
{
//Separate each quadrant into smaller quadrants called A and B
//Top left A is the top section above the screen.
//Top left B is the right section next to the screen.
//This goes on for all quadrants. Only the position chance for each section.
_QuadrantTopLeft = new SpawnQuadrant()
{
Name = QuadrantNames.TopLeft,
BoundsA = new Rect(_CameraBounds.center.x, _CameraBounds.center.y + _CameraBounds.max.y + MinSpawnBoundMargin,
_CameraBounds.min.x - MinSpawnBoundMargin, MaxSpawnBoundMargin - MinSpawnBoundMargin),
BoundsB = new Rect(_CameraBounds.center.x - _CameraBounds.max.x - MaxSpawnBoundMargin, _CameraBounds.center.y,
MaxSpawnBoundMargin - MinSpawnBoundMargin, _CameraBounds.max.y + MaxSpawnBoundMargin)
};
_QuadrantTopRight = new SpawnQuadrant()
{
Name = QuadrantNames.TopRight,
BoundsA = new Rect(_CameraBounds.center.x, _CameraBounds.center.y + _CameraBounds.max.y + MinSpawnBoundMargin,
_CameraBounds.max.x + MinSpawnBoundMargin, MaxSpawnBoundMargin - MinSpawnBoundMargin),
BoundsB = new Rect(_CameraBounds.center.x + _CameraBounds.max.x + MinSpawnBoundMargin, _CameraBounds.center.y,
MaxSpawnBoundMargin - MinSpawnBoundMargin, _CameraBounds.max.y + MaxSpawnBoundMargin)
};
_QuadrantBottomLeft = new SpawnQuadrant()
{
Name = QuadrantNames.BottomLeft,
BoundsA = new Rect(_CameraBounds.center.x, _CameraBounds.center.y - _CameraBounds.max.y - MinSpawnBoundMargin,
_CameraBounds.min.x - MinSpawnBoundMargin, MinSpawnBoundMargin - MaxSpawnBoundMargin),
BoundsB = new Rect(_CameraBounds.center.x - _CameraBounds.max.x - MaxSpawnBoundMargin, _CameraBounds.center.y,
MaxSpawnBoundMargin - MinSpawnBoundMargin, _CameraBounds.min.y - MaxSpawnBoundMargin)
};
_QuadrantBottomRight = new SpawnQuadrant()
{
Name = QuadrantNames.BottomRight,
BoundsA = new Rect(_CameraBounds.center.x, _CameraBounds.center.y - _CameraBounds.max.y - MinSpawnBoundMargin,
_CameraBounds.max.x + MinSpawnBoundMargin, MinSpawnBoundMargin - MaxSpawnBoundMargin),
BoundsB = new Rect(_CameraBounds.center.x + _CameraBounds.max.x + MinSpawnBoundMargin, _CameraBounds.center.y,
MaxSpawnBoundMargin - MinSpawnBoundMargin, _CameraBounds.min.y - MaxSpawnBoundMargin)
};
}
///
/// Call if you want to show the spawn quadrants
///
private void DebugSpawnQuadrants()
{
GameController.Instance.DebugRect(_QuadrantTopLeft.BoundsA);
GameController.Instance.DebugRect(_QuadrantTopLeft.BoundsB);
GameController.Instance.DebugRect(_QuadrantTopRight.BoundsA);
GameController.Instance.DebugRect(_QuadrantTopRight.BoundsB);
GameController.Instance.DebugRect(_QuadrantBottomLeft.BoundsA);
GameController.Instance.DebugRect(_QuadrantBottomLeft.BoundsB);
GameController.Instance.DebugRect(_QuadrantBottomRight.BoundsA);
GameController.Instance.DebugRect(_QuadrantBottomRight.BoundsB);
}
// Update is called once per frame
private void Update()
{
//DEBUG!!
if (Input.GetKeyDown(KeyCode.K))
{
_LightSourceClone.GetComponent().DisableLight();
}
}
///
/// Move the light opposite of the direction the player goes.
/// This is because the player stands still on 0,0 and only updates a vector and a facing direction.
///
/// The direction the player faces
/// The speed the player moves
/// Rotation in degrees of the player
/// The position of the light in world space
public Vector2 MoveLight(Vector3 moveDir, float moveSpeed, float angle)
{
if (_GameController.GamePaused)
return Vector2.zero;
if (_SourceSpawnedIn)
{
_LightSourceClone.GetComponent().Move(moveDir, moveSpeed);
if (IsLightOutOfBounds(_LightSourceClone.transform.position))
_LightSourceClone.GetComponent().DisableLight();
return _LightSourceClone.transform.position;
}
else if (!_SourceSpawnedIn)
{
_SpawnTimer += Time.deltaTime;
if (_SpawnTimer >= LightSourceSpawnTime)
{
if (Random.Range(0f, 100f) <= LightSourceSpawnChance)
Spawn(GetSpawnQuandrant(angle));
_SpawnTimer = 0f;
}
}
return Vector3.zero;
}
///
/// Create a new light source.
/// Only one can exist
///
///
public void CreateLightSource(Vector3 createPos)
{
_LightSourceClone = Instantiate(GetRandomLightSource(), createPos, Quaternion.identity) as GameObject;
}
///
/// Get a random lightsource from the prefab list.
///
/// Random lightsource
public GameObject GetRandomLightSource()
{
//TODO Legacy code might work better with random spawning, still testing...
//int size = LightSourcePrefabs.Length - 1;
//if (index > size)
// index = 0;
//float chance = LightSourcePrefabs[index].GetComponent().SpawnChance;
//if (chance > 0 && Random.Range(0f, 100f) <= chance)
// return LightSourcePrefabs[index];
//return GetRandomLightSource(++index);
int size = LightSourcePrefabs.Length;
int[] rolledDice = new int[size + 1];
for (int i = 0; i < LightSourcePrefabs.Length; i++)
{
float chance = LightSourcePrefabs[i].GetComponent().SpawnChance;
float rollDice = Random.Range(0f, 100f);
//check if a legit dice has been rolled
if (chance > 0 && rollDice <= chance)
rolledDice[i + 1] = (int)rollDice;
}
int index = Array.IndexOf(rolledDice, rolledDice.Max());
//Keep rolling the dice until a legit dice has been rolled
if (index <= 0)
return GetRandomLightSource();
//Return the lightsource who has rolled the highest
return LightSourcePrefabs[index - 1];
}
///
/// Destroy the current lightsource
///
public void DestroyLightSource()
{
DestroyObject(_LightSourceClone);
_SourceSpawnedIn = false;
}
///
/// Get the current lightsource
///
/// Current lightsource
public GameObject GetLightSource()
{
return _LightSourceClone;
}
///
/// Spawn the lightsource in a quadrant
///
/// The quadrant that the player faces
private void Spawn(SpawnQuadrant spawnQuadrant)
{
CreateLightSource(GetRandomSpawnPosition(spawnQuadrant));
_SourceSpawnedIn = true;
}
///
/// Get a random position for the lightsource between the two sections of a quadrant
///
/// The quadrant that the player faces
///
private Vector3 GetRandomSpawnPosition(SpawnQuadrant spawnQuadrant)
{
//Choose a random spawnpoint between bound A or B.
Rect spawnPoint = (Random.Range(0, 100) <= 50 ? spawnQuadrant.BoundsA : spawnQuadrant.BoundsB);
//Randomize spawnpoint in the bounds
float randPosX = Random.Range(spawnPoint.x, spawnPoint.xMax);
float randPosY = Random.Range(spawnPoint.y, spawnPoint.yMax);
return new Vector3(randPosX, randPosY, -5f);
}
///
/// Get a spawnquadrant facing towards the player
///
/// The angle from the player
/// A spawnQuadrant
private SpawnQuadrant GetSpawnQuandrant(float angle)
{
SpawnQuadrant spawnQuadrant = new SpawnQuadrant();
if (angle >= 0f && angle <= 90f)
spawnQuadrant = _QuadrantTopRight;
else if (angle >= 90 && angle <= 180)
spawnQuadrant = _QuadrantTopLeft;
else if (angle >= 180 && angle <= 270)
spawnQuadrant = _QuadrantBottomLeft;
else if (angle >= 270 && angle <= 360)
spawnQuadrant = _QuadrantBottomRight;
return spawnQuadrant;
}
///
/// Check if the light is out of the max bounds
///
/// Light source position
///
private bool IsLightOutOfBounds(Vector3 pos)
{
return (pos.x > (_CameraBounds.min.x + _CameraBounds.size.x) + MaxSpawnBoundMargin ||
pos.x < _CameraBounds.min.x - MaxSpawnBoundMargin ||
pos.y > (_CameraBounds.min.y + _CameraBounds.size.y) + MaxSpawnBoundMargin ||
pos.y < _CameraBounds.min.y - MaxSpawnBoundMargin);
}
}