Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_RoadGeneratorEntity.c
Go to the documentation of this file.
1[EntityEditorProps(category: "GameScripted/Generators", description: "Road Generator - use this instead of RoadGeneratorEntity", visible: false, dynamicBox: true)]
5
6class SCR_RoadGeneratorEntity : RoadGeneratorEntity
7{
8 /*
9 Debug
10 */
11
12 [Attribute(defvalue: "10", category: "Debug", desc: "(metres) 2D distance between checks", uiwidget: UIWidgets.Slider, params: "1 100 1")]
13 protected float m_fMeasurementStep;
14
15 [Attribute(defvalue: MAX_POSSIBLE_ANGLE.ToString(), category: "Debug", desc: "(degrees) Maximum acceptable absolute slope for the road.\nPercent to degree formula: Math.Atan2(7 / 100, 1) * Math.RAD2DEG == 4.00", uiwidget: UIWidgets.Slider, params: "0 90 0.01")]
16 protected float m_fMaxSlopeAngle;
17
18 [Attribute(defvalue: MAX_POSSIBLE_ANGLE.ToString(), category: "Debug", desc: "(degrees) Maximum acceptable absolute slope for the roadside compared to its middle (checks both sides)", uiwidget: UIWidgets.Slider, params: "0 90 0.01")]
19 protected float m_fMaxRollAngle;
20
21 [Attribute(defvalue: "1", category: "Debug", desc: "Check road roll angle per side (middle to left and middle to right), otherwise from left to right")]
22 protected bool m_bRollCheckPerSide;
23
25
26 protected static const float MAX_POSSIBLE_ANGLE = 90;
27
28#ifdef WORKBENCH
29
30 //------------------------------------------------------------------------------------------------
31 protected void CheckSlopes(bool printDebugLink)
32 {
33 WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
34 if (!worldEditorAPI || worldEditorAPI.UndoOrRedoIsRestoring())
35 return;
36
37 m_DebugShapeManager.Clear();
38
39 if (m_fMaxSlopeAngle >= MAX_POSSIBLE_ANGLE && m_fMaxRollAngle >= MAX_POSSIBLE_ANGLE)
40 return;
41
42 BaseWorld world = worldEditorAPI.GetWorld();
43 if (!world)
44 return;
45
46 IEntitySource thisSource = worldEditorAPI.EntityToSource(this);
47 if (!thisSource)
48 return;
49
50 IEntitySource parentSource = thisSource.GetParent();
51 if (!parentSource)
52 return;
53
54 ShapeEntity shapeEntity = ShapeEntity.Cast(worldEditorAPI.SourceToEntity(parentSource));
55
56 SCR_ShapeNextPointHelper shapeNextPointHelper = SCR_ShapeNextPointHelper.CreateFromShape(shapeEntity);
57 if (!shapeNextPointHelper)
58 {
59 Print("Cannot check road generator slope with invalid shape at " + Debug.GetEntityLinkString(shapeEntity), LogLevel.WARNING);
60 return;
61 }
62
63 float shapeLength = shapeNextPointHelper.GetShapeLength();
64 if (shapeLength <= 0.02) // boo
65 return;
66
67 float measurementStep;
68 if (shapeLength <= m_fMeasurementStep)
69 measurementStep = shapeLength - 0.01;
70 else
71 measurementStep = m_fMeasurementStep;
72
73 bool checkSlope = m_fMaxSlopeAngle < MAX_POSSIBLE_ANGLE;
74
75 float roadWidth;
76 bool checkSides = thisSource.Get("RoadWidth", roadWidth) && roadWidth > 0;
77 if (!checkSides && !checkSlope) // neither checkSides or checkSlope, checkNothing is not an option
78 return;
79
80 float halfRoadWidth = 0.5 * roadWidth;
81
82 bool hasIssues;
83 vector currPoint;
84 vector prevPoint = shapeEntity.CoordToParent(shapeNextPointHelper.GetAnchorPoints()[0]);
85 prevPoint[1] = world.GetSurfaceY(prevPoint[0], prevPoint[2]);
86
87 while (shapeNextPointHelper.GetNextPoint(measurementStep, currPoint, xzMode: true))
88 {
89 currPoint = shapeEntity.CoordToParent(currPoint);
90 currPoint[1] = world.GetSurfaceY(currPoint[0], currPoint[2]);
91
92 if (checkSlope)
93 {
94 float angle = Math.Atan2(currPoint[1] - prevPoint[1], measurementStep) * Math.RAD2DEG;
95
96 if (angle < 0)
97 angle = -angle;
98
99 if (angle > m_fMaxSlopeAngle)
100 {
101 float delta01;
102 if (m_fMaxSlopeAngle == 0)
103 delta01 = 1;
104 else
105 delta01 = Math.InverseLerp(m_fMaxSlopeAngle, m_fMaxSlopeAngle * 2, angle);
106
107 m_DebugShapeManager.AddLine(prevPoint, currPoint, GetGradientColour(delta01));
108 hasIssues = true;
109 }
110 }
111
112 if (checkSides)
113 {
114 vector currDir = shapeNextPointHelper.GetCurrentDirection();
115 currDir[1] = 0; // to 2D
116 currDir.Normalize();
117 vector rightVector = (vector.Up * shapeEntity.VectorToParent(currDir)) * halfRoadWidth;
118 vector leftPoint = currPoint - rightVector;
119 vector rightPoint = currPoint + rightVector;
120
121 vector leftRightPoints[2] = { leftPoint, rightPoint };
122
124 {
125 foreach (vector sidePoint : leftRightPoints)
126 {
127 sidePoint[1] = world.GetSurfaceY(sidePoint[0], sidePoint[2]);
128 float angle = Math.Atan2(currPoint[1] - sidePoint[1], halfRoadWidth) * Math.RAD2DEG;
129
130 if (angle < 0)
131 angle = -angle;
132
133 if (angle > m_fMaxRollAngle)
134 {
135 float delta01;
136 if (m_fMaxRollAngle == 0)
137 delta01 = 1;
138 else
139 delta01 = Math.InverseLerp(m_fMaxRollAngle, m_fMaxRollAngle * 2, angle);
140
141 m_DebugShapeManager.AddLine(currPoint, sidePoint, GetGradientColour(delta01));
142 hasIssues = true;
143 }
144 }
145 }
146 else // full road width
147 {
148 foreach (int i, vector sidePoint : leftRightPoints)
149 {
150 leftRightPoints[i][1] = world.GetSurfaceY(sidePoint[0], sidePoint[2]);
151 }
152
153 float angle = Math.Atan2(leftRightPoints[0][1] - leftRightPoints[1][1], roadWidth) * Math.RAD2DEG;
154
155 if (angle < 0)
156 angle = -angle;
157
158 if (angle > m_fMaxRollAngle)
159 {
160 float delta01;
161 if (m_fMaxRollAngle == 0)
162 delta01 = 1;
163 else
164 delta01 = Math.InverseLerp(m_fMaxRollAngle, m_fMaxRollAngle * 2, angle);
165
166 m_DebugShapeManager.AddLine(leftRightPoints[0], leftRightPoints[1], GetGradientColour(delta01));
167 hasIssues = true;
168 }
169 }
170 }
171
172 prevPoint = currPoint;
173 }
174
175 if (printDebugLink && hasIssues)
176 Print("[SCR_RoadGeneratorEntity.CheckSlope] shape has slope issue " + Debug.GetEntityLinkString(shapeEntity), LogLevel.WARNING);
177 }
178
179 //------------------------------------------------------------------------------------------------
180 protected int GetGradientColour(float value01)
181 {
182 if (value01 < 0)
183 return 0xFF00FF00;
184
185 if (value01 > 1)
186 return 0xFFFF0000;
187
188 int r, g; // b is always 0, unused
189 if (value01 <= 0.5)
190 {
191 r = 255 * (2 * value01);
192 g = 255;
193 }
194 else
195 {
196 r = 255;
197 g = 255 * (1 - 2 * (value01 - 0.5));
198 }
199
200 return (0xFF << 24) | (r << 16) | (g << 8); // | (0 << 0)
201 }
202
203 //------------------------------------------------------------------------------------------------
204 override event protected void OnShapeChangedInternal(IEntitySource shapeEntitySrc, ShapeEntity shapeEntity, array<vector> mins, array<vector> maxes)
205 {
206 super.OnShapeChangedInternal(shapeEntitySrc, shapeEntity, mins, maxes);
207
208 CheckSlopes(false);
209 }
210
211 //------------------------------------------------------------------------------------------------
212 override bool _WB_OnKeyChanged(BaseContainer src, string key, BaseContainerList ownerContainers, IEntity parent)
213 {
214 bool result = super._WB_OnKeyChanged(src, key, ownerContainers, parent);
215
216 CheckSlopes(false);
217
218 return result;
219 }
220
221 //------------------------------------------------------------------------------------------------
222 override event void _WB_OnInit(inout vector mat[4], IEntitySource src)
223 {
224 super._WB_OnInit(mat, src);
225
226 CheckSlopes(true);
227 }
228
229#endif // WORKBENCH
230}
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
override void _WB_OnInit(IEntity owner, inout vector mat[4], IEntitySource src)
override bool _WB_OnKeyChanged(IEntity owner, BaseContainer src, string key, BaseContainerList ownerContainers, IEntity parent)
Any property value has been changed. You can use editor API here and do some additional edit actions ...
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
float m_fMaxSlopeAngle
ref SCR_DebugShapeManager m_DebugShapeManager
float m_fMaxRollAngle
bool m_bRollCheckPerSide
enum EVehicleType IEntity
Definition Debug.c:13
Shape AddLine(vector from, vector to, int colour=DEFAULT_SHAPE_COLOUR, ShapeFlags additionalFlags=0)
static SCR_ShapeNextPointHelper CreateFromShape(notnull ShapeEntity shapeEntity, bool reverse=false)
bool GetNextPoint(float distance, out vector result, int anchorLimit=-1, bool straightLine=true, bool doNotMove=false, bool xzMode=false)
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
SCR_FieldOfViewSettings Attribute
void OnShapeChangedInternal(IEntitySource shapeEntitySrc, ShapeEntity shapeEntity, array< vector > mins, array< vector > maxes)
void Debug()
Definition Types.c:327