2022-08-25 17:58:26 +02:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
2022-10-10 19:45:07 +02:00
|
|
|
using System.Data;
|
2022-08-28 22:42:21 +02:00
|
|
|
using System.Linq;
|
2022-08-25 17:58:26 +02:00
|
|
|
using TMPro;
|
2022-10-10 22:13:42 +02:00
|
|
|
using Unity.VisualScripting;
|
2022-08-25 17:58:26 +02:00
|
|
|
using UnityEngine;
|
2022-10-06 21:52:35 +02:00
|
|
|
using UnityEngine.Assertions;
|
2022-09-08 00:43:34 +02:00
|
|
|
using UnityEngine.UI;
|
2022-08-25 17:58:26 +02:00
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
namespace Parking
|
2022-08-25 17:58:26 +02:00
|
|
|
{
|
2022-08-31 20:50:59 +02:00
|
|
|
public class ParkingManager : MonoBehaviour
|
2022-08-28 22:42:21 +02:00
|
|
|
{
|
2022-08-31 20:50:59 +02:00
|
|
|
public const float Width = 68;
|
|
|
|
public const float Height = 29;
|
2022-08-28 22:42:21 +02:00
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
public static ParkingManager Instance;
|
2022-08-28 22:42:21 +02:00
|
|
|
|
2022-09-04 00:35:45 +02:00
|
|
|
private static readonly TimeSpan StartTime = TimeSpan.FromHours(5) + TimeSpan.FromMinutes(45);
|
|
|
|
private static readonly TimeSpan EndTime = TimeSpan.FromHours(17) + TimeSpan.FromMinutes(15);
|
|
|
|
private static TimeSpan _currentTime = StartTime;
|
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
[SerializeField] private int stepTime = 15;
|
|
|
|
[SerializeField] private TextMeshProUGUI timeText;
|
2022-09-09 23:48:31 +02:00
|
|
|
[SerializeField] private TextMeshProUGUI dateText;
|
2022-08-31 20:50:59 +02:00
|
|
|
[SerializeField] public TextMeshProUGUI countsText;
|
2022-09-03 00:23:15 +02:00
|
|
|
[SerializeField] public TextMeshProUGUI rejectedText;
|
2022-09-07 21:47:41 +02:00
|
|
|
[SerializeField] public TextMeshProUGUI pathText;
|
|
|
|
[SerializeField] public GameObject startPanel;
|
|
|
|
[SerializeField] public GameObject notFoundPanel;
|
2022-08-31 20:50:59 +02:00
|
|
|
[SerializeField] public GameObject spotPrefabA;
|
|
|
|
[SerializeField] public GameObject spotPrefabB;
|
|
|
|
[SerializeField] public GameObject spotPrefabC;
|
2022-08-31 21:19:20 +02:00
|
|
|
[SerializeField] public GameObject spotPrefabD;
|
2022-09-01 22:31:57 +02:00
|
|
|
[SerializeField] public GameObject carPrefab;
|
2022-09-05 01:15:04 +02:00
|
|
|
[SerializeField] public Transform mainPlanContainer;
|
|
|
|
[SerializeField] public Transform emergencyPlanContainer;
|
2022-09-08 00:43:34 +02:00
|
|
|
[SerializeField] public Toggle reconfigurationToggle;
|
|
|
|
[SerializeField] public string defaultPath = "Assets/Data/Tablica2.csv";
|
2022-08-28 22:42:21 +02:00
|
|
|
|
2022-10-05 21:56:02 +02:00
|
|
|
public static readonly float[] SpotHeights = {4f, 4.5f, 5f, 7.5f};
|
2022-08-28 22:42:21 +02:00
|
|
|
|
2022-09-04 00:35:45 +02:00
|
|
|
private readonly List<List<Spot>> _spotMap = new()
|
2022-09-03 00:23:15 +02:00
|
|
|
{new List<Spot>(), new List<Spot>(), new List<Spot>(), new List<Spot>()};
|
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
private bool _emergencyActivated;
|
|
|
|
|
2022-09-04 00:35:45 +02:00
|
|
|
private int _initialConfigurationSpotCount;
|
2022-09-06 23:20:53 +02:00
|
|
|
private int[,] _initialSolution;
|
2022-09-08 22:48:36 +02:00
|
|
|
private bool _reconfigurationActive = true;
|
2022-09-03 21:27:31 +02:00
|
|
|
private int[] _rejectedDrivers = {0, 0, 0, 0};
|
2022-09-06 23:20:53 +02:00
|
|
|
private List<GameObject> _spotPrefabs;
|
2022-08-28 22:42:21 +02:00
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
private void Awake()
|
2022-08-28 22:42:21 +02:00
|
|
|
{
|
2022-08-31 20:50:59 +02:00
|
|
|
Instance = this;
|
2022-08-28 22:42:21 +02:00
|
|
|
}
|
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
private void Start()
|
|
|
|
{
|
2022-09-06 23:20:53 +02:00
|
|
|
_spotPrefabs = new List<GameObject> {spotPrefabA, spotPrefabB, spotPrefabC, spotPrefabD};
|
2022-09-08 00:43:34 +02:00
|
|
|
startPanel.SetActive(true);
|
|
|
|
reconfigurationToggle.onValueChanged.AddListener(ReconfigurationToggle);
|
|
|
|
}
|
2022-09-07 21:47:41 +02:00
|
|
|
|
2022-09-08 00:43:34 +02:00
|
|
|
public void ReconfigurationToggle(bool value)
|
|
|
|
{
|
|
|
|
_reconfigurationActive = value;
|
|
|
|
Debug.Log($"Reconfiguration {(value ? "activated" : "deactivated")}");
|
2022-09-07 21:47:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void ReadDataButtonClick()
|
|
|
|
{
|
2022-09-08 00:43:34 +02:00
|
|
|
string path = pathText.text.Replace("\u200B", "");
|
|
|
|
if (path.Length == 0)
|
|
|
|
path = defaultPath;
|
|
|
|
if (!DataImporter.ReadFile(path)) {
|
2022-09-07 21:47:41 +02:00
|
|
|
notFoundPanel.SetActive(true);
|
|
|
|
return;
|
|
|
|
}
|
2022-09-08 00:43:34 +02:00
|
|
|
|
2022-09-09 23:48:31 +02:00
|
|
|
dateText.text = path.Substring(path.Length - 1 - 4 - 9, 10);
|
2022-09-12 23:28:39 +02:00
|
|
|
|
2022-09-07 21:47:41 +02:00
|
|
|
InitiateManager();
|
|
|
|
startPanel.SetActive(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void InitiateManager()
|
|
|
|
{
|
2022-08-31 20:50:59 +02:00
|
|
|
timeText.text = _currentTime.ToString();
|
2022-09-03 21:27:31 +02:00
|
|
|
rejectedText.text = $"Małe: {_rejectedDrivers[0]} Średnie: {_rejectedDrivers[1]} " +
|
|
|
|
$"Duże: {_rejectedDrivers[2]}";
|
2022-09-05 01:15:04 +02:00
|
|
|
GenerateEmergencyPlan();
|
2022-09-05 22:01:52 +02:00
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
InitialConfigurationGenerator generator = new();
|
2022-09-06 23:20:53 +02:00
|
|
|
_initialSolution = generator.FindSolution();
|
|
|
|
ArrangeSpots(_initialSolution);
|
2022-09-04 00:35:45 +02:00
|
|
|
ReserveInitialSpots();
|
|
|
|
}
|
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
public void Emergency()
|
|
|
|
{
|
|
|
|
ResetDrivers();
|
|
|
|
_emergencyActivated = true;
|
|
|
|
}
|
|
|
|
|
2022-09-04 00:35:45 +02:00
|
|
|
private void ReserveInitialSpots()
|
|
|
|
{
|
2022-10-10 19:45:07 +02:00
|
|
|
return;
|
2022-09-05 01:15:04 +02:00
|
|
|
for (int j = 3; j >= 0; j--)
|
2022-09-04 12:47:46 +02:00
|
|
|
foreach (Spot spot in _spotMap[j]) {
|
|
|
|
spot.Reserved = false;
|
|
|
|
spot.ReservedPriority = 0;
|
|
|
|
}
|
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
for (int i = 0; i < Math.Min(DataImporter.Drivers.Count, _initialConfigurationSpotCount); i++) {
|
2022-09-04 00:35:45 +02:00
|
|
|
bool found = false;
|
|
|
|
// Find spot
|
2022-09-05 01:15:04 +02:00
|
|
|
for (int j = 3; j >= 0 && !found; j--)
|
2022-09-04 00:35:45 +02:00
|
|
|
foreach (Spot spot in _spotMap[j])
|
|
|
|
if (spot.Size == DataImporter.Drivers[i].Size && !spot.Reserved) {
|
|
|
|
spot.Reserved = true;
|
|
|
|
spot.ReservedPriority = DataImporter.Drivers[i].Priority;
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-08-28 22:42:21 +02:00
|
|
|
}
|
2022-10-10 19:45:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
private void ReserveSpotsInTimeRange(float hours)
|
|
|
|
{
|
2022-10-10 22:13:42 +02:00
|
|
|
for (int j = 3; j >= 0; j--)
|
|
|
|
foreach (Spot spot in _spotMap[j]) {
|
|
|
|
spot.Reserved = false;
|
|
|
|
spot.ReservedPriority = 0;
|
|
|
|
}
|
2022-10-10 19:45:07 +02:00
|
|
|
|
2022-10-10 22:13:42 +02:00
|
|
|
foreach (Driver driver in DataImporter.Drivers) {
|
|
|
|
driver.Reserved = false;
|
|
|
|
}
|
|
|
|
|
2022-10-11 23:35:25 +02:00
|
|
|
float rightTime = 12.0f;//(float)_currentTime.TotalHours;
|
2022-10-10 22:13:42 +02:00
|
|
|
float leftTime = 16.0f;//(float)(_currentTime + TimeSpan.FromHours(hours)).TotalHours;
|
|
|
|
|
2022-10-10 19:45:07 +02:00
|
|
|
TimeSpan maxArrivalTime = _currentTime + TimeSpan.FromHours(hours);
|
|
|
|
List<Driver> nextDrivers = new List<Driver>();
|
|
|
|
foreach (Driver driver in DataImporter.Drivers) {
|
2022-10-10 22:13:42 +02:00
|
|
|
if (driver.RealArrival >= _currentTime && driver.PlannedArrival < maxArrivalTime && !driver.Reserved) {
|
2022-10-10 19:45:07 +02:00
|
|
|
nextDrivers.Add(driver);
|
|
|
|
}
|
|
|
|
}
|
2022-10-13 20:16:26 +02:00
|
|
|
// nextDrivers.Sort(((a, b) => Comparer<TimeSpan>.Default.Compare(a.PlannedDeparture, b.PlannedDeparture)));
|
|
|
|
nextDrivers.Sort(((a, b) => Comparer<int>.Default.Compare(a.Priority, b.Priority)));
|
2022-10-11 23:35:25 +02:00
|
|
|
//nextDrivers.Sort(((a, b) => Comparer<TimeSpan>.Default.Compare(a.RealDeparture, b.RealDeparture)));
|
|
|
|
//nextDrivers.Sort(((a, b) => Comparer<TimeSpan>.Default.Compare(a.PlannedArrival, b.PlannedArrival)));
|
2022-10-10 19:45:07 +02:00
|
|
|
|
|
|
|
List<Spot> availableSpots = new List<Spot>();
|
|
|
|
|
|
|
|
foreach (List<Spot> list in _spotMap)
|
|
|
|
foreach (Spot spot in list)
|
2022-10-11 23:35:25 +02:00
|
|
|
// if (!spot.Reserved && spot.Free)
|
2022-10-10 19:45:07 +02:00
|
|
|
availableSpots.Add(spot);
|
|
|
|
|
2022-10-10 22:13:42 +02:00
|
|
|
// availableSpots.Reverse();
|
2022-10-10 19:45:07 +02:00
|
|
|
|
2022-10-10 22:13:42 +02:00
|
|
|
// leftTime = (float)nextDrivers.Max(d => d.PlannedDeparture).TotalHours;
|
2022-10-11 23:35:25 +02:00
|
|
|
|
|
|
|
Driver FindOccupyingDriver(Spot spot)
|
|
|
|
{
|
|
|
|
return spot.OccupyingDriver;
|
|
|
|
}
|
2022-10-10 22:13:42 +02:00
|
|
|
|
2022-10-10 19:45:07 +02:00
|
|
|
for (int i = 0; i < nextDrivers.Count; i++) {
|
|
|
|
Driver driver = nextDrivers[i];
|
2022-10-10 22:13:42 +02:00
|
|
|
|
2022-10-11 23:35:25 +02:00
|
|
|
float driverTime = (float)driver.PlannedDeparture.TotalHours;
|
|
|
|
//float driverTime = (float)driver.RealDeparture.TotalHours;
|
2022-10-10 22:13:42 +02:00
|
|
|
float timeProgress = (driverTime - rightTime) / (leftTime - rightTime);
|
|
|
|
float xPosition = Width / 2.0f - (Width * timeProgress);
|
|
|
|
availableSpots.Sort(((a, b) => Comparer<float>.Default.Compare(Mathf.Abs(xPosition - a.Position.x), Mathf.Abs(xPosition - b.Position.x))));
|
|
|
|
|
|
|
|
bool useBottomLane = true;
|
2022-10-10 19:45:07 +02:00
|
|
|
for (int j = 0; j < availableSpots.Count; j++) {
|
|
|
|
Spot spot = availableSpots[j];
|
2022-10-11 23:35:25 +02:00
|
|
|
if (driver.Size == spot.Size && (spot.Lane != 0)) {
|
|
|
|
TimeSpan leaveTime = spot.Free ? TimeSpan.Zero : FindOccupyingDriver(spot).PlannedDeparture;
|
|
|
|
if (((!spot.Reserved && spot.Free)
|
|
|
|
|| (!spot.Free &&
|
|
|
|
leaveTime <
|
|
|
|
driver.PlannedArrival))) {
|
|
|
|
spot.Reserved = true;
|
|
|
|
driver.Reserved = true;
|
|
|
|
driver.ReservedSpot = spot;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if (Mathf.Abs(spot.Position.x - xPosition) > 20.0f) {
|
|
|
|
// if (useBottomLane)
|
|
|
|
// break;
|
|
|
|
// // useBottomLane = true;
|
|
|
|
// // j = -1;
|
|
|
|
// }
|
|
|
|
if(!driver.Reserved)
|
|
|
|
for (int j = 0; j < availableSpots.Count; j++) {
|
|
|
|
Spot spot = availableSpots[j];
|
|
|
|
if (driver.Size == spot.Size && !spot.Reserved) {
|
2022-10-10 19:45:07 +02:00
|
|
|
spot.Reserved = true;
|
|
|
|
driver.Reserved = true;
|
|
|
|
driver.ReservedSpot = spot;
|
|
|
|
break;
|
|
|
|
}
|
2022-10-10 22:13:42 +02:00
|
|
|
|
|
|
|
// if (Mathf.Abs(spot.Position.x - xPosition) > 20.0f) {
|
|
|
|
// if (useBottomLane)
|
|
|
|
// break;
|
|
|
|
// // useBottomLane = true;
|
|
|
|
// // j = -1;
|
|
|
|
// }
|
2022-10-10 19:45:07 +02:00
|
|
|
}
|
|
|
|
}
|
2022-10-10 22:13:42 +02:00
|
|
|
// done:
|
|
|
|
// {
|
|
|
|
// }
|
2022-10-10 19:45:07 +02:00
|
|
|
|
|
|
|
// for (int i = 0; i < Math.Min(DataImporter.Drivers.Count, _initialConfigurationSpotCount); i++) {
|
|
|
|
// bool found = false;
|
|
|
|
// // Find spot
|
|
|
|
// for (int j = 3; j >= 0 && !found; j--)
|
|
|
|
// foreach (Spot spot in _spotMap[j])
|
|
|
|
// if (spot.Size == DataImporter.Drivers[i].Size && !spot.Reserved) {
|
|
|
|
// spot.Reserved = true;
|
|
|
|
// spot.ReservedPriority = DataImporter.Drivers[i].Priority;
|
|
|
|
// found = true;
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}
|
2022-08-29 23:01:18 +02:00
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
public void AdvanceTime()
|
|
|
|
{
|
2022-09-04 00:35:45 +02:00
|
|
|
// Update time
|
2022-09-03 21:27:31 +02:00
|
|
|
_currentTime += TimeSpan.FromMinutes(stepTime);
|
2022-09-04 00:35:45 +02:00
|
|
|
if (_currentTime > EndTime) {
|
2022-09-03 21:27:31 +02:00
|
|
|
_currentTime = StartTime;
|
2022-09-05 01:15:04 +02:00
|
|
|
timeText.text = _currentTime.ToString();
|
2022-09-04 00:35:45 +02:00
|
|
|
_rejectedDrivers = new[] {0, 0, 0, 0};
|
2022-09-03 21:27:31 +02:00
|
|
|
rejectedText.text = $"Małe: {_rejectedDrivers[0]} Średnie: {_rejectedDrivers[1]} " +
|
|
|
|
$"Duże: {_rejectedDrivers[2]}";
|
2022-09-05 01:15:04 +02:00
|
|
|
if (_emergencyActivated) {
|
|
|
|
emergencyPlanContainer.gameObject.SetActive(true);
|
|
|
|
mainPlanContainer.gameObject.SetActive(false);
|
|
|
|
}
|
|
|
|
else {
|
2022-09-06 23:20:53 +02:00
|
|
|
ArrangeSpots(_initialSolution);
|
2022-09-05 01:15:04 +02:00
|
|
|
ReserveInitialSpots();
|
|
|
|
ResetDrivers();
|
|
|
|
}
|
2022-09-05 22:01:52 +02:00
|
|
|
|
2022-09-03 21:27:31 +02:00
|
|
|
return;
|
|
|
|
}
|
2022-09-04 00:35:45 +02:00
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
timeText.text = _currentTime.ToString();
|
2022-09-04 00:35:45 +02:00
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
if (_emergencyActivated)
|
|
|
|
return;
|
2022-09-04 00:35:45 +02:00
|
|
|
|
2022-09-08 22:48:36 +02:00
|
|
|
if (_reconfigurationActive)
|
2022-09-08 00:43:34 +02:00
|
|
|
ReconfigureSpots();
|
2022-10-10 19:45:07 +02:00
|
|
|
|
2022-10-10 22:13:42 +02:00
|
|
|
if((_currentTime.Hours - 6) % 3 == 0 && _currentTime.Minutes == 0)
|
|
|
|
ReserveSpotsInTimeRange(3);
|
|
|
|
// if(_currentTime.Hours == 6 && _currentTime.Minutes == 0)
|
|
|
|
// ReserveSpotsInTimeRange(10);
|
2022-10-10 19:45:07 +02:00
|
|
|
|
|
|
|
UpdateIncomingOutgoingDrivers();
|
|
|
|
|
|
|
|
UpdateCounts();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void UpdateIncomingOutgoingDrivers()
|
|
|
|
{
|
2022-09-06 23:20:53 +02:00
|
|
|
|
2022-09-04 00:35:45 +02:00
|
|
|
foreach (Driver driver in DataImporter.Drivers) {
|
2022-09-04 12:47:46 +02:00
|
|
|
// TODO: Check if car can stay before other reservation - may not work for priority-based reservations
|
2022-09-05 01:15:04 +02:00
|
|
|
bool triesToPark = _currentTime <= driver.Times[3].TimeOfDay &&
|
|
|
|
_currentTime > driver.Times[2].TimeOfDay;
|
|
|
|
bool leftTheParking = _currentTime > driver.Times[3].TimeOfDay && driver.Parked;
|
2022-09-04 13:36:19 +02:00
|
|
|
bool reservedButTimedout =
|
2022-09-05 01:15:04 +02:00
|
|
|
(_currentTime - driver.Times[0].TimeOfDay).TotalMinutes > driver.UpdateInterval &&
|
2022-09-04 13:36:19 +02:00
|
|
|
GetReservedSpotCount(driver.Priority, driver.Size) > 0
|
|
|
|
&& !driver.Parked && !driver.Rejected && _currentTime <= driver.Times[3].TimeOfDay;
|
2022-10-10 19:45:07 +02:00
|
|
|
// if (driver.Reserved && !reservedButTimedout) {
|
|
|
|
//
|
|
|
|
// }
|
2022-09-04 00:35:45 +02:00
|
|
|
if (triesToPark && !driver.Parked && !driver.Rejected) {
|
|
|
|
if (!PlaceCarOnParking(driver)) {
|
2022-09-08 00:43:34 +02:00
|
|
|
if (_reconfigurationActive && TryReconfigureSpotForSize(driver.Size)) {
|
2022-09-06 23:20:53 +02:00
|
|
|
if (!PlaceCarOnParking(driver)) {
|
|
|
|
Debug.Log($"Placing failed for car {driver.Number} size {driver.Size}");
|
|
|
|
driver.Rejected = true;
|
|
|
|
_rejectedDrivers[(int) driver.Size]++;
|
|
|
|
rejectedText.text = $"Małe: {_rejectedDrivers[0]} Średnie: {_rejectedDrivers[1]} " +
|
|
|
|
$"Duże: {_rejectedDrivers[2]}";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Debug.Log($"Placing failed for car {driver.Number} size {driver.Size}");
|
|
|
|
driver.Rejected = true;
|
|
|
|
_rejectedDrivers[(int) driver.Size]++;
|
|
|
|
rejectedText.text = $"Małe: {_rejectedDrivers[0]} Średnie: {_rejectedDrivers[1]} " +
|
|
|
|
$"Duże: {_rejectedDrivers[2]}";
|
|
|
|
}
|
2022-09-03 00:23:15 +02:00
|
|
|
}
|
|
|
|
}
|
2022-09-04 00:35:45 +02:00
|
|
|
else if (leftTheParking) {
|
|
|
|
driver.Spot.Reserved = false;
|
2022-10-10 22:13:42 +02:00
|
|
|
driver.Reserved = false;
|
2022-09-03 21:27:31 +02:00
|
|
|
driver.Reset();
|
2022-09-05 01:15:04 +02:00
|
|
|
}
|
|
|
|
else if (reservedButTimedout) {
|
2022-09-04 13:36:19 +02:00
|
|
|
Debug.Log($"Reserved but timed out driver {driver.Number}");
|
|
|
|
driver.Rejected = true;
|
2022-09-01 22:31:57 +02:00
|
|
|
}
|
2022-09-04 00:35:45 +02:00
|
|
|
}
|
2022-09-06 23:20:53 +02:00
|
|
|
}
|
2022-09-04 13:36:19 +02:00
|
|
|
|
2022-09-06 23:20:53 +02:00
|
|
|
private void UpdateCounts()
|
|
|
|
{
|
|
|
|
|
|
|
|
int[] counts = {0, 0, 0, 0};
|
|
|
|
for (int i = 0; i < _spotMap.Count; i++)
|
|
|
|
for (int j = 0; j < _spotMap[i].Count; j++)
|
|
|
|
counts[(int) _spotMap[i][j].Size]++;
|
|
|
|
|
|
|
|
string countsString = $"Małe: {counts[0]} Średnie: {counts[1]} Duże: {counts[2]} " +
|
|
|
|
$"Suma: {counts.Sum()}";
|
|
|
|
UpdateText(countsString);
|
2022-09-01 22:31:57 +02:00
|
|
|
}
|
|
|
|
|
2022-09-03 21:27:31 +02:00
|
|
|
private void ResetDrivers()
|
|
|
|
{
|
2022-09-05 01:15:04 +02:00
|
|
|
foreach (Driver driver in DataImporter.Drivers) {
|
2022-09-04 12:47:46 +02:00
|
|
|
if (driver.Spot != null) {
|
|
|
|
driver.Spot.Reserved = false;
|
|
|
|
driver.Spot.ReservedPriority = 0;
|
|
|
|
}
|
2022-09-05 01:15:04 +02:00
|
|
|
|
2022-09-03 21:27:31 +02:00
|
|
|
driver.Reset();
|
2022-09-04 12:47:46 +02:00
|
|
|
}
|
2022-09-04 00:35:45 +02:00
|
|
|
}
|
|
|
|
|
2022-09-04 13:36:19 +02:00
|
|
|
private int GetReservedSpotCount(int priority, Size size)
|
|
|
|
{
|
|
|
|
int count = 0;
|
2022-09-08 00:43:34 +02:00
|
|
|
foreach (List<Spot> list in _spotMap)
|
2022-09-05 01:15:04 +02:00
|
|
|
foreach (Spot spot in list)
|
|
|
|
if (spot.Size == size && spot.Reserved && spot.ReservedPriority == priority)
|
|
|
|
count++;
|
2022-09-04 13:36:19 +02:00
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2022-09-04 00:35:45 +02:00
|
|
|
private bool FindReservedSpot(Driver driver, out Spot spot)
|
|
|
|
{
|
2022-10-10 19:45:07 +02:00
|
|
|
if (driver.Reserved) {
|
2022-10-11 23:35:25 +02:00
|
|
|
if(driver.ReservedSpot.GameObject == null || !driver.ReservedSpot.Free)
|
|
|
|
Debug.Log("Spot not viable anymore");
|
2022-10-10 19:45:07 +02:00
|
|
|
else {
|
|
|
|
spot = driver.ReservedSpot;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-11 23:35:25 +02:00
|
|
|
// foreach (List<Spot> list in _spotMap)
|
|
|
|
// foreach (Spot spot1 in list)
|
|
|
|
// if (spot1.Reserved && spot1.ReservedPriority == driver.Priority && driver.Size == spot1.Size) {
|
|
|
|
// spot = spot1;
|
|
|
|
// return true;
|
|
|
|
// }
|
2022-09-04 00:35:45 +02:00
|
|
|
|
|
|
|
spot = new Spot();
|
|
|
|
|
|
|
|
return false;
|
2022-09-03 21:27:31 +02:00
|
|
|
}
|
|
|
|
|
2022-09-03 00:23:15 +02:00
|
|
|
private bool PlaceCarOnParking(Driver driver)
|
2022-09-01 22:31:57 +02:00
|
|
|
{
|
2022-09-04 00:35:45 +02:00
|
|
|
if (FindReservedSpot(driver, out Spot reservedSpot)) {
|
|
|
|
if (reservedSpot.Free) {
|
|
|
|
PlaceDriverOnSpot(driver, reservedSpot);
|
|
|
|
return true;
|
|
|
|
}
|
2022-09-05 01:15:04 +02:00
|
|
|
|
|
|
|
Debug.Log("Spot should be reserved but is taken");
|
2022-09-04 00:35:45 +02:00
|
|
|
}
|
2022-09-03 00:23:15 +02:00
|
|
|
|
2022-09-04 00:35:45 +02:00
|
|
|
|
2022-09-08 00:43:34 +02:00
|
|
|
foreach (List<Spot> t in _spotMap)
|
2022-09-04 00:35:45 +02:00
|
|
|
foreach (Spot spot in t) {
|
2022-09-05 01:15:04 +02:00
|
|
|
bool spotAvailable = spot.Size == driver.Size && spot.Free &&
|
|
|
|
(spot.ParkingDirection == driver.ParkingPreference ||
|
|
|
|
spot.ParkingDirection == ParkingPreference.Any)
|
|
|
|
&& !spot.Reserved;
|
|
|
|
|
2022-09-04 00:35:45 +02:00
|
|
|
if (spotAvailable) {
|
|
|
|
PlaceDriverOnSpot(driver, spot);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-08 00:43:34 +02:00
|
|
|
foreach (List<Spot> t in _spotMap)
|
2022-09-04 00:35:45 +02:00
|
|
|
foreach (Spot spot in t)
|
|
|
|
if (spot.Size == driver.Size && spot.Free && !spot.Reserved) {
|
|
|
|
PlaceDriverOnSpot(driver, spot);
|
|
|
|
return true;
|
|
|
|
}
|
2022-09-03 00:23:15 +02:00
|
|
|
|
|
|
|
return false;
|
2022-08-31 20:50:59 +02:00
|
|
|
}
|
2022-08-29 23:01:18 +02:00
|
|
|
|
2022-09-04 00:35:45 +02:00
|
|
|
private void PlaceDriverOnSpot(Driver driver, Spot spot)
|
|
|
|
{
|
2022-10-10 19:45:07 +02:00
|
|
|
if (spot.GameObject == null) {
|
|
|
|
Debug.LogError("Spot is null");
|
|
|
|
}
|
2022-09-04 00:35:45 +02:00
|
|
|
spot.Free = false;
|
|
|
|
spot.Reserved = false;
|
2022-10-11 23:35:25 +02:00
|
|
|
spot.OccupyingDriver = driver;
|
2022-09-04 00:35:45 +02:00
|
|
|
driver.Spot = spot;
|
|
|
|
driver.Parked = true;
|
2022-09-05 23:31:33 +02:00
|
|
|
driver.GameObject = Instantiate(carPrefab);
|
2022-09-04 00:35:45 +02:00
|
|
|
driver.GameObject.GetComponentInChildren<TextMeshProUGUI>().text = driver.Number.ToString();
|
|
|
|
driver.GameObject.GetComponentInChildren<TextMeshProUGUI>().transform.rotation =
|
2022-09-06 23:20:53 +02:00
|
|
|
Quaternion.Euler(new Vector3(0, 0, (spot.Flipped ? 180 : 0) + (!spot.Perpendicular ? -90 : 0)));
|
2022-09-05 23:31:33 +02:00
|
|
|
driver.GameObject.transform.rotation =
|
|
|
|
Quaternion.Euler(new Vector3(0, 0, (spot.Flipped ? 180 : 0) + (!spot.Perpendicular ? 90 : 0)));
|
2022-09-04 00:35:45 +02:00
|
|
|
driver.GameObject.transform.position = spot.GameObject.transform.position;
|
2022-09-05 23:31:33 +02:00
|
|
|
driver.GameObject.transform.SetParent(spot.GameObject.transform, true);
|
2022-09-05 22:00:15 +02:00
|
|
|
driver.GameObject.transform.localPosition += new Vector3(0, 0, -1);
|
2022-09-04 00:35:45 +02:00
|
|
|
}
|
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
public void UpdateText(string text)
|
2022-08-29 23:01:18 +02:00
|
|
|
{
|
2022-08-31 20:50:59 +02:00
|
|
|
countsText.text = text;
|
2022-08-29 23:01:18 +02:00
|
|
|
}
|
2022-08-29 23:32:16 +02:00
|
|
|
|
2022-09-03 21:27:31 +02:00
|
|
|
private void ReconfigureSpots()
|
|
|
|
{
|
2022-09-05 01:15:04 +02:00
|
|
|
int[] freeSpots = GetFreeSpotCount();
|
2022-09-08 00:43:34 +02:00
|
|
|
List<Driver> nextCars = GetNextCars(1);
|
2022-09-04 00:35:45 +02:00
|
|
|
int[] plannedSpots = {0, 0, 0, 0};
|
2022-09-03 21:27:31 +02:00
|
|
|
foreach (Driver driver in nextCars)
|
2022-09-04 00:35:45 +02:00
|
|
|
plannedSpots[(int) driver.Size]++;
|
|
|
|
|
|
|
|
int[] neededSpots = {0, 0, 0, 0};
|
2022-09-03 21:27:31 +02:00
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
for (int i = 0; i < neededSpots.Length; i++)
|
2022-09-04 13:36:19 +02:00
|
|
|
neededSpots[i] = Math.Max(plannedSpots[i] - freeSpots[i], 0);
|
2022-09-06 23:20:53 +02:00
|
|
|
if (neededSpots.Sum() > 1) {
|
2022-09-03 21:27:31 +02:00
|
|
|
Debug.Log($"Needed spots = {neededSpots[0]} {neededSpots[1]} {neededSpots[2]} {neededSpots[3]}");
|
2022-09-04 00:35:45 +02:00
|
|
|
Debug.Log("Attempting reconfiguration...");
|
2022-09-03 21:27:31 +02:00
|
|
|
|
2022-09-08 22:48:36 +02:00
|
|
|
List<Driver> spotlessCars = new();
|
2022-09-06 23:20:53 +02:00
|
|
|
|
|
|
|
// Filter drivers by assigning free space
|
|
|
|
foreach (Driver nextCar in nextCars)
|
|
|
|
if (freeSpots[(int) nextCar.Size] != 0)
|
|
|
|
freeSpots[(int) nextCar.Size]--;
|
|
|
|
else
|
|
|
|
spotlessCars.Add(nextCar);
|
|
|
|
|
|
|
|
|
2022-10-10 19:45:07 +02:00
|
|
|
int count = 0;
|
|
|
|
|
2022-09-08 00:43:34 +02:00
|
|
|
foreach (Driver nextCar in spotlessCars)
|
2022-10-10 19:45:07 +02:00
|
|
|
if (TryReconfigureSpotForSize(nextCar.Size))
|
|
|
|
count++;
|
|
|
|
|
|
|
|
Debug.Log($"Created {count} out of {spotlessCars.Count}");
|
2022-09-06 23:20:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool TryReconfigureSpotForSize(Size newSize)
|
|
|
|
{
|
2022-10-05 21:56:02 +02:00
|
|
|
if (newSize == Size.C) {
|
2022-10-10 19:45:07 +02:00
|
|
|
// Debug.Log("Reconfiguring using new method");
|
2022-10-05 21:56:02 +02:00
|
|
|
int lane1 = 2;
|
|
|
|
int lane2 = 1;
|
|
|
|
for (int i = _spotMap[lane2].Count - 1; i >= 0; i--)
|
|
|
|
// Check if both spots free
|
|
|
|
if (_spotMap[lane1][i].Free && _spotMap[lane2][i].Free) {
|
|
|
|
// Check if we can make space on lane 1
|
|
|
|
Spot lowerSpot = _spotMap[lane2][i];
|
|
|
|
Spot higherSpot = _spotMap[lane1][i];
|
|
|
|
float lowerBorder = GetNextBorderVectical(lowerSpot.GameObject.transform.position, 1, false,
|
|
|
|
lowerSpot.Size, false);
|
|
|
|
float lowerReconfiguredBorder = Height / 2.0f - 5.0f - 5.5f - 5.0f - 5.0f;
|
|
|
|
if (lowerReconfiguredBorder - lowerBorder >= 5.5f) {
|
|
|
|
// We have space
|
|
|
|
higherSpot.Size = Size.C;
|
|
|
|
lowerSpot.Size = Size.C;
|
|
|
|
Vector3 higherPosition = higherSpot.Position;
|
|
|
|
higherPosition.y = Height / 2.0f - 5.0f - 5.5f - 5.0f / 2.0f;
|
|
|
|
Vector3 lowerPosition = lowerSpot.Position;
|
|
|
|
lowerPosition.y = Height / 2.0f - 5.0f - 5.5f - 5.0f - 5.0f / 2.0f;
|
|
|
|
higherSpot.Position = higherPosition;
|
|
|
|
lowerSpot.Position = lowerPosition;
|
|
|
|
lowerSpot.Reserved = false;
|
|
|
|
higherSpot.Reserved = false;
|
|
|
|
Destroy(lowerSpot.GameObject);
|
|
|
|
Destroy(higherSpot.GameObject);
|
|
|
|
lowerSpot.GameObject = Instantiate(_spotPrefabs[(int)Size.C],
|
|
|
|
lowerPosition, lowerSpot.GameObject.transform.rotation, mainPlanContainer);
|
|
|
|
higherSpot.GameObject = Instantiate(_spotPrefabs[(int)Size.C],
|
|
|
|
higherPosition, higherSpot.GameObject.transform.rotation, mainPlanContainer);
|
|
|
|
lowerSpot.LastReconfiguration = _currentTime;
|
|
|
|
higherSpot.LastReconfiguration = _currentTime;
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else {
|
2022-10-10 22:13:42 +02:00
|
|
|
List<int> conflictingSpots = GetConflictingSpotsLower(lowerSpot.GameObject.transform.position, 0, true,
|
2022-10-05 21:56:02 +02:00
|
|
|
lowerSpot.Size, 0.0f);
|
|
|
|
|
|
|
|
// verify we can delete them
|
2022-10-10 22:13:42 +02:00
|
|
|
int maxASpotsDeleted = GetSpotCountOfSize(Size.A) - 2;
|
|
|
|
int maxBSpotsDeleted = GetSpotCountOfSize(Size.B) - 2;
|
2022-10-10 19:45:07 +02:00
|
|
|
bool allSpotsFree = true;
|
2022-10-05 21:56:02 +02:00
|
|
|
foreach (int conflictingSpotId in conflictingSpots) {
|
2022-10-10 19:45:07 +02:00
|
|
|
Spot conflictingSpot = _spotMap[0][conflictingSpotId];
|
2022-10-10 22:13:42 +02:00
|
|
|
if (conflictingSpot.Size == Size.A)
|
|
|
|
maxASpotsDeleted--;
|
|
|
|
if (conflictingSpot.Size == Size.B)
|
|
|
|
maxBSpotsDeleted--;
|
2022-10-10 19:45:07 +02:00
|
|
|
if (!conflictingSpot.Free || conflictingSpot.Reserved)
|
|
|
|
allSpotsFree = false;
|
2022-10-05 21:56:02 +02:00
|
|
|
}
|
2022-10-10 22:13:42 +02:00
|
|
|
if(maxASpotsDeleted < 0 || maxBSpotsDeleted < 0)
|
|
|
|
continue;
|
2022-10-10 19:45:07 +02:00
|
|
|
if(!allSpotsFree)
|
|
|
|
continue;
|
|
|
|
|
2022-10-05 21:56:02 +02:00
|
|
|
// delete them
|
|
|
|
int removed = 0;
|
|
|
|
conflictingSpots.Sort();
|
|
|
|
foreach (int conflictingSpotId in conflictingSpots) {
|
|
|
|
Destroy(_spotMap[0][conflictingSpotId - removed].GameObject);
|
|
|
|
_spotMap[0].RemoveAt(conflictingSpotId - removed);
|
|
|
|
removed++;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Adjust new spots
|
|
|
|
higherSpot.Size = Size.C;
|
|
|
|
lowerSpot.Size = Size.C;
|
|
|
|
Vector3 higherPosition = higherSpot.Position;
|
|
|
|
higherPosition.y = Height / 2.0f - 5.0f - 5.5f - 5.0f / 2.0f;
|
|
|
|
Vector3 lowerPosition = lowerSpot.Position;
|
|
|
|
lowerPosition.y = Height / 2.0f - 5.0f - 5.5f - 5.0f - 5.0f / 2.0f;
|
|
|
|
higherSpot.Position = higherPosition;
|
|
|
|
lowerSpot.Position = lowerPosition;
|
|
|
|
lowerSpot.Reserved = false;
|
|
|
|
higherSpot.Reserved = false;
|
|
|
|
Destroy(lowerSpot.GameObject);
|
|
|
|
Destroy(higherSpot.GameObject);
|
|
|
|
lowerSpot.GameObject = Instantiate(_spotPrefabs[(int)Size.C],
|
|
|
|
lowerPosition, lowerSpot.GameObject.transform.rotation, mainPlanContainer);
|
|
|
|
higherSpot.GameObject = Instantiate(_spotPrefabs[(int)Size.C],
|
|
|
|
higherPosition, higherSpot.GameObject.transform.rotation, mainPlanContainer);
|
|
|
|
lowerSpot.LastReconfiguration = _currentTime;
|
|
|
|
higherSpot.LastReconfiguration = _currentTime;
|
|
|
|
|
2022-10-06 21:52:35 +02:00
|
|
|
|
2022-10-05 21:56:02 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-10-06 21:52:35 +02:00
|
|
|
// Try regeneration before returning false
|
2022-10-11 23:35:25 +02:00
|
|
|
if (RegenerateSpots(newSize))
|
|
|
|
return true;
|
2022-10-05 21:56:02 +02:00
|
|
|
}
|
|
|
|
|
2022-09-08 00:43:34 +02:00
|
|
|
foreach (List<Spot> currentLaneSpots in _spotMap)
|
2022-09-11 23:43:19 +02:00
|
|
|
for (int i = 0; i < currentLaneSpots.Count; i++) {
|
|
|
|
Spot spot = currentLaneSpots[i];
|
2022-10-11 23:35:25 +02:00
|
|
|
if (!spot.Free || spot.Size == Size.D)// || spot.Reserved)
|
2022-09-11 23:43:19 +02:00
|
|
|
continue;
|
|
|
|
if (GetSpotCountOfSize(Size.A) <= 2 && spot.Size == Size.A)
|
|
|
|
continue;
|
|
|
|
if (GetSpotCountOfSize(Size.B) <= 2 && spot.Size == Size.B)
|
|
|
|
continue;
|
|
|
|
if (spot.LastReconfiguration == _currentTime)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
int size = (int) newSize;
|
|
|
|
Vector3 position = spot.GameObject.transform.position;
|
|
|
|
Quaternion rotation = spot.GameObject.transform.rotation;
|
|
|
|
|
2022-10-05 21:56:02 +02:00
|
|
|
float diff = (SpotHeights[(int) spot.Size] - SpotHeights[size]) / 2.0f;
|
2022-09-11 23:43:19 +02:00
|
|
|
if (!spot.AlignToTop)
|
|
|
|
diff *= -1;
|
|
|
|
Vector3 offset = spot.Perpendicular ? new Vector3(0, diff, 0) : new Vector3(-diff, 0, 0);
|
|
|
|
Vector3 newPosition = position + offset;
|
|
|
|
|
|
|
|
if (spot.Size > newSize) {
|
|
|
|
if (!spot.Perpendicular) {
|
2022-09-12 23:28:39 +02:00
|
|
|
float newX =
|
|
|
|
GetNextBorderHorizontal(position, spot.Lane, spot.Perpendicular, newSize, true) -
|
2022-10-05 21:56:02 +02:00
|
|
|
SpotHeights[(int) spot.Size] / 2.0f - 0.5f;
|
2022-09-11 23:43:19 +02:00
|
|
|
newPosition = new Vector3(newX,
|
|
|
|
newPosition.y, newPosition.z);
|
2022-09-08 00:43:34 +02:00
|
|
|
}
|
|
|
|
else {
|
2022-09-12 23:28:39 +02:00
|
|
|
float newX =
|
|
|
|
GetNextBorderHorizontal(position, spot.Lane, spot.Perpendicular, newSize, true) -
|
|
|
|
2.25f / 2.0f;
|
2022-09-11 23:43:19 +02:00
|
|
|
if (spot.Lane == 0) {
|
|
|
|
float xRelativeToRight = newX - Width / 2.0f - 2.25f / 2.0f;
|
|
|
|
xRelativeToRight -= (xRelativeToRight + 2.25f / 2.0f) % 2.25f;
|
|
|
|
newX = xRelativeToRight + Width / 2.0f;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
float xRelativeToLeft = newX + Width / 2.0f;
|
|
|
|
xRelativeToLeft -= (xRelativeToLeft + 2.25f / 2.0f) % 2.25f;
|
|
|
|
newX = xRelativeToLeft - Width / 2.0f;
|
|
|
|
}
|
2022-09-06 23:20:53 +02:00
|
|
|
|
2022-09-11 23:43:19 +02:00
|
|
|
newPosition = new Vector3(newX,
|
|
|
|
newPosition.y, newPosition.z);
|
|
|
|
}
|
2022-09-08 20:42:11 +02:00
|
|
|
}
|
2022-09-11 23:43:19 +02:00
|
|
|
else if (spot.Size < newSize) {
|
|
|
|
float spotBorder;
|
|
|
|
float thisSizeOffset;
|
|
|
|
if (spot.Perpendicular)
|
2022-10-05 21:56:02 +02:00
|
|
|
thisSizeOffset = SpotHeights[size] / 2.0f;
|
2022-09-11 23:43:19 +02:00
|
|
|
else
|
|
|
|
thisSizeOffset = 2.25f / 2.0f;
|
|
|
|
if (!spot.AlignToTop)
|
|
|
|
spotBorder = newPosition.y + thisSizeOffset;
|
|
|
|
else
|
|
|
|
spotBorder = newPosition.y - thisSizeOffset;
|
|
|
|
if (spot.Perpendicular) {
|
2022-09-12 23:28:39 +02:00
|
|
|
float nextBorder = GetNextBorderVectical(newPosition, spot.Lane, spot.Perpendicular,
|
|
|
|
newSize,
|
2022-09-11 23:43:19 +02:00
|
|
|
!spot.AlignToTop);
|
|
|
|
if (Math.Abs(spotBorder - nextBorder) < 5.5f)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else {
|
2022-09-12 23:28:39 +02:00
|
|
|
float nextBorderLeft = GetNextBorderHorizontal(position, spot.Lane, spot.Perpendicular,
|
2022-09-11 23:43:19 +02:00
|
|
|
spot.Size,
|
|
|
|
false);
|
|
|
|
float nextBorderRight = GetNextBorderHorizontal(position, spot.Lane, spot.Perpendicular,
|
|
|
|
spot.Size,
|
|
|
|
true);
|
2022-10-05 21:56:02 +02:00
|
|
|
if (nextBorderRight - nextBorderLeft < SpotHeights[(int) newSize] + 1f) {
|
2022-09-11 23:43:19 +02:00
|
|
|
// Try perpendicular
|
|
|
|
float bottomBorder = newPosition.y - 2.25f / 2.0f;
|
|
|
|
float topBorder = newPosition.y + 2.25f / 2.0f;
|
|
|
|
bool foundByRemoval = false;
|
|
|
|
if (spot.AlignToTop) {
|
2022-10-05 21:56:02 +02:00
|
|
|
float newBottomBorder = topBorder - SpotHeights[size];
|
2022-09-11 23:43:19 +02:00
|
|
|
float newTopBorder = topBorder;
|
2022-10-05 21:56:02 +02:00
|
|
|
float nextBorder = GetNextBorderVectical(newPosition, spot.Lane,
|
|
|
|
spot.Perpendicular,
|
2022-09-11 23:43:19 +02:00
|
|
|
newSize,
|
|
|
|
!spot.AlignToTop);
|
|
|
|
if (Math.Abs(nextBorder - newBottomBorder) < 5.5f) {
|
|
|
|
if (i < currentLaneSpots.Count - 1) {
|
|
|
|
Spot nextSpot = currentLaneSpots[i + 1];
|
|
|
|
if (nextSpot.Free && !nextSpot.Reserved) {
|
|
|
|
Destroy(nextSpot.GameObject);
|
|
|
|
currentLaneSpots.RemoveAt(i + 1);
|
|
|
|
i--;
|
2022-10-05 21:56:02 +02:00
|
|
|
newPosition.x = nextBorderRight - SpotHeights[(int) newSize] -
|
|
|
|
0.5f;
|
2022-09-11 23:43:19 +02:00
|
|
|
newPosition.y = position.y;
|
|
|
|
foundByRemoval = true;
|
2022-09-12 23:28:39 +02:00
|
|
|
}
|
|
|
|
else
|
2022-09-11 23:43:19 +02:00
|
|
|
continue;
|
|
|
|
}
|
2022-09-10 22:34:20 +02:00
|
|
|
}
|
|
|
|
}
|
2022-09-11 23:43:19 +02:00
|
|
|
else {
|
|
|
|
float newBottomBorder = bottomBorder;
|
2022-10-05 21:56:02 +02:00
|
|
|
float newTopBorder = bottomBorder + SpotHeights[size];
|
|
|
|
float nextBorder = GetNextBorderVectical(newPosition, spot.Lane,
|
|
|
|
spot.Perpendicular,
|
2022-09-11 23:43:19 +02:00
|
|
|
newSize,
|
|
|
|
!spot.AlignToTop);
|
|
|
|
if (Math.Abs(newTopBorder - nextBorder) < 5.5f) {
|
|
|
|
if (i < currentLaneSpots.Count - 1) {
|
|
|
|
Spot nextSpot = currentLaneSpots[i + 1];
|
|
|
|
if (nextSpot.Free && !nextSpot.Reserved) {
|
|
|
|
Destroy(nextSpot.GameObject);
|
|
|
|
currentLaneSpots.RemoveAt(i + 1);
|
|
|
|
i--;
|
2022-10-05 21:56:02 +02:00
|
|
|
newPosition.x = nextBorderRight - SpotHeights[(int) newSize] -
|
|
|
|
0.5f;
|
2022-09-11 23:43:19 +02:00
|
|
|
newPosition.y = position.y;
|
|
|
|
foundByRemoval = true;
|
2022-09-12 23:28:39 +02:00
|
|
|
}
|
|
|
|
else
|
2022-09-11 23:43:19 +02:00
|
|
|
continue;
|
|
|
|
}
|
2022-09-10 22:34:20 +02:00
|
|
|
}
|
2022-09-12 23:28:39 +02:00
|
|
|
|
2022-09-11 23:43:19 +02:00
|
|
|
}
|
2022-09-08 22:38:15 +02:00
|
|
|
|
2022-09-11 23:43:19 +02:00
|
|
|
if (!foundByRemoval) {
|
2022-09-10 22:34:20 +02:00
|
|
|
|
2022-10-05 21:56:02 +02:00
|
|
|
newPosition.y = bottomBorder + SpotHeights[(int) newSize] / 2.0f;
|
2022-09-11 23:43:19 +02:00
|
|
|
float newX = nextBorderRight;
|
|
|
|
if (spot.Lane == 0) {
|
|
|
|
float xRelativeToRight = -(newX - Width / 2.0f);
|
|
|
|
xRelativeToRight -= (xRelativeToRight + 2.25f / 2.0f) % 2.25f;
|
|
|
|
xRelativeToRight += 2.25f;
|
|
|
|
xRelativeToRight = Math.Max(xRelativeToRight, 2.25f / 2.0f);
|
|
|
|
newX = -xRelativeToRight + Width / 2.0f;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
float xRelativeToLeft = newX + Width / 2.0f;
|
|
|
|
xRelativeToLeft -= (xRelativeToLeft + 2.25f / 2.0f) % 2.25f;
|
|
|
|
newX = xRelativeToLeft - Width / 2.0f;
|
|
|
|
}
|
2022-09-10 22:34:20 +02:00
|
|
|
|
|
|
|
|
2022-09-11 23:43:19 +02:00
|
|
|
if (spot.Lane == 0 && Width / 2.0f - newX < 5.5f + 0.5f + 2.25f) {
|
|
|
|
// Try to remove one spot next
|
|
|
|
continue;
|
|
|
|
}
|
2022-09-12 23:28:39 +02:00
|
|
|
|
|
|
|
newPosition.x = newX;
|
2022-10-05 21:56:02 +02:00
|
|
|
spot.Flipped =
|
|
|
|
currentLaneSpots.FindIndex(spotPredicate => spotPredicate == spot) %
|
2022-09-12 23:28:39 +02:00
|
|
|
2 == 0;
|
|
|
|
rotation *= Quaternion.Euler(0, 0, spot.Flipped ? 90 : -90);
|
|
|
|
spot.Perpendicular = true;
|
2022-09-10 22:34:20 +02:00
|
|
|
}
|
2022-09-08 22:38:15 +02:00
|
|
|
}
|
2022-09-11 23:43:19 +02:00
|
|
|
else {
|
2022-10-05 21:56:02 +02:00
|
|
|
newPosition.x = nextBorderRight - SpotHeights[(int) newSize] / 2.0f - 0.5f;
|
2022-09-11 23:43:19 +02:00
|
|
|
if (i == 0)
|
|
|
|
newPosition.x += 0.5f;
|
|
|
|
newPosition.y = position.y;
|
|
|
|
|
|
|
|
// if (i < currentLaneSpots.Count - 1) {
|
|
|
|
// Spot nextSpot = currentLaneSpots[i + 1];
|
|
|
|
// if (nextSpot.Free && !nextSpot.Reserved) {
|
|
|
|
// Destroy(nextSpot.GameObject);
|
|
|
|
// currentLaneSpots.RemoveAt(i + 1);
|
|
|
|
// i--;
|
|
|
|
// newPosition.x = nextBorderRight - _spotHeights[(int) newSize] - 0.5f;
|
|
|
|
// newPosition.y = position.y;
|
|
|
|
// continue;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// newPosition.x = nextBorderRight - _spotHeights[(int) newSize] - 0.5f;
|
|
|
|
}
|
2022-09-08 22:38:15 +02:00
|
|
|
}
|
2022-09-08 00:43:34 +02:00
|
|
|
}
|
2022-09-08 22:48:36 +02:00
|
|
|
|
2022-09-11 23:43:19 +02:00
|
|
|
Destroy(spot.GameObject);
|
|
|
|
spot.Size = (Size) size;
|
|
|
|
spot.Reserved = false;
|
|
|
|
spot.GameObject = Instantiate(_spotPrefabs[size],
|
|
|
|
newPosition, rotation, mainPlanContainer);
|
|
|
|
spot.LastReconfiguration = _currentTime;
|
|
|
|
return true;
|
|
|
|
}
|
2022-09-08 22:48:36 +02:00
|
|
|
|
2022-09-06 23:20:53 +02:00
|
|
|
return false;
|
2022-09-03 21:27:31 +02:00
|
|
|
}
|
2022-10-06 21:52:35 +02:00
|
|
|
|
|
|
|
private bool RegenerateSpots(Size size)
|
|
|
|
{
|
|
|
|
|
|
|
|
Vector3 newPosition = Vector3.zero;
|
|
|
|
|
|
|
|
float lastRightBorder = -Width / 2.0f + 5.5f;
|
2022-10-11 23:35:25 +02:00
|
|
|
float spaceNeeded = SpotHeights[(int)size] + 1.0f;
|
2022-10-10 22:13:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<int> conflictingSpots = new ();
|
|
|
|
for (int i = 0; i < _spotMap[0].Count; i++) {
|
|
|
|
Spot spot = _spotMap[0][i];
|
|
|
|
if (spot.Free && !spot.Reserved) {
|
|
|
|
conflictingSpots.Add(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int removed = 0;
|
|
|
|
conflictingSpots.Sort();
|
2022-10-06 21:52:35 +02:00
|
|
|
|
2022-10-10 22:13:42 +02:00
|
|
|
foreach (int conflictingSpotId in conflictingSpots) {
|
|
|
|
if(_spotMap[0][conflictingSpotId - removed].Size == Size.A && GetSpotCountOfSize(Size.A) == 2)
|
|
|
|
continue;
|
|
|
|
if(_spotMap[0][conflictingSpotId - removed].Size == Size.B && GetSpotCountOfSize(Size.B) == 2)
|
|
|
|
continue;
|
|
|
|
Destroy(_spotMap[0][conflictingSpotId - removed].GameObject);
|
|
|
|
_spotMap[0].RemoveAt(conflictingSpotId - removed);
|
|
|
|
removed++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = _spotMap[0].Count - 1; i >= -1; i--) {
|
|
|
|
|
|
|
|
float leftBorder;
|
|
|
|
if (i >= 0) {
|
|
|
|
leftBorder = _spotMap[0][i].LeftBorder;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
leftBorder = Width / 2.0f;
|
2022-10-06 21:52:35 +02:00
|
|
|
|
2022-10-10 22:13:42 +02:00
|
|
|
if (leftBorder - lastRightBorder >= spaceNeeded) {
|
2022-10-06 21:52:35 +02:00
|
|
|
Spot newSpot = new Spot(size, false);
|
2022-10-11 23:35:25 +02:00
|
|
|
//newPosition.x = (lastRightBorder + SpotHeights[(int)size] / 2.0f);
|
|
|
|
newPosition.x = (lastRightBorder + 0.5f + SpotHeights[(int)size] / 2.0f);
|
2022-10-06 21:52:35 +02:00
|
|
|
newPosition.y = (-Height / 2.0f) + 2.25f / 2.0f;
|
|
|
|
newSpot.Perpendicular = false;
|
|
|
|
newSpot.GameObject = Instantiate(_spotPrefabs[(int)size],
|
|
|
|
newPosition, Quaternion.Euler(0, 0, 90), mainPlanContainer);
|
|
|
|
_spotMap[0].Add(newSpot);
|
2022-10-10 19:45:07 +02:00
|
|
|
_spotMap[0].Sort((a, b) => Comparer<float>.Default.Compare(b.Position.x, a.Position.x));
|
2022-10-06 21:52:35 +02:00
|
|
|
return true;
|
|
|
|
}
|
2022-10-10 22:13:42 +02:00
|
|
|
if (i >= 0)
|
|
|
|
lastRightBorder = _spotMap[0][i].RightBorder;
|
2022-10-06 21:52:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// newPosition.y = bottomBorder + SpotHeights[(int) newSize] / 2.0f;
|
|
|
|
// float newX = nextBorderRight;
|
|
|
|
// if (spot.Lane == 0) {
|
|
|
|
// float xRelativeToRight = -(newX - Width / 2.0f);
|
|
|
|
// xRelativeToRight -= (xRelativeToRight + 2.25f / 2.0f) % 2.25f;
|
|
|
|
// xRelativeToRight += 2.25f;
|
|
|
|
// xRelativeToRight = Math.Max(xRelativeToRight, 2.25f / 2.0f);
|
|
|
|
// newX = -xRelativeToRight + Width / 2.0f;
|
|
|
|
// }
|
|
|
|
// else {
|
|
|
|
// float xRelativeToLeft = newX + Width / 2.0f;
|
|
|
|
// xRelativeToLeft -= (xRelativeToLeft + 2.25f / 2.0f) % 2.25f;
|
|
|
|
// newX = xRelativeToLeft - Width / 2.0f;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// if (spot.Lane == 0 && Width / 2.0f - newX < 5.5f + 0.5f + 2.25f) {
|
|
|
|
// // Try to remove one spot next
|
|
|
|
// continue;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// newPosition.x = newX;
|
|
|
|
// spot.Flipped =
|
|
|
|
// currentLaneSpots.FindIndex(spotPredicate => spotPredicate == spot) %
|
|
|
|
// 2 == 0;
|
|
|
|
// rotation *= Quaternion.Euler(0, 0, spot.Flipped ? 90 : -90);
|
|
|
|
// spot.Perpendicular = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-10-05 21:56:02 +02:00
|
|
|
private List<int> GetConflictingSpotsLower(Vector3 position, int lane, bool perpendicular, Size size, float margin = 0)
|
|
|
|
{
|
|
|
|
|
|
|
|
float minX = position.x - (perpendicular ? 2.25f : SpotHeights[(int) size]) - margin;
|
|
|
|
float maxX = position.x + (perpendicular ? 2.25f : SpotHeights[(int) size]) + margin;
|
|
|
|
|
|
|
|
List<float> allBorders = new();
|
|
|
|
List<Spot> targetLane = _spotMap[lane];
|
|
|
|
List<int> conflictingSpotsIds = new();
|
|
|
|
|
|
|
|
for (int i = 0; i < targetLane.Count; i++) {
|
|
|
|
Spot spot1 = targetLane[i];
|
|
|
|
Vector3 targetSpotPosition = spot1.GameObject.transform.position;
|
|
|
|
if (targetSpotPosition.x < minX || targetSpotPosition.x > maxX)
|
|
|
|
continue;
|
|
|
|
conflictingSpotsIds.Add(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
return conflictingSpotsIds;
|
|
|
|
}
|
2022-09-08 00:43:34 +02:00
|
|
|
|
|
|
|
private float GetNextBorderVectical(Vector3 position, int lane, bool perpendicular, Size size, bool up)
|
|
|
|
{
|
|
|
|
|
2022-10-05 21:56:02 +02:00
|
|
|
float minX = position.x - (perpendicular ? 2.25f : SpotHeights[(int) size]);
|
|
|
|
float maxX = position.x + (perpendicular ? 2.25f : SpotHeights[(int) size]);
|
2022-09-08 00:43:34 +02:00
|
|
|
|
|
|
|
List<float> allBorders = new();
|
|
|
|
List<Spot> targetLane = up ? _spotMap[lane + 1] : _spotMap[lane - 1];
|
|
|
|
|
|
|
|
foreach (Spot spot1 in targetLane) {
|
|
|
|
Vector3 targetSpotPosition = spot1.GameObject.transform.position;
|
|
|
|
if (targetSpotPosition.x < minX || targetSpotPosition.x > maxX)
|
|
|
|
continue;
|
|
|
|
float sizeOffset;
|
|
|
|
if (spot1.Perpendicular)
|
2022-10-05 21:56:02 +02:00
|
|
|
sizeOffset = SpotHeights[(int) spot1.Size] / 2.0f;
|
2022-09-08 00:43:34 +02:00
|
|
|
else
|
2022-09-10 15:36:48 +02:00
|
|
|
sizeOffset = 2.25f / 2.0f;
|
2022-09-08 00:43:34 +02:00
|
|
|
if (up)
|
|
|
|
allBorders.Add(targetSpotPosition.y - sizeOffset);
|
|
|
|
else
|
|
|
|
allBorders.Add(targetSpotPosition.y + sizeOffset);
|
|
|
|
}
|
2022-09-12 23:28:39 +02:00
|
|
|
|
|
|
|
if (12.85 - 2.5 / 2.0f <= maxX && lane == 2 && up)
|
2022-09-11 23:43:19 +02:00
|
|
|
allBorders.Add(Height / 2.0f - 5);
|
2022-09-08 00:43:34 +02:00
|
|
|
|
|
|
|
if (allBorders.Count == 0)
|
|
|
|
return up ? Height / 2.0f : -Height / 2.0f;
|
|
|
|
float nextBorder = up ? allBorders.Min() : allBorders.Max();
|
|
|
|
return nextBorder;
|
|
|
|
}
|
|
|
|
|
2022-09-08 20:42:11 +02:00
|
|
|
private float GetNextBorderHorizontal(Vector3 position, int lane, bool perpendicular, Size size, bool right)
|
2022-09-08 00:43:34 +02:00
|
|
|
{
|
2022-09-08 22:48:36 +02:00
|
|
|
List<float> allBorders = new();
|
2022-09-08 20:42:11 +02:00
|
|
|
List<Spot> targetLane = _spotMap[lane];
|
2022-09-08 00:43:34 +02:00
|
|
|
foreach (Spot spot1 in targetLane) {
|
2022-09-08 20:42:11 +02:00
|
|
|
if (spot1.GameObject.transform.position == position)
|
2022-09-08 00:43:34 +02:00
|
|
|
continue;
|
|
|
|
Vector3 spotPosition = spot1.GameObject.transform.position;
|
|
|
|
float sizeOffset;
|
|
|
|
if (spot1.Perpendicular)
|
|
|
|
sizeOffset = 2.25f / 2.0f;
|
|
|
|
else
|
2022-10-05 21:56:02 +02:00
|
|
|
sizeOffset = SpotHeights[(int) spot1.Size] / 2.0f;
|
2022-09-08 22:48:36 +02:00
|
|
|
if (right)
|
2022-09-08 22:38:15 +02:00
|
|
|
allBorders.Add(spotPosition.x - sizeOffset);
|
|
|
|
else
|
|
|
|
allBorders.Add(spotPosition.x + sizeOffset);
|
2022-09-08 00:43:34 +02:00
|
|
|
}
|
2022-09-12 23:28:39 +02:00
|
|
|
|
2022-09-08 00:43:34 +02:00
|
|
|
allBorders.Sort();
|
2022-09-10 22:34:20 +02:00
|
|
|
if (right) {
|
|
|
|
foreach (float adjacentBorder in allBorders)
|
|
|
|
if (adjacentBorder > position.x)
|
|
|
|
return adjacentBorder;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
allBorders.Reverse();
|
|
|
|
foreach (float adjacentBorder in allBorders)
|
|
|
|
if (adjacentBorder < position.x)
|
|
|
|
return adjacentBorder;
|
|
|
|
}
|
2022-09-08 00:43:34 +02:00
|
|
|
|
2022-09-08 20:42:11 +02:00
|
|
|
if (perpendicular)
|
2022-10-05 21:56:02 +02:00
|
|
|
return position.x + (right ? 1 : -1) * SpotHeights[(int) size] / 2.0f;
|
2022-09-10 22:34:20 +02:00
|
|
|
if (right)
|
|
|
|
return Width / 2.0f;
|
2022-09-12 23:28:39 +02:00
|
|
|
return -Width / 2.0f + 5.5f;
|
2022-09-08 00:43:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-09-07 20:35:01 +02:00
|
|
|
private int GetSpotCountOfSize(Size size)
|
|
|
|
{
|
|
|
|
int count = 0;
|
2022-09-08 00:43:34 +02:00
|
|
|
foreach (List<Spot> t in _spotMap)
|
2022-09-07 20:35:01 +02:00
|
|
|
foreach (Spot spot in t)
|
|
|
|
if (spot.Size == size)
|
|
|
|
count++;
|
|
|
|
return count;
|
|
|
|
}
|
2022-09-03 21:27:31 +02:00
|
|
|
|
|
|
|
private int[] GetFreeSpotCount()
|
|
|
|
{
|
2022-09-04 00:35:45 +02:00
|
|
|
int[] freeSpots = {0, 0, 0, 0};
|
2022-09-08 00:43:34 +02:00
|
|
|
foreach (List<Spot> t in _spotMap)
|
2022-09-03 21:27:31 +02:00
|
|
|
foreach (Spot spot in t)
|
|
|
|
if (spot.Free)
|
2022-09-04 00:35:45 +02:00
|
|
|
freeSpots[(int) spot.Size]++;
|
2022-09-03 21:27:31 +02:00
|
|
|
return freeSpots;
|
|
|
|
}
|
2022-09-04 00:35:45 +02:00
|
|
|
|
2022-09-06 23:20:53 +02:00
|
|
|
private List<Driver> GetNextCars(int steps)
|
2022-09-03 21:27:31 +02:00
|
|
|
{
|
2022-09-08 22:48:36 +02:00
|
|
|
List<Driver> nextCars = new();
|
2022-09-06 23:20:53 +02:00
|
|
|
TimeSpan updatedTime = _currentTime + TimeSpan.FromMinutes(stepTime * steps);
|
|
|
|
foreach (Driver driver in DataImporter.Drivers)
|
|
|
|
if (updatedTime <= driver.Times[1].TimeOfDay &&
|
|
|
|
updatedTime >= driver.Times[0].TimeOfDay &&
|
|
|
|
!driver.Parked && !driver.Rejected)
|
|
|
|
nextCars.Add(driver);
|
2022-09-03 21:27:31 +02:00
|
|
|
|
|
|
|
return nextCars;
|
|
|
|
}
|
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
private void ArrangeSpots(int[,] spotsCreated)
|
2022-08-29 23:01:18 +02:00
|
|
|
{
|
2022-09-08 00:43:34 +02:00
|
|
|
List<List<Spot>> spotMap = GenerateSpotMap(spotsCreated);
|
2022-08-31 20:50:59 +02:00
|
|
|
|
2022-09-05 00:47:52 +02:00
|
|
|
float[] spotSizes = {4, 4.5f, 5, 0};
|
|
|
|
float maxP3 = 0;
|
|
|
|
float maxP2 = 0;
|
2022-09-05 01:15:04 +02:00
|
|
|
foreach (Spot spot in spotMap[2])
|
|
|
|
if (spot.Size != Size.D)
|
2022-10-05 21:56:02 +02:00
|
|
|
maxP3 = Math.Max(maxP3, spot.Perpendicular ? SpotHeights[(int) spot.Size] : 2.25f);
|
2022-09-05 01:15:04 +02:00
|
|
|
foreach (Spot spot in spotMap[1])
|
|
|
|
if (spot.Size != Size.D)
|
2022-10-05 21:56:02 +02:00
|
|
|
maxP2 = Math.Max(maxP2, spot.Perpendicular ? SpotHeights[(int) spot.Size] : 2.25f);
|
2022-09-05 00:47:52 +02:00
|
|
|
|
2022-09-08 22:48:36 +02:00
|
|
|
List<GameObject> prefabs = new() {spotPrefabA, spotPrefabB, spotPrefabC, spotPrefabD};
|
2022-08-31 20:50:59 +02:00
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
for (int i = 0; i < 4; i++) {
|
2022-08-31 20:50:59 +02:00
|
|
|
float currentY;
|
2022-09-05 00:47:52 +02:00
|
|
|
bool parkingFromTop = i % 2 != 0;
|
2022-09-04 00:35:45 +02:00
|
|
|
switch (i) {
|
2022-08-31 20:50:59 +02:00
|
|
|
case 0:
|
2022-09-05 00:47:52 +02:00
|
|
|
currentY = -Height / 2.0f;
|
2022-08-31 20:50:59 +02:00
|
|
|
break;
|
|
|
|
case 1:
|
2022-09-05 00:47:52 +02:00
|
|
|
currentY = Height / 2.0f - 5.5f - 5.0f - maxP3;
|
2022-08-29 23:01:18 +02:00
|
|
|
break;
|
2022-08-31 20:50:59 +02:00
|
|
|
case 2:
|
2022-09-05 00:47:52 +02:00
|
|
|
currentY = Height / 2.0f - 5.5f - 5.0f - maxP3;
|
2022-08-29 23:01:18 +02:00
|
|
|
break;
|
2022-08-31 20:50:59 +02:00
|
|
|
case 3:
|
2022-09-05 00:47:52 +02:00
|
|
|
currentY = Height / 2.0f;
|
2022-08-29 23:01:18 +02:00
|
|
|
break;
|
|
|
|
default:
|
2022-08-31 20:50:59 +02:00
|
|
|
currentY = -10;
|
2022-08-29 23:01:18 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
float currentX;
|
2022-09-08 22:38:15 +02:00
|
|
|
if (i != 0) currentX = -Width / 2f;
|
2022-09-05 23:31:33 +02:00
|
|
|
else currentX = Width / 2f; // + 5.5f - 2.25f / 2f + 2.25f + 1.75f;
|
2022-08-28 22:42:21 +02:00
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
bool flipped = false;
|
2022-08-28 22:42:21 +02:00
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
for (int j = 0; j < spotMap[i].Count; j++) {
|
2022-09-10 15:44:24 +02:00
|
|
|
// currentX += (i != 0 ? 1 : -1) *
|
|
|
|
// (spotMap[i][j].Perpendicular
|
|
|
|
// ? 2.25f / 2.0f
|
|
|
|
// : spotSizes[(int) spotMap[i][j].Size] / 2.0f);
|
2022-09-12 23:28:39 +02:00
|
|
|
|
|
|
|
if (spotMap[i][j].Size != Size.D) {
|
2022-09-10 15:44:24 +02:00
|
|
|
currentX += (i != 0 ? 1 : -1) *
|
|
|
|
(spotMap[i][j].Perpendicular
|
|
|
|
? 2.25f / 2.0f
|
2022-09-10 20:40:50 +02:00
|
|
|
: spotSizes[(int) spotMap[i][j].Size] / 2.0f + (j != 0 ? 0.25f : 0));
|
2022-09-12 23:28:39 +02:00
|
|
|
}
|
|
|
|
else {
|
2022-09-10 15:44:24 +02:00
|
|
|
currentX += (i != 0 ? 1 : -1) *
|
|
|
|
(spotMap[i][j].Perpendicular
|
|
|
|
? 2.5f / 2.0f
|
2022-09-10 20:40:50 +02:00
|
|
|
: spotSizes[(int) spotMap[i][j].Size] / 2.0f + (j != 0 ? 0.25f : 0));
|
2022-09-12 23:28:39 +02:00
|
|
|
}
|
|
|
|
|
2022-09-05 23:31:33 +02:00
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
spotMap[i][j].Flipped = flipped;
|
2022-09-05 01:15:04 +02:00
|
|
|
bool alignTop = i % 2 != 0;
|
2022-09-05 23:31:33 +02:00
|
|
|
spotMap[i][j].GameObject = Instantiate(prefabs[(int) spotMap[i][j].Size], mainPlanContainer);
|
2022-09-05 01:15:04 +02:00
|
|
|
|
2022-09-05 23:31:33 +02:00
|
|
|
if (spotMap[i][j].Perpendicular) {
|
|
|
|
spotMap[i][j].GameObject.transform.position =
|
|
|
|
new Vector3(currentX,
|
|
|
|
currentY + (alignTop ? -1 : 1) * spotSizes[(int) spotMap[i][j].Size] / 2.0f, 0);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
spotMap[i][j].GameObject.transform.position =
|
|
|
|
new Vector3(currentX,
|
|
|
|
currentY + (alignTop ? -1 : 1) * 2.25f / 2.0f, 0);
|
|
|
|
}
|
2022-09-05 00:47:52 +02:00
|
|
|
|
2022-09-05 22:00:15 +02:00
|
|
|
spotMap[i][j].AlignToTop = alignTop;
|
2022-09-03 00:23:15 +02:00
|
|
|
|
2022-09-05 23:31:33 +02:00
|
|
|
|
|
|
|
if (!spotMap[i][j].Perpendicular)
|
|
|
|
spotMap[i][j].Flipped = alignTop;
|
|
|
|
|
|
|
|
if (spotMap[i][j].Perpendicular) {
|
|
|
|
spotMap[i][j].GameObject.transform.rotation =
|
|
|
|
Quaternion.Euler(new Vector3(0, 0, spotMap[i][j].Flipped ? 180 : 0));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
spotMap[i][j].GameObject.transform.rotation =
|
|
|
|
Quaternion.Euler(new Vector3(0, 0, (spotMap[i][j].Flipped ? 180 : 0) + 90));
|
|
|
|
}
|
2022-08-31 20:50:59 +02:00
|
|
|
|
2022-09-11 23:43:19 +02:00
|
|
|
bool frontalParking = !(!parkingFromTop ^ flipped);
|
2022-09-03 00:23:15 +02:00
|
|
|
spotMap[i][j].ParkingDirection = frontalParking ? ParkingPreference.Front : ParkingPreference.Back;
|
|
|
|
|
2022-09-05 22:00:15 +02:00
|
|
|
spotMap[i][j].Lane = i;
|
2022-09-05 22:01:52 +02:00
|
|
|
|
2022-09-12 23:28:39 +02:00
|
|
|
if (spotMap[i][j].Size != Size.D) {
|
2022-09-10 15:44:24 +02:00
|
|
|
currentX += (i != 0 ? 1 : -1) *
|
|
|
|
(spotMap[i][j].Perpendicular
|
|
|
|
? 2.25f / 2.0f
|
2022-09-10 22:34:20 +02:00
|
|
|
: spotSizes[(int) spotMap[i][j].Size] / 2.0f + 0.25f);
|
2022-09-12 23:28:39 +02:00
|
|
|
}
|
|
|
|
else {
|
2022-09-10 15:44:24 +02:00
|
|
|
currentX += (i != 0 ? 1 : -1) *
|
|
|
|
(spotMap[i][j].Perpendicular
|
|
|
|
? 2.5f / 2.0f
|
2022-09-10 22:34:20 +02:00
|
|
|
: spotSizes[(int) spotMap[i][j].Size] / 2.0f + 0.25f);
|
2022-09-12 23:28:39 +02:00
|
|
|
}
|
2022-08-31 20:50:59 +02:00
|
|
|
|
|
|
|
flipped = !flipped;
|
2022-08-28 22:42:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
private void GenerateEmergencyPlan()
|
|
|
|
{
|
|
|
|
emergencyPlanContainer.gameObject.SetActive(false);
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
float currentY;
|
|
|
|
switch (i) {
|
|
|
|
case 0:
|
|
|
|
currentY = -Height / 2.0f;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
currentY = Height / 2.0f - 5.5f - 5.0f - 5.0f;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
currentY = Height / 2.0f - 5.5f - 5.0f - 5.0f;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
currentY = Height / 2.0f;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
currentY = -10;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
float currentX;
|
|
|
|
if (i != 0) currentX = -Width / 2f - 2.25f / 2f + 2.25f;
|
|
|
|
else currentX = Width / 2f - 5.0f / 2f;
|
|
|
|
|
|
|
|
GameObject spawnedSpot;
|
|
|
|
|
2022-09-05 22:01:52 +02:00
|
|
|
int[] emergencyMap = {12, 27, 27, 20};
|
2022-09-05 01:15:04 +02:00
|
|
|
|
2022-09-05 22:01:52 +02:00
|
|
|
for (int j = 0; j < emergencyMap[i]; j++)
|
2022-09-05 01:15:04 +02:00
|
|
|
if (i == 0) {
|
2022-09-05 22:01:52 +02:00
|
|
|
Vector3 position = new(currentX, currentY + 2.25f / 2.0f, 0);
|
2022-09-06 23:20:53 +02:00
|
|
|
Instantiate(Instance.spotPrefabC, position,
|
2022-09-05 01:15:04 +02:00
|
|
|
Quaternion.Euler(new Vector3(0, 0, 90)), emergencyPlanContainer);
|
2022-09-05 22:01:52 +02:00
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
currentX -= 5;
|
2022-09-05 22:01:52 +02:00
|
|
|
}
|
|
|
|
else {
|
2022-09-05 01:15:04 +02:00
|
|
|
bool alignTop = i % 2 != 0;
|
2022-09-05 22:01:52 +02:00
|
|
|
Vector3 position = new(currentX, currentY, 0);
|
2022-09-05 01:15:04 +02:00
|
|
|
spawnedSpot = Instantiate(Instance.spotPrefabC, position,
|
|
|
|
Quaternion.Euler(new Vector3(0, 0, 0)), emergencyPlanContainer);
|
|
|
|
|
|
|
|
spawnedSpot.transform.position =
|
|
|
|
new Vector3(currentX,
|
|
|
|
currentY + (alignTop ? -1 : 1) * 5.0f / 2.0f,
|
|
|
|
0);
|
|
|
|
|
|
|
|
currentX += 2.25f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-31 20:50:59 +02:00
|
|
|
private List<List<Spot>> GenerateSpotMap(int[,] spotsCreated)
|
2022-08-28 22:42:21 +02:00
|
|
|
{
|
2022-09-08 00:43:34 +02:00
|
|
|
foreach (List<Spot> list in _spotMap) {
|
2022-09-06 23:20:53 +02:00
|
|
|
foreach (Spot spot in list)
|
|
|
|
if (spot.GameObject != null)
|
|
|
|
Destroy(spot.GameObject);
|
|
|
|
list.Clear();
|
|
|
|
}
|
|
|
|
|
2022-09-05 01:15:04 +02:00
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
for (int j = 0; j < spotsCreated.GetLength(1); j++)
|
|
|
|
for (int k = 0; k < spotsCreated[i, j]; k++) {
|
2022-09-05 23:31:33 +02:00
|
|
|
Spot spot = new((Size) (j % 4), false);
|
|
|
|
spot.Perpendicular = j < 4;
|
|
|
|
_spotMap[i].Add(spot);
|
2022-09-04 00:35:45 +02:00
|
|
|
_initialConfigurationSpotCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
_spotMap[0].Sort((a, b) => a.Size.CompareTo(b.Size)); // ascending sort
|
|
|
|
_spotMap[1].Sort((a, b) => b.Size.CompareTo(a.Size)); // descending sort
|
|
|
|
_spotMap[2].Sort((a, b) => b.Size.CompareTo(a.Size)); // descending sort
|
|
|
|
_spotMap[3].Sort((a, b) => a.Size.CompareTo(b.Size)); // ascending sort
|
|
|
|
_spotMap[2].Add(new Spot(Size.D, false));
|
|
|
|
return _spotMap;
|
2022-08-28 22:42:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|