using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;
namespace DunGen
{
public delegate void DungenCharacterDelegate(DungenCharacter character);
public delegate void CharacterTileChangedEvent(DungenCharacter character, Tile previousTile, Tile newTile);
///
/// Contains information about the dungeon the character is in
///
[AddComponentMenu("DunGen/Character")]
public class DungenCharacter : MonoBehaviour
{
#region Statics
public static event DungenCharacterDelegate CharacterAdded;
public static event DungenCharacterDelegate CharacterRemoved;
public static ReadOnlyCollection AllCharacters { get; private set; }
private static readonly List allCharacters = new List();
static DungenCharacter()
{
AllCharacters = new ReadOnlyCollection(allCharacters);
}
#endregion
public Tile CurrentTile
{
get
{
if (overlappingTiles == null || overlappingTiles.Count == 0)
return null;
else
return overlappingTiles[overlappingTiles.Count - 1];
}
}
public event CharacterTileChangedEvent OnTileChanged;
private List overlappingTiles;
protected virtual void OnEnable()
{
if (overlappingTiles == null)
overlappingTiles = new List();
allCharacters.Add(this);
if (CharacterAdded != null)
CharacterAdded(this);
}
protected virtual void OnDisable()
{
allCharacters.Remove(this);
if (CharacterRemoved != null)
CharacterRemoved(this);
}
internal void ForceRecheckTile()
{
overlappingTiles.Clear();
foreach (var tile in UnityUtil.FindObjectsByType())
if (tile.Placement.Bounds.Contains(transform.position))
{
OnTileEntered(tile);
break;
}
}
protected virtual void OnTileChangedEvent(Tile previousTile, Tile newTile) { }
internal void OnTileEntered(Tile tile)
{
if (overlappingTiles.Contains(tile))
return;
var previousTile = CurrentTile;
overlappingTiles.Add(tile);
if (CurrentTile != previousTile)
{
OnTileChanged?.Invoke(this, previousTile, CurrentTile);
OnTileChangedEvent(previousTile, CurrentTile);
}
}
internal void OnTileExited(Tile tile)
{
if (!overlappingTiles.Contains(tile))
return;
var previousTile = CurrentTile;
overlappingTiles.Remove(tile);
if (CurrentTile != previousTile)
{
OnTileChanged?.Invoke(this, previousTile, CurrentTile);
OnTileChangedEvent(previousTile, CurrentTile);
}
}
}
}