Skip to content

Commit 6a3ce09

Browse files
authored
Merge pull request #1746 from CitiesSkylinesMods/bugfix/potential-parking-vehicle-desync
Fixes for potential desync of parked vehicles when Parking AI is enabled
2 parents aa76470 + 9cea0ea commit 6a3ce09

File tree

4 files changed

+99
-20
lines changed

4 files changed

+99
-20
lines changed

TLM/TLM/Manager/Impl/AdvancedParkingManager.cs

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,51 +1994,84 @@ public bool TrySpawnParkedPassengerCar(uint citizenId,
19941994
() => $"Trying to spawn parked passenger car for citizen {citizenId}, " +
19951995
$"home {homeId} @ {refPos}");
19961996

1997-
bool roadParkSuccess = TrySpawnParkedPassengerCarRoadSide(
1997+
bool roadParkSuccess = TrySpawnParkedPassengerCarRoadSideInternal(
19981998
citizenId,
19991999
refPos,
20002000
vehicleInfo,
20012001
out Vector3 roadParkPos,
2002-
out ParkingError roadParkReason);
2002+
out ParkingError roadParkReason,
2003+
out ushort roadParkedVehicleId,
2004+
updateCitizenParkedVehicle: false);
20032005

2004-
bool buildingParkSuccess = TrySpawnParkedPassengerCarBuilding(
2006+
bool buildingParkSuccess = TrySpawnParkedPassengerCarBuildingInternal(
20052007
citizenId,
20062008
ref citizen,
20072009
homeId,
20082010
refPos,
20092011
vehicleInfo,
20102012
out Vector3 buildingParkPos,
2011-
out ParkingError buildingParkReason);
2013+
out ParkingError buildingParkReason,
2014+
out ushort buildingParkedVehicleId,
2015+
updateCitizenParkedVehicle: false);
20122016

2013-
if ((!roadParkSuccess && !buildingParkSuccess)
2014-
|| (roadParkSuccess && !buildingParkSuccess)) {
2017+
if (!buildingParkSuccess) {
2018+
if (roadParkSuccess) {
2019+
roadParkedVehicleId.AssignToCitizenAndMakeVisible(citizenId);
2020+
}
20152021
parkPos = roadParkPos;
20162022
reason = roadParkReason;
20172023
return roadParkSuccess;
20182024
}
20192025

20202026
if (!roadParkSuccess) {
2027+
buildingParkedVehicleId.AssignToCitizenAndMakeVisible(citizenId);
20212028
parkPos = buildingParkPos;
20222029
reason = buildingParkReason;
20232030
return true;
20242031
}
20252032

2033+
/*
2034+
* Two parked vehicles available, assign the closer one, release the other
2035+
*/
20262036
if ((roadParkPos - refPos).sqrMagnitude < (buildingParkPos - refPos).sqrMagnitude) {
2037+
VehicleManager.instance.ReleaseParkedVehicle(buildingParkedVehicleId);
2038+
roadParkedVehicleId.AssignToCitizenAndMakeVisible(citizenId);
20272039
parkPos = roadParkPos;
20282040
reason = roadParkReason;
20292041
return true;
20302042
}
20312043

2044+
VehicleManager.instance.ReleaseParkedVehicle(roadParkedVehicleId);
2045+
buildingParkedVehicleId.AssignToCitizenAndMakeVisible(citizenId);
20322046
parkPos = buildingParkPos;
20332047
reason = buildingParkReason;
20342048
return true;
20352049
}
20362050

2051+
[UsedImplicitly]
20372052
public bool TrySpawnParkedPassengerCarRoadSide(uint citizenId,
20382053
Vector3 refPos,
20392054
VehicleInfo vehicleInfo,
20402055
out Vector3 parkPos,
20412056
out ParkingError reason) {
2057+
return TrySpawnParkedPassengerCarRoadSideInternal(
2058+
citizenId,
2059+
refPos,
2060+
vehicleInfo,
2061+
out parkPos,
2062+
out reason,
2063+
out _,
2064+
updateCitizenParkedVehicle: true);
2065+
}
2066+
2067+
2068+
private bool TrySpawnParkedPassengerCarRoadSideInternal(uint citizenId,
2069+
Vector3 refPos,
2070+
VehicleInfo vehicleInfo,
2071+
out Vector3 parkPos,
2072+
out ParkingError reason,
2073+
out ushort roadParkVehicleId,
2074+
bool updateCitizenParkedVehicle = true) {
20422075
#if DEBUG
20432076
bool citizenDebug = DebugSettings.CitizenId == 0 || DebugSettings.CitizenId == citizenId;
20442077
bool logParkingAi = DebugSwitch.BasicParkingAILog.Get() && citizenDebug;
@@ -2054,6 +2087,7 @@ public bool TrySpawnParkedPassengerCarRoadSide(uint citizenId,
20542087
() => $"Trying to spawn parked passenger car at road side for citizen {citizenId} @ {refPos}");
20552088

20562089
parkPos = Vector3.zero;
2090+
roadParkVehicleId = 0;
20572091

20582092
if (FindParkingSpaceRoadSide(
20592093
0,
@@ -2075,9 +2109,10 @@ ref Singleton<SimulationManager>
20752109
parkRot,
20762110
citizenId))
20772111
{
2078-
CitizenManager.instance.m_citizens.m_buffer[citizenId].SetParkedVehicle(citizenId, parkedVehicleId);
2079-
2080-
parkedVehicleId.ToParkedVehicle().m_flags &= (ushort)(VehicleParked.Flags.All & ~VehicleParked.Flags.Parking);
2112+
roadParkVehicleId = parkedVehicleId;
2113+
if (updateCitizenParkedVehicle) {
2114+
parkedVehicleId.AssignToCitizenAndMakeVisible(citizenId);
2115+
}
20812116

20822117
if (logParkingAi) {
20832118
Log._Debug(
@@ -2100,13 +2135,35 @@ ref Singleton<SimulationManager>
21002135
return false;
21012136
}
21022137

2138+
[UsedImplicitly]
21032139
public bool TrySpawnParkedPassengerCarBuilding(uint citizenId,
21042140
ref Citizen citizen,
21052141
ushort homeId,
21062142
Vector3 refPos,
21072143
VehicleInfo vehicleInfo,
21082144
out Vector3 parkPos,
21092145
out ParkingError reason) {
2146+
return TrySpawnParkedPassengerCarBuildingInternal(
2147+
citizenId,
2148+
ref citizen,
2149+
homeId,
2150+
refPos,
2151+
vehicleInfo,
2152+
out parkPos,
2153+
out reason,
2154+
out _,
2155+
updateCitizenParkedVehicle: true);
2156+
}
2157+
2158+
public bool TrySpawnParkedPassengerCarBuildingInternal(uint citizenId,
2159+
ref Citizen citizen,
2160+
ushort homeId,
2161+
Vector3 refPos,
2162+
VehicleInfo vehicleInfo,
2163+
out Vector3 parkPos,
2164+
out ParkingError reason,
2165+
out ushort buildingParkVehicleId,
2166+
bool updateCitizenParkedVehicle = true) {
21102167
#if DEBUG
21112168
bool citizenDebug = DebugSettings.CitizenId == 0 || DebugSettings.CitizenId == citizenId;
21122169
bool logParkingAi = DebugSwitch.BasicParkingAILog.Get() && citizenDebug;
@@ -2122,6 +2179,7 @@ public bool TrySpawnParkedPassengerCarBuilding(uint citizenId,
21222179
$"{citizenId} @ {refPos}");
21232180

21242181
parkPos = Vector3.zero;
2182+
buildingParkVehicleId = 0;
21252183

21262184
if (FindParkingSpaceBuilding(
21272185
vehicleInfo,
@@ -2144,9 +2202,10 @@ public bool TrySpawnParkedPassengerCarBuilding(uint citizenId,
21442202
parkRot,
21452203
citizenId))
21462204
{
2147-
citizen.SetParkedVehicle(citizenId, parkedVehicleId);
2148-
2149-
parkedVehicleId.ToParkedVehicle().m_flags &= (ushort)(VehicleParked.Flags.All & ~VehicleParked.Flags.Parking);
2205+
buildingParkVehicleId = parkedVehicleId;
2206+
if (updateCitizenParkedVehicle) {
2207+
parkedVehicleId.AssignToCitizenAndMakeVisible(citizenId);
2208+
}
21502209

21512210
if (extendedLogParkingAi && homeId != 0) {
21522211
Log._Debug(
@@ -2274,7 +2333,7 @@ public bool FindParkingSpaceInVicinity(Vector3 targetPos,
22742333
Randomizer rng = Singleton<SimulationManager>.instance.m_randomizer;
22752334

22762335
// choose nearest parking position, after a bit of randomization
2277-
if ((roadParkPos - targetPos).magnitude < (buildingParkPos - targetPos).magnitude
2336+
if ((roadParkPos - targetPos).sqrMagnitude < (buildingParkPos - targetPos).sqrMagnitude
22782337
&& rng.Int32(GlobalConfig.Instance.ParkingAI.VicinityParkingSpaceSelectionRand) != 0) {
22792338
// road parking space is closer
22802339

TLM/TLM/Manager/Impl/ExtCitizenInstanceManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,8 @@ bool citizenDebug
636636
rotation: parkedVehicle.m_rotation,
637637
electricVehicleInfo: out VehicleInfo electricVehicleInfo)) {
638638
vehicleInfo = electricVehicleInfo;
639+
parkedVehicleId = citizen.m_parkedVehicle;
640+
parkedVehicle = ref parkedVehicleId.ToParkedVehicle();
639641
}
640642
}
641643

TLM/TLM/Patch/_VehicleAI/UpdatePathTargetPositionsPatch.cs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,9 @@ public static bool Prefix(VehicleAI __instance,
971971
Mathf.Min(targetPos.w, curMaxSpeed));
972972
float sqrMagnitude2 = (bezierPos - refPos).sqrMagnitude;
973973

974-
Log._Debug(
974+
Log._DebugIf(
975+
logLogic,
976+
() =>
975977
$"CustomVehicle.CustomUpdatePathTargetPositions({vehicleID}): " +
976978
"Preparing to update node target positions (2). " +
977979
$"pathOffset={pathOffset}, bezierPos={bezierPos}, " +
@@ -981,7 +983,9 @@ public static bool Prefix(VehicleAI __instance,
981983
continue;
982984
}
983985

984-
Log._Debug(
986+
Log._DebugIf(
987+
logLogic,
988+
() =>
985989
$"CustomVehicle.CustomUpdatePathTargetPositions({vehicleID}): " +
986990
$"sqrMagnitude2={sqrMagnitude2} >= minSqrDistA={minSqrDistA} and no need to stop at node");
987991

@@ -1030,13 +1034,17 @@ ref nextNodeId.ToNode(),
10301034
refPos = targetPos;
10311035
targetPos.w = 1000f;
10321036

1033-
Log._Debug(
1037+
Log._DebugIf(
1038+
logLogic,
1039+
() =>
10341040
$"CustomVehicle.CustomUpdatePathTargetPositions({vehicleID}): " +
10351041
$"After updating node target positions. minSqrDistA={minSqrDistA}, " +
10361042
$"refPos={refPos}");
10371043

10381044
if (index == max) {
1039-
Log._Debug(
1045+
Log._DebugIf(
1046+
logLogic,
1047+
() =>
10401048
$"CustomVehicle.CustomUpdatePathTargetPositions({vehicleID}): " +
10411049
$"index == max ({max}). " +
10421050
"FINISH.");
@@ -1046,7 +1054,9 @@ ref nextNodeId.ToNode(),
10461054
}
10471055
} else {
10481056
PathUnit.CalculatePathPositionOffset(nextLaneId, targetPos, out nextSegOffset);
1049-
Log._Debug(
1057+
Log._DebugIf(
1058+
logLogic,
1059+
() =>
10501060
$"CustomVehicle.CustomUpdatePathTargetPositions({vehicleID}): " +
10511061
$"Same lane or cargo lane. curLaneId={curLaneId}, nextLaneId={nextLaneId}, " +
10521062
$"laneInfo.m_laneType={laneInfo.m_laneType}, targetPos={targetPos}, " +
@@ -1136,7 +1146,9 @@ ref nextNodeId.ToNode(),
11361146
laneInfo = nextLaneInfo;
11371147
firstIter = false; // NON-STOCK CODE
11381148

1139-
Log._Debug(
1149+
Log._DebugIf(
1150+
logLogic,
1151+
() =>
11401152
$"CustomVehicle.CustomUpdatePathTargetPositions({vehicleID}): " +
11411153
"Prepared next main loop iteration. currentPosition" +
11421154
$"=[seg={currentPosition.m_segment}, lane={currentPosition.m_lane}, " +

TLM/TLM/Util/Extensions/ParkedVehicleExtensions.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@ public static class ParkedVehicleExtensions
77
private static readonly VehicleParked[] _parkedVehiclesBuffer = Singleton<VehicleManager>.instance.m_parkedVehicles.m_buffer;
88

99
public static ref VehicleParked ToParkedVehicle(this ushort parkedVehicleId) => ref _parkedVehiclesBuffer[parkedVehicleId];
10-
10+
1111
public static ref VehicleParked ToParkedVehicle(this uint parkedVehicleId) => ref _parkedVehiclesBuffer[parkedVehicleId];
1212

1313
public static bool IsCreated(this ref VehicleParked parkedVehicle) =>
1414
((VehicleParked.Flags)parkedVehicle.m_flags).IsFlagSet(VehicleParked.Flags.Created);
15+
16+
public static void AssignToCitizenAndMakeVisible(this ushort parkedVehicleId,
17+
uint citizenId) {
18+
CitizenManager.instance.m_citizens.m_buffer[citizenId].SetParkedVehicle(citizenId, parkedVehicleId);
19+
_parkedVehiclesBuffer[parkedVehicleId].m_flags &= (ushort)(VehicleParked.Flags.All & ~VehicleParked.Flags.Parking);
20+
}
1521
}
1622
}
1723

0 commit comments

Comments
 (0)