using HPJ.Simulation; using HPJ.Simulation.Enums; using HPJ.Simulation.Map; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace HPJ.Presentation.Obstacle { public class NavigationObstacleSimpleSquare : NavigationObstacle { #region Unity // Start is called before the first frame update public override void Start() { if (!NavigationManager.Instance.Initialized) { Invoke(nameof(Start), 01f); return; } MapTileRelationships = new Dictionary(); _previousPositionRect = new PositionSquareRect(Vector3.one * 1000, _obstacleSize); _newPositionRect = new PositionSquareRect(transform.position, _obstacleSize); base.Start(); } public virtual void OnDrawGizmosSelected() { PositionSquareRect obstacleRect = new PositionSquareRect(transform.position, _obstacleSize); Gizmos.color = Color.red; for (int i = 1; i < obstacleRect.Corners.Length; i++) { Gizmos.DrawLine(obstacleRect.Corners[i], obstacleRect.Corners[i - 1]); } Gizmos.DrawLine(obstacleRect.Corners[0], obstacleRect.Corners[3]); Gizmos.color = Color.blue; Gizmos.DrawLine(transform.position, transform.position - Vector3.up * _checkMapHeight); } #endregion #region Obstacle /// /// Revalidate Tiles /// public override void RevalidateTiles() { foreach (MapObstacleRelationshipData Data in MapTileRelationships.Values) { Data.Revalidate(); } } /// /// The size of the obstacle in the x and z world directions /// [SerializeField] private Vector2 _obstacleSize = Vector2.one; public Vector2 ObstacleSize { get { return _obstacleSize; } set { _obstacleSize = value; } } private PositionSquareRect _previousPositionRect; private PositionSquareRect _newPositionRect; /// /// Checks to see if the new position changes and if so it changes the mesh to block out the new corresponding tiles /// /// /// public override void UpdatePosition(Vector3 NewPosition, bool ForceCheck = false) { if (!NavigationManager.Instance.Initialized) { return; } if (_previousPositionRect.Position != NewPosition || ForceCheck) { _newPositionRect.UpdatePosition(NewPosition); // No need to update if no tiles need updating if (PositionChanged(NewPosition)) { _previousPositionRect.UpdatePosition(NewPosition); foreach (MapObstacleRelationshipData Data in MapTileRelationships.Values) { Data.UnvalidateTiles(); } foreach (MapSet Set in NavigationManager.Instance.MapSets) { if (!NavigationManager.Instance.RectOnMap(Set, _newPositionRect, _checkMapHeight)) { continue; } MapObstacleRelationshipData RelationshipData; if (MapTileRelationships.ContainsKey(Set)) { RelationshipData = MapTileRelationships[Set]; } else { RelationshipData = new MapObstacleRelationshipData(Set, this, _obstacleTileType); MapTileRelationships.Add(Set, RelationshipData); } IntVector2 HigherBound = Set.GetMapTileIndex(NavigationManager.Instance.GetTileWorldPosition(_newPositionRect.Corners[0])); IntVector2 LowerBound = Set.GetMapTileIndex(NavigationManager.Instance.GetTileWorldPosition(_newPositionRect.Corners[2])); for (int x = LowerBound.x; x <= HigherBound.x; x++) { for (int y = LowerBound.y; y <= HigherBound.y; y++) { if (Set.GetTileType(x, y) != TileTypes.OutOfBounds) { //Debug.Log("Change Tile"); IntVector3 TileKey = new IntVector3(x, y, Set.InstanceID); RelationshipData.AddOrValidateTile(TileKey); } } } } foreach (MapObstacleRelationshipData Data in MapTileRelationships.Values) { ChangeMapJob GeneratedMapChangeJob = Data.GenerateMapChangeJob(); if (GeneratedMapChangeJob != null) { //Debug.Log("Change Map From Job"); Data.Map.ChangeMap(GeneratedMapChangeJob); } Data.SortRelatedTileData(); } } } else { RevalidateTiles(); } } /// /// What happens the the obstacle mesh position changes /// /// /// protected override bool PositionChanged(Vector3 NewPosition) { return true; foreach (MapSet set in NavigationManager.Instance.MapSets) { // Find out which maps this Obstacle is on. And if the change in position was enough to change the map for (int i = 0; i < _newPositionRect.Corners.Length; i++) { // Did the height change effect the map that it should previously had not IntVector3 NewTileWorldPosition = NavigationManager.Instance.GetTileWorldPosition(_newPositionRect.Corners[i]); IntVector3 PreviousTileWorldPosition = NavigationManager.Instance.GetTileWorldPosition(_previousPositionRect.Corners[i]); if (_newPositionRect.Corners[i].y - set.SetSettings.MapSettings.Offset.y / 100 <= _checkMapHeight && set.PointInMap(NewTileWorldPosition)) { if (!set.PointInMap(PreviousTileWorldPosition) || _previousPositionRect.Corners[i].y - set.SetSettings.MapSettings.Offset.y / 100f > _checkMapHeight) { return true; } if (set.GetMapTileIndex(PreviousTileWorldPosition) != set.GetMapTileIndex(NewTileWorldPosition)) { return true; } } else if (_previousPositionRect.Corners[i].y - set.SetSettings.MapSettings.Offset.y / 100f <= _checkMapHeight && set.PointInMap(PreviousTileWorldPosition)) { return true; } } } return false; } protected Quaternion _previousRotation = Quaternion.identity; /// /// 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 /// /// public override void Rotate(Quaternion Rotation) { // Can use that later for more complex rotations. This Rotate just rotates 90* every time you ask this //if (Rotation == _previousRotation) //{ // return; //} if (_obstacleSize.y == _obstacleSize.x) { return; } _previousRotation = Rotation; _obstacleSize = new Vector2(_obstacleSize.y, _obstacleSize.x); _newPositionRect.UpdateSize(_obstacleSize); UpdatePosition(transform.position, true); } #endregion } }