mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-06-27 03:44:54 +00:00
269 lines
9.1 KiB
C#
269 lines
9.1 KiB
C#
using HPJ.Simulation;
|
|
using HPJ.Simulation.Enums;
|
|
using HPJ.Simulation.Map;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace HPJ.Presentation.Obstacle
|
|
{
|
|
/// <summary>
|
|
/// The Base class for all navigation obstacles
|
|
/// </summary>
|
|
public abstract class NavigationObstacle : MonoBehaviour
|
|
{
|
|
#region Unity
|
|
|
|
// Start is called before the first frame update
|
|
public virtual void Start()
|
|
{
|
|
if (!NavigationManager.Instance.Initialized)
|
|
{
|
|
Invoke(nameof(Start), 01f);
|
|
return;
|
|
}
|
|
UpdatePosition(transform.position, true);
|
|
NavigationManager.Instance?.AddObstacle(this);
|
|
}
|
|
|
|
public virtual void OnDestroy()
|
|
{
|
|
NavigationManager.Instance?.RemoveObstacle(this);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Obstacle
|
|
|
|
/// <summary>
|
|
/// Does the obstacle update automatically through the built in systems
|
|
/// </summary>
|
|
[SerializeField]
|
|
protected bool _automaticUpdate = true;
|
|
public bool AutomaticUpdate { get { return _automaticUpdate; } set { _automaticUpdate = value; } }
|
|
/// <summary>
|
|
/// The Height difference from the map to count as being on top of the map
|
|
/// </summary>
|
|
[SerializeField, Tooltip("The Height from the transform y position to the ground that this counts as an obstacle")]
|
|
protected float _checkMapHeight = 1f;
|
|
public float CheckMapHeight { get { return _checkMapHeight; } set { _checkMapHeight = value; } }
|
|
/// <summary>
|
|
/// The tile type the obstacle changes the tiles beneath it too
|
|
/// </summary>
|
|
[SerializeField]
|
|
protected TileTypes _obstacleTileType = TileTypes.Obstacle;
|
|
public TileTypes ObstacleTileType { get { return _obstacleTileType; } }
|
|
|
|
/// <summary>
|
|
/// The Update cycle of the obstacle
|
|
/// </summary>
|
|
public virtual void UpdateObstacle()
|
|
{
|
|
if (_automaticUpdate)
|
|
{
|
|
UpdatePosition(transform.position);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The tiles and map relationship data with this obstacle
|
|
/// </summary>
|
|
public Dictionary<MapSet, MapObstacleRelationshipData> MapTileRelationships { get; protected set; }
|
|
/// <summary>
|
|
/// Checks to see if the new position changes and if so it changes the mesh to block out the new corresponding tiles
|
|
/// </summary>
|
|
/// <param name="NewPosition"></param>
|
|
/// <param name="ForceCheck"></param>
|
|
public abstract void UpdatePosition(Vector3 NewPosition, bool ForceCheck = false);
|
|
|
|
/// <summary>
|
|
/// What happens the the obstacle mesh position changes
|
|
/// </summary>
|
|
/// <param name="NewPosition"></param>
|
|
/// <returns></returns>
|
|
protected abstract bool PositionChanged(Vector3 NewPosition);
|
|
|
|
/// <summary>
|
|
/// Rotates the obstacle based on the desired Rotation. Basic NavigationObstacle will only swap the object size x and y values. Inherit to ovverride this behaviour
|
|
/// </summary>
|
|
/// <param name="Rotation"></param>
|
|
public abstract void Rotate(Quaternion Rotation);
|
|
|
|
/// <summary>
|
|
/// Revalidates the tiles of the obstacle in case another obstacle travels over top of this one
|
|
/// </summary>
|
|
public abstract void RevalidateTiles();
|
|
|
|
#endregion
|
|
}
|
|
|
|
[Serializable]
|
|
public struct PositionSquareRect
|
|
{
|
|
public Vector3 Position;
|
|
public Vector2 Size;
|
|
public Vector3[] Corners;
|
|
|
|
public PositionSquareRect(Vector3 position, Vector2 size)
|
|
{
|
|
Position = position;
|
|
Size = size;
|
|
Corners = new Vector3[4];
|
|
|
|
Corners[0] = Position + new Vector3(Size.x / 2, 0, Size.y / 2);
|
|
Corners[1] = Position + new Vector3(Size.x / 2, 0, -Size.y / 2);
|
|
Corners[2] = Position + new Vector3(-Size.x / 2, 0, -Size.y / 2);
|
|
Corners[3] = Position + new Vector3(-Size.x / 2, 0, Size.y / 2);
|
|
}
|
|
|
|
public PositionSquareRect(Vector3 position, Vector3 LowerBounds, Vector3 HigherBounds)
|
|
{
|
|
Position = position;
|
|
Size = new Vector2(HigherBounds.x - LowerBounds.x, HigherBounds.z - LowerBounds.z);
|
|
Corners = new Vector3[4];
|
|
LowerBounds.y = 0;
|
|
HigherBounds.y = 0;
|
|
|
|
Corners[0] = HigherBounds;
|
|
Corners[1] = new Vector3(HigherBounds.x, 0, LowerBounds.z);
|
|
Corners[2] = LowerBounds;
|
|
Corners[3] = new Vector3(LowerBounds.x, 0, HigherBounds.z);
|
|
}
|
|
|
|
public void UpdatePosition(Vector3 position)
|
|
{
|
|
Position = position;
|
|
|
|
Corners[0] = Position + new Vector3(Size.x / 2, 0, Size.y / 2);
|
|
Corners[1] = Position + new Vector3(Size.x / 2, 0, -Size.y / 2);
|
|
Corners[2] = Position + new Vector3(-Size.x / 2, 0, -Size.y / 2);
|
|
Corners[3] = Position + new Vector3(-Size.x / 2, 0, Size.y / 2);
|
|
}
|
|
|
|
public void UpdateSize(Vector2 newSize)
|
|
{
|
|
Size = newSize;
|
|
|
|
Corners[0] = Position + new Vector3(Size.x / 2, 0, Size.y / 2);
|
|
Corners[1] = Position + new Vector3(Size.x / 2, 0, -Size.y / 2);
|
|
Corners[2] = Position + new Vector3(-Size.x / 2, 0, -Size.y / 2);
|
|
Corners[3] = Position + new Vector3(-Size.x / 2, 0, Size.y / 2);
|
|
}
|
|
|
|
public bool InBounds(Vector3 Point)
|
|
{
|
|
if (Point.x > Corners[0].x || Point.x < Corners[2].x || Point.z > Corners[0].z || Point.z < Corners[2].z)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class MapObstacleRelationshipData
|
|
{
|
|
public MapSet Map;
|
|
public NavigationObstacle Obstacle;
|
|
public Dictionary<IntVector3, ObstacleData> RelatedTilesData;
|
|
public HashSet<IntVector3> ValidatedTiles;
|
|
public HashSet<IntVector3> InvalidatedTiles;
|
|
public HashSet<IntVector3> AddedTiles;
|
|
public TileTypes ObstacleTileType;
|
|
|
|
public MapObstacleRelationshipData(MapSet map, NavigationObstacle obstacle, TileTypes ObstacleType)
|
|
{
|
|
ValidatedTiles = new HashSet<IntVector3>();
|
|
InvalidatedTiles = new HashSet<IntVector3>();
|
|
AddedTiles = new HashSet<IntVector3>();
|
|
RelatedTilesData = new Dictionary<IntVector3, ObstacleData>();
|
|
Map = map;
|
|
Obstacle = obstacle;
|
|
ObstacleTileType = ObstacleType;
|
|
}
|
|
|
|
public void UnvalidateTiles()
|
|
{
|
|
InvalidatedTiles.Clear();
|
|
ValidatedTiles.Clear();
|
|
AddedTiles.Clear();
|
|
foreach (ObstacleData Data in RelatedTilesData.Values)
|
|
{
|
|
InvalidatedTiles.Add(Data.TileIndexKey);
|
|
Data.UnValidate();
|
|
}
|
|
}
|
|
|
|
public void AddOrValidateTile(IntVector3 tileIndex)
|
|
{
|
|
if (RelatedTilesData.ContainsKey(tileIndex))
|
|
{
|
|
RelatedTilesData[tileIndex].Validate();
|
|
InvalidatedTiles.Remove(tileIndex);
|
|
ValidatedTiles.Add(tileIndex);
|
|
}
|
|
else
|
|
{
|
|
ObstacleData NewTile = new ObstacleData(tileIndex);
|
|
RelatedTilesData.Add(tileIndex, NewTile);
|
|
AddedTiles.Add(tileIndex);
|
|
}
|
|
}
|
|
|
|
public void SortRelatedTileData()
|
|
{
|
|
foreach(IntVector3 InvalidatedTile in InvalidatedTiles)
|
|
{
|
|
RelatedTilesData.Remove(InvalidatedTile);
|
|
}
|
|
}
|
|
|
|
public ChangeMapJob GenerateMapChangeJob()
|
|
{
|
|
if (AddedTiles.Count == 0 && InvalidatedTiles.Count == 0)
|
|
{
|
|
//Debug.Log("No Tiles Changed");
|
|
return null;
|
|
}
|
|
|
|
ChangeMapJob MapChange = new ChangeMapJob();
|
|
|
|
// Set to Obstacle type
|
|
foreach (IntVector3 Tile in AddedTiles)
|
|
{
|
|
MapChange.AddTileChange(Tile.Vector2(), Obstacle.ObstacleTileType);
|
|
}
|
|
|
|
// Set back to default
|
|
foreach (IntVector3 Tile in InvalidatedTiles)
|
|
{
|
|
MapChange.AddTileChange(Tile.Vector2(), (TileTypes)Map.SetSettings.MapSettings.MapInfo.SavedTiles[Tile.x, Tile.y]);
|
|
}
|
|
//Debug.Log($"Tiles To Change {MapChange.TilesToBeChanged.Count} -> Added {AddedTiles.Count} -> Removed {InvalidatedTiles.Count}");
|
|
|
|
return MapChange;
|
|
}
|
|
|
|
internal void Revalidate()
|
|
{
|
|
ChangeMapJob MapChange = new ChangeMapJob();
|
|
|
|
bool ChangedTiles = false;
|
|
foreach (IntVector3 Tile in ValidatedTiles)
|
|
{
|
|
if (Map.GetTileType(Tile.Vector2()) != ObstacleTileType)
|
|
{
|
|
ChangedTiles = true;
|
|
MapChange.AddTileChange(Tile.Vector2(), ObstacleTileType);
|
|
}
|
|
}
|
|
|
|
if (ChangedTiles)
|
|
{
|
|
Map.ChangeMap(MapChange);
|
|
}
|
|
}
|
|
}
|
|
}
|