using System; using CIG; using UnityEngine; namespace SUISSEngine { [RequireComponent(typeof(SpriteRenderer))] public class Vehicle : MonoBehaviour { public int RoadType { get { return this.roadType; } } public GridPoint CurrentLocation { get { return this.location; } } public Vehicle.Direction CurrentDirection { get { return this.direction; } } public bool IsStuck { get { return this.stuck; } } public Balloon Balloon { get { return this._balloon; } } protected virtual void Awake() { this.cachedName = base.name; this.originalScale = base.transform.localScale; } protected virtual void Start() { } protected virtual void Update() { float num = Time.deltaTime; bool flag = false; while (!this.stuck && num > 0f) { float num2 = this.location.DistanceTo(this.targetLocation); if ((double)num2 < 1E-06 && flag) { break; } float num3 = this.speed * num; if (num3 < num2) { GridPoint gridPoint = new GridPoint(0f, 0f); switch (this.direction) { case Vehicle.Direction.North: gridPoint = new GridPoint(0f, -this.speed); break; case Vehicle.Direction.East: gridPoint = new GridPoint(this.speed, 0f); break; case Vehicle.Direction.South: gridPoint = new GridPoint(0f, this.speed); break; case Vehicle.Direction.West: gridPoint = new GridPoint(-this.speed, 0f); break; } this.location.u = this.location.u + gridPoint.u * num; this.location.v = this.location.v + gridPoint.v * num; num2 -= num3; num = 0f; } else { this.location = this.targetLocation; this.FindDirection(true); flag = true; num -= num2 / this.speed; } } if (!this.stuck && this.requiredRoadType > 0) { GridIndex index; index.u = Mathf.FloorToInt(this.location.u); index.v = Mathf.FloorToInt(this.location.v); if (!Road.RoadExists(this.grid, index, this.roadType, this.canMoveOnBriges)) { this.stuck = true; } } if (this.stuck) { IsometricIsland.GetParent(this).vehicleManager.VehicleStuck(this); } if (this.cachedName.StartsWith("Boat")) { Vector2 vector = base.transform.position; Vector2 vector2 = base.transform.position; vector += this.frontPosition[(int)this.direction]; vector2 += this.backPosition[(int)this.direction]; GridIndex index2 = this.grid.ConvertIslandCoordinateToGridIndex(vector); GridIndex index3 = this.grid.ConvertIslandCoordinateToGridIndex(vector2); bool flag2 = Road.RoadExists(this.grid, index2, 1, true) || Road.RoadExists(this.grid, index3, 1, true) || Road.RoadExists(this.grid, index2, 2, true) || Road.RoadExists(this.grid, index3, 2, true); this.spriteRenderer.enabled = !flag2; } this.UpdateTransform(); } private void OnDestroy() { if (this._balloon != null) { this._balloon.CollectedEvent -= this.OnBalloonCollected; this._balloon.ExpiredEvent -= this.OnBalloonExpired; this._balloon = null; } } public static bool DirectionsAreOpposite(Vehicle.Direction dir1, Vehicle.Direction dir2) { return Math.Abs(dir1 - dir2) == 2; } public static GridIndex ApplyDirection(GridIndex index, Vehicle.Direction dir) { return new GridIndex(index.u + Vehicle.__du[(int)dir], index.v + Vehicle.__dv[(int)dir]); } public static Vehicle.Direction InvertDirection(Vehicle.Direction dir) { return dir ^ Vehicle.Direction.South; } public virtual void SpawnAt(GridIndex index, int roadType) { this.grid = IsometricIsland.GetParent(this).grid; if (this.grid == null) { UnityEngine.Debug.LogError("Vehicle " + this + " couldn't find a grid in SpawnAt()."); return; } this.roadType = roadType; base.transform.parent = this.grid.transform; this.speed = UnityEngine.Random.Range(this.minSpeed, this.maxSpeed); this.location = new GridPoint(index); this.location.u = this.location.u + 0.5f; this.location.v = this.location.v + 0.5f; this.UpdateTransform(); this.FindDirection(false); } public void ShowBalloon(Balloon balloon) { if (this._balloon != null) { UnityEngine.Debug.LogError("Can't show two balloons on a vehicle."); return; } if (balloon == null) { UnityEngine.Debug.LogError("Balloon to show on vehicle is null."); return; } this._balloon = balloon; this._balloon.CollectedEvent += this.OnBalloonCollected; this._balloon.ExpiredEvent += this.OnBalloonExpired; BalloonView balloonView = this._gridTileIconManager.SetIcon(this._balloon.GridTileIcon); balloonView.Init(this._balloon); } protected virtual void FindDirection(bool dontTurnBack) { GridIndex[] array = new GridIndex[4]; Vehicle.Direction[] array2 = new Vehicle.Direction[4]; int num = 0; GridIndex gridIndex; gridIndex.u = Mathf.FloorToInt(this.location.u); gridIndex.v = Mathf.FloorToInt(this.location.v); if (!Road.RoadExists(this.grid, gridIndex, this.roadType, this.canMoveOnBriges)) { this.stuck = true; return; } Road roadOfTypeAt = Road.GetRoadOfTypeAt(this.grid, gridIndex, this.roadType, true); if (roadOfTypeAt == null) { return; } GridIndex gridIndex2 = gridIndex; gridIndex2.v--; if (this.HasAccessableNeighbour(gridIndex2, Vehicle.Direction.North) && roadOfTypeAt.IsAccessableFrom(Vehicle.Direction.North, this.roadType)) { array[num] = gridIndex2; array2[num] = Vehicle.Direction.North; num++; } gridIndex2.v++; gridIndex2.u++; if (this.HasAccessableNeighbour(gridIndex2, Vehicle.Direction.East) && roadOfTypeAt.IsAccessableFrom(Vehicle.Direction.East, this.roadType)) { array[num] = gridIndex2; array2[num] = Vehicle.Direction.East; num++; } gridIndex2.u--; gridIndex2.v++; if (this.HasAccessableNeighbour(gridIndex2, Vehicle.Direction.South) && roadOfTypeAt.IsAccessableFrom(Vehicle.Direction.South, this.roadType)) { array[num] = gridIndex2; array2[num] = Vehicle.Direction.South; num++; } gridIndex2.v--; gridIndex2.u--; if (this.HasAccessableNeighbour(gridIndex2, Vehicle.Direction.West) && roadOfTypeAt.IsAccessableFrom(Vehicle.Direction.West, this.roadType)) { array[num] = gridIndex2; array2[num] = Vehicle.Direction.West; num++; } gridIndex2.u++; if (dontTurnBack && num > 1) { for (int i = 0; i < num; i++) { if (Vehicle.DirectionsAreOpposite(this.direction, array2[i])) { for (int j = i; j < num - 1; j++) { array[j] = array[j + 1]; array2[j] = array2[j + 1]; } num--; break; } } } if (num == 0) { this.stuck = true; } else { this.stuck = false; int num2 = UnityEngine.Random.Range(0, num); this.targetLocation = new GridPoint(array[num2]); this.targetLocation.u = this.targetLocation.u + 0.5f; this.targetLocation.v = this.targetLocation.v + 0.5f; this.SetDirection(array2[num2]); } } protected virtual void SetDirection(Vehicle.Direction direction) { this.direction = direction; if (this.animator != null) { this.animator.SetInteger("Direction", (int)this.direction); } else if (this.spriteRenderer != null) { Sprite sprite = null; bool flag = false; if (this.sprites != null && (Vehicle.Direction)this.sprites.Length > this.direction) { sprite = this.sprites[(int)this.direction]; } if (sprite == null) { Vehicle.Direction direction2 = Vehicle.Direction.North; switch (this.direction) { case Vehicle.Direction.North: direction2 = Vehicle.Direction.West; break; case Vehicle.Direction.East: direction2 = Vehicle.Direction.South; break; case Vehicle.Direction.South: direction2 = Vehicle.Direction.East; break; case Vehicle.Direction.West: direction2 = Vehicle.Direction.North; break; } if (this.sprites != null && (Vehicle.Direction)this.sprites.Length > direction2) { sprite = this.sprites[(int)direction2]; if (sprite != null) { flag = true; } } } this.spriteRenderer.sprite = sprite; Vector3 localScale = this.originalScale; if (flag) { localScale.x = -localScale.x; } base.transform.localScale = localScale; } this.UpdateTransform(); } protected virtual void UpdateTransform() { GridPoint point = location; if ((offsets != null) & (offsets.Length > (int)direction)) { point.u += offsets[(int)direction].x; point.v += offsets[(int)direction].y; } Vector3 localPosition = grid.GetPositionForGridPoint(point); localPosition.z = 0f; base.transform.localPosition = localPosition; int num = (int)CurrentDirection / 2; spriteRenderer.sortingOrder = GridTile.GetSortingOrder(new GridIndex(location), new GridSize(1, 1)) + num; } private bool HasAccessableNeighbour(GridIndex index, Vehicle.Direction dir) { Road roadOfTypeAt = Road.GetRoadOfTypeAt(this.grid, index, this.roadType, this.canMoveOnBriges); return !(roadOfTypeAt == null) && roadOfTypeAt.IsAccessableFrom(dir, this.roadType); } private void RemoveBalloon(Balloon balloon) { if (this._gridTileIconManager != null) { this._gridTileIconManager.RemoveIcon(this._balloon.GridTileIcon); } this._balloon.CollectedEvent -= this.OnBalloonCollected; this._balloon.ExpiredEvent -= this.OnBalloonExpired; this._balloon = null; } private void OnBalloonCollected(Balloon balloon) { this.RemoveBalloon(balloon); } private void OnBalloonExpired(Balloon balloon) { this.RemoveBalloon(balloon); } // Note: this type is marked as 'beforefieldinit'. static Vehicle() { int[] array = new int[4]; array[0] = -1; array[2] = 1; Vehicle.__dv = array; } private static int[] __du = new int[] { 0, 1, 0, -1 }; private static int[] __dv; public float minSpeed = 0.5f; public float maxSpeed = 0.5f; public Sprite[] sprites = new Sprite[4]; public Vector2[] offsets = new Vector2[4]; public Vector2[] frontPosition = new Vector2[4]; public Vector2[] backPosition = new Vector2[4]; public bool canMoveOnBriges; public Vehicle.VehicleType type = Vehicle.VehicleType.Civilian; [SerializeField] private Vector3 _iconOffset; public int requiredRoadType; [SelfReference] public SpriteRenderer spriteRenderer; [SelfReference(true)] public Animator animator; [SerializeField] private GridTileIconManager _gridTileIconManager; protected IsometricGrid grid; protected int roadType = -1; protected Vector3 originalScale; protected float speed; protected GridPoint location = new GridPoint(-1f, -1f); protected GridPoint targetLocation = new GridPoint(-1f, -1f); protected Vehicle.Direction direction; protected bool stuck = true; protected string cachedName = string.Empty; private Balloon _balloon; public enum VehicleType { None = -99, Civilian = -2, Taxi, Ambulance = 1, FireTruck, Police } public enum Direction { North, East, South, West } } }