Skip to content

Commit

Permalink
Parking AI & Priority rules code improvements, performance optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorPhilipp committed Jun 11, 2017
1 parent ce52829 commit 9bb8b8a
Show file tree
Hide file tree
Showing 30 changed files with 1,730 additions and 1,139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
using System.Collections.Generic;
using System.Text;

namespace TrafficManager.Traffic {
namespace CSUtil.Commons {
public enum ArrowDirection {
None,
Left,
Forward,
Right,
Turn
None = 0,
Left = 1,
Forward = 2,
Right = 3,
Turn = 4
}
}
73 changes: 73 additions & 0 deletions TLM/CSUtil.Commons/ArrowDirectionUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CSUtil.Commons {
public class ArrowDirectionUtil {
public static ArrowDirection InvertLeftRight(ArrowDirection dir) {
if (dir == ArrowDirection.Left)
dir = ArrowDirection.Right;
else if (dir == ArrowDirection.Right)
dir = ArrowDirection.Left;
return dir;
}

/// <summary>
/// Calculates the direction of <paramref name="toRelDir"/> in relation to ArrowDirection.TURN.
/// </summary>
/// <param name="fromDir">source direction</param>
/// <param name="toRelDir">target direction, relative to <paramref name="fromDir"/></param>
/// <returns></returns>
public static ArrowDirection MakeAbsolute(ArrowDirection fromDir, ArrowDirection toRelDir) {
if (fromDir == ArrowDirection.None) {
// invalid direction
return ArrowDirection.None;
}

if (toRelDir == ArrowDirection.None) {
// invalid direction
return ArrowDirection.None;
}

if (fromDir == ArrowDirection.Turn) {
// toRelDir is already relative to TURN
return toRelDir;
}

if (toRelDir == ArrowDirection.Turn) {
// toRelDir is fromDir
return fromDir;
}

int fromDirBase0 = (int)fromDir - 1;
int toRelDirBase1 = (int)toRelDir;
/*
* Direction | Base 0 | Base 1
* ==========+========+=======
* Left | 0 | 1
* Forward | 1 | 2
* Right | 2 | 3
*
*
* Direction 1 | Direction 2 | Dir. 1 B0 | Dir. 2 B1 | Sum | (Sum + 1) % 4 | Desired dir.
* ============+=============+===========+===========+=====|===============+=============
* Left | Left | 0 | 1 | 1 | 2 | (Forward, 2)
* Left | Forward | 0 | 2 | 2 | 3 | (Right, 3)
* Left | Right | 0 | 3 | 3 | 0 | (Turn, 4)
* Forward | Left | 1 | 1 | 2 | 3 | (Right, 3)
* Forward | Forward | 1 | 2 | 3 | 0 | (Turn, 4)
* Forward | Right | 1 | 3 | 4 | 1 | (Left, 1)
* Right | Left | 2 | 1 | 3 | 0 | (Turn, 4)
* Right | Forward | 2 | 2 | 4 | 1 | (Left, 1)
* Right | Right | 2 | 3 | 5 | 2 | (Forward, 2)
*/

int ret = (fromDirBase0 + toRelDirBase1 + 1) % 4;
if (ret == 0) {
ret = 4;
}
return (ArrowDirection)ret;
}
}
}
2 changes: 2 additions & 0 deletions TLM/CSUtil.Commons/CSUtil.Commons.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ArrowDirection.cs" />
<Compile Include="ArrowDirectionUtil.cs" />
<Compile Include="EnumUtil.cs" />
<Compile Include="Log.cs" />
<Compile Include="LogicUtil.cs" />
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/Custom/AI/CustomAmbulanceAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vecto
#endif

ExtVehicleType vehicleType = (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0 ? ExtVehicleType.Emergency : ExtVehicleType.Service;
VehicleStateManager.Instance.VehicleStates[VehicleStateManager.Instance.GetFrontVehicleId(vehicleID, ref vehicleData)].vehicleType = vehicleType;
VehicleStateManager.Instance.OnStartPathFind(vehicleID, ref vehicleData, vehicleType);

VehicleInfo info = this.m_info;
bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
Expand Down
52 changes: 13 additions & 39 deletions TLM/TLM/Custom/AI/CustomCarAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ public void Awake() {
/// <param name="vehicleData"></param>
/// <param name="physicsLodRefPos"></param>
public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vector3 physicsLodRefPos) {
PathManager pathMan = Singleton<PathManager>.instance;

if ((vehicleData.m_flags & Vehicle.Flags.WaitingPath) != 0) {
PathManager pathManager = Singleton<PathManager>.instance;
byte pathFindFlags = pathManager.m_pathUnits.m_buffer[vehicleData.m_path].m_pathFindFlags;
Expand All @@ -45,7 +43,7 @@ public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vect
}

if (Options.prohibitPocketCars) {
mainPathState = AdvancedParkingManager.Instance.UpdatePathState(vehicleId, ref vehicleData, mainPathState);
mainPathState = AdvancedParkingManager.Instance.UpdateCarPathState(vehicleId, ref vehicleData, mainPathState);
}
// NON-STOCK CODE END

Expand All @@ -68,6 +66,10 @@ public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vect
}
}

// NON-STOCK CODE START
VehicleStateManager.Instance.UpdateVehiclePosition(vehicleId, ref vehicleData);
// NON-STOCK CODE END

Vector3 lastFramePosition = vehicleData.GetLastFramePosition();
int lodPhysics;
if (Vector3.SqrMagnitude(physicsLodRefPos - lastFramePosition) >= 1210000f) {
Expand Down Expand Up @@ -100,6 +102,8 @@ public void CustomSimulationStep(ushort vehicleId, ref Vehicle vehicleData, Vect
Singleton<VehicleManager>.instance.ReleaseVehicle(vehicleId);
} else if ((int)vehicleData.m_blockCounter >= maxBlockCounter && Options.enableDespawning) { // NON-STOCK CODE
Singleton<VehicleManager>.instance.ReleaseVehicle(vehicleId);
} else if (!Options.enableDespawning) {
vehicleData.m_blockCounter = 0; // NON-STOCK CODE
}
}

Expand All @@ -113,17 +117,6 @@ public override bool TrySpawn(ushort vehicleId, ref Vehicle vehicleData) {
}
vehicleData.Spawn(vehicleId);
vehicleData.m_flags &= ~Vehicle.Flags.WaitingSpace;

// NON-STOCK CODE START
if (Options.prioritySignsEnabled || Options.timedLightsEnabled) {
#if DEBUG
if (GlobalConfig.Instance.DebugSwitches[9])
Log._Debug($"CustomCarAI.TrySpawn({vehicleId}): calling OnSpawnVehicle in TrySpawn");
#endif
VehicleStateManager.Instance.OnSpawnVehicle(vehicleId, ref vehicleData);
}
// NON-STOCK CODE END

return true;
}

Expand Down Expand Up @@ -162,45 +155,26 @@ public void CustomCalculateSegmentPosition(ushort vehicleId, ref Vehicle vehicle
bool withinBrakingDistance = Vector3.Distance(lastFrameVehiclePos, vehiclePosOnBezier) >= crazyValue - 1f;

// NON-STOCK CODE START
ushort frontVehicleId = VehicleStateManager.Instance.GetFrontVehicleId(vehicleId, ref vehicleData);
#if DEBUG
if (GlobalConfig.Instance.DebugSwitches[9])
Log._Debug($"CustomCarAI.CustomCalculateSegmentPosition({vehicleId}): processing front vehicle {frontVehicleId} @ PREV seg. {prevPos.m_segment}, lane {prevPos.m_lane}, off {prevPos.m_offset} -> CURRENT seg. {position.m_segment}, lane {position.m_lane}, off {position.m_offset} -> NEXT seg. {nextPosition.m_segment}, lane {nextPosition.m_lane}, off {nextPosition.m_offset} || prevOffset: {prevOffset}, offset: {offset} || prevTargetNodeId: {prevTargetNodeId}, targetNodeId: {targetNodeId}, nextTargetNodeId: {nextTargetNodeId} || pathPositionIndex: {vehicleData.m_pathPositionIndex}");
#endif
if (vehicleId == frontVehicleId) {
if (Options.prioritySignsEnabled || Options.timedLightsEnabled) {
// update vehicle position for timed traffic lights and priority signs
int pathPosIndex = vehicleData.m_pathPositionIndex >> 1;
PathUnit.Position curPathPos = Singleton<PathManager>.instance.m_pathUnits.m_buffer[vehicleData.m_path].GetPosition(pathPosIndex);
PathUnit.Position nextPathPos;
Singleton<PathManager>.instance.m_pathUnits.m_buffer[vehicleData.m_path].GetNextPosition(pathPosIndex, out nextPathPos);
VehicleStateManager.Instance.VehicleStates[frontVehicleId].UpdatePosition(ref vehicleData, sqrVelocity, ref curPathPos, ref nextPathPos);
}
} else {
#if DEBUG
if (GlobalConfig.Instance.DebugSwitches[9])
Log._Debug($"CustomCarAI.CustomCalculateSegmentPosition({vehicleId}): processing non-front vehicle! frontVehicleId={frontVehicleId}");
#endif
}
VehicleStateManager.Instance.UpdateVehiclePosition(vehicleId, ref vehicleData, sqrVelocity);
// NON-STOCK CODE END

bool isRecklessDriver = VehicleStateManager.Instance.IsRecklessDriver(vehicleId, ref vehicleData); // NON-STOCK CODE
if (targetNodeId == prevTargetNodeId && withinBrakingDistance) {
// NON-STOCK CODE START
if (vehicleId == frontVehicleId && !Options.isStockLaneChangerUsed()) {
if (!Options.isStockLaneChangerUsed()) {
// Advanced AI traffic measurement
VehicleStateManager.Instance.LogTraffic(frontVehicleId, ref vehicleData, position.m_segment, position.m_lane, true);
VehicleStateManager.Instance.LogTraffic(vehicleId, ref vehicleData, position.m_segment, position.m_lane, true);
}
// NON-STOCK CODE END

if (!VehicleBehaviorManager.Instance.MayChangeSegment(frontVehicleId, ref VehicleStateManager.Instance.VehicleStates[frontVehicleId], ref vehicleData, ref lastFrameData, isRecklessDriver, ref prevPos, ref netManager.m_segments.m_buffer[prevPos.m_segment], prevTargetNodeId, prevLaneID, ref position, targetNodeId, ref netManager.m_nodes.m_buffer[targetNodeId], laneID, ref nextPosition, nextTargetNodeId, out maxSpeed)) // NON-STOCK CODE
if (!VehicleBehaviorManager.Instance.MayChangeSegment(vehicleId, ref VehicleStateManager.Instance.VehicleStates[vehicleId], ref vehicleData, ref lastFrameData, isRecklessDriver, ref prevPos, ref netManager.m_segments.m_buffer[prevPos.m_segment], prevTargetNodeId, prevLaneID, ref position, targetNodeId, ref netManager.m_nodes.m_buffer[targetNodeId], laneID, ref nextPosition, nextTargetNodeId, out maxSpeed)) // NON-STOCK CODE
return;
}

var info2 = netManager.m_segments.m_buffer[position.m_segment].Info;
if (info2.m_lanes != null && info2.m_lanes.Length > position.m_lane) {
var laneSpeedLimit = Options.customSpeedLimitsEnabled ? SpeedLimitManager.Instance.GetLockFreeGameSpeedLimit(position.m_segment, position.m_lane, laneID, info2.m_lanes[position.m_lane]) : info2.m_lanes[position.m_lane].m_speedLimit; // info2.m_lanes[position.m_lane].m_speedLimit; // NON-STOCK CODE
maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, laneSpeedLimit, netManager.m_lanes.m_buffer[(int)((UIntPtr)laneID)].m_curve);
maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, laneSpeedLimit, netManager.m_lanes.m_buffer[laneID].m_curve);
} else {
maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
}
Expand Down Expand Up @@ -245,7 +219,7 @@ public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vecto
uint path;

// NON-STOCK CODE START
ExtVehicleType vehicleType = VehicleStateManager.Instance.VehicleStates[VehicleStateManager.Instance.GetFrontVehicleId(vehicleID, ref vehicleData)].vehicleType;
ExtVehicleType vehicleType = VehicleStateManager.Instance.VehicleStates[vehicleID].vehicleType;
if (vehicleType == ExtVehicleType.None) {
#if DEBUG
Log.Warning($"CustomCarAI.CustomStartPathFind: Vehicle {vehicleID} does not have a valid vehicle type!");
Expand Down
1 change: 0 additions & 1 deletion TLM/TLM/Custom/AI/CustomCitizenAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ public bool CustomStartPathFind(ushort instanceID, ref CitizenInstance citizenDa
if (GlobalConfig.Instance.DebugSwitches[2])
Log._Debug($"Citizen instance {instanceID} will try to move parkedVehicleId={parkedVehicleId} towards home. distHomeToParked={distHomeToParked}");
#endif
vehicleInfo = Singleton<VehicleManager>.instance.m_parkedVehicles.m_buffer[parkedVehicleId].Info;
carUsageMode = CarUsagePolicy.Forced;
}
}
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/Custom/AI/CustomFireTruckAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public bool CustomStartPathFind(ushort vehicleID, ref Vehicle vehicleData, Vecto
#endif

ExtVehicleType vehicleType = (vehicleData.m_flags & Vehicle.Flags.Emergency2) != 0 ? ExtVehicleType.Emergency : ExtVehicleType.Service;
VehicleStateManager.Instance.VehicleStates[VehicleStateManager.Instance.GetFrontVehicleId(vehicleID, ref vehicleData)].vehicleType = vehicleType;
VehicleStateManager.Instance.OnStartPathFind(vehicleID, ref vehicleData, vehicleType);

VehicleInfo info = this.m_info;
bool allowUnderground = (vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;
Expand Down
Loading

0 comments on commit 9bb8b8a

Please sign in to comment.