1 using System;
2 using OpenBveApi.Interface;
3 using OpenBveApi.Math;
4 using OpenBveApi.Objects;
5 using OpenBveApi.Routes;
6 using OpenBveApi.Textures;
7 using OpenBveApi.World;
8 using RouteManager2.Events;
9 
10 namespace CsvRwRouteParser
11 {
12 	internal class Limit
13 	{
14 		/// <summary>The track position at which the limit is placed</summary>
15 		internal readonly double TrackPosition;
16 		/// <summary>The speed limit to be enforced</summary>
17 		/// <remarks>Stored in km/h, has been transformed by UnitOfSpeed if appropriate</remarks>
18 		internal readonly double Speed;
19 		/// <summary>The side of the auto-generated speed limit post</summary>
20 		internal readonly int Direction;
21 		/// <summary>The cource (little arrow) on the speed limit post denoting a diverging JA limit</summary>
22 		internal readonly int Cource;
23 
Limit(double trackPosition, double speed, int direction, int cource)24 		internal Limit(double trackPosition, double speed, int direction, int cource)
25 		{
26 			TrackPosition = trackPosition;
27 			Speed = speed;
28 			Direction = direction;
29 			Cource = cource;
30 		}
31 
Create(Vector3 wpos, Transformation RailTransformation, double StartingDistance, double EndingDistance, double b, double UnitOfSpeed)32 		internal void Create(Vector3 wpos, Transformation RailTransformation, double StartingDistance, double EndingDistance, double b, double UnitOfSpeed)
33 		{
34 			if (Direction == 0)
35 			{
36 				return;
37 			}
38 			double dx = 2.2 * Direction;
39 			double dz = TrackPosition - StartingDistance;
40 			wpos += dx * RailTransformation.X + dz * RailTransformation.Z;
41 			double tpos = TrackPosition;
42 			if (Speed <= 0.0 | Speed >= 1000.0)
43 			{
44 				if (CompatibilityObjects.LimitPostInfinite == null)
45 				{
46 					return;
47 				}
48 				CompatibilityObjects.LimitPostInfinite.CreateObject(wpos, RailTransformation, Transformation.NullTransformation, -1, StartingDistance, EndingDistance, tpos, b);
49 			}
50 			else
51 			{
52 				if (Cource < 0)
53 				{
54 					if (CompatibilityObjects.LimitPostLeft == null)
55 					{
56 						return;
57 					}
58 					CompatibilityObjects.LimitPostLeft.CreateObject(wpos, RailTransformation, Transformation.NullTransformation, -1, StartingDistance, EndingDistance, tpos, b);
59 				}
60 				else if (Cource > 0)
61 				{
62 					if (CompatibilityObjects.LimitPostRight == null)
63 					{
64 						return;
65 					}
66 					CompatibilityObjects.LimitPostRight.CreateObject(wpos, RailTransformation, Transformation.NullTransformation, -1, StartingDistance, EndingDistance, tpos, b);
67 				}
68 				else
69 				{
70 					if (CompatibilityObjects.LimitPostStraight == null)
71 					{
72 						return;
73 					}
74 					CompatibilityObjects.LimitPostStraight.CreateObject(wpos, RailTransformation, Transformation.NullTransformation, -1, StartingDistance, EndingDistance, tpos, b);
75 				}
76 
77 				double lim = Speed / UnitOfSpeed;
78 				if (lim < 10.0)
79 				{
80 					if (CompatibilityObjects.LimitOneDigit == null)
81 					{
82 						return;
83 					}
84 					if (CompatibilityObjects.LimitOneDigit is StaticObject)
85 					{
86 						int d0 = (int) Math.Round(lim);
87 						StaticObject o = (StaticObject) CompatibilityObjects.LimitOneDigit.Clone();
88 						if (o.Mesh.Materials.Length >= 1)
89 						{
90 							Plugin.CurrentHost.RegisterTexture(OpenBveApi.Path.CombineFile(CompatibilityObjects.LimitGraphicsPath, "limit_" + d0 + ".png"), new TextureParameters(null, null), out o.Mesh.Materials[0].DaytimeTexture);
91 						}
92 
93 						o.CreateObject(wpos, RailTransformation, Transformation.NullTransformation, -1, StartingDistance, EndingDistance, tpos, b);
94 					}
95 					else
96 					{
97 						Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Attempted to use an animated object for LimitOneDigit, where only static objects are allowed.");
98 					}
99 
100 				}
101 				else if (lim < 100.0)
102 				{
103 					if (CompatibilityObjects.LimitTwoDigits == null)
104 					{
105 						return;
106 					}
107 					if (CompatibilityObjects.LimitTwoDigits is StaticObject)
108 					{
109 						int d1 = (int) Math.Round(lim);
110 						int d0 = d1 % 10;
111 						d1 /= 10;
112 						StaticObject o = (StaticObject) CompatibilityObjects.LimitTwoDigits.Clone();
113 						if (o.Mesh.Materials.Length >= 1)
114 						{
115 							Plugin.CurrentHost.RegisterTexture(OpenBveApi.Path.CombineFile(CompatibilityObjects.LimitGraphicsPath, "limit_" + d1 + ".png"), new TextureParameters(null, null), out o.Mesh.Materials[0].DaytimeTexture);
116 						}
117 
118 						if (o.Mesh.Materials.Length >= 2)
119 						{
120 							Plugin.CurrentHost.RegisterTexture(OpenBveApi.Path.CombineFile(CompatibilityObjects.LimitGraphicsPath, "limit_" + d0 + ".png"), new TextureParameters(null, null), out o.Mesh.Materials[1].DaytimeTexture);
121 						}
122 
123 						o.CreateObject(wpos, RailTransformation, Transformation.NullTransformation, -1, StartingDistance, EndingDistance, tpos, b);
124 					}
125 					else
126 					{
127 						Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Attempted to use an animated object for LimitTwoDigits, where only static objects are allowed.");
128 					}
129 				}
130 				else
131 				{
132 					if (CompatibilityObjects.LimitThreeDigits == null)
133 					{
134 						return;
135 					}
136 					if (CompatibilityObjects.LimitThreeDigits is StaticObject)
137 					{
138 						int d2 = (int) Math.Round(lim);
139 						int d0 = d2 % 10;
140 						int d1 = (d2 / 10) % 10;
141 						d2 /= 100;
142 						StaticObject o = (StaticObject) CompatibilityObjects.LimitThreeDigits.Clone();
143 						if (o.Mesh.Materials.Length >= 1)
144 						{
145 							Plugin.CurrentHost.RegisterTexture(OpenBveApi.Path.CombineFile(CompatibilityObjects.LimitGraphicsPath, "limit_" + d2 + ".png"), new TextureParameters(null, null), out o.Mesh.Materials[0].DaytimeTexture);
146 						}
147 
148 						if (o.Mesh.Materials.Length >= 2)
149 						{
150 							Plugin.CurrentHost.RegisterTexture(OpenBveApi.Path.CombineFile(CompatibilityObjects.LimitGraphicsPath, "limit_" + d1 + ".png"), new TextureParameters(null, null), out o.Mesh.Materials[1].DaytimeTexture);
151 						}
152 
153 						if (o.Mesh.Materials.Length >= 3)
154 						{
155 							Plugin.CurrentHost.RegisterTexture(OpenBveApi.Path.CombineFile(CompatibilityObjects.LimitGraphicsPath, "limit_" + d0 + ".png"), new TextureParameters(null, null), out o.Mesh.Materials[2].DaytimeTexture);
156 						}
157 
158 						o.CreateObject(wpos, RailTransformation, Transformation.NullTransformation, -1, StartingDistance, EndingDistance, tpos, b);
159 					}
160 					else
161 					{
162 						Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Attempted to use an animated object for LimitThreeDigits, where only static objects are allowed.");
163 					}
164 				}
165 
166 			}
167 		}
168 
CreateEvent(double StartingDistance, ref double CurrentSpeedLimit, ref TrackElement Element)169 		internal void CreateEvent(double StartingDistance, ref double CurrentSpeedLimit, ref TrackElement Element)
170 		{
171 			int m = Element.Events.Length;
172 			Array.Resize(ref Element.Events, m + 1);
173 			double d = TrackPosition - StartingDistance;
174 			Element.Events[m] = new LimitChangeEvent(d, CurrentSpeedLimit, Speed);
175 			CurrentSpeedLimit = Speed;
176 		}
177 	}
178 }
179