Skip to content

Commit

Permalink
Merge pull request #794 from CitiesSkylinesMods/cs_1.13
Browse files Browse the repository at this point in the history
Compatibility with Sunset Harbor
  • Loading branch information
krzychu124 committed Mar 29, 2020
2 parents e25c239 + 8deaca4 commit fd8af9b
Show file tree
Hide file tree
Showing 21 changed files with 333 additions and 101 deletions.
2 changes: 1 addition & 1 deletion TLM/SharedAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
// Minor Version
// Build Number
// Revision
[assembly: AssemblyVersion("11.1.2.*")]
[assembly: AssemblyVersion("11.2.0.*")]
2 changes: 1 addition & 1 deletion TLM/TLM/Custom/AI/CustomRoadBaseAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class CustomRoadBaseAI : RoadBaseAI {

NetManager netManager = Singleton<NetManager>.instance;
NetInfo info = netManager.m_segments.m_buffer[segmentId].Info;
if ((info.m_vehicleTypes & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Tram)) ==
if ((info.m_vehicleTypes & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Trolleybus)) ==
VehicleInfo.VehicleType.None) {
return;
}
Expand Down
4 changes: 4 additions & 0 deletions TLM/TLM/Custom/AI/CustomTransportLineAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ public class CustomTransportLineAI : TransportLineAI {
extVehicleType = ExtVehicleType.CableCar;
}

if ((vehicleType & VehicleInfo.VehicleType.Trolleybus) != VehicleInfo.VehicleType.None) {
extVehicleType = ExtVehicleType.Trolleybus;
}

// Log._Debug($"Transport line. extVehicleType={extVehicleType}");
// NON-STOCK CODE START
PathCreationArgs args;
Expand Down
213 changes: 213 additions & 0 deletions TLM/TLM/Custom/AI/CustomTrolleybusAI.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
namespace TrafficManager.Custom.AI {
using ColossalFramework;
using JetBrains.Annotations;
using Manager.Impl;
using State;
using TrafficManager.API.Traffic.Data;
using TrafficManager.API.Traffic.Enums;
using TrafficManager.Custom.PathFinding;
using TrafficManager.RedirectionFramework.Attributes;
using UnityEngine;

[TargetType(typeof(TrolleybusAI))]
public class CustomTrolleybusAI : CarAI {
[RedirectMethod]
public void CustomCalculateSegmentPosition(ushort vehicleId,
ref Vehicle vehicleData,
PathUnit.Position nextPosition,
PathUnit.Position prevPosition,
uint prevLaneId,
byte prevOffset,
PathUnit.Position refPosition,
uint refLaneId,
byte refOffset,
int index,
out Vector3 pos,
out Vector3 dir,
out float maxSpeed) {
NetManager netManager = Singleton<NetManager>.instance;
ushort prevSourceNodeId;
ushort prevTargetNodeId;
NetSegment[] segBuffer = netManager.m_segments.m_buffer;

if (prevOffset < prevPosition.m_offset) {
prevSourceNodeId = segBuffer[prevPosition.m_segment].m_startNode;
prevTargetNodeId = segBuffer[prevPosition.m_segment].m_endNode;
} else {
prevSourceNodeId = segBuffer[prevPosition.m_segment].m_endNode;
prevTargetNodeId = segBuffer[prevPosition.m_segment].m_startNode;
}

ushort refTargetNodeId = refOffset == 0
? segBuffer[refPosition.m_segment].m_startNode
: segBuffer[refPosition.m_segment].m_endNode;
Vehicle.Frame lastFrameData = vehicleData.GetLastFrameData();
float sqrVelocity = lastFrameData.m_velocity.sqrMagnitude;

netManager.m_lanes.m_buffer[prevLaneId].CalculatePositionAndDirection(
Constants.ByteToFloat(prevOffset),
out pos,
out dir);
Vector3 b = netManager.m_lanes.m_buffer[refLaneId].CalculatePosition(
Constants.ByteToFloat(refOffset));
Vector3 a = lastFrameData.m_position;
Vector3 a2 = lastFrameData.m_position;
Vector3 b2 = lastFrameData.m_rotation * new Vector3(
0f,
0f,
m_info.m_generatedInfo.m_wheelBase * 0.5f);
a += b2;
a2 -= b2;
float crazyValue = 0.5f * sqrVelocity / m_info.m_braking;
float a3 = Vector3.Distance(a, b);
float b3 = Vector3.Distance(a2, b);

if (Mathf.Min(a3, b3) >= crazyValue - 1f) {
// dead stock code
/*Segment3 segment;
segment.a = pos;
if (prevOffset < prevPosition.m_offset) {
segment.b = pos + dir.normalized * this.m_info.m_generatedInfo.m_size.z;
} else {
segment.b = pos - dir.normalized * this.m_info.m_generatedInfo.m_size.z;
}*/
if (prevSourceNodeId == refTargetNodeId) {
if (!VehicleBehaviorManager.Instance.MayChangeSegment(
vehicleId,
ref vehicleData,
sqrVelocity,
ref refPosition,
ref segBuffer[refPosition.m_segment],
refTargetNodeId,
refLaneId,
ref prevPosition,
prevSourceNodeId,
ref netManager.m_nodes.m_buffer[
prevSourceNodeId],
prevLaneId,
ref nextPosition,
prevTargetNodeId,
out maxSpeed)) {
maxSpeed = 0;
return;
}

ExtVehicleManager.Instance.UpdateVehiclePosition(
vehicleId,
ref vehicleData
/*, lastFrameData.m_velocity.magnitude*/
);
}
}

NetInfo info = segBuffer[prevPosition.m_segment].Info;
if (info.m_lanes != null && info.m_lanes.Length > prevPosition.m_lane) {
float speedLimit = Options.customSpeedLimitsEnabled
? SpeedLimitManager.Instance.GetLockFreeGameSpeedLimit(
prevPosition.m_segment,
prevPosition.m_lane,
prevLaneId,
info.m_lanes[prevPosition.m_lane])
: info.m_lanes[prevPosition.m_lane].m_speedLimit;

// NON-STOCK CODE
maxSpeed = CalculateTargetSpeed(
vehicleId,
ref vehicleData,
speedLimit,
netManager.m_lanes.m_buffer[prevLaneId].m_curve);
} else {
maxSpeed = CalculateTargetSpeed(vehicleId, ref vehicleData, 1f, 0f);
}
}


[RedirectMethod]
[UsedImplicitly]
public bool CustomStartPathFind(ushort vehicleId,
ref Vehicle vehicleData,
Vector3 startPos,
Vector3 endPos,
bool startBothWays,
bool endBothWays) {
VehicleInfo info = m_info;
bool allowUnderground =
(vehicleData.m_flags & (Vehicle.Flags.Underground | Vehicle.Flags.Transition)) != 0;

if (!PathManager.FindPathPosition(
startPos,
ItemClass.Service.Road,
NetInfo.LaneType.Vehicle,
info.m_vehicleType,
allowUnderground,
false,
32f,
out PathUnit.Position startPosA,
out PathUnit.Position startPosB,
out float startDistSqrA,
out float startDistSqrB)
|| !PathManager.FindPathPosition(
endPos,
ItemClass.Service.Road,
NetInfo.LaneType.Vehicle,
info.m_vehicleType,
false,
false,
32f,
out PathUnit.Position endPosA,
out PathUnit.Position endPosB,
out float endDistSqrA,
out float endDistSqrB)) {
return false;
}

if (!startBothWays || startDistSqrB > startDistSqrA * 1.2f) {
startPosB = default(PathUnit.Position);
}

if (!endBothWays || endDistSqrB > endDistSqrA * 1.2f) {
endPosB = default(PathUnit.Position);
}

// NON-STOCK CODE START
PathCreationArgs args;
args.extPathType = ExtPathType.None;
args.extVehicleType = ExtVehicleType.Trolleybus;
args.vehicleId = vehicleId;
args.spawned = (vehicleData.m_flags & Vehicle.Flags.Spawned) != 0;
args.buildIndex = Singleton<SimulationManager>.instance.m_currentBuildIndex;
args.startPosA = startPosA;
args.startPosB = startPosB;
args.endPosA = endPosA;
args.endPosB = endPosB;
args.vehiclePosition = default;
args.laneTypes = NetInfo.LaneType.Vehicle;
args.vehicleTypes = info.m_vehicleType;
args.maxLength = 20000f;
args.isHeavyVehicle = IsHeavyVehicle();
args.hasCombustionEngine = CombustionEngine();
args.ignoreBlocked = IgnoreBlocked(vehicleId, ref vehicleData);
args.ignoreFlooded = false;
args.randomParking = false;
args.ignoreCosts = false;
args.stablePath = true;
args.skipQueue = true;

if (CustomPathManager._instance.CustomCreatePath(
out uint path,
ref Singleton<SimulationManager>.instance.m_randomizer,
args)) {
// NON-STOCK CODE END
if (vehicleData.m_path != 0u) {
Singleton<PathManager>.instance.ReleasePath(vehicleData.m_path);
}

vehicleData.m_path = path;
vehicleData.m_flags |= Vehicle.Flags.WaitingPath;
return true;
}

return false;
}
}
}
17 changes: 10 additions & 7 deletions TLM/TLM/Custom/PathFinding/CustomPathFind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ private struct BufferItem {
bool detourMissing =
(vehicleTypes_ & (VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train |
VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Monorail |
VehicleInfo.VehicleType.Metro)) != VehicleInfo.VehicleType.None &&
VehicleInfo.VehicleType.Metro | VehicleInfo.VehicleType.Trolleybus)) != VehicleInfo.VehicleType.None &&
!queueItem_.queued;

if (detourMissing) {
Expand Down Expand Up @@ -781,7 +781,7 @@ ref netManager.m_segments.m_buffer
255f);
#if PARKINGAI
PathUnits.m_buffer[unit].m_laneTypes = (byte)finalBufferItem.LanesUsed;
PathUnits.m_buffer[unit].m_vehicleTypes = (ushort)finalBufferItem.VehiclesUsed;
PathUnits.m_buffer[unit].m_vehicleTypes = (uint)finalBufferItem.VehiclesUsed;
#endif

uint currentPathUnitId = unit;
Expand Down Expand Up @@ -1960,7 +1960,7 @@ ref netManager.m_segments.m_buffer
#endif

if (exploreUturn
&& (vehicleTypes_ & VehicleInfo.VehicleType.Tram) == VehicleInfo.VehicleType.None)
&& (vehicleTypes_ & (VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Trolleybus)) == VehicleInfo.VehicleType.None)
{
if (isLogEnabled) {
DebugLog(
Expand Down Expand Up @@ -2553,9 +2553,11 @@ ref netManager.m_segments.m_buffer
bool acuteTurningAngle = false;
if (prevLaneType == NetInfo.LaneType.Vehicle &&
(prevVehicleType & VehicleInfo.VehicleType.Car) == VehicleInfo.VehicleType.None) {
float turningAngle = 0.01f - Mathf.Min(
nextSegmentInfo.m_maxTurnAngleCos,
prevSegmentInfo.m_maxTurnAngleCos);
float turningAngle = !nextSegment.m_overridePathFindDirectionLimit
? (0.01f - Mathf.Min(
nextSegmentInfo.m_maxTurnAngleCos,
prevSegmentInfo.m_maxTurnAngleCos))
: 1f;
if (turningAngle < 1f) {
Vector3 vector = nextNodeId != prevSegment.m_startNode
? prevSegment.m_endDirection
Expand Down Expand Up @@ -3652,7 +3654,7 @@ ref netManager.m_segments.m_buffer
*/
bool isUturnAllowedHere = false; // is u-turn allowed at this place?
if ((vehicleTypes_ &
(VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Monorail)) ==
(VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Monorail | VehicleInfo.VehicleType.Trolleybus)) ==
VehicleInfo.VehicleType.None) {
// is vehicle able to perform a u-turn?
bool isStockUturnPoint = (nextNode.m_flags & (NetNode.Flags.End | NetNode.Flags.OneWayOut)) != NetNode.Flags.None;
Expand Down Expand Up @@ -4060,6 +4062,7 @@ ref netManager.m_segments.m_buffer
if (!Options.vehicleRestrictionsEnabled ||
queueItem_.vehicleType == ExtVehicleType.None ||
queueItem_.vehicleType == ExtVehicleType.Tram ||
queueItem_.vehicleType == ExtVehicleType.Trolleybus ||
(laneInfo.m_vehicleType &
(VehicleInfo.VehicleType.Car | VehicleInfo.VehicleType.Train)) ==
VehicleInfo.VehicleType.None) {
Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/Custom/PathFinding/CustomPathManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public class CustomPathManager : PathManager {
m_pathUnits.m_buffer[unit].m_position03 = args.endPosB;
m_pathUnits.m_buffer[unit].m_position11 = args.vehiclePosition;
m_pathUnits.m_buffer[unit].m_laneTypes = (byte)args.laneTypes;
m_pathUnits.m_buffer[unit].m_vehicleTypes = (ushort)args.vehicleTypes;
m_pathUnits.m_buffer[unit].m_vehicleTypes = (uint)args.vehicleTypes;
m_pathUnits.m_buffer[unit].m_length = args.maxLength;
m_pathUnits.m_buffer[unit].m_positionCount = 20;

Expand Down
2 changes: 1 addition & 1 deletion TLM/TLM/Custom/PathFinding/StockPathFind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ private struct BufferItem {
nextSegmentId = netManager.m_segments.m_buffer[nextSegmentId].GetRightSegment(nextNodeId);
}

if (isUturnAllowedHere && (m_vehicleTypes & VehicleInfo.VehicleType.Tram) == VehicleInfo.VehicleType.None) {
if (isUturnAllowedHere && (m_vehicleTypes & VehicleInfo.VehicleType.Tram | VehicleInfo.VehicleType.Trolleybus) == VehicleInfo.VehicleType.None) {
nextSegmentId = item.m_position.m_segment;
ProcessItemCosts(item, nextNodeId, nextSegmentId, ref netManager.m_segments.m_buffer[nextSegmentId], ref prevRelSimilarLaneIndex, connectOffset, true, false);
}
Expand Down

0 comments on commit fd8af9b

Please sign in to comment.