1 #define DEBUG_NEARBY_CONTEXT_DISPLAY
6 [
Attribute(
"3", UIWidgets.Slider,
"Maximum distance of actions that can be presented to player. (meters)",
category:
"NearbyContextDisplay",
params:
"0 100 0.1")]
7 protected float m_fWidgetMaximumRange;
8 [
Attribute(
"0.7", UIWidgets.Slider,
"Minimum assumed distance of actions (for scaling). (meters)",
category:
"NearbyContextDisplay",
params:
"0 100 0.1")]
9 protected float m_fWidgetMinimumRange;
11 [
Attribute(
"128", UIWidgets.Slider,
"Amount of widgets that are created on initialization and then re-used.",
category:
"NearbyContextDisplay",
params:
"0 256 1")]
12 protected int m_iPrecachedWidgetCount;
14 [
Attribute(
"", UIWidgets.ResourceNamePicker,
"Layout",
"layout",
category:
"NearbyContextDisplay")]
15 ResourceName m_wIconLayoutPath;
18 protected vector m_vVisibleWidgetColor;
19 [
Attribute(
"0.1 0.1 0.1 1", UIWidgets.ColorPicker,
category:
"NearbyContextDisplay")]
20 protected vector m_vNotVisibleWidgetColor;
26 [
Attribute(
"0 0 1 1", UIWidgets.GraphDialog,
desc:
"Horizontal opacity (y) based on screen center distance (x).",
category:
"NearbyContextDisplay")]
27 private ref Curve m_pHorizontalOpacityCurve;
31 [
Attribute(
"0 0 1 1", UIWidgets.GraphDialog,
desc:
"Vertical opacity (y) based on screen center distance (x).",
category:
"NearbyContextDisplay")]
32 private ref Curve m_pVerticalOpacityCurve;
34 private ref Color m_pColorVisible;
35 private ref Color m_pColorNotVisible;
38 private InteractionHandlerComponent m_pInteractionHandlerComponent;
41 private ref array<Widget> m_aWidgets = {};
43 private int m_iVisibleWidgets;
45 private float m_fOriginalSizeX;
47 private float m_fOriginalSizeY;
54 for (
int i = widgetsCount-1; i >= 0; i--)
62 m_pColorVisible =
null;
63 m_pColorNotVisible =
null;
67 override void DisplayStartDraw(IEntity owner)
71 Print(
"Pre-cached SCR_NearbyContextDisplay widgets cannot be detected; re-rooting to m_wRoot cannot happen!", LogLevel.ERROR);
77 Print(
"The SCR_NearbyContextDisplay root is NULL, the pre-cached SCR_NearbyContextDisplay widgets cannot be re-rooted!", LogLevel.ERROR);
88 override void DisplayInit(IEntity owner)
90 m_pInteractionHandlerComponent = InteractionHandlerComponent.Cast(owner.FindComponent(InteractionHandlerComponent));
91 if (!m_pInteractionHandlerComponent)
92 Print(
"Interaction handler component could not be found! SCR_NearbyContextDisplay will not work.", LogLevel.WARNING);
95 m_pColorVisible =
new Color(m_vVisibleWidgetColor[0], m_vVisibleWidgetColor[1], m_vVisibleWidgetColor[2], 1.0);
96 m_pColorNotVisible =
new Color(m_vNotVisibleWidgetColor[0], m_vNotVisibleWidgetColor[1], m_vNotVisibleWidgetColor[2], 1.0);
99 for (
int i = 0; i < m_iPrecachedWidgetCount; i++)
102 Widget iconWidget =
GetGame().GetWorkspace().CreateWidgets(m_wIconLayoutPath);
105 if (m_wIconLayoutPath.IsEmpty())
106 Print(
"SCR_NearbyContextDisplay could not create widgets! Verify that provided Icon Layout Path is valid!", LogLevel.ERROR);
112 iconWidget.SetVisible(
false);
114 FrameSlot.SetAnchor(iconWidget, 0, 0);
115 FrameSlot.SetAlignment(iconWidget, 0.5, 0.5);
116 FrameSlot.SetSizeToContent(iconWidget,
true);
123 vector size = FrameSlot.GetSize(icon);
124 m_fOriginalSizeX = size[0];
125 m_fOriginalSizeY = size[1];
130 override void DisplayStopDraw(IEntity owner)
134 if (m_iVisibleWidgets > 0)
135 SetVisibleWidgets(0);
140 override void DisplayUpdate(IEntity owner,
float timeSlice)
144 if (!m_pInteractionHandlerComponent.GetNearbyCollectionEnabled() || !bCameraActive)
148 if (m_iVisibleWidgets > 0)
149 SetVisibleWidgets(0);
155 array<UserActionContext> contexts = {};
156 int count = m_pInteractionHandlerComponent.GetNearbyAvailableContextList(contexts);
162 BaseWorld world = owner.GetWorld();
163 int cameraIndex = world.GetCurrentCameraId();
165 world.GetCamera(cameraIndex, mat);
166 vector referencePos = mat[3];
171 const float threshold = 0.25;
172 const float fovBase = 100;
176 CameraManager cameraManager =
GetGame().GetCameraManager();
179 CameraBase camera = cameraManager.CurrentCamera();
181 #ifdef DEBUG_NEARBY_CONTEXT_DISPLAY
182 if(camera.GetProjType() == CameraType.NONE)
183 Print(
string.Format(
"%1 [DisplayUpdate] None Projection",
this));
186 if (camera && camera.GetProjType() != CameraType.NONE)
187 zoom = fovBase / Math.Max(camera.GetVerticalFOV(), 1);
189 float distanceLimit = m_fWidgetMaximumRange * zoom;
190 float distanceLimitSq = distanceLimit * distanceLimit;
193 float resX;
float resY;
194 GetGame().GetWorkspace().GetScreenSize(resX, resY);
196 UserActionContext currentContext = m_pInteractionHandlerComponent.GetCurrentContext();
200 if (currentContext == ctx)
204 if (actualCount >= m_iPrecachedWidgetCount)
208 float distanceSq = vector.DistanceSq(
position, referencePos);
211 if (distanceSq < distanceLimitSq && IsInLineOfSight(
position, mat, threshold))
216 SetWidgetWorldPosition(world, cameraIndex, widget,
position);
221 Widget child = FindIconWidget(widget);
225 float distance = Math.Sqrt(distanceSq);
226 bool visible = ctx.IsInVisibilityAngle(referencePos);
227 SetWidgetScale(child,
distance, zoom);
228 SetWidgetAlpha(child,
distance, distanceLimit, resX, resY);
229 SetWidgetColor(child,
distance, visible);
237 SetVisibleWidgets(actualCount);
243 protected void SetVisibleWidgets(
int count)
249 if (count > m_iVisibleWidgets)
251 for (
int i = m_iVisibleWidgets; i < count; i++)
254 m_iVisibleWidgets = count;
257 else if (count < m_iVisibleWidgets)
259 for (
int i = count; i < m_iVisibleWidgets; i++)
262 m_iVisibleWidgets = count;
267 protected void SetWidgetScale(Widget widget,
float distance,
float zoom)
271 float scale = zoom / Math.Max(
distance, m_fWidgetMinimumRange);
273 FrameSlot.SetSize(widget, scale * m_fOriginalSizeX, scale * m_fOriginalSizeY);
277 protected void SetWidgetAlpha(Widget widget,
float distance,
float limit,
float resX,
float resY)
282 alpha = Math.Clamp(limit -
distance, 0, limit) / limit;
286 widget.GetScreenPos(x, y);
290 float xDistance = Math.AbsFloat(x - resX * 0.5) / resX;
291 float yDistance = Math.AbsFloat(y - resY * 0.5) / resY;
294 x = Math3D.Curve(ECurveType.CurveProperty2D, xDistance, m_pHorizontalOpacityCurve)[1];
295 y = Math3D.Curve(ECurveType.CurveProperty2D, yDistance, m_pVerticalOpacityCurve)[1];
299 float min = Math.Min(x, y);
302 widget.SetOpacity(alpha * min);
306 protected void SetWidgetColor(Widget widget,
float distance,
bool isInVisibilityRange)
308 if (isInVisibilityRange)
309 widget.SetColor(m_pColorVisible);
311 widget.SetColor(m_pColorNotVisible);
320 protected void SetWidgetWorldPosition(BaseWorld world,
int cameraIndex, Widget widget, vector worldPosition)
322 vector screenPosition =
GetGame().GetWorkspace().ProjWorldToScreen(worldPosition, world, cameraIndex);
323 float x = screenPosition[0];
324 float y = screenPosition[1];
325 FrameSlot.SetPos(widget, x, y);
333 protected bool IsInLineOfSight(vector point, vector transform[4],
float val)
338 const float threshold = 0.25;
339 if (vector.Dot(
direction, transform[2]) > val)
349 protected Widget FindIconWidget(Widget
layout)
351 return layout.GetChildren();