public void CustomSegmentSimulationStep(ushort segmentID, ref NetSegment data) { if (initDone) { try { TrafficPriority.segmentHousekeeping(segmentID); } catch (Exception e) { Log.Error($"Error occured while housekeeping segment {segmentID}: " + e.ToString()); } if (!Options.isStockLaneChangerUsed()) { try { InStartupPhase = simStartFrame == 0 || simStartFrame >> 14 >= Singleton <SimulationManager> .instance.m_currentFrameIndex >> 14; // approx. 3 minutes // calculate traffic density uint curLaneId = data.m_lanes; int nextNumLanes = data.Info.m_lanes.Length; uint laneIndex = 0; bool firstWithTraffic = true; bool resetDensity = false; while (laneIndex < nextNumLanes && curLaneId != 0u) { uint buf = currentLaneTrafficBuffer[curLaneId]; uint currentDensities = currentLaneDensities[curLaneId]; //currentMeanDensity = (byte)Math.Min(100u, (uint)((currentDensities * 100u) / Math.Max(1u, maxDens))); // 0 .. 100 byte currentMeanSpeed = 25; // we use integer division here because it's faster if (buf > 0) { uint currentSpeeds = currentLaneSpeeds[curLaneId]; if (!InStartupPhase) { currentMeanSpeed = (byte)Math.Min(100u, ((currentSpeeds * 100u) / buf) / ((uint)(Math.Max(SpeedLimitManager.GetLockFreeGameSpeedLimit(segmentID, laneIndex, curLaneId, data.Info.m_lanes[laneIndex]) * 8f, 1f)))); // 0 .. 100, m_speedLimit of highway is 2, actual max. vehicle speed on highway is 16, that's why we use x*8 == x<<3 (don't ask why CO uses different units for velocity) } } else { if (!InStartupPhase) { currentMeanSpeed = 100; } } /*if (segmentID == 22980) { * Log._Debug($"Lane {curLaneId}: currentMeanSpeed={currentMeanSpeed} currentMeanDensity={currentMeanDensity}"); * }*/ if (currentMeanSpeed >= laneMeanSpeeds[curLaneId]) { laneMeanSpeeds[curLaneId] = (byte)Math.Min((int)laneMeanSpeeds[curLaneId] + 5, currentMeanSpeed); } else { laneMeanSpeeds[curLaneId] = (byte)Math.Max((int)laneMeanSpeeds[curLaneId] - 5, 0); } //laneMeanDensities[curLaneId] = currentMeanDensity; currentLaneTrafficBuffer[curLaneId] = 0; currentLaneSpeeds[curLaneId] = 0; if (currentLaneDensities[curLaneId] > 0 && firstWithTraffic) { resetDensity = (currentLaneDensities[curLaneId] > 1000000); firstWithTraffic = false; } if (resetDensity) { currentLaneDensities[curLaneId] /= 2u; } laneIndex++; curLaneId = Singleton <NetManager> .instance.m_lanes.m_buffer[curLaneId].m_nextLane; } } catch (Exception e) { Log.Error("Error occured while calculating lane traffic density: " + e.ToString()); } } } try { OriginalSimulationStep(segmentID, ref data); } catch (Exception ex) { Log.Error("Error in CustomRoadAI.SimulationStep: " + ex.ToString()); } }