/// <summary> /// Tries to retrieve targeted <see cref="IMyTerminalBlock"/> on a grid within a given distance. /// </summary> private bool TryGetTargetedBlockInternal(double maxDist, out IMyTerminalBlock target) { IMyCubeGrid cubeGrid; IHitInfo rayInfo; MatrixD transform = MyAPIGateway.Session.Camera.WorldMatrix; Vector3D headPos = transform.Translation, forward = transform.Forward; if (!LocalPlayer.IsSpectating) { headPos += (headPos - LocalPlayer.Position).Length() * forward; } LineD line = new LineD(headPos, headPos + forward * maxDist); target = null; if ((LocalPlayer.IsControllingCharacter || LocalPlayer.IsSpectating) && LocalPlayer.TryGetTargetedGrid(line, out cubeGrid, out rayInfo)) { // Retrieve blocks within about half a block of the ray intersection point. var sphere = new BoundingSphereD(rayInfo.Position, (cubeGrid.GridSizeEnum == MyCubeSize.Large) ? 1.3 : .3); double currentDist = double.PositiveInfinity, currentCenterDist = double.PositiveInfinity; tempGrid.SetGrid(cubeGrid, true); targetBuffer.Clear(); tempGrid.GetBlocksInsideSphere(cubeGrid, targetBuffer, ref sphere); foreach (IMySlimBlock slimBlock in targetBuffer) { IMyCubeBlock cubeBlock = slimBlock?.FatBlock; if (cubeBlock != null) { var topBlock = cubeBlock as IMyAttachableTopBlock; if (topBlock != null) { cubeBlock = topBlock.Base; } } var tBlock = cubeBlock as IMyTerminalBlock; if (tBlock != null) { // Find shortest dist between the bb and the intersection. BoundingBoxD box = cubeBlock.WorldAABB; double newDist = Math.Round(box.DistanceSquared(rayInfo.Position), 3), newCenterDist = Math.Round(Vector3D.DistanceSquared(box.Center, rayInfo.Position), 3); // If this is a terminal block, check to see if this block is any closer than the last. // If the distance to the bb is zero, use the center dist, favoring smaller blocks. if ( (currentDist > 0d && newDist < currentDist) || (Math.Abs(currentDist - newDist) < 0.02 && newCenterDist < currentCenterDist) ) { target = tBlock; currentDist = newDist; currentCenterDist = newCenterDist; } } } } tempGrid.Reset(); return(target != null); }
/// <summary> /// Checks if the player can access the targeted block. /// </summary> private bool CanAccessTargetBlock() => BlockInRange() && target.CanLocalPlayerAccess && (!Cfg.closeIfNotInView || LocalPlayer.IsLookingInBlockDir(target.TBlock));
protected override void Layout() { var specCon = MyAPIGateway.Session.CameraController as MySpectator; float scale = BvConfig.Current.genUI.hudScale; if (BvConfig.Current.genUI.resolutionScaling) { scale *= HudMain.ResScale; } if (Target.TBlock != null && Open) { Vector3D targetWorldPos, targetScreenPos; Vector2 screenBounds = new Vector2(HudMain.ScreenWidth, HudMain.ScreenHeight) * HudMain.ResScale * .5f, menuPos; if (!BvConfig.Current.genUI.useCustomPos) { if (LocalPlayer.IsLookingInBlockDir(Target.TBlock)) { targetWorldPos = Target.Position + Target.ModelOffset * .75d; targetScreenPos = LocalPlayer.GetWorldToScreenPos(targetWorldPos) / 2d; menuPos = new Vector2((float)targetScreenPos.X, (float)targetScreenPos.Y); menuPos = HudMain.GetPixelVector(menuPos) / scale; } else { menuPos = lastPos; } } else { menuPos = BvConfig.Current.genUI.hudPos; menuPos = HudMain.GetPixelVector(menuPos) / scale; if (menuPos.X < 0) { menuPos.X += .5f * quickActionMenu.Width; } else { menuPos.X -= .5f * quickActionMenu.Width; } if (menuPos.Y < 0) { menuPos.Y += .5f * quickActionMenu.Height; } else { menuPos.Y -= .5f * quickActionMenu.Height; } } if (BvConfig.Current.genUI.clampHudPos || BvConfig.Current.genUI.useCustomPos) { screenBounds -= .5f * quickActionMenu.Size; menuPos.X = MathHelper.Clamp(menuPos.X, -screenBounds.X, screenBounds.X); menuPos.Y = MathHelper.Clamp(menuPos.Y, -screenBounds.Y, screenBounds.Y); } if ((lastPos - menuPos).LengthSquared() > 1f && !(HudMain.EnableCursor && SharedBinds.LeftButton.IsPressed)) { posLerpFactor = 0f; lastPos = menuPos; } if (BvConfig.Current.genUI.useCustomPos) { posLerpFactor = 1f; } lerpScale = frameTimer.ElapsedMilliseconds / 16.6667f; posLerpFactor = Math.Min(posLerpFactor + .4f * lerpScale, 1f); quickActionMenu.Offset = Vector2.Lerp(quickActionMenu.Offset, lastPos, posLerpFactor); quickActionMenu.Visible = bpTick > 30; if (specCon != null && lastSpecSpeeds != null) { specCon.SpeedModeAngular = lastSpecSpeeds.Value.X; specCon.SpeedModeLinear = lastSpecSpeeds.Value.Y; } } else if (specCon != null) { lastSpecSpeeds = new Vector2(specCon.SpeedModeAngular, specCon.SpeedModeLinear); } // Rescale draw matrix based on config PlaneToWorldRef[0] = MatrixD.CreateScale(scale, scale, 1d) * HudMain.PixelToWorld; base.Layout(); frameTimer.Restart(); }