Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@ This changelog includes all versions and major variants of the mod going all the

> Date format: dd/mm/yyyy

#### TM:PE V[11.7.3.0](https://github.com/CitiesSkylinesMods/TMPE/compare/11.7.2.0...11.7.3.0) STABLE, 13/12/2022

- [Meta] Compatibility patch for the game update 1.16.0-f3 (krzychu124)
- [New] Improved bus/trolleybus stop path (pull to side earlier and use more of available space) #1688, #1690 (kianzarrin)
- [Fixed] Cargo truck pathfinding via CargoVehicle networks (cargo stations/terminals) #1701, #1703 (krzychu124)
- [Fixed] Lane connector on overlapping lanes #1706 (kianzarrin)
- [Fixed] Parking signs on lanes with bus stop #1707 (kianzarrin)
- [Updated] Minor changes in debug tools #1696, #1697 (kianzarrin)
- [Updated] TMPE API Updates compatibility with other mods #1689 #1692 (kianzarrin)
- [Steam] [TM:PE v11 STABLE](https://steamcommunity.com/sharedfiles/filedetails/?id=1637663252)

#### TM:PE V11.7.3.0 TEST, 13/12/2022

- [Meta] Compatibility patch for the game update 1.16.0-f3 (krzychu124)
- [New] Improved bus/trolleybus stop path (pull to side earlier and use more of available space) #1688, #1690 (kianzarrin)
- [Fixed] Cargo truck pathfinding via CargoVehicle networks (cargo stations/terminals) #1701, #1703 (krzychu124)
- [Fixed] Lane connector on overlapping lanes #1706 (kianzarrin)
- [Fixed] Parking signs on lanes with bus stop #1707 (kianzarrin)
- [Updated] Minor changes in debug tools #1696, #1697 (kianzarrin)
- [Updated] TMPE API Updates compatibility with other mods #1689 #1692 (kianzarrin)
- [Steam] [TM:PE v11 TEST](https://steamcommunity.com/sharedfiles/filedetails/?id=2489276785)

#### TM:PE V[11.7.2.0](https://github.com/CitiesSkylinesMods/TMPE/compare/11.7.1.2...11.7.2.0) STABLE, 15/11/2022

- [Meta] Compatibility patch for the game update 1.15.1-f4 (krzychu124)
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<a href="https://github.com/CitiesSkylinesMods/TMPE/wiki/Report-a-Bug">Report a Bug</a><br />
</p>
<p align="center">
<a href="https://store.steampowered.com/app/255710/Cities_Skylines/"><img src="https://img.shields.io/static/v1?label=cities:%20skylines&message=v1.15.1-f4&color=01ABF8&logo=unity" /></a>
<a href="https://store.steampowered.com/app/255710/Cities_Skylines/"><img src="https://img.shields.io/static/v1?label=cities:%20skylines&message=v1.16.0-f3&color=01ABF8&logo=unity" /></a>
<a href="https://steamcommunity.com/sharedfiles/filedetails/?id=1637663252"><img src="https://img.shields.io/github/v/release/CitiesSkylinesMods/TMPE?label=stable&color=7cc17b&logo=steam&logoColor=F5F5F5" /></a>
<a href="https://steamcommunity.com/sharedfiles/filedetails/?id=2489276785"><img src="https://img.shields.io/github/v/release/CitiesSkylinesMods/TMPE?include_prereleases&label=test&color=f7b73c&logo=steam&logoColor=F5F5F5" /></a>
<a href="https://github.com/CitiesSkylinesMods/TMPE/releases/latest"><img src="https://img.shields.io/github/v/release/CitiesSkylinesMods/TMPE?label=origin&color=F56C2D&logo=origin&logoColor=F56C2D" /></a>
Expand Down
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.7.2.*")]
[assembly: AssemblyVersion("11.7.3.*")]
48 changes: 40 additions & 8 deletions TLM/TLM/Custom/PathFinding/CustomPathFind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ public override string ToString() {

// custom fields
private PathUnitQueueItem queueItem_;
/// <summary>
/// Contains allowed extVehicle types, in normal conditions just QueueIten.vehicleType,
/// when path may include CargoVehicle lanes then it contains also respective cargo vehicle types
/// </summary>
private ExtVehicleType allowedPathVehicleTypes_;
private bool isHeavyVehicle_;

private bool debugLog_; // this will be false in non-Debug
Expand Down Expand Up @@ -293,8 +298,15 @@ private void PathFindImplementation(uint unit, ref PathUnit data) {
disableMask_ |= NetSegment.Flags.Flooded;
}

allowedPathVehicleTypes_ = queueItem_.vehicleType;
if ((laneTypes_ & NetInfo.LaneType.Vehicle) != NetInfo.LaneType.None) {
laneTypes_ |= NetInfo.LaneType.TransportVehicle;

// allow mixed vehicle path when requested path is Vehicle + CargoVehicle (e.g.: CargoTruck and PostVanAI)
bool allowMixedCargoPath = (laneTypes_ & NetInfo.LaneType.CargoVehicle) != NetInfo.LaneType.None;
if (allowMixedCargoPath) {
allowedPathVehicleTypes_ |= VehicleTypesToMixedCargoExtVehicle(vehicleTypes_);
}
}

#if ROUTING
Expand Down Expand Up @@ -2634,12 +2646,6 @@ private bool ProcessItemCosts(
$"\toffsetLength={offsetLength}");
}
#endif
if ((vehicleCategory_ & VehicleInfo.VehicleCategory.PublicTransportRoad) != 0 &&
(vehicleCategory_ & ~(VehicleInfo.VehicleCategory.Bus | VehicleInfo.VehicleCategory.Trolleybus | VehicleInfo.VehicleCategory.Taxi)) == 0)
{
offsetLength *= 0.75f;
}

float baseLength = offsetLength / (prevLaneSpeed * maxLength_); // NON-STOCK CODE
float comparisonValue = item.ComparisonValue; // NON-STOCK CODE
#if ROUTING
Expand Down Expand Up @@ -3134,6 +3140,11 @@ private bool ProcessItemCosts(
$"ProcessItemCosts: Adding next item\n\tnextItem={nextItem}");
}

if ((nextLaneInfo.vehicleCategory & VehicleInfo.VehicleCategory.PublicTransportRoad) != 0 &&
(nextLaneInfo.vehicleCategory & ~(VehicleInfo.VehicleCategory.Bus | VehicleInfo.VehicleCategory.Trolleybus | VehicleInfo.VehicleCategory.Taxi)) == 0) {
nextItem.ComparisonValue -= baseLength * 0.25f;
}

AddBufferItem(
#if DEBUG
isLogEnabled,
Expand Down Expand Up @@ -4092,15 +4103,36 @@ private bool CanUseLane(ushort segmentId,
return true;
}

ExtVehicleType allowedTypes = vehicleRestrictionsManager.GetAllowedVehicleTypes(
ExtVehicleType allowedLaneVehicleTypes = vehicleRestrictionsManager.GetAllowedVehicleTypes(
segmentId,
segmentInfo,
(uint)laneIndex,
laneInfo,
VehicleRestrictionsMode.Configured);
return (allowedLaneVehicleTypes & allowedPathVehicleTypes_) != ExtVehicleType.None;
}

/// <summary>
/// Maps all allowed vehicle types to mixed ExtVehicleType
/// Later used to correctly test lane for match with configured allowed vehicle types
/// </summary>
/// <param name="vehicleTypes">Allowed additional vehicle types</param>
/// <returns>Combined ExtVehicleType of all alowed cargo vehicle lane types</returns>
private ExtVehicleType VehicleTypesToMixedCargoExtVehicle(VehicleInfo.VehicleType vehicleTypes) {
ExtVehicleType extVehicleType = ExtVehicleType.None;
if ((vehicleTypes & VehicleInfo.VehicleType.Train) != VehicleInfo.VehicleType.None) {
extVehicleType |= ExtVehicleType.CargoTrain;
}
if ((vehicleTypes & VehicleInfo.VehicleType.Plane) != VehicleInfo.VehicleType.None) {
extVehicleType |= ExtVehicleType.CargoPlane;
}
if ((vehicleTypes & VehicleInfo.VehicleType.Ship) != VehicleInfo.VehicleType.None) {
extVehicleType |= ExtVehicleType.CargoShip;
}

return (allowedTypes & queueItem_.vehicleType) != ExtVehicleType.None;
return extVehicleType;
}

#endif

#if ADVANCEDAI && ROUTING
Expand Down
1 change: 1 addition & 0 deletions TLM/TLM/Custom/PathFinding/PathfinderUpdates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public static class PathfinderUpdates {
// Edition History:
// 0 - An old save, unknown pathfinder edition
// 1 - #1338 Aircraft pathfinding fix
// TODO: This feature is not used and does not persist. if we increment this we need to also serialize this.

/// <summary>
/// Update this each time a despawn-requiring change is
Expand Down
32 changes: 20 additions & 12 deletions TLM/TLM/Lifecycle/SerializableDataExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public class SerializableDataExtension

private const string DATA_ID = "TrafficManager_v1.0";
private const string VERSION_INFO_DATA_ID = "TrafficManager_VersionInfo_v1.0";
private const string OPTIONS_ID = "TMPE_OptionsXML";
private const string OPTIONS_LEGACY_ID = "TMPE_Options";


private static ISerializableData SerializableData => SimulationManager.instance.m_SerializableDataWrapper;
private static Configuration _configuration;
Expand Down Expand Up @@ -80,16 +83,21 @@ public static void Load() {
if (TMPELifecycle.InGameOrEditor()) {
// Always force default options on new game
// See: https://github.com/CitiesSkylinesMods/TMPE/pull/1425
byte[] options = TMPELifecycle.IsNewGame
? null
: SerializableData.LoadData("TMPE_Options");

if (!OptionsManager.Instance.LoadData(options ?? new byte[0])) {
loadingSucceeded = false;
if (!TMPELifecycle.IsNewGame) {
if (Version <= 3) {
byte[] data = SerializableData.LoadData(OPTIONS_ID);
if (data != null) {
loadingSucceeded &= OptionsManager.Instance.LoadData(data);
}
} else {
byte[] data = SerializableData.LoadData(OPTIONS_LEGACY_ID);
if (data != null) {
loadingSucceeded &= OptionsManager.Instance.LoadDataLegacy(data);
}
}
}
}
}
catch (Exception e) {
} catch (Exception e) {
Log.Error($"OnLoadData: Error while loading options: {e}");
loadingSucceeded = false;
}
Expand Down Expand Up @@ -217,9 +225,6 @@ private static void LoadDataState(out bool error) {
return;
}

// load Path Find Update
PathfinderUpdates.SavegamePathfinderEdition = _configuration.SavegamePathfinderEdition;

// load ext. citizens
if (_configuration.ExtCitizens != null) {
if (!ExtCitizenManager.Instance.LoadData(_configuration.ExtCitizens)) {
Expand Down Expand Up @@ -454,7 +459,10 @@ public static void Save() {

try {
if (TMPELifecycle.PlayMode) {
SerializableData.SaveData("TMPE_Options", OptionsManager.Instance.SaveData(ref success));
SerializableData.SaveData(OPTIONS_ID, OptionsManager.Instance.SaveData(ref success));

// forward compatibility. only needed for a short time:
SerializableData.SaveData(OPTIONS_LEGACY_ID, OptionsManager.Instance.SaveDataLegacy(ref success));
}
} catch (Exception ex) {
Log.Error("Unexpected error while saving options: " + ex.Message);
Expand Down
2 changes: 2 additions & 0 deletions TLM/TLM/Lifecycle/TMPELifecycle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ internal void Load() {

IsGameLoaded = true;

SerializableUIOptionBase.UpdateAll();

ModUI.OnLevelLoaded();
if (PlayMode) {
Log._Debug("PlayMode");
Expand Down
104 changes: 94 additions & 10 deletions TLM/TLM/Manager/Impl/OptionsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace TrafficManager.Manager.Impl {

public class OptionsManager
: AbstractCustomManager,
IOptionsManager {
IOptionsManager, ICustomDataManager<byte[]> {

public static OptionsManager Instance = new OptionsManager();

Expand Down Expand Up @@ -67,6 +67,7 @@ public override void OnBeforeLoadData() {
public override void OnAfterLoadData() {
base.OnAfterLoadData();
Log.Info("OptionsManger.OnAfterLoadData() checking for queued method calls");
SerializableUIOptionBase.UpdateAll();

if (_needUpdateDedicatedTurningLanes) {
_needUpdateDedicatedTurningLanes = false;
Expand Down Expand Up @@ -103,29 +104,112 @@ private static void ToOption(byte[] data, uint idx, ILegacySerializableOption op
/// <returns>Returns <c>true</c> if successful, otherwise <c>false</c>.</returns>
public byte[] SaveData(ref bool success) {
try {
return SavedGameOptions.Instance.Serialize();
string xml = SavedGameOptions.Instance.Serialize();
return Encoding.ASCII.GetBytes(xml);
} catch (Exception ex) {
ex.LogException();
success = false;
return null; // try and salvage some of the settings
}
}

public bool LoadData(byte[] data) {
try {
string xml = Encoding.ASCII.GetString(data);
Log._Debug("OptionsManager.LoadedData() called. XML =\n" + xml);
SavedGameOptions.Available = false;
int dataVersion = SerializableDataExtension.Version;
if (data.IsNullOrEmpty()) {
return true;
} else if (dataVersion < 4) {
return LoadDataLegacy(data);
} else {
return SavedGameOptions.Deserialize(data);
}
return SavedGameOptions.Deserialize(xml);
} catch(Exception ex) {
ex.LogException();
return false;
} finally {
SavedGameOptions.Available = true;
}
}

// forward compatibility. This method is only necessary for a short time.
public byte[] SaveDataLegacy(ref bool success) {

var save = new byte[61];

try {
save[0] = GeneralTab_SimulationGroup.SimulationAccuracy.Save();
save[1] = 0; // SavedGameOptions.Instance.laneChangingRandomization
save[2] = GameplayTab_VehicleBehaviourGroup.RecklessDrivers.Save();
save[3] = (byte)(SavedGameOptions.Instance.relaxedBusses ? 1 : 0);
save[4] = (byte)(SavedGameOptions.Instance.nodesOverlay ? 1 : 0);
save[5] = (byte)(SavedGameOptions.Instance.allowEnterBlockedJunctions ? 1 : 0);
save[6] = (byte)(SavedGameOptions.Instance.advancedAI ? 1 : 0);
save[7] = (byte)(SavedGameOptions.Instance.highwayRules ? 1 : 0);
save[8] = (byte)(SavedGameOptions.Instance.prioritySignsOverlay ? 1 : 0);
save[9] = (byte)(SavedGameOptions.Instance.timedLightsOverlay ? 1 : 0);
save[10] = (byte)(SavedGameOptions.Instance.speedLimitsOverlay ? 1 : 0);
save[11] = (byte)(SavedGameOptions.Instance.vehicleRestrictionsOverlay ? 1 : 0);
save[12] = GameplayTab_VehicleBehaviourGroup.StrongerRoadConditionEffects.Save();
save[13] = (byte)(SavedGameOptions.Instance.allowUTurns ? 1 : 0);
save[14] = (byte)(SavedGameOptions.Instance.allowLaneChangesWhileGoingStraight ? 1 : 0);
save[15] = (byte)(SavedGameOptions.Instance.disableDespawning ? 1 : 0);
save[16] = 0; // SavedGameOptions.Instance.IsDynamicPathRecalculationActive
save[17] = (byte)(SavedGameOptions.Instance.connectedLanesOverlay ? 1 : 0);
save[18] = (byte)(SavedGameOptions.Instance.prioritySignsEnabled ? 1 : 0);
save[19] = (byte)(SavedGameOptions.Instance.timedLightsEnabled ? 1 : 0);
save[20] = (byte)(SavedGameOptions.Instance.customSpeedLimitsEnabled ? 1 : 0);
save[21] = (byte)(SavedGameOptions.Instance.vehicleRestrictionsEnabled ? 1 : 0);
save[22] = (byte)(SavedGameOptions.Instance.laneConnectorEnabled ? 1 : 0);
save[23] = (byte)(SavedGameOptions.Instance.junctionRestrictionsOverlay ? 1 : 0);
save[24] = (byte)(SavedGameOptions.Instance.junctionRestrictionsEnabled ? 1 : 0);
save[25] = (byte)(SavedGameOptions.Instance.parkingAI ? 1 : 0);
save[26] = (byte)(SavedGameOptions.Instance.preferOuterLane ? 1 : 0);
save[27] = GameplayTab_VehicleBehaviourGroup.IndividualDrivingStyle.Save();
save[28] = (byte)(SavedGameOptions.Instance.evacBussesMayIgnoreRules ? 1 : 0);
save[29] = 0; // (byte)(SavedGameOptions.Instance.instantEffects ? 1 : 0);
save[30] = (byte)(SavedGameOptions.Instance.parkingRestrictionsEnabled ? 1 : 0);
save[31] = (byte)(SavedGameOptions.Instance.parkingRestrictionsOverlay ? 1 : 0);
save[32] = (byte)(SavedGameOptions.Instance.banRegularTrafficOnBusLanes ? 1 : 0);
save[33] = (byte)(SavedGameOptions.Instance.showPathFindStats ? 1 : 0);
save[34] = SavedGameOptions.Instance.altLaneSelectionRatio;
save[35] = PoliciesTab_OnRoadsGroup.VehicleRestrictionsAggression.Save();
save[36] = (byte)(SavedGameOptions.Instance.trafficLightPriorityRules ? 1 : 0);
save[37] = (byte)(SavedGameOptions.Instance.realisticPublicTransport ? 1 : 0);
save[38] = (byte)(SavedGameOptions.Instance.turnOnRedEnabled ? 1 : 0);
save[39] = (byte)(SavedGameOptions.Instance.allowNearTurnOnRed ? 1 : 0);
save[40] = (byte)(SavedGameOptions.Instance.allowFarTurnOnRed ? 1 : 0);
save[41] = (byte)(SavedGameOptions.Instance.automaticallyAddTrafficLightsIfApplicable ? 1 : 0);

save[42] = PoliciesTab_RoundaboutsGroup.RoundAboutQuickFix_StayInLaneMainR.Save();
save[43] = PoliciesTab_RoundaboutsGroup.RoundAboutQuickFix_StayInLaneNearRabout.Save();
save[44] = PoliciesTab_RoundaboutsGroup.RoundAboutQuickFix_DedicatedExitLanes.Save();
save[45] = PoliciesTab_RoundaboutsGroup.RoundAboutQuickFix_NoCrossMainR.Save();
save[46] = PoliciesTab_RoundaboutsGroup.RoundAboutQuickFix_NoCrossYieldR.Save();
save[47] = PoliciesTab_RoundaboutsGroup.RoundAboutQuickFix_PrioritySigns.Save();

save[48] = PoliciesTab_PriorityRoadsGroup.PriorityRoad_CrossMainR.Save();
save[49] = PoliciesTab_PriorityRoadsGroup.PriorityRoad_AllowLeftTurns.Save();
save[50] = PoliciesTab_PriorityRoadsGroup.PriorityRoad_EnterBlockedYeild.Save();
save[51] = PoliciesTab_PriorityRoadsGroup.PriorityRoad_StopAtEntry.Save();

save[52] = PoliciesTab_RoundaboutsGroup.RoundAboutQuickFix_KeepClearYieldR.Save();
save[53] = PoliciesTab_RoundaboutsGroup.RoundAboutQuickFix_RealisticSpeedLimits.Save();
save[54] = PoliciesTab_RoundaboutsGroup.RoundAboutQuickFix_ParkingBanMainR.Save();
save[55] = PoliciesTab_RoundaboutsGroup.RoundAboutQuickFix_ParkingBanYieldR.Save();

save[56] = PoliciesTab_OnRoadsGroup.NoDoubleCrossings.Save();
save[57] = PoliciesTab_AtJunctionsGroup.DedicatedTurningLanes.Save();

save[58] = PathfinderUpdates.SavegamePathfinderEdition;

save[59] = OverlaysTab_OverlaysGroup.ShowDefaultSpeedSubIcon.Save();

save[60] = PoliciesTab_OnHighwaysGroup.HighwayMergingRules.Save();

return save;
} catch (Exception ex) {
ex.LogException();
return save; // try and salvage some of the settings
}
}


/// <summary>
/// Restores the mod options based on supplied <paramref name="data"/>.
/// </summary>
Expand Down
Loading