From 57b3a44e1f4ace29ec343a543f0bf6c0c3b27956 Mon Sep 17 00:00:00 2001 From: egi Date: Mon, 25 May 2020 02:35:08 +0200 Subject: [PATCH 1/7] - no need to allocate a new List each time if we can work with locks instead. - use of lock statement instead Monitor directly. - removed commented out debug.log calls. - formatting (cherry picked from commit c878dd26c2d04de71e8dbf109883e83bef19a5f0) --- TLM/TLM/State/GlobalConfig.cs | 4 ++-- TLM/TLM/Util/GenericObservable.cs | 40 +++++++++++++------------------ 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/TLM/TLM/State/GlobalConfig.cs b/TLM/TLM/State/GlobalConfig.cs index 4a104d9ed..7377f5586 100644 --- a/TLM/TLM/State/GlobalConfig.cs +++ b/TLM/TLM/State/GlobalConfig.cs @@ -17,8 +17,8 @@ public static GlobalConfig Instance { get => instance; private set { if (value != null && instance != null) { - value.Observers = instance.Observers; - value.ObserverLock = instance.ObserverLock; + value._observers = instance._observers; + value._lock = instance._lock; } instance = value; diff --git a/TLM/TLM/Util/GenericObservable.cs b/TLM/TLM/Util/GenericObservable.cs index 0ea46eb77..58b283229 100644 --- a/TLM/TLM/Util/GenericObservable.cs +++ b/TLM/TLM/Util/GenericObservable.cs @@ -1,8 +1,7 @@ -namespace TrafficManager.Util { +namespace TrafficManager.Util { using CSUtil.Commons; - using System.Collections.Generic; - using System.Threading; using System; + using System.Collections.Generic; using TrafficManager.API.Util; public abstract class GenericObservable : IObservable { @@ -10,12 +9,12 @@ public abstract class GenericObservable : IObservable { /// Holds a list of observers which are being notified as soon as the managed node's /// geometry is updated (but not neccessarily modified) /// - protected List> Observers = new List>(); + protected List> _observers = new List>(); /// /// Lock object. Acquire this before accessing the HashSets. /// - protected object ObserverLock = new object(); + protected object _lock = new object(); /// /// Registers an observer. @@ -23,33 +22,26 @@ public abstract class GenericObservable : IObservable { /// /// An unsubscriber public IDisposable Subscribe(IObserver observer) { - // Log._Debug($"GenericObserable.Subscribe: Subscribing observer {observer} to observable {this}"); - try { - Monitor.Enter(ObserverLock); - Observers.Add(observer); - } - finally { - Monitor.Exit(ObserverLock); + lock (_lock) { + _observers.Add(observer); } - return new GenericUnsubscriber(Observers, observer, ObserverLock); + return new GenericUnsubscriber(_observers, observer, _lock); } /// /// Notifies all observers that the observable object' state has changed /// public virtual void NotifyObservers(T subject) { - // Log._Debug($"GenericObserable.NotifyObservers: Notifying observers of observable {this}"); - // in case somebody unsubscribes while iterating over subscribers - var myObservers = new List>(Observers); - - foreach (IObserver observer in myObservers) { - try { - observer.OnUpdate(subject); - } - catch (Exception e) { - Log.Error("GenericObserable.NotifyObservers: An exception occured while " + - $"notifying an observer of observable {this}: {e}"); + lock (_lock) { + foreach (IObserver observer in _observers) { + try { + observer.OnUpdate(subject); + } + catch (Exception e) { + Log.Error("GenericObserable.NotifyObservers: An exception occured while " + + $"notifying an observer of observable {this}: {e}"); + } } } } From d0633b44b30e389763e51ac5fce09435c672ab86 Mon Sep 17 00:00:00 2001 From: "kian.zarrin" Date: Tue, 2 Jun 2020 09:45:00 +0200 Subject: [PATCH 2/7] fixed stay-in-lane for MOM tracks. (cherry picked from commit 4d281c850c2422d6ee716bcc480d734d3e502f3b) --- TLM/TLM/UI/SubTools/LaneConnectorTool.cs | 28 ++++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/TLM/TLM/UI/SubTools/LaneConnectorTool.cs b/TLM/TLM/UI/SubTools/LaneConnectorTool.cs index bb8a1a0cc..483c08188 100644 --- a/TLM/TLM/UI/SubTools/LaneConnectorTool.cs +++ b/TLM/TLM/UI/SubTools/LaneConnectorTool.cs @@ -553,7 +553,7 @@ public static bool GetSortedSegments(ushort nodeId, out List segments) { /// /// /// determines for which side to connect lanes. - /// false if there is only one incomming/outgoing lane, true otherwise + /// true if any lanes were connectde, false otherwise public static bool StayInLane(ushort nodeId, StayInLaneMode mode = StayInLaneMode.None) { Log._Debug($"Stay In Lane called node:{nodeId} mode:{mode}"); LaneConnectionManager.Instance.RemoveLaneConnectionsFromNode(nodeId); @@ -629,12 +629,12 @@ private static bool StayInLane( // count relavent source(going toward the junction) lanes and // target (going aginst the junction) lanes on each segment. - int laneCountMinorSource = minorSegmentId == 0 ? 0 : PriorityRoad.CountLanesTowardJunction(minorSegmentId, nodeId); - int laneCountMinorTarget = minorSegmentId == 0 ? 0 : PriorityRoad.CountLanesAgainstJunction(minorSegmentId, nodeId); - int laneCountMinor2Source = minorSegment2Id == 0 ? 0 : PriorityRoad.CountLanesTowardJunction(minorSegment2Id, nodeId); - int laneCountMinor2Target = minorSegment2Id == 0 ? 0 : PriorityRoad.CountLanesAgainstJunction(minorSegment2Id, nodeId); - int laneCountMainSource = PriorityRoad.CountLanesTowardJunction(mainSegmentSourceId, nodeId); - int laneCountMainTarget = PriorityRoad.CountLanesAgainstJunction(mainSegmentTargetId, nodeId); + int laneCountMinorSource = minorSegmentId == 0 ? 0 : CountLanesTowardJunction(minorSegmentId, nodeId); + int laneCountMinorTarget = minorSegmentId == 0 ? 0 : CountLanesAgainstJunction(minorSegmentId, nodeId); + int laneCountMinor2Source = minorSegment2Id == 0 ? 0 : CountLanesTowardJunction(minorSegment2Id, nodeId); + int laneCountMinor2Target = minorSegment2Id == 0 ? 0 : CountLanesAgainstJunction(minorSegment2Id, nodeId); + int laneCountMainSource = CountLanesTowardJunction(mainSegmentSourceId, nodeId); + int laneCountMainTarget = CountLanesAgainstJunction(mainSegmentTargetId, nodeId); int totalSource = laneCountMinorSource + laneCountMainSource + laneCountMinor2Source; int totalTarget = laneCountMinorTarget + laneCountMainTarget + laneCountMinor2Target; @@ -779,6 +779,20 @@ bool ConnectToMinor2(int sourceIdx, int targetIdx) { return true; } + private static int CountLanes(ushort segmentId, ushort nodeId, bool toward) { + return netService.GetSortedLanes( + segmentId, + ref segmentId.ToSegment(), + netService.IsStartNode(segmentId, nodeId) ^ (!toward), + LaneConnectionManager.LANE_TYPES, + LaneConnectionManager.VEHICLE_TYPES, + true + ).Count; + } + internal static int CountLanesTowardJunction(ushort segmentId, ushort nodeId) => CountLanes(segmentId, nodeId, true); + internal static int CountLanesAgainstJunction(ushort segmentId, ushort nodeId) => CountLanes(segmentId, nodeId, false); + + public override void OnPrimaryClickOverlay() { #if DEBUG bool logLaneConn = DebugSwitch.LaneConnections.Get(); From c052823b386e97b73a9a183e73d57474d52a3be8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cham=C3=ABleon?= Date: Thu, 30 Jul 2020 14:09:45 +0200 Subject: [PATCH 3/7] Updated icons for RoadSelectionPanel to optimized 8bit as the previous version causes sometimes at rebuild strange white pixel artifacts. (cherry picked from commit 4544d30fbb8a244f08ad7f1ef0a229a5a3e456eb) --- .../RoadSelectionPanel/Clear-fg-disabled.png | Bin 1727 -> 1848 bytes .../RoadSelectionPanel/Clear-fg-normal.png | Bin 1906 -> 1845 bytes .../HighPriority_LHT-fg-disabled.png | Bin 898 -> 1403 bytes .../HighPriority_LHT-fg-normal.png | Bin 830 -> 1427 bytes .../HighPriority_RHT-fg-disabled.png | Bin 896 -> 1405 bytes .../HighPriority_RHT-fg-normal.png | Bin 845 -> 1424 bytes .../RoundButton-bg-active.png | Bin 2581 -> 2592 bytes .../RoundButton-bg-disabled.png | Bin 508 -> 1564 bytes .../RoundButton-bg-hovered.png | Bin 2548 -> 2481 bytes .../RoundButton-bg-normal.png | Bin 2107 -> 2043 bytes .../Roundabout_LHT-fg-disabled.png | Bin 1241 -> 1496 bytes .../Roundabout_LHT-fg-normal.png | Bin 1088 -> 1530 bytes .../Roundabout_RHT-fg-disabled.png | Bin 1233 -> 1493 bytes .../Roundabout_RHT-fg-normal.png | Bin 1089 -> 1531 bytes .../Stop_LHT-fg-disabled.png | Bin 918 -> 1453 bytes .../RoadSelectionPanel/Stop_LHT-fg-normal.png | Bin 938 -> 1468 bytes .../Stop_RHT-fg-disabled.png | Bin 930 -> 1441 bytes .../RoadSelectionPanel/Stop_RHT-fg-normal.png | Bin 951 -> 1450 bytes .../Yield_LHT-fg-disabled.png | Bin 1025 -> 1432 bytes .../Yield_LHT-fg-normal.png | Bin 893 -> 1452 bytes .../Yield_RHT-fg-disabled.png | Bin 967 -> 1428 bytes .../Yield_RHT-fg-normal.png | Bin 904 -> 1446 bytes 22 files changed, 0 insertions(+), 0 deletions(-) diff --git a/TLM/TLM/Resources/RoadSelectionPanel/Clear-fg-disabled.png b/TLM/TLM/Resources/RoadSelectionPanel/Clear-fg-disabled.png index e1cc1a312cee07fc7c00d02597f18e0b105f337c..33a10fb323f77c5062af3ab591ae41be39d088a3 100644 GIT binary patch literal 1848 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 delta 1504 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 diff --git a/TLM/TLM/Resources/RoadSelectionPanel/HighPriority_LHT-fg-normal.png b/TLM/TLM/Resources/RoadSelectionPanel/HighPriority_LHT-fg-normal.png index 5a3bdc314e9108457bbd25d22c193368f9861f3e..e1533e941b86085af8f6c6f5fabd53cdcc5d2ca0 100644 GIT binary patch literal 1427 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvNA9*GX(gAxB|s_czCR=tgNlA9UUD#Jw3g=yb===lai8>lao_YQZh3$v$C>E zOH0ej$|@@>tE#H1tE+2jYHDk1|8LR$zs;brv9Y$Yv%{@SHvfOJ<;amEM~@yoapJ`7+qduEzyI>(%U7>ny?*`r z|Myq_f4u(x^WFcSAO8RP^#Avl|G&Tf`t|Gg@8AFb{`~*{KhR&JU^D~>hJZki_%vWX zVJHdm3kD{ekqj7uzq6|X1B|o4BeIx*f$ty)Gwzs}{T3KN0-i38Ar}5`C*2G?WFX)m zC=zpHiiTKZm%;z(UbL$-8il>eaY0V9LWlMXPD-D^=~}CvbOW~K3V3- zKDp%gdrG>pKZFFByXw!IS=+2`9rxgyeEF6&p3YyTp9*hzB)D6agFoxl^+ZG7sYe9n zHvZl>`P-+;m|X{*k~&_sO_^u^_sXIv-X?*+uPEKHJIwOo^^0$Rp1&9Lt9QO);4-7i iI&c&JB7Jrhu8-V|wSIRwNRs6bc25*ng1deT(RD z`$ET$h<<*ea=FaY{S^5(tsblr8xo8@#|#Do3Iqa*Zf^XY=)<9C&eX|cePnqggTWwA z_cc5&_+g0+gK2Fi;&gplnQ7)s9Y5658jS`&c!cWY`-FxBqt7usf*28{SS(@$zro}S zxjAtJpW{zm$K!$@me`nrHGjv6zzytP%NkTgb3AfbgOy5!*C1~cXKPRo*qGPPyO?*g z(X{66B$LUDU3_Bh;gWcBFA4XsN3Owvz!oE>T5!lvNA9*GX(gAxB|s_czDds%`Ge}92^`R9UY^hqGDrXR> z^78WY^9u?J3JVL1i;GK2N=i#hD=RCjs;a81t7~d%>g(%gHw4aZ3hwIa>hA7dHnU;* z%%Pbe*O9lYgcYq2SlqktXs2j!`h7- z)@|IdVe{tAM~@yob?VgV)2D%M8wH~wK+_Nq=Ve?6%qI*bL4LviM>b#x{?4un3~bH< zkH}&M2EGFz%$RkplM^WT%hSa%#KQmWq}!9440s%_Yrojk{b=i}b&viw&3g5}K6-oZ zr67rvnvyxT`koJbJTmN$O#aht*`V~PN$I|=>OBjGnGp*$9DpZ;{+4JMBot{MU>LaK7(iAW9 zPl~AO$<>S7ado%CkEo_3Wu~kCvoCl(FI&()@8u4=-*YGRz3bWHEBAY5T)~gIN77!) zUO%Wf_qq0@|ArhJ86K3M;W_u<-w&$=lQk`*+(o`dicVg1xXiV>`pMae0gfpy%|btW rxgIq}Y}@Mm@0muNug;@h7sY=JSxN0hw@&K&fYPC-tDnm{r-UW|hh^&W delta 857 zcmV-f1E&1_3V;WY83+ad004~sxNVUkAAbM|a7bBm000ia000ia0czHX2><{C6-h)v zR9HvtmQP62VHn4sFPik3yW2+cS%5@TB}zgHETj8}iECjL^t!R)MM8m7ut|_#XEg8X7cQ zB-~011Q3m23G@THAoY@fG28g~xUH$F>1Ev9Nf9wC9L+FD;c%FO!64zs$!fJyG#af$UyC&%NHWR5sDBQ?Xn$;Zd3guj zH}aG)M}^%8JwSSHA*B?FL}+z&b$sL4iDbJW7t8bPL|Kwzk$n6bglCZ7qFZ z*koa0A-P;GnxCKNp^S!^XzOn{ktgkxa1% zpF)2&X_h#uinpL|C=A{1?rw#}Vv(vB=Ny%mmP%T1$xG-NOs2w8^RR#tB| zoAp-#A3gGv5K1>R-z1N_y1HuX>gs4}YKlfjM`tm1ANs-zl1Y9+^9{pAgd1f}9#VwT ztIh}YxZUp0OG`_?VD2OOccDY(klMXe&wJd_{135&5P2+cikkcT`*+YO=%@pkWCi`rP6&zD5ZBlzIvX1Om_TlDX5?);5du3P&*O#M8@F40TI`XNgq%?<9z( j_|#Dis;H>^-w^!<3~wH|jP41S00000NkvXXu0mjf2Y{N0 diff --git a/TLM/TLM/Resources/RoadSelectionPanel/HighPriority_RHT-fg-normal.png b/TLM/TLM/Resources/RoadSelectionPanel/HighPriority_RHT-fg-normal.png index c7fce5a098dacddf806c9df1552450825b1a766f..e96f59d0831ac43c0ca17c3799e705a07e357d83 100644 GIT binary patch literal 1424 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvNA9*GX(gAxB|s_czCR=tgNlA9UUD#Jw3g=yb===lai8>lao_YQZh3$v$C>E zOH0ej$|@@>tE#H1tE+2jYHDk1|8LR$zs;brv9Y$Yv%{@SHvfOJ<;amEM~@yoapJ`7+qduEzyI>(%U7>ny?*`r z|Myq_f4u(x^WFcSAO8RP^#Avl|G&Tf`t|Gg@8AFb{`~*{KhR&JU^D~>hJZki_%vWX zVJHdm3kD{ekqj7uzq6|X1B|o4BeIx*f$ty)Gwzs}{T3KNyq+$OAr}5`Cq)JyG7xBB zJjiV0z!c=LvPq+(Nyh2vw}k)y^|?IDE-#aP@!^C)jsEW0b(?R_RXbGvM1zf?>x5j_ z;)i~VjM+GZ7mHYOI32lsu(PZ5CF7OQg@#A2oQ{9X6Z|sq*`v;z%PWgRPp-H#Ge`XM zw=Gj&>zsDgIeM*b%Zz>VYYmR=;$H2b&gkKD>-4q{60iS9h2PH-XR+rF=m~!qTY0Eu zllgW=*|-;dd*?qY^>9CzFPFCI`SU}YUZ^xwpS}C|i*H_R(A9z^O^xQ~b4%|<+|1Nr zP~%IJO8#*A`v2#}r)nQ-@=R3Umoy{i*Ue=w_Q`!LVhItj3sgS(@tdTrLP>V>gVPh= g%-+$-EMyta9Pww;Cy~4ZyFkgy)78&qol`;+0O?mTO#lD@ delta 806 zcmV+>1KIqL3(W?Q83+ad004~sxNVUkAAbM|a7bBm000ic000ic0Tn1pfB*mj;z>k7 zR9Hvtn9XYwK^Vq&y$OMw6+#Y;UKEv3NJ{7_3AD%j5BA=FB01%t_0Y6AD3}Na@=SI}>*&voYIkOQ89|!_K@jJAL}j*S2P}*)(PulYfXr zaW=Uoo-@nbU{K};gL0V$&vabOGZ>VsZLrm9twRk_JsW)0owsnmuXVfK4U{Dumrq~P z2E7DsLEoT|t{ui!`~ChZ$|~G0pT0Ep6q}|QkHup3{r&yxp-^ZK^{8laVuizDOO%}u zrdkwzqI0bZq!Nilr`>MTU@)M1y?;&%3kz)IjpseB=&yTc0r@(S1lWA2d z6{3?bMDLyu{W+nntu0zyT&$w~zWNS~KExV)jIzYl?nm076iB4g>Du=8Hqp;dMDI&P z)&rssFgy54#bS|`mX^xscTe{|jIKisUE8$M23g=PruF6K<|fgv&qRmMh<|o5qf*CB zWVBEDe4gU*cnSS^15J(N=eTfsu-nyu9W;y^(P*?~XAYU7qvvjOQXhAThCghRkw~Q6 z>-F%uFKkmP9G7xcMnS{qRI61K!QoTAIVm;?c)Cx=9v{z360f=)b5=${!?=kI?)*Q4 zuaLp-R45b({Vy+rEWm59R(~pCW7um@$>cHCzF33U&AbM0>&BTRFI;_`6;&Xa&1P%m za#`$RY#83fNB?$lDwT5WVhQhF-o>Ii!a2UPzhtak4X6UkIBIt6HEExNxMFb*^7JEf zFVGIhuKqSC+wghF=b{LY`b{fsP!&ielgW-{Su`9DsnKWt?_TiAmmFI@xK`!&=gpLPP{XB+5!JvzFPfY&o3~ z7DBj?krXRdh?q4WGOe_Za;i&DKc(95MPQ;D22zBA=XvQU3Uc^HDVLWaIA6+s{)gx0+Y&dP;!M2TZKth`*74CyMn-}0NE-6M}<#O6S-;< zS4B!ylX+?^M}tezVp4QIT#XM`hv#aDJPpXz5_noXPlw^^eb!gw)*CQ9Be-6V;~VjO zJyB2%@(l#R3?qrBq3~yD$$Xu!KM=O47Fcfr_+}u@f=;&}(oP}-rw{@wLU4P-MY~te8w2M9wskGR-ux z5iPa@Vh12@M2gR$vYL=tEl6oAD!T=cwIXG0D0wSVevv4)_=v4ou?;WzoseY(vup&J z%~xz9i_K)Q#aC*fN=$wdGcC(Rm74ve7Jr$UCbN*GR*K9@%C=GDHmcm}mt&(TY*>jM zBXQuMEC(j55hrT|v+SVML6F%AG6$I5NRT&TWlcWvCY-zlBX7meG>TTDq6x2PA!XYs zaywb>@KrRB6^&Gd-B015DIFw56J4mIi}ZnFeSp|Nmly-H41rljhSb228W}QUfXoz- zZJsAT7AQBH~3quZ>7&+!3#S9BmX`w5u^ORQl23vsA#!y-r8*R)@R=Uy-$lH{cf(-wEd5Ar?5vg?Gq> z{q&vvjG}(VuKu9nyUg9Lpxt*DKr`GSd+vtpaYG>`?$EvNuoCyo35*^_ABDj@UW;JSaCfIv2dnv%8pky}wNe3n&9i zx<77zTf^R1{O4!&^}m?EzHEB9V|VVgFZY-BJ$T@J_|U1$K6ma>=?gDSRNcODFDPYS z_2l8vM8#rU^Mm1qTFxn})#k!>EqT3Bapr1c>ZShi@hztD0*OFNsDq}_o9x}D)R6tA zw%EP+g)YG=pAQYd;^B?lOZ}~_t#9?>>V;g_D+;;2eRXt0M9}l$#;K{PH{VCQC3z#t z_#PI}5l3m;!MpIy z6szt$lbC=jKe%r6_UMyU0_c&(k63;f=kAj1M6~OgJ3qKj57ySYJ^P|XLWSBV%A=whUfvii{Qd0sr@E5^Cr+F{*IN^@bb$hTI^nUaKv}V( z!?o?_>&l%#2AR=;*<~&|l@MMhX$xPW(%07)p4-v&7`kC^yHFJB zJ|7rIaj}*cO-`yvi@uADWH4kDPydb%^BUE=4{uy|*7ml_-#uj(ymj_o-&m=>m7MuF zJh`oHRq-ybAAZ>O#<|?%H!qJlPo^iW(w8^UK%Z9>GlJz{uHmM zkbnZkmYkQPqp!c6h_G}RjiaN5g(Fnw(4*E8na{!c`+ltXVea0Ml&Yh?M+V9-OB((= zwIxOox56#`1U}!I+fmwk?&|oh4IL{TSYl+uKykvyxjzy{?%kX4zQ6x#vF)ZC0_nz#Iif2atfBRHU_mFa8zyK_HyA$TVhPV@J?kf>+Nvx4k^L@FDbYceyjc6Tg3I&UIQR zjIpPvEbe#tpz>6ivvasvse$A5iUK)+{mOA?8{%2hXd_HsEnIPab94ATdhY11BzGm) zJ$Y@mXt=XJ3DsX>?krY?3?;ul3wkpDes)(Tspe`Y=Igd>V^l0@k}w z(}8U><;%#c1(~U(@e?c-y?xJ_l((b+v_g^?7*dYm^Tb+~z;XS}R^d zP=&yR_xLeI)N{(K@*sdQuR_e>&H?u3I-*~NH@`c$@Zfe;x)Pa2v4DTvlC|b3%7+VX zuvQVmED~Uqa>%Qdp=k-H!RH10s15<@<~F!3Zj;;gG=fYH@$ny|&E`GlZ8<*bw%1YV zkP;>sgS`k$=#dT{je#l^{E)CF4n!T?XVd0>ES!U*2OfEmuKujruOJg1oasLFIOf$c zH@Zazi-LP;LT^2M+SGs2j09;$tYaIojnZ09>*lt&P0ZtC%)!$U2?Y5KkvMl+Hs9eJ zo&XjBF92ID2!<>O)z=UfM@_G`T2_EMcl7Wg+CvN8+552PW!Ru#j2^-DC|M1Q z59^TO(L97Ye05!1Mxk|T8*IyMGY96voS2&sOei^w74~kojk#B%C-OQQV{@)TO)E6b z8*YeedWtSCqlkagVkhx}gaf!FE;$?sVoUGg(W8>)q{~#6Bnf`>?N)7 zI^L|@)HIXc5h3VGw+$l(dH{ohd*Z?IDD8ZjUr(AJ;t@pW%V}K7`h3Z&r#ZxFoUaU6 z*m6cx5B8DMrxd#kdZ5F>6>D1KLGOW+ambrMoacc@$cycQ9-st=S~7fZk-JMp5VtQ_ zt@8arCoq5R4-&=`UE)5?c4DI_YVdlt(K>@|TpvPhi|vF1xKx}xL0k=2Ft|5NYYv7y z4=P~jB`u-Cr%MiF8;1UBd14!t4e)71s`dck04{}fD}f;2Tls2en%xnZ6dl3v!1WBC zH#`iQ4tX4Eo{!ftkr$T*WSFD0*c%)bzyU;GY2<&&%|MVZ)lgnRY?V51k)CLe1aa?U zJ)oZCutdI~mN$VZb>ShQ=^R8H*VBT2(f{@bu;=Y85*m*-uAsu}cJ=@{OjPY9PjrFy z)b}=y7jd44=xTOxzSgUw!)s~)rG_JG1;T3#Jmr|lgf)8605PI%6hX4%sS za@)my{PMHo{K#jnWvy0WXSxrXtlf6oeGtb>oO`SiM>$?OFhJ*79irzMo3cQBb^Ld`v5$*NM`oXIyBEDWBbkF^G65Lc1`MwZ&HrG-0I9{CvXHmMfqT{?Ei_} z#$Sm>)n}A&*xaQS=EIbP7fUuvX8wO3vfX?6Yr=I5^103a=s9}fk=s0{a%X~&_LIv^ zV_Qpx%xOyn?#!E6+5a<@Of(-<73@}vC&(X)tPpz#nXEIyjpP!%c@~G3<-vuef8+C8 zEa3xY;|yO7q3OB7T2>DJj_V>uhrbu{$4nM};WuVL2E^J2u?Y56A29JEC|q>@%zyL) zW?lG#pSJhm4s9OA^^iXS<8otq@Dz^dPENr{5243#Nj?FuU@rb1ufQwg!PE<8pvzliB0000< KMNUMnLSTX%nlNtw diff --git a/TLM/TLM/Resources/RoadSelectionPanel/RoundButton-bg-disabled.png b/TLM/TLM/Resources/RoadSelectionPanel/RoundButton-bg-disabled.png index 6aacb026a69d89a312a5816edc7cff53430a0918..a194720e1d9c255485a0c0ce2f979d3705e77712 100644 GIT binary patch literal 1564 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*HX>Ft%knI|q0=J1Ybf<)>xlqynYS zPn~G%aX3Jv)jxQvk|?{iN8yP8)`LweIu^TZuOb*>n-~y@%ns)=}zl} zBrL@O8rg1sZT^4o{mrPKD?Rl!H5l*e_kA{GVkv8MJ6pJ~Uv_yR(~tR$+Iyd_ztVWq z|5CQDZV?Ml4zu`mUEiC`dgToZ)t${!!#`aX`c(PgZ_hqWZk~Hgwb}RX%zAE7%W%nL z^;78w4+JE11HM(Ymw(@O{_T0|cYhTAGR*l>w8M9Umlp#AGedw+h$}FHM!{$ZjMxy^ zZ1AN6SUNG31o;L3AK8E*_&d8QFd=XjctjR6Fz6|QFe7{PpZ`EX6;Bt(5DWk0AO0#5 xp&jBqT1U9uL?5v(=K9za*jjP$LHLjV_6$1HtfYh2>Yf6nCQnyCmvv4FO#of6+c*FK delta 91 zcmbQk^M`qYBnKM<14GZh9l0A7r!cxRa29w(7BevDDS6#lQz^KbyNfM9x-qy__Hv|?B&i0A3*=d#Wzp$Pzx!Wa|) diff --git a/TLM/TLM/Resources/RoadSelectionPanel/RoundButton-bg-hovered.png b/TLM/TLM/Resources/RoadSelectionPanel/RoundButton-bg-hovered.png index 7b562e7d7e683d6cb10cd6f077f787c7a45220fb..15a33b342822dfad8690660a87625d889d207d21 100644 GIT binary patch delta 2065 zcmchXTToMn7KUT3T2Pd+P^%yyP%GskDprpLMHDrA?`%SnO+pAoxk$YhL?{Hv4!Pe5 zfdDNCT5S-RC@}^TAw;4?1|x}p7_JGIcC5!4Qaf5HN07sLJ1>3ppKsQzS?l5dAJ(il zpQ=BVZTw_827}T29ZOMfku5`)WAG3uc4=}fSAoq_9Q&aW%vS*U4M2V)RL}qwG~(zD zFuf5dXg*e;1nJEHU5TaNz|wDG3tO;-Dr`{;P^5wio1sD_T-1y!Qo;-+RIGv-DxgRW zFm7WR8Z4s~i{8PaS{y?Sp&EQqBfhvfp0R`ykD@AosRfxj98-fU(c(&UaV%{dTL+Z1 zgRC|zs~u$PvFv*w#{h6TVNM&&)#JDZm}ej`l?0}W#8e_IC5fd<;Hcu6Y644*XKC)kaJ2-kj>J|Y95uq#ka-#sS4-mR5S|v{>j=EIc)mWKj~d7V9Z{es2n-}a8%d~7 z5Va+U^oYnn;i?mPY6?$76=)~|Ek&rKinLUbjwaU9#JWUrTcTJ`5gVwIHmXFQB-JNM z3{z7OI8hHyY=*>-VM#9}vA|LbSlS1c_5;#> zP&xpXJq61K!Lnz7>=`Jtf#pMB`3P9C#3)!X23C%Pm3FYw0m;W8`8ZTL230OqJA_s_ z;A%Ur+JP4u2_j>>xGP?4!i&3!5)(nvO%fXsiIF7fN|1ITr6y8oHzGA5((ZUk55Ck) zl=cv$=6Go@sjP=0HB!pD$g*yNtQV2>P-RA{tSeDwqLg>j%8j)0E_}5e|Dyx{lLM)- zlWH7Dtv#XEkx+|Hkn1KWmnJB64oclbV%_A@C4NYu|8KVQdX*;zvkY^Q023EKjL;8b z^N%h*|G2>rXIFh8S1sFsE;nEgA0+LKD;=CW;Bms+n7yyMr8F>jH0DkfyqAb)x3plU-@AUe3?odR<>Ld&Y3`%Ab_% z#gXl@41Q?!iE2;y;q@3>x*|vv7$o|-_WJ0ftc$X%r~jhc7vAkN+(WBVS03ehHM#T* zjB>__l-#>>g$a_Uf!B!$CF1)KXJ$W=MU}=`w{@biD=*bKgaFe zV)iYcSm77F8i^eb4f^*?aj0!9iEv?7d%5)$i@%j{1)v4V&`-u9(pay5be}xl9Kf8mpk8a z{`1z&*Aex{%hTs9R%=M=Wbm@ureNy191uL3nTakMjYje(=-P#a`ufeGp%&_lr>l?m z&uZ#TgDukOeyH^E^E1@k-H}qy8#|^nxnom3ckk}4`YLMSLF_p9&BZF$uvj05_8FhK zTQ_~ADUw-^d4loquK4QN#-;XkcQLo(I-|6BUK@m8t^@$MPowtGtlo|IMK=DadC5@YyOqS9Z!pK_26ay zu2y`sIC+b6zQySTGVp!-UkqoD?}%8nBB;vgY7cN|^ z+mm^4N`Z!1=OfVe!>QkRQNuVVlZ5H?_e6$fa!W}5z50*0X^XVRz`VJ^N;gb;z|__n zmyzLK*4eXtA=v?&R(u&_g^=c%#;Yfz^KX&K_o-(B0%OigT5b+U4vlWQbjoJS*+U+D ze}0U8$J^8U`q;tuIMm+7mv UK=;Lxk^enBY%F}ZCFVHmzii`6RR910 delta 2151 zcmV-t2$=V=6Z8|183+ad004~sxNWf^kO6-H32;bRa{vGf6951U69E94oEQKA2pCC3 zK~z{r-B{gkT}Kh$*?X?{NHj$#6(KJ?@efcT0VOT1nkqtw z@=#S&Y6%HN2>KWB#6v$&DnuJ3P+kiNlc>ZG6>6HA+Kv<7k8^hU{pRePyZ72o9Rz<8 zVy@=y?9A-$Z)d-c`(GzX=`GVk&-||F&fR%?t1X|3&M%0_ZV917TlBskW4tCVEceUu za=G%}l{cUHVyOjhk!~5_=YM)>c8_yMQ1lDn!y*m%v<5vZLn zR2Dzwq}8I+vJ2s2kn;Ht2XCMI;}c)oQA9ry;IY$-9aj_&Ks@Q4I|>j}u|#`SPwm9g zRANGnQxnCkfICi#DS{sa=iY$!c~_PfUVr>hpT67CO#y!C**|qUv(t}w?@xcYSRIT* z)D632Q`*?pGZaD7(oB*Uv zM{lH~9DrE5bIujr6%6+ed|CbCl_w6>lRHt0#fU7zK~UA;4i#-o>NDkl-ja0C|5x6hTg6#ZGZiNLsBL1=vkSt(vyL8Ub>xZpiXxr*B?X>q6FK zw#7DMDBC{xr;nZfGbUzD4M07zG1Et5oCZu) z&$CR=vvFHvr@T$wO`E_Fqs)dNv&5zVv2wb&5qIn1nJAFw6Xy*Y8<0srxjnCA%s!FF zs_tNa)XT2|+!5K%kdx&{yT&+^EH%n)Taf}Dkpc`M_V9m(z;><~gc+QM%JLj8%9>`q zZFCdd=rZ52I<{y-Q=Ey|75g}2^p2PoiLBy()wK#3Qx~y;MqD|@@_H2kQ%{B*l77=K zx9Qboq7L&*ddoYH3$4U8@1wq5YJfg0L%Hnme&9TeiB-lH5V47>jxw3HBsczMGp0|{ zt8eZ@nRS2CMmaHM#lZIq9$XX@AfARx=)`52!UeMK3<_k-k)WQYOs{^hHU71@wJkA8 z*SH|E11Cq=AvRb0A0_3|D)UbXFvg^#%JxYIMJyc!lbrY3ZHRhAE+LGPMSRKYj zl%+FIaT)XS_phG1Uw3Q;ND5{DJXZ51nFc^iRO^}b++>YNijvCU%4FJ;Poo2?FUpvY zMl1PRJ#3S06GJF_ZzWjcr_7gMy7U#?34a~due9U(dqB?%CY%!M{SAJ0e32;UsgXse zNt1uf)E2HWudTA{4(E668wRPq`r4!Sy{3ggO$153tM8r*;@^%~MWeK+p zTwWP5GVHm`Kh;qtnSh2ZQ4xPCGo6(AX=H!TC!O!ky@ODG{go5H@lZ zR;FiHW$w;;eoU~!wU&ULrv#%;=>*9 z;>W$nli~W+g}CxA#sWJKY|8l4f=o@`f-F*F5lnh+$TEMI^D}#wapJrHz^8Zga5sO_ zPao~pxA0~-g~$7RT*tQ5$BD>=gMTYXfO%@9!16S)4jQ&H*|m?4_LV5|oD8dCS}CBO?ApEPDsy_4i%8@lWUQxFI#*n!k*ICShwpy7q0l7-Z&lyfZqN zFwSSL`@zd^e*4p7UlVe=DL~S((|>>KxE5dh;UwR!uIx>P^{W7iqq6L84bI3w799Xv zz&5g%pE(9WL_fbp%(>q@cKF}_{Fak_z;v}2?(|L6zIN#X+^O&-DS^&rOhFk-YH*R=)IG>hw!-hyH4BXm=1cuFA5 zvV<}ID{SY{mH*x+;7L0E+}p))W_n*s;(qU104TFj>T5b4VE`D{aNsRhQI^`*H?G*( d`hP~w{R@5lbAB3QW>WwF002ovPDHLkV1j&YCKdny diff --git a/TLM/TLM/Resources/RoadSelectionPanel/RoundButton-bg-normal.png b/TLM/TLM/Resources/RoadSelectionPanel/RoundButton-bg-normal.png index 81f981b7ab7f25db1b0ab6a22c2215f0be257a34..9da7dc4e49e600089c51c013bffe3d26b13abea5 100644 GIT binary patch literal 2043 zcmeH{`#Y2g6vyA#NVZy2NvbDOR$^R6Gj28Jel@puX5M$qm@yef<2K2vamhoPG#Ztb zmV}V*%2T8@ld@72S|R0@LbcVSs8uO;`XlzI-Sd3D=lpPf`+lEu4sckMMGNg00sydx zMkVr0)8)Gsn45Zo162k9^D?&+2pk%L;J`_UkK7&;VOn?QA7QuWMX|?ty@ZMyFMbi1TiNXsPw8=sMdv`o=?f`KOlG9I2kWUJ=Qw zDE2=g8}=K1d@=SA6^xTjDM}vlkKB6#K2OtzaQfC=%@Nq%!`;% z*PJ>1@6F{(Tp=ZL?fr-u%l7ww7~Z3!nd zIm)*Pnj>w*jB59Rp9cyquW5Z$HC4b^@ju`uY4VqZkp z=*zqwo7+y#Ge;1!1vjydNKkSQerD&qS8wx)oBpmr?D4q&DEpi~Xzb`jV=bY_HZ}Ik z?2D5V>1%MGog}{V)5igeA=0p0RO}3=ak28){PqFu)S{?8ckQcfsAJx>3WStBdOWi1 zmAz_w()jJo&Q!}CuT)rCHS)v0$A!mcA5_-DUhexiYL+tWIB;TCz2UN3X@2qk!TDu zEto=Mk?Fw{I-9~|Qt50OgF|PU;L?M63>L^_^GRGHnMWe?$Ycmd;ZZ4)AexXyhv;k> zgDqnQa|A4|ki&zyd=Zx)0t&^TP{M~ygz{t{UlhWJB?4F~6v>1kQb;0&Lc(CNoFT_C z)B52%L5zTe1TjDZG#{M3~lE_FQREj z9{d7V!Ldz(LKi`iiH*V{S7Fg6=(rnnViRnl#0@TU7ndW&>#A`)?NjPFrp;Ic=q;igp5k_0sQ}2NV_C z0f3n$jfms>vi04c#R#0;%^jTxcg8*DL&Mt}2G1+r6BU76RCj&vt=ogX%Y+8`s;uJ8A`2Y2r*fjD7U!RT6qu^bGCKK`vc2tzpj36JYqW*p_gU3_b+#q%8&7Mo zwss{6lPlc9MnqxC-mR74rGtLH0_)9&(Q7%1g)``ME32%t*p5P+IjZAntu4KzHDif| zh4U63y7|V~?6mgFv9z`{S9$m5Zyn87UsD&=)PL&jE~hr;X?Ju_xA52M2rk#9V)dWT ze?6R7IiA0-NUhbvzlB8;mYP+aG+<`Cn(Ad$^1PJUrX~#1Y6Mk>{;(XcnV15tWlvAn zc=oE~KQ2CM1zm&BXkR;a#Z4^*+Z)s)A3WZ~diUh8`YO&O$DE^owRZFinb0W8l_$2K zGL6^l*V?NLZ`-#@*2V5o?G7uGC!(r+ev(?I|1yYq@Da7(xfwpM?^@3lz1hdQZ$GS8 zQCa47xldC3YuD5T4FL|L#lx-_8^mSRi8)v$4!s^asc-u`K=Wi1<^w@jLY?$)>xT)o z`2hwmJH%7x%4v)&}YJ6DcKWABIoB#j- delta 1707 zcmV;c22}a`54#YM83+ad004~sxNWf^kO6-H32;bRa{vGf6951U69E94oEQKA246`; zK~z{r-B{gkR7Dg&^Rc`4ZnxWZw=D7{El@s06JkU}5qJ<3Q4=5V!Dr)xfKMVXYDf%; z;2Q}12R=v)#K=b=F@V1CfDtrUD9{2?q3msUyX}75y?4gn+%8*|E?S@;#^2`LyLW%? z+&RBFbI#0}q5nEq<^IrEyQ59ECS-~tG><8s)WjMY!xNx2l^E%q=F0I3)SbzAw@>Zp z@q!N@5)Vyq)#o$gsn+NkPW)xY*b=lbk2EFGR3rWe1o2$LC5LARWUpzhJAJLsq@AJD zKYjY=Ku~9l7&F05n@G~y`Rg?o+Zcc6i%^tggAHNU-%OOZiQEv8FNP}%pD0`=iWW$> zWJt$`TutPVuP-z0?WR*#PaHf*W3uSK5`25#lM%)vD~Pd=g_7%7!49)@g4i7xtpH+U zfn6j$Els+$kF;HIeeRuvAMDnuboS8Z8?g3+QR#AhytOkGk$zFfS{+ce> z^*O{Gkn>=%vBHzYvT>pe#OH!p<%K-tzoeP)I#$Z_mwp(6$?M~R1UK$~GGip&J(={Y{7Ox-G+nVVmMU^ zHaE-ZSojy~Tr{kQ!YHZJ!$}aM+i);k3?~#06BJ?52Gh1HCsuztm_#ugkhZl;o7$=b znb0PLl6nxnSHE+UCWZreCKYl_lnfKpikeW^q>GXi9;Q+V958>xaV!?dEGh&!=N1Yr z?PAse)2S5g1(YHPmLT~Jo<@KQ!F6ioUIYY{Qbjmu5lam^QR}pmEhK_mp@e@U6E)+M zMdW13D%bsJGKC@mhXDnt5`+yMTpZTmj{0D-#c+VJ9F85KVHOa?*02Zfx<%_CoB)x8 zhp7=oh6Da~`$d21sS-5%R^vGk4@58AQXk$vm~bvmbor(J-qeiZ`BaC;HlSJ|KMS@ioz=4rEO%o=tI3R87JXU zk0OivNVXKOGN!g4{iv@SZ>p%Vpn=QzStLDsWotfbEls0_>1W-xA6rb@Mh8YK3*XyQ z)bgw;z88Nr7BskYB<;;zuP;b$`Le0JOf;6Geg=tT8U7fwIu5|F@`f@+m!&B*E9W4K z`La+>??1BnX0cMEictg&%npCv#@H`X30K7ZUUV002ovPDHLkV1gbE BElU6Z diff --git a/TLM/TLM/Resources/RoadSelectionPanel/Roundabout_LHT-fg-disabled.png b/TLM/TLM/Resources/RoadSelectionPanel/Roundabout_LHT-fg-disabled.png index 4a2982e5e3be48403177d91cd2b92c87f1e3f399..5f557502da196bda542f22caa2e1df37ed40a2a8 100644 GIT binary patch literal 1496 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvNA9*GX(gAxB|sFIXQK7baZufjf{-U&CR{Ny?uOqe0_Zb0s^9o=@jxnUg;t=_P1&BhID zH*Q$Bal?kqn>TOSvSsVmt=qP3+rEAKjvYI8?%cU+*RI{WckkJ=XYby<`}XbIzkmOM z0|yQsJP36EC>RX^vP0m7&bbC)K4B;c@(cbyvH?TzcXm}^Kyns%L>4nJ@ErhQ#;j|d zoWKAI^>lFzvG9L8`DWN*1p$YMxzspsvfRfWk56lvg2H^hTl`YGHm_-lnL&%v(LFrk$F8t-IV{;K zFt?YtG@)u@xS2rG)oqJDaaUZNZn7h8d*FqaN3Q8^F8*4yF*EtrtpnZfZXf>qefG=9 zB;)IET~-*JjeGCL?^=};6mHS6$1u0(SK0jMKa(fQoa{Nl{KJS@VcW79Z`aK5&_6%l zesb(g@4)ZhkM=4Cea;kKTGXSkroDM-`mUQzlJo8OzJ;(ion;VQb+6oX*8WD$y&Na@ z@00cI`f}vifjJtJ7T!6|^X;Oc{;A0`;|`syaGGfL%!uz;_O9LzmzJ}+h1=B?MAA8? zUTj@+c3!5_L`9Lx&<{DZb?Kz zR9Hvtmu*O7RUF2TZM(ft(IO&dP*7r-y%1roZ66GT4a9Z84U`=O9jUan+Gs@!A_xa* zAtaUxnQff1>{1a+n51R1idyOleJFZer{8n$on_wVjIXmQQ=mYB0{=lKCMGWR;!dhz_(--uKZx=qw7MS7`GaF)uFiV!r%|WNsPl zM>2dKj6{(Sl~H^I-HRgL&E-X2BY#K-K|(V+jGjZ!q7X*@B4&kacN5+~@6x`{skFd) z1nJ-ff;!nn2d@&<$tfFif_5heyU=bgmlakcNWuW&F(h+8JC*6FKwly~+O+M+bp_!h z8Y0(gPGuHyjvxuICg{=nbC|mmz1P>*cNy_hbe$@b@pAZ4(94|_n@9X4I)6&y({3>> zngoZty1H(ysj1o4-rg>=FQZ#@G8r$|QKZ~i$!d^0yqKWJd&H?o&wc2rmX?;f`ucja zxVUJ1KA&l9YgK7+`|;A(Lp-e*Vfi%R##We{QSJx+}t#?v$JMx zZO!!b^qAV(T0Ma-qzUA}sD)9KL*@94<4Na48gd!D7A?4k322r+&%iwx2m~B+b8~a< z8IPHn8MCpmVS0OeW%41a4k2A9w1&peN)lgAz-E%9 zYTD=b`_0PAiit!bj@h!ZGBY$Z6dSph&{w)326@%@4)Xr))?7HW4vz6oM#JH76jRah z@$o1VNH;Ws5|)voq9SMAlR@w1{~1WO9qmz4l)SiVC;7O$yMH@6IyxHd=;)BS4^YBR zf;q9>D_UXuv7mPP%pX8I(Q%2#6aOWn?d?rw?9BrM1A3f3l(Iz0VHCV#POJG1T;kt-hlO5}Ikc1lqeMM{3Za`WlYEV4iBK@OeGxs6VqHTq> zL6ToiSVVgN^nV|62-EsPwu0+5Sw2V8=z!{MuztjXPPC_LbpAjuqL0uKjAq)eb&b~1 zZnOtILECp!Z%bYVXh$)b(h;z=w(J?{g zO_jH7FdmZLM9?GDzp`e#elPVue438FA!a4Xpq8O?F(QKn3jCXR6QscZ31j{Sz5I=P Tp=Ske00000NkvXXu0mjf0EkZ_ diff --git a/TLM/TLM/Resources/RoadSelectionPanel/Roundabout_LHT-fg-normal.png b/TLM/TLM/Resources/RoadSelectionPanel/Roundabout_LHT-fg-normal.png index 7c0dd48e369d78f52e7d484eb84ecfaeb2e632e9..2d5d895bd3cf1b5f6c067c0f447061f8f431ce52 100644 GIT binary patch literal 1530 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvNA9*GX(gAxB|sFIXMjt4ULS9OiWB19UYyVoI*lELPJAiV`Jmu;*ye*Qc_Yf zGc&WYvT}2C^Yily3k!>iii(SiOG``tZ_)n0&7iflwXLnKr>AH7^yxEZ%$PZI=B!z> zX3w6zWXY1HOP8))yLR2Wbz8S?-L`Gp{~MG3-(_7JzJ34x{r}Go|9^e@ z|NG1T-(P?H`0?}S&tJcO{r>&?|KFc~|Ni~=@8AFb|A8Se3Px-QbaZV8<^e{Ak|4ie zU}6}_fFbxhyDBgta29w(7BevL9Ry*<9TT(P0t2Yr)5S5w!vF2$n_-6xL|o?!@De)9fzRNl~KchK5vIT~&T z;YSSRrbTcpE^93pStjxLp0LX+CxI7>`sbWzJmX-;(x%3yyUY7TQy4?zq>eIaCdJ7H zlgd6FcX@Nzife-TiA*uO0Z5=rM6mXJYE|gV*-Fd~&Vw?&JL;s$QF_ zzZ#camk#hg=CUa&XC4pNCrhnkuA3_E*iXqzopr0NNRc1ONa4 delta 1051 zcmV+$1myer3&04F83+ad004~sxNVUkAAbM|a7bBm000ic000ic0Tn1pfB*mk)k#D_ zR9Hvtm(6RGR}_b5ing_+MX4KwFqNc5P_%?V5=KEx0$qwAxDsrIiYpiX0R>62Fr{D@ znIyCdCW0wRm6}<`g~`rpX%>}Mqllm=6!AMV(c|-b=S(u6ab_|Jg7d(S`<`>}J%8_+ zJNN4i)u>Tpg)uXKstzA``OZ>Nf{fC~UamtQNRv!kQq{Ls*l+3f#j*MBy9HEaF-{np&vJWPGwJQa%Rv9lIgS>M)6LUn7k{@b=nnhz>?7;y>awP$rWozDfC7lAO+3wObjhpAgN{E) zZf3F}5{aA-MvjrPnKRkRrFHkBS@KzsWPN?TMskBX6H|*MlU?$c4IPUmI59jt97ML8 zrwS*RmXZYh-SnH^Bypuj@s_*Fht7wQet9k%8Nmy0AHhEu!Kc>U-G6PgpC3U%-1I2^ z=&tgivlhuUH*?V(9ErtP7{MIO8Ob|i^K+2ZtU35qs@np@)>&TpA`t}8&R^_W*4o+G zIWjmn=&P6oqg6b!u!^J6Xu(yinCK%nmj;1~3U;#9TnOf5un(RL_CfvqjNDo3vrZs- z1p6L+mEhZs&e9>+YJc>Nf}-5bHQL(RIuVb@EtyQ(*w~nH?B$&#Bo{`j-K-uYq+h!R z>3CwpD|iRgSv);8HKnuoDt1KvJSoW>UsWK`=ST^P8%TG-+_SdS+sr06s|$gdV3tHe z7uJJbRT8vUa=H)pxvP2*^b>Rp34Mng@T!uaz4pC-5KDat7k`AsAn*}%0PRP*iLm)C zzK^Ni+o}D2cb81rpPgxVnJ$}$(RWBAas}N$vq<}!u4qbr4*h~+e1blr%!61|X@RGn zDP+HvU2%e$5Ogzz_B(wm>+|v@()aLRyy!aRqU0o~ZRk}x!5TGI5?>%S-X}t#H|)!> Vcq{$atpET300>D%PDHLkV1fxx2?GEC diff --git a/TLM/TLM/Resources/RoadSelectionPanel/Roundabout_RHT-fg-disabled.png b/TLM/TLM/Resources/RoadSelectionPanel/Roundabout_RHT-fg-disabled.png index 3fc4e20e007f32d6ab03824c1ba75c104ee50c70..c2858aa558b1be346aa96b69f1333531df6f40d2 100644 GIT binary patch literal 1493 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvNA9*GX(gAxB|s_czDds%`Ge}92^`R9UY^hqGDrXR> z^78WY^9u?J3JVL1i;GK2N=i#hD=RCjs;a81t7~d%>g(%gHw4aZ3hwIa>hA7dHnU;* z%%_Q`VI2^y-mq@X#tmyXZdkW*!-mb9 zH*eXpW$V_h+qP}nzJ2?S9XodJ+_`JluHCzL@7c3w@7}%p_U+rhfB%642Y_xK1*0KA zl@KU9U>F6=Ck!P)e!>4oHed+;&aMg!RL%mA$YKTtz5^i4n02j_6Bs~2o-U3d7XEK1 z-3)6s5OBDw6>>2vc4hY6RT<7JCJ21`e_wR7kJy4QKh}L$om}9VW^_|%|C9JTCmL>q zv}|Bgo7H!sYfp%>yU^aG%uIfQdjUDUnpZl(;_O3vESH1dj`SR0;g=g$cRlmiv{N$s=Z&P~L zpShyS_h|c`_}cd4?C<+CXW6A+T>3BIX3?9z3mq0GpI!34e0_b!BC!>|m%1YIEoLcg zoo{wAqV{#?5fhzF*86IX?V8v1^6LVLjQQs;hFsP?Rya+%3F(i$Lkv)78&q Iol`;+03vuJpa1{> delta 1197 zcmV;e1XBCe3(*OX83+ad004~sxNVUkAAbM|a7bBm000ia000ia0czHX2><{DW=TXr zR9HvtmupC5Wf;fb$!)v2&|)HH&{Zt63lY}Z_Q4NAfw)fSlCmP{NTsdO)+XAA2o?t^ zD2eTYSuAXZba70nKCK%hMMW$jl9rg_Sn5hqLEFvK?|;r28)s+coDudzFn{>*oPYD4 z_kG^yJn!uslT}t(W%WPR`1trvm)-9Dh4zCC6>#mgMaNfRuBooBKH-!&qPzuj7yN1$ z81p^+LcQ0WTYuVCfNnM(f>yW;K7;${+``(TPCe!rTm=6>4g{$a!TQ#DuJtWCuEorQ zvhy$<7J@q749?XE9Dpb&xW6D{Wq*`Gf(v8n-~j^q#4b!D>hHiP%g?~m@C3X=+it8c z`OYAnJ&V~3d;A0^QSWbzhQFKZSFw9wuj|W~d}R=aAM zPoW=Qui1rZAr=_Ju!M+SP>S3Z>U&led(<*I%yrCw!hWDslkX(1e;f98W%Brd= zv$(iug2AAvsj0b_@*cQFm6Aw4Lv9}_<(0u(;WTgjopXDZ?tp{)P+eV}Sz1~$3kwUj zC5xuAva*rqkHF2U952`BX@5{3DU~un-fRN%Ih1j2f%dg{mBAr8s&8&?HY+PDW^QiI zY;0_pnVA{0y1HsQJ3CE9MTJJ79khTF^(AaCK%~7ZewFJ!CauyVByN8w6taVxot<@_ zxSF1xHtXx_rmL$-BmC0r2iGO*`!S`GnpFQco(9qEP0|Nu5sHn)4l$5x|TUAz8 zX7cm%O*kAj6B85K^DcLuY^n%;bS{(2E5NrPnvgw7nRse+boA}P!9i0{P+*FSw@$Ir z(o&O`muLF=`po3yq<>BkogP2f5C7Bcpm~^5o+k;5;{wc|1ey3TAl(UvYHMrjo0^); z^768opP#pbEi5cF{r&y1%)JO-t3gcoRo|E3H{Is%Ega>#&QeMH;3#v_8W|a}2+A58 z8?#tIdZ8iMvPuJiK-zupTuCR%iH?pAD-wxVt*xyJ?gQ97Nq>0B9n9NZ!^6YXT%Ye2 zd&<|xf=}sqJI0E=p|`hJ!x;o^BX)3@8ev)1Ph?Ri%$XF^W{Z3WNGDfg);#9SSzj}> zQx^4^b{MXO7vKnf*0G-QTE+3wM*ATh>T@ZTzJ*;7{}Sb(ZA!uE`!L6Ea8f1#9)v0Q zf*{i#Pw^s{H-9jCx!*xUy-53uvA&e?9K`wknCIamI7$F1_c7{fpX-2o;4#<r0yf;!N4JXlzeh?gO#wMDa`?nz6q+Wko^i>*Np6zIh!eI1T9_yn?Tvu^B5dK+O;P z?<-w^@uJ@K7!A4pkM%ox26Tp>qWw46tg^~TntSeLRvKBIdl~aDr>u!7Lc9DL00000 LNkvXXu0mjf9~D`e diff --git a/TLM/TLM/Resources/RoadSelectionPanel/Roundabout_RHT-fg-normal.png b/TLM/TLM/Resources/RoadSelectionPanel/Roundabout_RHT-fg-normal.png index ab7b3203b52e46611356237146ed0a06d6ac597c..7f55b2098f3873e25123bd356a203459fb4d74e3 100644 GIT binary patch literal 1531 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvNA9*GX(gAxB|s_czCR=tgNlA9UUD#Jw3g=yb===lai8>lao_YQZh3$v$C>E zOH0ej$|@@>tE#H1tE+2jYHDk1|8LR$zs;brv9Y#r0wj4Qf>C^@bTlvPoF-0{`~pNmoMMGef$3X`~ROG{{Q;)|M!>wzrX(Y z@#E*upTB|AL#v2Fp@)nU#N5nFrP4#1o;I6)5Ayx z48h;oRe@=Nv%n*=n1O-sAP6(=n3(+*7(f-CE{-7<{%Dt&?>^ z8@ZK}jr}K2=vgMV@!y$8oR+g%-@HuCGHjWcD|79f^-t3kCDGkkt;NNS4OCoR0NtJC&$)t@cXE16fjYEA6mT;BD? zt74;P@t;_)FHh#r4L7!{NeQn|t`MwEHr}xJ>R+w-pVwvHUi44syo9dSHhwMfn(Mm* zw1bqQ^{<_?YUK%;wdKS#zr&9$PjEWBnEkam*na8uY7N!HE|t{+3yQdw=e^ z_sp65?tS;ZOp_)}?jmO9wfb?7m;YNDmLRivzv~gV9|(?=WWB5ze)w^UC$rh?JoOA^ z-2OU64&4k5nar=~2L6vDvw>(f&^u@e{f5q>Eb<tjYHWi1zzOsVN`E94L%Y`^u$APS=yxwQ_Jq6Z3xQ9fuh9W-+5tYV zZ9&^%bj<4qkYbz+&U!(><4EhR)tjpE6w;=s+D|b&)^Tsz8wA>qR?rb|szz65XXlR# z3k&P5t*zf;w@1x8Q7n(S-AFrZf?$s#iGs3%veW9M}L9#Ly>zY zimBLc)&>Ez$hBiTy{QsM2L=YtO-@dlt*x3}{LpM;&Bn&Yth>8=3jg7#TN1_e*e%|a z9tL-#B{wV4)8F4eJw85e_Rk+?Kj+N~JiV(VTfAW-BO}(=*Ed1G=c4XO6kEUHW;z)7 z75W#&oOM^svpm+%M@L7^Zhx_yE}t>GaA-@{cz3T|x1pgS>+0&t(_b4X0Wm*8wQUv# zzM!nOv3-*qY;SKr7iNx`vMZk^lZ&-{!L0OGNV2W1O*45g8XiH+_aryd!{DpR49aJ3 zerjqe@?2&TDkT?7NrE0X;}S1Qn)jUGDFuh}SIlF~;Q8HW@JnX!Pk$R89ya<{n!yS5 zmYeBeur|rEo8@Q?PUrJ%jIajFX7bwX<{D%-YYjdf4cmg)-|IKrtPKL}L)ETjy@P{; z(-RX+MA*e_813RKTe~=y%T?UPiivhRnRZ7(Zj+!m%B$vlSd-yBcsjfX_4t{&&+zNi zP@G7ajNYxGemBYW_J8)y7YYR{l}a`{J8K+!iIaqcT5M(IVOw2&k@|h!yf@;1dM5&% z#Y>Bei#m(H!`?iL@yB<=Gq$mzBkn=8=i7V&0zQFK-)0!YjtO_cOGqfeN8MdN2+9r! zcezvxoBqd;F07)2PP?nV5Lk~%N&bX(yLu&{|7$4zK6w{Cs5U8`=0Q3@aX+YE&-=pDvm@0p38mE`5V8p*6G*>3XK**U?8P zPps>dsVPtJUILZeuA1O>==ThT9=X1c^>Ka+=^OY5#$Tjt(j*mHdtPnQr14}j{{c}0 Wt1kIHsowwq00{s|MNUMnLSTXvVgg+N diff --git a/TLM/TLM/Resources/RoadSelectionPanel/Stop_LHT-fg-disabled.png b/TLM/TLM/Resources/RoadSelectionPanel/Stop_LHT-fg-disabled.png index 3151b24a64caa0e04a11e05e234165acdab6e90e..e3ae3027df0b00083f6b1d9d3c497b7efa6a40bb 100644 GIT binary patch literal 1453 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvNA9*GX(gAxB|s_czBHD=YI4m6XiQ%`Ge}9F&wC)YPIC6k-$R>^78WY z^9u?J3JVL1i;GK2N=i#hD=RCjs;a81t7~d%>g(&<+}$Uqr_XK(oZS@M)z#JA-Myft zWl>MhvY8FbXErUL)x3Om+lo0IE9Q2toZq`*)~uBa`d2NOuzvme4Qp3!SO-L_H>_K; zal_h;8`f>yuwnD&&0Dr?0eWW?jD`U5A>eo~q#u}17)pZtg8z?fz!3bMT@@H|oCO|{ z#S9F52SAuH>slu#Fo3i?T^vI!{NGM~9dyWn$4xL`&w``UtZT(yvu>>rcXeI8=KX)K zY%@;hP1|Juy`K5fxcZC7di zKB1K(P~JbkzUX_QNb=hWi(<=^WGnX1w&j&O7T6@a;D}^;;d>AZg|!a00t_K9XwU#Iu;_9w0X{If}Jjl`uD3H^UR*>=r17|qZA{qYM4 zYlp5^GLJdV8Co8=rRbuc_V%*p!Rd;;4`%4bz7J^hxY!?=SoLRyW|5q2?@YIjxHC2_ n7T@DnBz@yno%T`OHM^c+-e)75Qd#egTe~DWM4fIjI7U delta 879 zcmV-#1Cac!3zi3v83+ad004~sxNVUkAAbM|a7bBm000ia000ia0czHX2><{CD@jB_ zR9HvtmrqEOaTv#+Z8Qaq4uLpgjF4#{7K~7E2VHm+4_!S38s(HuLrn>SI(Uol5FSFo z!wyZFPU%>5*+mMfDXd6jvtdk61>y+azR$DwUF&tz_pR4P@P6RS@6Yq&<-6aX=YRJb z+1S|F*ciqMU4|5g!||KAPmS@Injz*`RSaq-EybahMqmR3L(c_y-`wj9-%W8Obj(<~KU7eKba6LZg&D7M?50vkr0C!rAET`U>CN0hb zb+kh-hK7cecs#C*j*jw}mr#&{C*e{{BgCOFS73;X5@jd&3iP#D6}WwOU|`@n_AG60 zZ&M%;-~)Ftl}epQ>c$Fb_S4!g_-$Y$gS1ZaF93357y8!r?IGa(_A6+S($Q z%SByXU37SOcqyGu^S)$*Y_uYl=BzUKAVj*myKj$=k5fLMr_IgHVg$6dwo-F*GtJM> z6Hfm#bUlRl#~s1U3>w7)-GjMXlarIQx3@c{wzaj9$K#=eg#}t!SxKOa4`5D$Wt_$m^D?Eg z*{nO0$z1L0>!XH-1~IC^GpFsrL?RJG*L~=-1a+9XNz6RAK0;5D$$#Y2+1XiYYHE@h zMEOi1XbM!W@fMhddHP2X@-}G(~y=2xy&N>ox?%s=tiU%gRMYjN$V5iuYw{8Fc002ovPDHLk FV1i8=rdt32 diff --git a/TLM/TLM/Resources/RoadSelectionPanel/Stop_LHT-fg-normal.png b/TLM/TLM/Resources/RoadSelectionPanel/Stop_LHT-fg-normal.png index 3d48550ef829c5a3d63c9d56d3797740966b6cd3..81078d53733d44a00ce878276f8753cb322fb0ad 100644 GIT binary patch literal 1468 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU3?z3ec*FxK#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvNA9*GX(gAxB|s_czCR=tgNlA1J%`|m6gkZNL#x?S-C<*#nI8x)6>(-%PTQ4 zF)1l2IXO8cB_%U6Gb<~rw6wIWtgN!KvZ|`8y1Kfirlz*GcCV=D1%Cbuf`U&N7~V55 z{0AaN#{V1~|M~g_Wr*``~NnB#>U3x=H`}`me$tRwzjtR_V%8hp6S!4&zLb| z=FFM1X3d&Cd-jqgOO`HOx_0f_b?eq`-MV$#wr&3#8vbwE^nd^U|2HQ6zcKm$t?B=7 z&G>(J{{OoR{@+{t|K5`SkJkNvwEq8-&HtZlIdbI4(W6KIU%U4I`>X#yUjP63?*GpZ z|9^e@|NG1T-(P?I`t|$w@Be>){{Ihj<0u%pA&|(oQxcd@7)pZtf`N%)Bm;)v@9e6; zl)zcw5n0T@z;_UY8Fx&~ehUmBOHUWa5DWjelQV-4Iq4jdK_t)dH?$PYYWT*F3SC|nDWzU^BmpKzqKz+eBMm>EVVx9 z)bd+_T-ABdH+9dvOfURwVpR;ROpXUDBaQ$^oxeAMfH}CAec9kiFLGbR3-a5bA zObSWiXMQa^-YePM=UpM_K>? delta 899 zcmV-}1AP3v3#tc@83+ad004~sxNVUkAAbM|a7bBm000ib000ib0l1NC?EnA+KS@ME zR9HvtSifsiQ51d&Eo4Xu9WqoX8Im?bq?S-fN^ojBWl~4~khWWvcIu=<(q>RF5fqwe zZL^sy?Wk0RAVMohT@}l1Wja($2dn%cMiM{cEX{dp{bj} zAnp5nh#;BB8jo>~G}jJAQQ~4GLi?km=phuyCYMl2>pZ*c{3LO^d4?XefzPLD$Hy)` zas-`!GiRLYYmiW0Af!&LVB(L*Tk zDaNiL$2t#)1cSlS=H@2VYBk!~*`Zi0R)(Ii=1LSriN-ebqKj<(?CflIZEcOH_J!ze zj;J(E^d>{};{$DMY|z}?+(YEWj5!ip1p)2!3osFlMl&lbE2!8p(YqqicI2D~cZp6v zQaYXH*Zlzbm#sbwwhB7TeSd~EuN{H0@$vDjGFSgjbhO=U&fwuaRavfNAQ0f!JtjV{ zMF7w?ZQ$tFKm#0`(G+vKdaaCh<_sR(QEB;np68X(RUXW26)doh|B1jDDw17YT}1`I z!Q>O!Tyq5!lvNA9*GX(gAxB|s_czBHD=YI4m6XiQ%`Ge}9F&wC)YPIC6k-$R>^78WY z^9u?J3JVL1i;GK2N=i#hD=RCjs;a81t7~d%>g(&<+}$Uqr_XK(oZS@M)z#JA-Myft zWl>MhvY8FbXErUL)x3Om+lo0IE9Q2toZq`*)~uBa`d2NOuzvme4Qp3!SO-L_H>_K; zal_h;8`f>yuwnD&&0Dr?0eWW?jD`U5A>eo~q#u}17)pZtg8z?fz!3bMT@@H|oCO|{ z#S9F52SAuH>slu#Fo5JdT^vI!{NGM~8Ft7(!0qN8fnMn?8KP^Y1w_oZXho&g{15MX zdFG0jXVAaHw#%1KerfADxlVVbWn`D1PLgj%mW{)iq@@!(db#+8dmeFBIlaj#a84HS zy!@unIazG6+?T}Hd@SZB!AUdUD+wtqdi!vnYtFqjfd{#}V>iDjzpoz^5&BvsFRZX5 zCF%K_&viv5U0YvQ97_0OQPFq%y2T;p_~Vm2k4`?^udeyj`%P@2I(v7WK>rr?r?OK@Qoqw^^cwgPmE%R+QzxUWZQ&IG4r9quU&$6=I&YOiR z&KoY6yCeBox%%`ksa;8B1-rdiGo_->Z2BT{L}#f+TK$JZ+h(NhNd7jz^1oB~8Lmi| bz?JdaBaCcT%>I85l<+)V{an^LB{Ts556}OV delta 891 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 delta 929 zcmV;S177@;3&#hL83+ad004~sxNVUkAAbM|a7bBm000ia000ia0czHX2><{CTuDSh zR9HvtmS0GdQ5eSG*{0?nN>VTb*NsMV-B=KACgp{6AxZ^-cBS5_7hQDG41ytfAs8XV z2tw#8@J11ffuR?oH`T=~!l{wEWdE8>n!&X8^}OE>ICS5p>zfAd2M_0*_nhr}IDhB7 z=N!tAAwz~^jz*NKq0wk^MKuu;2#b0`R5b{5{C{&=t=3pjP!J97A{Y#E(FcQ%{3nZc{j{pRN8+b~GH>6e$6NvG3MU0oe{z1~Y`YcXa8 zQZo4lO356P$e&>&Ct@)5?=un2n6IauD-sWTrO8N#HWE1TIV0ef|b>w zh(uclN6Fw>=qYCIPDe)vd4D_}T3A?!_6YobKNS`hQbR)nFZ&gkJc;lJC?pTqA!T!n z(#D-^ZEd{)(aOpSEiNvK@LrIiR9ad}0|NszH8n-!ohqTU#C#ZkhJUFNWNTGzZ7pSI zXVd!n&K5Hm3{+fPESsC1oqd7O0L00nDv6TB2f48KPKCqaD!x}adp9;VsIszBUe>|E zL7JYP=9zmAec>OeO|oO=JLH+4pFe{O|3Xbo4QD0k^?Di_8X~*h{u=$yAO{a-(4Pxw zlZe0jC;AI@kZ+Q%u756RbaYfgW-Hz#`1mKxv{Y176j$hHJrTo`a**qX@8VZIJv|ru z`ugTjzXk2tbNKj?y$3lv-(k;npyWf`&%rnx>3fh5#6oEIVZ56odk^j#EcKzk2M-Jk z9ol;^C1C2G--BrfzHE?5H2*(fj-Oi@GGsWW5d8%|QD;*aaSn@}00000NkvXXu0mjf D%?+^s diff --git a/TLM/TLM/Resources/RoadSelectionPanel/Yield_RHT-fg-normal.png b/TLM/TLM/Resources/RoadSelectionPanel/Yield_RHT-fg-normal.png index dd8ee54ebd063ba0bd332735e3f91a9ccaacd79e..31e5396c9575d7c86da29cf396dcb8df0df6422c 100644 GIT binary patch literal 1446 zcmeHG`%jVq6#dM^RBV*#Txqyc@;PmD&0&sV5RXzEx;eFFAWosCEyD#qnj$(KL~0wT z`KYjIDNaLXmX#CQ)JBgrbC%4=nU7HBPz0*m=igyx_uR94f4leW)TgD=e7%o)BM9Ql zpi|hWhVSx#JKA4_&~s67D`C@;5sfiu1s(PmkWm%1{K|7u~;IJ zn3$MICX*Qq29wF;a5!8pH!m-b$K&z&e1Sk96begAOGP4)SS&6pD=RNAuc)X11OX2Z z@bUsI7H~N5^Mil@z~g~HfQSf)j)tTppwofNh5URdECjI_Dl0)71-iJZsw#;@Qd3hS zl}c-CYwPOjWHOmjsZ^;{EiEmrt*vcsZECf;ySux;zh9%#3=a?MbUKhoK&1k;8is~o zwh3mNVNMBiDwywt`7SU$0+Sld8ZZyQ;xky(>h*eq!2q+fu(SmBRoGbr$2wT8V6(yY zHaM){+ys{mTw6}3)8%pjT7Mh>=w<)0Cq8iF-nVo#C&*29YC7usUIvnG_Y6Z#_qtBc zDnXEg9ufGBReE*+mx@B>iV1j@`=IR zQ@#Adp*tAG5y!f1nMW&@y_$R-IQ3rN`{4BC!dXnU^B4`^=|N*?4{jNrXBkEOp!U#( zJCmM9d%*{~K##dkscXiwCVKoU2e&j{{vY+@wtY+~>(^Yx*P?SN@#fq0Z~Xjn49%7A02^d_WWvbg6I6an~B;a-Fm!e6^jyMs4 z@b}CLOCk>z|FB#b&6Hzp!LAt}qj7C0pTq5~Gzicia>Y$N0qQ0;M1*S?QGsiYiIwKRBEe?)$WH&erYAQvO He5Lvy-!NiP delta 865 zcmV-n1D^b*3y24h83+ad004~sxNVUkAAbM|a7bBm000ib000ib0l1NC?EnA+9Z5t% zR9Hvtn9)m{cgR;y-!)vDnGto=4)S?)}!oFG6lQ!cC8254CpKUc-&>XFvgW6!Cb z9rHQH03X@)lVk#{DI(X=(gJL60|y6%%+Irj?2?P>SOwLr8j%P_Mp(?#;UVDlvQ_S} zrjJul&8iW(Om?xp&T2-Zqim74EPv@^N}!shpl*;K#G|zrAo37hT|hbw?CsH!L&6j) zeaoPl8dPs*XXonj^73zw$McT$lP44Tgm4%L1Xz>DYM&EOO(&GUzrTNJad8o;R0=aQ zGwA5(NYKBf_0J*F4YxZ5%Q6eY-Z4&#YUV=)hK7b_CnqPlbA1Qap8|i9n17gcRd>jJ<15x(7t&Oh* zs%fBlcv)YELLuPj8?f;LSl|`SvK41W_Ye#Q(c9Y_W`DDQvSV{%&6Oz@$l1>*fBr1G zDRR~8_0HOvW2UhAvM{(TUw;?4N`Klxwzs#NOkUM~PotEI`Z*2T6j_>@nqraKc&-PR z#RN&2%YFR&1#%h%bu*Du#?Gh6uuYL`%;4O~8GOSG9$;*2jE98x{4!{u%sn_AHv5=; z4>~fr70ca&T+QYlys7<8DN3oRpVP>P@(m9UPe-HC%qr%BF{^m<-+wCh`~78Cu~U_{ z<@#u5K2(5P&76Ht+WX)Wdml8HpP75bc1D~xM#NnKmkP#|K{cIFexJ{`lt?6aw5Ab@ z#lT}vKS@N^;Bon}w@$d-A0(OF=WJK(8BeMD{&5FB%F)p?em^)%a7OiiKWJGl2A9s% rPObU}Sf!dTkE&HOz-rat0gC(ue3#(i2@|IB00000NkvXXu0mjfMaZQJ From eb34bdda37849478e1e3fcdf18df44bf215dee83 Mon Sep 17 00:00:00 2001 From: krzychu124 Date: Fri, 14 Aug 2020 03:36:12 +0200 Subject: [PATCH 4/7] Bugfix floating vehicles if ParkingAI disabled (cherry picked from commit e32778ac804477d1a76a895a18bc36d1a4283f84) --- .../Manager/Impl/AdvancedParkingManager.cs | 44 +++++++++++++++++++ .../Manager/Impl/VehicleBehaviorManager.cs | 14 +++--- .../Manager/IAdvancedParkingManager.cs | 25 +++++++++++ 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/TLM/TLM/Manager/Impl/AdvancedParkingManager.cs b/TLM/TLM/Manager/Impl/AdvancedParkingManager.cs index d738359f4..a8aca6101 100644 --- a/TLM/TLM/Manager/Impl/AdvancedParkingManager.cs +++ b/TLM/TLM/Manager/Impl/AdvancedParkingManager.cs @@ -2883,6 +2883,50 @@ public bool FindParkingSpaceBuilding(VehicleInfo vehicleInfo, out parkOffset) != 0; } + public bool VanillaFindParkingSpaceWithoutRestrictions(bool isElectric, + ushort homeId, + Vector3 refPos, + Vector3 searchDir, + ushort segment, + float width, + float length, + out Vector3 parkPos, + out Quaternion parkRot, + out float parkOffset) { + if (!CustomPassengerCarAI.FindParkingSpace(isElectric, + homeId, + refPos, + searchDir, + segment, + width, + length, + out parkPos, + out parkRot, + out parkOffset)) { + return false; + } + + // in vanilla parkOffset is always >= 0 for RoadSideParkingSpace + if (Options.parkingRestrictionsEnabled && parkOffset >= 0) { + if (Singleton.instance.m_segments.m_buffer[segment].GetClosestLanePosition( + refPos, + NetInfo.LaneType.Parking, + VehicleInfo.VehicleType.Car, + out _, + out _, + out int laneIndex, + out _)) { + NetInfo.Direction direction + = Singleton.instance.m_segments.m_buffer[segment].Info.m_lanes[laneIndex].m_finalDirection; + if (!ParkingRestrictionsManager.Instance.IsParkingAllowed(segment, direction)) { + return false; + } + } + } + + return true; + } + public bool GetBuildingInfoViewColor(ushort buildingId, ref Building buildingData, ref ExtBuilding extBuilding, diff --git a/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs b/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs index e7e5ef3f2..d0bca5b33 100644 --- a/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs +++ b/TLM/TLM/Manager/Impl/VehicleBehaviorManager.cs @@ -241,16 +241,16 @@ bool citizenDebug } if (!searchedParkingSpace) { + bool isElectric = vehicleInfo.m_class.m_subService != ItemClass.SubService.ResidentialLow; foundParkingSpace = - Constants.ManagerFactory.AdvancedParkingManager.FindParkingSpaceInVicinity( + Constants.ManagerFactory.AdvancedParkingManager.VanillaFindParkingSpaceWithoutRestrictions( + isElectric, + homeID, refPos, searchDir, - vehicleInfo, - homeID, - vehicleID, - GlobalConfig.Instance.ParkingAI.MaxBuildingToPedestrianLaneDistance, - out ExtParkingSpaceLocation parkLoc, - out ushort parkId, + pathPos.m_segment, + vehicleInfo.m_generatedInfo.m_size.x, + vehicleInfo.m_generatedInfo.m_size.z, out parkPos, out parkRot, out parkOffset); diff --git a/TLM/TMPE.API/Manager/IAdvancedParkingManager.cs b/TLM/TMPE.API/Manager/IAdvancedParkingManager.cs index d2778ce15..ea3be4c3a 100644 --- a/TLM/TMPE.API/Manager/IAdvancedParkingManager.cs +++ b/TLM/TMPE.API/Manager/IAdvancedParkingManager.cs @@ -367,5 +367,30 @@ bool FindParkingSpacePropAtBuilding(VehicleInfo vehicleInfo, out Vector3 parkPos, out Quaternion parkRot, out float parkOffset); + + /// + /// Tries to find parking space using vanilla code, preserving parking restrictions + /// + /// Is electric vehicle + /// Home building id of the citizen (citizens are not allowed to park their car on foreign residential premises) + /// Target position that is used as a center point for the search procedure + /// Search direction + /// If != 0, the building is forced to be "accessible" from this segment (where accessible means "close enough") + /// Vehicle width + /// Vehicle length + /// Identified parking space position (only valid if method returns true) + /// Identified parking space rotation (only valid if method returns true) + /// Identified parking space offset (only valid if method returns true and a segment id was given) + /// + bool VanillaFindParkingSpaceWithoutRestrictions(bool isElectric, + ushort homeId, + Vector3 refPos, + Vector3 searchDir, + ushort segment, + float width, + float length, + out Vector3 parkPos, + out Quaternion parkRot, + out float parkOffset); } } \ No newline at end of file From 37c5d0200111690d3f2fa89e7e9f6a7c5ed4db70 Mon Sep 17 00:00:00 2001 From: krzychu124 Date: Sat, 14 Nov 2020 18:53:49 +0100 Subject: [PATCH 5/7] Apply Shift+Click speed limit to entire roundabout (#920) #869: Apply Shift+Click speed limit to entire roundabout (cherry picked from commit ec3227dcdce6a7df9dc8f8cee280e399280625e3) --- TLM/TLM/Manager/Impl/ExtSegmentEndManager.cs | 58 +++++---- .../SubTools/SpeedLimits/SpeedLimitsTool.cs | 122 ++++++++++++++---- 2 files changed, 130 insertions(+), 50 deletions(-) diff --git a/TLM/TLM/Manager/Impl/ExtSegmentEndManager.cs b/TLM/TLM/Manager/Impl/ExtSegmentEndManager.cs index 6e5a9b207..1254a841d 100644 --- a/TLM/TLM/Manager/Impl/ExtSegmentEndManager.cs +++ b/TLM/TLM/Manager/Impl/ExtSegmentEndManager.cs @@ -12,17 +12,10 @@ public class ExtSegmentEndManager : AbstractCustomManager, IExtSegmentEndManager { - public static ExtSegmentEndManager Instance { get; } - static ExtSegmentEndManager() { Instance = new ExtSegmentEndManager(); } - /// - /// All additional data for segment ends - /// - public ExtSegmentEnd[] ExtSegmentEnds { get; } - private ExtSegmentEndManager() { ExtSegmentEnds = new ExtSegmentEnd[NetManager.MAX_SEGMENT_COUNT * 2]; for (uint i = 0; i < NetManager.MAX_SEGMENT_COUNT; ++i) { @@ -31,6 +24,13 @@ private ExtSegmentEndManager() { } } + public static ExtSegmentEndManager Instance { get; } + + /// + /// All additional data for segment ends + /// + public ExtSegmentEnd[] ExtSegmentEnds { get; } + #if DEBUG public string GenerateVehicleChainDebugInfo(ushort segmentId, bool startNode) { int index = GetIndex(segmentId, startNode); @@ -298,23 +298,33 @@ private void Recalculate(ref ExtSegmentEnd segEnd) { public void CalculateCorners(ushort segmentId, bool startNode) { if (!Shortcuts.netService.IsSegmentValid(segmentId)) return; - ref ExtSegmentEnd segEnd = ref ExtSegmentEnds[GetIndex(segmentId, startNode)]; - segmentId.ToSegment().CalculateCorner( - segmentID: segmentId, - heightOffset: true, - start: startNode, - leftSide: false, - cornerPos: out segEnd.RightCorner, - cornerDirection: out segEnd.RightCornerDir, - smooth: out _); - segmentId.ToSegment().CalculateCorner( - segmentID: segmentId, - heightOffset: true, - start: startNode, - leftSide: true, - cornerPos: out segEnd.LeftCorner, - cornerDirection: out segEnd.LeftCornerDir, - smooth: out _); + if (!segmentId.ToSegment().Info) { + Log.Warning($"segment {segmentId} has null info"); + return; + } + + try { + ref ExtSegmentEnd segEnd = ref ExtSegmentEnds[GetIndex(segmentId, startNode)]; + segmentId.ToSegment().CalculateCorner( + segmentID: segmentId, + heightOffset: true, + start: startNode, + leftSide: false, + cornerPos: out segEnd.RightCorner, + cornerDirection: out segEnd.RightCornerDir, + smooth: out _); + segmentId.ToSegment().CalculateCorner( + segmentID: segmentId, + heightOffset: true, + start: startNode, + leftSide: true, + cornerPos: out segEnd.LeftCorner, + cornerDirection: out segEnd.LeftCornerDir, + smooth: out _); + } catch (Exception e) { + Log.Error($"failed calculating corner for segment:{segmentId}, info={segmentId.ToSegment().Info}\n" + + e.Message); + } } private void CalculateIncomingOutgoing(ushort segmentId, diff --git a/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs b/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs index 9ff9e56f8..c152c5173 100644 --- a/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs +++ b/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs @@ -43,7 +43,7 @@ public const int /// 0 = no limit /// null = default /// - private SpeedValue ?currentPaletteSpeedLimit = new SpeedValue(-1f); + private SpeedValue? currentPaletteSpeedLimit = new SpeedValue(-1f); private readonly Dictionary> segmentCenterByDir = new Dictionary>(); @@ -96,12 +96,21 @@ private struct RenderData { private RenderData renderData_; public SpeedLimitsTool(TrafficManagerTool mainTool) - : base(mainTool) - { + : base(mainTool) { CachedVisibleSegmentIds = new GenericArrayCache(NetManager.MAX_SEGMENT_COUNT); LastCachedCamera = new CameraTransformValue(); } + internal static void SetSpeedLimit(LanePos lane, SpeedValue? speed) { + ushort segmentId = lane.laneId.ToLane().m_segment; + SpeedLimitManager.Instance.SetSpeedLimit( + segmentId: segmentId, + laneIndex: lane.laneIndex, + laneInfo: segmentId.ToSegment().Info.m_lanes[lane.laneIndex], + laneId: lane.laneId, + speedLimit: speed?.GameUnits); + } + public override bool IsCursorInPanel() { return base.IsCursorInPanel() || cursorInSecondaryPanel; } @@ -156,17 +165,21 @@ public override void OnToolGUI(Event e) { private void RenderLaneOverlay(RenderManager.CameraInfo cameraInfo, uint laneId) { var marker = new SegmentLaneMarker(laneBuffer[laneId].m_bezier); bool pressed = Input.GetMouseButton(0); - Color color = MainTool.GetToolColor(pressed,false); + Color color = MainTool.GetToolColor(pressed, false); if (!ShowLimitsPerLane) { marker.Size = 3f; // lump the lanes together. } marker.RenderOverlay(cameraInfo, color, pressed); } + /// + /// Renders all lanes with the given + /// if NetInfo.Direction.None, all lanes are rendered. + /// private int RenderSegmentSideOverlay( RenderManager.CameraInfo cameraInfo, ushort segmentId, - NetInfo.Direction finalDirection) { + NetInfo.Direction finalDirection = NetInfo.Direction.None) { int count = 0; bool pressed = Input.GetMouseButton(0); Color color = MainTool.GetToolColor(pressed, false); @@ -180,7 +193,7 @@ private int RenderSegmentSideOverlay( byte laneIndex) => { bool render = (laneInfo.m_laneType & SpeedLimitManager.LANE_TYPES) != 0; render &= (laneInfo.m_vehicleType & SpeedLimitManager.VEHICLE_TYPES) != 0; - render &= laneInfo.m_finalDirection == finalDirection; + render &= laneInfo.m_finalDirection == finalDirection || finalDirection == NetInfo.Direction.None; if (render) { RenderLaneOverlay(cameraInfo, laneId); count++; @@ -193,6 +206,10 @@ private int RenderSegmentSideOverlay( private void RenderLanes(RenderManager.CameraInfo cameraInfo) { if (!MultiSegmentMode) { RenderLaneOverlay(cameraInfo, renderData_.LaneId); + } else if (RoundaboutMassEdit.Instance.TraverseLoop(renderData_.SegmentId, out var segmentList)) { + var lanes = FollowRoundaboutLane(segmentList, renderData_.SegmentId, renderData_.SortedLaneIndex); + foreach (var lane in lanes) + RenderLaneOverlay(cameraInfo, lane.laneId); } else { bool LaneVisitorFun(SegmentLaneTraverser.SegmentLaneVisitData data) { if (data.SortedLaneIndex == renderData_.SortedLaneIndex) { @@ -200,6 +217,7 @@ bool LaneVisitorFun(SegmentLaneTraverser.SegmentLaneVisitData data) { } return true; } + { SegmentLaneTraverser.Traverse( renderData_.SegmentId, SegmentTraverser.TraverseDirection.AnyDirection, @@ -211,10 +229,53 @@ bool LaneVisitorFun(SegmentLaneTraverser.SegmentLaneVisitData data) { LaneVisitorFun); } } + } + + /// + /// iterates through the given roundabout returning an enumeration + /// of all lanes with a matching based on + /// + /// input list of roundabout segments (must be oneway, and in the same direction). + /// The segment to match lane agaisnt + /// + private IEnumerable FollowRoundaboutLane(List segmentList, ushort segmentId0, int sortedLaneIndex) { + bool invert0 = segmentId0.ToSegment().m_flags.IsFlagSet(NetSegment.Flags.Invert); + int count0 = netService.GetSortedLanes( + segmentId: segmentId0, + segment: ref segmentId0.ToSegment(), + startNode: null, + laneTypeFilter: SpeedLimitManager.LANE_TYPES, + vehicleTypeFilter: SpeedLimitManager.VEHICLE_TYPES, + sort: false).Count; + foreach (ushort segmentId in segmentList) { + bool invert = segmentId.ToSegment().m_flags.IsFlagSet(NetSegment.Flags.Invert); + var lanes = netService.GetSortedLanes( + segmentId: segmentId, + segment: ref segmentId.ToSegment(), + startNode: null, + laneTypeFilter: SpeedLimitManager.LANE_TYPES, + vehicleTypeFilter: SpeedLimitManager.VEHICLE_TYPES, + reverse: invert != invert0, + sort: true); + int index = sortedLaneIndex; + + // if lane count does not match, assume segments are connected from outer side of the roundabout. + if (invert0) { + int diff = lanes.Count - count0; + index += diff; + } + if (0 <= index && index < lanes.Count) { + yield return lanes[index]; + } + } // foreach + } private void RenderSegmentsSide(RenderManager.CameraInfo cameraInfo) { if (!MultiSegmentMode) { RenderSegmentSideOverlay(cameraInfo, renderData_.SegmentId, renderData_.FinalDirection); + } else if (RoundaboutMassEdit.Instance.TraverseLoop(renderData_.SegmentId, out var segmentList)) { + foreach (ushort segmentId in segmentList) + RenderSegmentSideOverlay(cameraInfo, segmentId); } else { SegmentTraverser.Traverse( renderData_.SegmentId, @@ -305,8 +366,7 @@ private void ShowSigns(bool viewOnly) { bool hover = false; for (int segmentIdIndex = CachedVisibleSegmentIds.Size - 1; segmentIdIndex >= 0; - segmentIdIndex--) - { + segmentIdIndex--) { ushort segmentId = CachedVisibleSegmentIds.Values[segmentIdIndex]; // draw speed limits if ((MainTool.GetToolMode() == ToolMode.VehicleRestrictions) && @@ -315,7 +375,7 @@ private void ShowSigns(bool viewOnly) { } // no speed limit overlay on selected segment when in vehicle restrictions mode - hover|= DrawSpeedLimitHandles( + hover |= DrawSpeedLimitHandles( segmentId, ref netManager.m_segments.m_buffer[segmentId], viewOnly, @@ -485,8 +545,7 @@ private void GuiDefaultsWindow(int num) { GUILayout.FlexibleSpace(); if (GUILayout.Button(Translation.SpeedLimits.Get("Button:Save"), - GUILayout.Width(70))) - { + GUILayout.Width(70))) { SpeedLimitManager.Instance.FixCurrentSpeedLimits(info); SpeedLimitManager.Instance.SetCustomNetInfoSpeedLimit(info, currentSpeedLimit.GameUnits); } @@ -512,8 +571,7 @@ private void UpdateRoadTex(NetInfo info) { if (info != null) { if ((info.m_Atlas != null) && (info.m_Atlas.material != null) && (info.m_Atlas.material.mainTexture != null) && - info.m_Atlas.material.mainTexture is Texture2D mainTex) - { + info.m_Atlas.material.mainTexture is Texture2D mainTex) { UITextureAtlas.SpriteInfo spriteInfo = info.m_Atlas[info.m_Thumbnail]; if ((spriteInfo != null) && (spriteInfo.texture != null) && @@ -569,7 +627,7 @@ private void GuiSpeedLimitsWindow(int num) { foreach (SpeedValue speedLimit in allSpeedLimits) { // Highlight palette item if it is very close to its float speed - if (currentPaletteSpeedLimit !=null && + if (currentPaletteSpeedLimit != null && FloatUtil.NearlyEqual( (float)currentPaletteSpeedLimit?.GameUnits, speedLimit.GameUnits)) { @@ -589,7 +647,7 @@ private void GuiSpeedLimitsWindow(int num) { } } { - if (currentPaletteSpeedLimit == null ) { + if (currentPaletteSpeedLimit == null) { GUI.color = Color.gray; } GuiSpeedLimitsWindow_AddClearButton(); @@ -606,7 +664,7 @@ private void GuiSpeedLimitsWindow(int num) { if (GUILayout.Button(Translation.SpeedLimits.Get("Window.Title:Default speed limits"), GUILayout.Width(200))) { - TrafficManagerTool.ShowAdvisor(this.GetType().Name + "_Defaults"); + TrafficManagerTool.ShowAdvisor(GetType().Name + "_Defaults"); defaultsWindowVisible = true; } @@ -728,7 +786,7 @@ private bool DrawSpeedLimitHandles(ushort segmentId, Vector3 center = segment.m_bounds.center; NetManager netManager = Singleton.instance; - SpeedValue ?speedLimitToSet = viewOnly + SpeedValue? speedLimitToSet = viewOnly ? new SpeedValue(-1f) : currentPaletteSpeedLimit; @@ -812,8 +870,7 @@ private bool DrawSpeedLimitHandles(ushort segmentId, if (!viewOnly && !onlyMonorailLanes && ((laneInfo.m_vehicleType & VehicleInfo.VehicleType.Monorail) != - VehicleInfo.VehicleType.None)) - { + VehicleInfo.VehicleType.None)) { Texture2D tex1 = RoadUI.VehicleInfoSignTextures[ LegacyExtVehicleType.ToNew(ExtVehicleType.PassengerTrain)]; MainTool.DrawStaticSquareOverlayGridTexture( @@ -845,8 +902,15 @@ private bool DrawSpeedLimitHandles(ushort segmentId, speedLimitToSet?.GameUnits); if (MultiSegmentMode) { + if (new RoundaboutMassEdit().TraverseLoop(segmentId, out var segmentList)) { + var lanes = FollowRoundaboutLane(segmentList, segmentId, sortedLaneIndex); + foreach (var lane in lanes) { + if (lane.laneId == laneId) // the speed limit for this lane has already been set. + continue; + SetSpeedLimit(lane, speedLimitToSet); + } + } else { int slIndexCopy = sortedLaneIndex; - SegmentLaneTraverser.Traverse( segmentId, SegmentTraverser.TraverseDirection.AnyDirection, @@ -883,6 +947,7 @@ private bool DrawSpeedLimitHandles(ushort segmentId, }); } } + } ++x; } @@ -897,7 +962,7 @@ private bool DrawSpeedLimitHandles(ushort segmentId, GeometryUtil.CalculateSegmentCenterByDir( segmentId, segCenter, - speedLimitSignSize*TrafficManagerTool.MAX_ZOOM); + speedLimitSignSize * TrafficManagerTool.MAX_ZOOM); } foreach (KeyValuePair e in segCenter) { @@ -941,6 +1006,13 @@ private bool DrawSpeedLimitHandles(ushort segmentId, currentPaletteSpeedLimit?.GameUnits); if (MultiSegmentMode) { + if (new RoundaboutMassEdit().TraverseLoop(segmentId, out var segmentList)) { + foreach (ushort segId in segmentList) { + SpeedLimitManager.Instance.SetSpeedLimit( + segId, + currentPaletteSpeedLimit?.GameUnits); + } + } else { NetInfo.Direction normDir = e.Key; if ((netManager.m_segments.m_buffer[segmentId].m_flags & NetSegment.Flags.Invert) != NetSegment.Flags.None) { normDir = NetInfo.InvertDirection(normDir); @@ -954,8 +1026,7 @@ private bool DrawSpeedLimitHandles(ushort segmentId, SegmentTraverser.SegmentStopCriterion.Junction, SpeedLimitManager.LANE_TYPES, SpeedLimitManager.VEHICLE_TYPES, - data => - { + data => { if (data.SegVisitData.Initial) { return true; } @@ -974,8 +1045,7 @@ private bool DrawSpeedLimitHandles(ushort segmentId, if (((netManager.m_segments.m_buffer[otherSegmentId].m_flags & NetSegment.Flags.Invert) - != NetSegment.Flags.None) ^ reverse) - { + != NetSegment.Flags.None) ^ reverse) { otherNormDir = NetInfo.InvertDirection(otherNormDir); } @@ -988,6 +1058,7 @@ private bool DrawSpeedLimitHandles(ushort segmentId, return true; }); + } } } @@ -1124,6 +1195,5 @@ public static float GetVerticalTextureScale() { ? 1.25f : 1.0f; } - } // end class } From 2278e4cd1ea35d26990c9fad8ac102721f8c772c Mon Sep 17 00:00:00 2001 From: krzychu124 Date: Sat, 14 Nov 2020 19:09:46 +0100 Subject: [PATCH 6/7] Right-click close main menu if no tool selected, right-click exit tool - set current tool to None, update OSD (cherry picked from commit 3c0b6e42833e82c15470f400281b37184a2acd93) Road selection Panel - close on single right click, but leave menu open (cherry picked from commit 39087f6ce21f075d0284e6aa07550d3b3ca5e002) --- .../UI/SubTools/JunctionRestrictionsTool.cs | 8 +++-- TLM/TLM/UI/SubTools/LaneConnectorTool.cs | 4 +++ .../UI/SubTools/ManualTrafficLightsTool.cs | 10 ++++-- .../UI/SubTools/ParkingRestrictionsTool.cs | 4 +++ .../PrioritySigns/PrioritySignsTool.cs | 8 +++-- .../SubTools/SpeedLimits/SpeedLimitsTool.cs | 4 +++ .../TimedTrafficLightsTool.cs | 8 +++-- .../UI/SubTools/ToggleTrafficLightsTool.cs | 4 +++ .../UI/SubTools/VehicleRestrictionsTool.cs | 9 ++++-- TLM/TLM/UI/TrafficManagerTool.cs | 31 +++++++++++++++---- 10 files changed, 72 insertions(+), 18 deletions(-) diff --git a/TLM/TLM/UI/SubTools/JunctionRestrictionsTool.cs b/TLM/TLM/UI/SubTools/JunctionRestrictionsTool.cs index 2dc7e7f49..3cc977216 100644 --- a/TLM/TLM/UI/SubTools/JunctionRestrictionsTool.cs +++ b/TLM/TLM/UI/SubTools/JunctionRestrictionsTool.cs @@ -164,8 +164,12 @@ public override void OnPrimaryClickOverlay() { } public override void OnSecondaryClickOverlay() { - SelectedNodeId = 0; - MainTool.RequestOnscreenDisplayUpdate(); + if (SelectedNodeId != 0) { + SelectedNodeId = 0; + MainTool.RequestOnscreenDisplayUpdate(); + } else { + MainTool.SetToolMode(ToolMode.None); + } } public override void OnActivate() { diff --git a/TLM/TLM/UI/SubTools/LaneConnectorTool.cs b/TLM/TLM/UI/SubTools/LaneConnectorTool.cs index 483c08188..f82c24e87 100644 --- a/TLM/TLM/UI/SubTools/LaneConnectorTool.cs +++ b/TLM/TLM/UI/SubTools/LaneConnectorTool.cs @@ -966,6 +966,10 @@ public override void OnSecondaryClickOverlay() { break; } } + + if (GetSelectionMode() == SelectionMode.None) { + MainTool.SetToolMode(ToolMode.None); + } } public override void OnActivate() { diff --git a/TLM/TLM/UI/SubTools/ManualTrafficLightsTool.cs b/TLM/TLM/UI/SubTools/ManualTrafficLightsTool.cs index b6f05ae07..098fa434f 100644 --- a/TLM/TLM/UI/SubTools/ManualTrafficLightsTool.cs +++ b/TLM/TLM/UI/SubTools/ManualTrafficLightsTool.cs @@ -27,9 +27,13 @@ public override void OnSecondaryClickOverlay() { return; } - Cleanup(); - SelectedNodeId = 0; - MainTool.RequestOnscreenDisplayUpdate(); + if (SelectedNodeId != 0) { + Cleanup(); + SelectedNodeId = 0; + MainTool.RequestOnscreenDisplayUpdate(); + } else { + MainTool.SetToolMode(ToolMode.None); + } } public override void OnPrimaryClickOverlay() { diff --git a/TLM/TLM/UI/SubTools/ParkingRestrictionsTool.cs b/TLM/TLM/UI/SubTools/ParkingRestrictionsTool.cs index 5b022569f..8540b8dc7 100644 --- a/TLM/TLM/UI/SubTools/ParkingRestrictionsTool.cs +++ b/TLM/TLM/UI/SubTools/ParkingRestrictionsTool.cs @@ -66,6 +66,10 @@ public override void OnActivate() { public override void OnPrimaryClickOverlay() { } + public override void OnSecondaryClickOverlay() { + MainTool.SetToolMode(ToolMode.None); + } + private void RenderSegmentParkings(RenderManager.CameraInfo cameraInfo) { bool allowed = parkingManager.IsParkingAllowed(renderInfo_.SegmentId, renderInfo_.FinalDirection); bool pressed = Input.GetMouseButton(0); diff --git a/TLM/TLM/UI/SubTools/PrioritySigns/PrioritySignsTool.cs b/TLM/TLM/UI/SubTools/PrioritySigns/PrioritySignsTool.cs index c08da5371..ac34d1552 100644 --- a/TLM/TLM/UI/SubTools/PrioritySigns/PrioritySignsTool.cs +++ b/TLM/TLM/UI/SubTools/PrioritySigns/PrioritySignsTool.cs @@ -76,7 +76,7 @@ public override void OnPrimaryClickOverlay() { if (!isRoundabout) { record_ = PriorityRoad.FixRoad(HoveredSegmentId); } - // TODO: benchmark why bulk setup takes a long time. + // TODO: benchmark why bulk setup takes a long time. Log.Info("After FixRoundabout/FixRoad. Before RefreshMassEditOverlay"); // log time for benchmarking. RefreshMassEditOverlay(); Log.Info("After RefreshMassEditOverlay."); // log time for benchmarking. @@ -125,7 +125,7 @@ public override void OnPrimaryClickOverlay() { massEditMode = PrioritySignsMassEditMode.Min; } } - + // refresh cache if(ControlIsPressed) RefreshMassEditOverlay(); @@ -133,6 +133,10 @@ public override void OnPrimaryClickOverlay() { RefreshCurrentPriorityNodeIds(); } + public override void OnSecondaryClickOverlay() { + MainTool.SetToolMode(ToolMode.None); + } + public override void OnToolGUI(Event e) { } /// diff --git a/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs b/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs index c152c5173..3ddcc598c 100644 --- a/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs +++ b/TLM/TLM/UI/SubTools/SpeedLimits/SpeedLimitsTool.cs @@ -122,6 +122,10 @@ public override void OnActivate() { public override void OnPrimaryClickOverlay() { } + public override void OnSecondaryClickOverlay() { + MainTool.SetToolMode(ToolMode.None); + } + public override void OnToolGUI(Event e) { base.OnToolGUI(e); diff --git a/TLM/TLM/UI/SubTools/TimedTrafficLights/TimedTrafficLightsTool.cs b/TLM/TLM/UI/SubTools/TimedTrafficLights/TimedTrafficLightsTool.cs index 036f1ad6c..1c8a3cbff 100644 --- a/TLM/TLM/UI/SubTools/TimedTrafficLights/TimedTrafficLightsTool.cs +++ b/TLM/TLM/UI/SubTools/TimedTrafficLights/TimedTrafficLightsTool.cs @@ -106,8 +106,12 @@ public override void OnActivate() { public override void OnSecondaryClickOverlay() { if (!IsCursorInPanel()) { - Cleanup(); - this.SetToolMode(TTLToolMode.SelectNode); + if (ttlToolMode_ != TTLToolMode.SelectNode) { + Cleanup(); + this.SetToolMode(TTLToolMode.SelectNode); + } else { + MainTool.SetToolMode(ToolMode.None); + } } } diff --git a/TLM/TLM/UI/SubTools/ToggleTrafficLightsTool.cs b/TLM/TLM/UI/SubTools/ToggleTrafficLightsTool.cs index a5e92d3ab..ae19e4eb4 100644 --- a/TLM/TLM/UI/SubTools/ToggleTrafficLightsTool.cs +++ b/TLM/TLM/UI/SubTools/ToggleTrafficLightsTool.cs @@ -51,6 +51,10 @@ public override void OnPrimaryClickOverlay() { }); } + public override void OnSecondaryClickOverlay() { + MainTool.SetToolMode(ToolMode.None); + } + public void ToggleTrafficLight(ushort nodeId, ref NetNode node, bool showMessageOnError = true) { diff --git a/TLM/TLM/UI/SubTools/VehicleRestrictionsTool.cs b/TLM/TLM/UI/SubTools/VehicleRestrictionsTool.cs index b531e4b3c..2b07ea1ce 100644 --- a/TLM/TLM/UI/SubTools/VehicleRestrictionsTool.cs +++ b/TLM/TLM/UI/SubTools/VehicleRestrictionsTool.cs @@ -122,8 +122,12 @@ public override void OnPrimaryClickOverlay() { public override void OnSecondaryClickOverlay() { if (!IsCursorInPanel()) { - SelectedSegmentId = 0; - MainTool.RequestOnscreenDisplayUpdate(); + if (SelectedSegmentId != 0) { + SelectedSegmentId = 0; + MainTool.RequestOnscreenDisplayUpdate(); + } else { + MainTool.SetToolMode(ToolMode.None); + } } } @@ -195,7 +199,6 @@ public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) { RenderRoadLane(cameraInfo); } else { RenderLaneOverlay(cameraInfo, renderData_.laneId); - } } } diff --git a/TLM/TLM/UI/TrafficManagerTool.cs b/TLM/TLM/UI/TrafficManagerTool.cs index 69cf6b13e..d8cb114b7 100644 --- a/TLM/TLM/UI/TrafficManagerTool.cs +++ b/TLM/TLM/UI/TrafficManagerTool.cs @@ -286,6 +286,8 @@ public void SetToolMode(ToolMode newToolMode) { toolMode_ = ToolMode.None; Log._Debug($"SetToolMode: reset because toolmode not found {newToolMode}"); + OnscreenDisplay.DisplayIdle(); + ModUI.Instance.MainMenu.UpdateButtons(); return; } @@ -329,6 +331,10 @@ private void SetToolMode_Activate(ToolMode newToolMode) { // Overridden to disable base class behavior protected override void OnEnable() { + // If TMPE was enabled by switching back from another tool (eg: buldozer, free camera), show main menue panel. + if (ModUI.Instance != null && !ModUI.Instance.IsVisible()) + ModUI.Instance.ShowMainMenu(); + if (legacySubTools_ != null) { Log._Debug("TrafficManagerTool.OnEnable(): Performing cleanup"); foreach (KeyValuePair e in legacySubTools_) { @@ -339,7 +345,10 @@ protected override void OnEnable() { } protected override void OnDisable() { - // Overridden to disable base class behavior + // If TMPE was disabled by switching to another tool, hide main menue panel. + if (ModUI.Instance != null && ModUI.Instance.IsVisible()) + ModUI.Instance.CloseMainMenu(); + // no call to base method to disable base class behavior } public override void RenderGeometry(RenderManager.CameraInfo cameraInfo) { @@ -459,7 +468,7 @@ protected override void OnToolUpdate() { } bool primaryMouseClicked = Input.GetMouseButtonDown(0); - bool secondaryMouseClicked = Input.GetMouseButtonDown(1); + bool secondaryMouseClicked = Input.GetMouseButtonUp(1); // check if clicked if (!primaryMouseClicked && !secondaryMouseClicked) { @@ -485,8 +494,17 @@ protected override void OnToolUpdate() { } if (secondaryMouseClicked) { - activeLegacySubTool_?.OnSecondaryClickOverlay(); - activeSubTool_?.OnToolRightClick(); + if (GetToolMode() == ToolMode.None) { + RoadSelectionPanels roadSelectionPanels = UIView.GetAView().GetComponent(); + if (roadSelectionPanels && roadSelectionPanels.RoadWorldInfoPanelExt && roadSelectionPanels.RoadWorldInfoPanelExt.isVisible) { + RoadSelectionPanels.RoadWorldInfoPanel.Hide(); + } else { + ModUI.Instance.CloseMainMenu(); + } + } else { + activeLegacySubTool_?.OnSecondaryClickOverlay(); + activeSubTool_?.OnToolRightClick(); + } } } } @@ -510,6 +528,9 @@ public void OnToolGUIImpl(Event e) { if (!Input.GetMouseButtonDown(0)) { _mouseClickProcessed = false; } + if (e.type == EventType.keyDown && e.keyCode == KeyCode.Escape) { + ModUI.Instance.CloseMainMenu(); + } if (Options.nodesOverlay) { DebugGuiDisplaySegments(); @@ -575,8 +596,6 @@ void DefaultOnToolGUI(Event e) { instanceID, HitPos); }); - } else if (e.type == EventType.MouseDown && e.button == 1) { - SimulationManager.instance.m_ThreadingWrapper.QueueMainThread(RoadSelectionPanels.RoadWorldInfoPanel.Hide); } } From 2914bdcbd8a7870d774a0eb83322643e1417eb24 Mon Sep 17 00:00:00 2001 From: krzychu124 Date: Sat, 14 Nov 2020 19:26:04 +0100 Subject: [PATCH 7/7] Version bump --- TLM/SharedAssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TLM/SharedAssemblyInfo.cs b/TLM/SharedAssemblyInfo.cs index 050b42ab7..3a0de65f5 100644 --- a/TLM/SharedAssemblyInfo.cs +++ b/TLM/SharedAssemblyInfo.cs @@ -20,4 +20,4 @@ // Minor Version // Build Number // Revision -[assembly: AssemblyVersion("11.5.0.*")] +[assembly: AssemblyVersion("11.5.1.*")]