// Local helper method for use object highlighting. private void HighlightUseObject(IMyUseObject useObject, MyHighlightData data) { // Use the helper to perform preprocessing m_highlightCalculationHelper.HighlightAttribute = null; m_highlightCalculationHelper.Highlight(useObject); // For objects with dummy prepare dummy data if (useObject.Dummy != null) { object attributeData; useObject.Dummy.CustomData.TryGetValue(MyModelDummy.ATTRIBUTE_HIGHLIGHT, out attributeData); string highlightAttribute = attributeData as string; m_highlightCalculationHelper.HighlightAttribute = highlightAttribute; } // Send message to renderer MyRenderProxy.UpdateModelHighlight( (uint)m_highlightCalculationHelper.InteractiveObject.RenderObjectID, m_highlightCalculationHelper.SectionIndices, m_highlightCalculationHelper.SubpartIndices, data.OutlineColor, data.Thickness, data.PulseTimeInFrames, m_highlightCalculationHelper.InteractiveObject.InstanceID); }
/// <returns>Abort</returns> private bool SetObjectInternal(IMyUseObject obj) { if (CurrentObject.Instance == obj) return false; bool transition = CheckForTransition(); ResetCurrent(); CurrentObject.Instance = obj; return transition; }
public void Reset() { Instance = null; SectionIndices = null; SubpartIndices = null; Style = MyHudObjectHighlightStyle.None; }
void GetNotification(IMyUseObject useObject, UseActionEnum actionType, ref MyHudNotification notification) { if ((useObject.SupportedActions & actionType) != 0) { var actionInfo = useObject.GetActionInfo(actionType); Character.RemoveNotification(ref notification); notification = new MyHudNotification(actionInfo.Text, 0, level: actionInfo.IsTextControlHint ? MyNotificationLevel.Control : MyNotificationLevel.Normal); if (!MyInput.Static.IsJoystickConnected()) { notification.SetTextFormatArguments(actionInfo.FormatParams); } else { if (actionInfo.JoystickText.HasValue) notification.Text = actionInfo.JoystickText.Value; if (actionInfo.JoystickFormatParams != null) notification.SetTextFormatArguments(actionInfo.JoystickFormatParams); } } }
internal void Highlight(IMyUseObject obj) { bool transition = SetObjectInternal(obj); if (transition) return; if (m_visible) { if (State == MyHudSelectedObjectState.MarkedForNotVisible) State = MyHudSelectedObjectState.VisibleStateSet; } else { State = MyHudSelectedObjectState.MarkedForVisible; } }
public DetectorData(IMyUseObject useObject, Matrix mat) { UseObject = useObject; Matrix = mat; }
protected static void HandleInteractiveObject(IMyUseObject interactive) { if (MyFakes.ENABLE_USE_NEW_OBJECT_HIGHLIGHT) { if (interactive is MyFloatingObject) { MyHud.SelectedObjectHighlight.HighlightAttribute = null; MyHud.SelectedObjectHighlight.HighlightStyle = MyHudObjectHighlightStyle.HighlightStyle2; } else { bool found = false; MyModelDummy dummy = interactive.Dummy; if (dummy != null && dummy.CustomData != null) { object data; found = dummy.CustomData.TryGetValue(MyModelDummy.ATTRIBUTE_HIGHLIGHT, out data); string highlightAttribute = data as string; if (found && highlightAttribute != null) { MyHud.SelectedObjectHighlight.HighlightAttribute = highlightAttribute; MyHud.SelectedObjectHighlight.HighlightStyle = MyHudObjectHighlightStyle.HighlightStyle2; } } if (!found) { MyHud.SelectedObjectHighlight.HighlightAttribute = null; MyHud.SelectedObjectHighlight.HighlightStyle = MyHudObjectHighlightStyle.HighlightStyle1; } } } else { MyHud.SelectedObjectHighlight.HighlightAttribute = null; MyHud.SelectedObjectHighlight.HighlightStyle = MyHudObjectHighlightStyle.HighlightStyle1; } MyHud.SelectedObjectHighlight.Highlight(interactive); }
public static bool IsActionSupported(this IMyUseObject useObject, UseActionEnum action) { return((useObject.SupportedActions & action) == action); }
public DetectorData(IMyUseObject useObject, Matrix mat, string name) { UseObject = useObject; Matrix = mat; DetectorName = name; }
public void Reset() { Instance = null; SectionIndices = null; Style = MyHudObjectHighlightStyle.HighlightStyle1; }
void HandleInputs_CyclePalette() { if (LocalInfo == null) { return; } if (!LocalInfo.ApplySkin && !LocalInfo.ApplyColor) { return; } int cycleDir = 0; bool cycleSkins = false; if (Main.GameConfig.UsingGamepad) { // x button is used for both, if it's not pressed then ignore if (!MyAPIGateway.Input.IsJoystickButtonNewPressed(Constants.GamepadBind_CyclePalette)) { return; } cycleDir = -1; // cycle right cycleSkins = MyAPIGateway.Input.IsJoystickButtonPressed(Constants.GamepadBind_CycleSkinsModifier); if (!cycleSkins) { IMyUseObject useObject = MyAPIGateway.Session?.Player?.Character?.Components?.Get <MyCharacterDetectorComponent>()?.UseObject; if (useObject != null) { return; // aiming at an interactive object while pressing only X, ignore } } } else // keyboard & mouse { if (MyAPIGateway.Input.IsAnyAltKeyPressed()) { return; // ignore combos with alt to allow other systems to use these controls with alt } cycleDir = MyAPIGateway.Input.DeltaMouseScrollWheelValue(); if (cycleDir == 0) { if (MyAPIGateway.Input.IsNewGameControlPressed(MyControlsSpace.SWITCH_RIGHT)) { cycleDir = -1; } else if (MyAPIGateway.Input.IsNewGameControlPressed(MyControlsSpace.SWITCH_LEFT)) { cycleDir = 1; } } if (cycleDir == 0) { return; } cycleSkins = MyAPIGateway.Input.IsAnyShiftKeyPressed(); bool ctrl = MyAPIGateway.Input.IsAnyCtrlKeyPressed(); // ignore ctrl+shift+scroll combo, leave it to other systems if (cycleSkins && ctrl) { return; } // color cycling requires it pressed or explicitly requires it not pressed depending on user pref if (!cycleSkins && Main.Settings.requireCtrlForColorCycle != ctrl) { return; } } if (cycleDir == 0) { return; } if (cycleSkins && !Main.Palette.HasAnySkin) { return; } // skin or color applying is off, can't cycle turned off palette if (cycleSkins ? !LocalInfo.ApplySkin : !LocalInfo.UseColor) { Main.HUDSounds.PlayUnable(); // there's no gamepad equivalent to toggle palettes so it'll just show kb/m binds for both. string assigned = InputHandler.GetFriendlyStringForControl(MyAPIGateway.Input.GetGameControl(MyControlsSpace.CUBE_COLOR_CHANGE)); bool showBind = true; string message = cycleSkins ? "Skin applying is turned off." : "Color applying is turned off."; if (!cycleSkins && !LocalInfo.SkinAllowsColor) { message = $"[{LocalInfo.SelectedSkinInfo.Name}] skin cannot be colored."; showBind = false; } Main.Notifications.Show(0, message, MyFontEnum.Red, 1000); if (showBind) { Main.Notifications.Show(1, cycleSkins ? $"Press [Shift] + [{assigned}] to enable" : $"Press [{assigned}] to enable", MyFontEnum.Debug, 1000); } return; } if (cycleDir < 0) { if (cycleSkins) { for (int i = 0; i < Main.Palette.SkinsForHUD.Count; i++) { SkinInfo skin = Main.Palette.SkinsForHUD[i]; if (skin.SubtypeId == LocalInfo.SelectedSkin) { i++; if (i < Main.Palette.SkinsForHUD.Count) { LocalInfo.SelectedSkin = Main.Palette.SkinsForHUD[i].SubtypeId; } else { LocalInfo.SelectedSkin = MyStringHash.NullOrEmpty; } break; } } } else { int slot = LocalInfo.SelectedColorSlot; if (Main.Settings.selectColorZigZag) { if (slot >= 13) { slot = 0; } else if (slot >= 7) { slot -= 6; } else { slot += 7; } } else { if (++slot >= LocalInfo.ColorsMasks.Count) { slot = 0; } } LocalInfo.SelectedColorSlot = slot; } } else { if (cycleSkins) { for (int i = (Main.Palette.SkinsForHUD.Count - 1); i >= 0; i--) { SkinInfo skin = Main.Palette.SkinsForHUD[i]; if (skin.SubtypeId == LocalInfo.SelectedSkin) { i--; if (i >= 0) { LocalInfo.SelectedSkin = Main.Palette.SkinsForHUD[i].SubtypeId; } else { LocalInfo.SelectedSkin = Main.Palette.SkinsForHUD[Main.Palette.SkinsForHUD.Count - 1].SubtypeId; } break; } } } else { int slot = LocalInfo.SelectedColorSlot; if (Main.Settings.selectColorZigZag) { if (slot >= 7) { slot -= 7; } else { slot += 6; } } else { if (--slot < 0) { slot = (LocalInfo.ColorsMasks.Count - 1); } } LocalInfo.SelectedColorSlot = slot; } } if (cycleSkins) { Main.HUDSounds.PlayItem(); } else { MyAPIGateway.Session.Player.SelectedBuildColorSlot = LocalInfo.SelectedColorSlot; Main.HUDSounds.PlayClick(); } }
protected override void DoDetection(bool useHead) { ProfilerShort.Begin("DoDetection"); if (Character == MySession.Static.ControlledEntity) { MyHud.SelectedObjectHighlight.RemoveHighlight(); } var head = Character.GetHeadMatrix(false); var headPos = head.Translation - (Vector3D)head.Forward * 0.3; // Move to center of head, we don't want eyes (in front of head) Vector3D from; Vector3D dir; if (!useHead) { //Ondrej version var cameraMatrix = MySector.MainCamera.WorldMatrix; dir = cameraMatrix.Forward; from = MyUtils.LinePlaneIntersection(headPos, (Vector3)dir, cameraMatrix.Translation, (Vector3)dir); } else { //Petr version dir = head.Forward; from = headPos; } Vector3D to = from + dir * MyConstants.DEFAULT_INTERACTIVE_DISTANCE; //EnableDetectorsInArea(from); GatherDetectorsInArea(from); float closestDetector = float.MaxValue; IMyEntity closestEntity = null; IMyUseObject closestInteractive = null; foreach (var entity in m_detectableEntities) { if (entity == Character) { continue; } var use = entity.Components.Get <MyUseObjectsComponentBase>() as MyUseObjectsComponent; if (use != null) { float detectorDistance; var interactive = use.RaycastDetectors(from, to, out detectorDistance); if (Math.Abs(detectorDistance) < Math.Abs(closestDetector)) { closestDetector = detectorDistance; closestEntity = entity; closestInteractive = interactive; } } //Floating object handling - give FO useobject component! var use2 = entity as IMyUseObject; if (use2 != null) { var m = use2.ActivationMatrix; var ray = new RayD(from, to - from); var obb = new MyOrientedBoundingBoxD(m); var dist = obb.Intersects(ref ray); if (dist.HasValue && Math.Abs(dist.Value) < Math.Abs(closestDetector)) { closestDetector = (float)dist.Value; closestEntity = entity; closestInteractive = use2; } } } m_detectableEntities.Clear(); //VRageRender.MyRenderProxy.DebugDrawLine3D(from, to, Color.Red, Color.Green, true); //VRageRender.MyRenderProxy.DebugDrawSphere(headPos, 0.05f, Color.Red.ToVector3(), 1.0f, false); StartPosition = from; MyPhysics.CastRay(from, to, m_hits, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer); bool hasInteractive = false; int index = 0; while (index < m_hits.Count && (m_hits[index].HkHitInfo.Body == null || m_hits[index].HkHitInfo.GetHitEntity() == Character || m_hits[index].HkHitInfo.GetHitEntity() == null || m_hits[index].HkHitInfo.Body.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT) || m_hits[index].HkHitInfo.Body.Layer == MyPhysics.CollisionLayers.VoxelLod1CollisionLayer)) // Skip invalid hits and self character { index++; } if (index < m_hits.Count && m_hits[index].HkHitInfo.HitFraction > closestDetector - 0.05f)//compensation { // TODO: Uncomment to enforce that character must face object by front to activate it //if (TestInteractionDirection(head.Forward, h.Position - GetPosition())) //return; HitPosition = from + dir * closestDetector; MyUseObjectsComponentBase useObject; if (closestEntity.Components.TryGet <MyUseObjectsComponentBase>(out useObject)) { var detectorPhysics = useObject.DetectorPhysics; HitMaterial = detectorPhysics.GetMaterialAt(HitPosition); HitBody = ((MyPhysicsBody)detectorPhysics).RigidBody; } else { HitMaterial = closestEntity.Physics.GetMaterialAt(HitPosition); HitBody = ((MyPhysicsBody)closestEntity.Physics).RigidBody; } DetectedEntity = closestEntity; var interactive = closestInteractive; if (UseObject != null && interactive != null && UseObject != interactive) { UseObject.OnSelectionLost(); } //if (interactive != null && interactive.SupportedActions != UseActionEnum.None && (Vector3D.Distance(from, (Vector3D)h.Position)) < interactive.InteractiveDistance && Character == MySession.Static.ControlledEntity) if (interactive != null && interactive.SupportedActions != UseActionEnum.None && closestDetector * MyConstants.DEFAULT_INTERACTIVE_DISTANCE < interactive.InteractiveDistance && Character == MySession.Static.ControlledEntity) { HandleInteractiveObject(interactive); UseObject = interactive; hasInteractive = true; } } if (!hasInteractive) { if (UseObject != null) { UseObject.OnSelectionLost(); } UseObject = null; } ProfilerShort.End(); }
private void DoDetection(bool useHead, bool doModelIntersection) { bool flag; if (ReferenceEquals(base.Character, MySession.Static.ControlledEntity)) { MyHud.SelectedObjectHighlight.RemoveHighlight(); } MatrixD xd = base.Character.GetHeadMatrix(false, true, false, false, false); Vector3D translation = xd.Translation; Vector3D forward = xd.Forward; if (!useHead) { Vector3D planePoint = xd.Translation - (xd.Forward * 0.3); if (!ReferenceEquals(base.Character, MySession.Static.LocalCharacter)) { translation = planePoint; forward = xd.Forward; } else { translation = MySector.MainCamera.WorldMatrix.Translation; forward = MySector.MainCamera.WorldMatrix.Forward; translation = MyUtils.LinePlaneIntersection(planePoint, (Vector3)forward, translation, (Vector3)forward); } } Vector3D to = translation + (forward * 2.5); base.StartPosition = translation; MatrixD transform = MatrixD.CreateTranslation(translation); HkShape shape = (HkShape) new HkSphereShape(this.ShapeRadius); IMyEntity objA = null; base.ShapeKey = uint.MaxValue; base.HitPosition = Vector3D.Zero; base.HitNormal = Vector3.Zero; base.HitMaterial = MyStringHash.NullOrEmpty; base.HitTag = null; this.m_hits.Clear(); Vector3 zero = (Vector3)Vector3D.Zero; try { bool flag2; bool flag3; int num; base.EnableDetectorsInArea(translation); MyPhysics.CastShapeReturnContactBodyDatas(to, shape, ref transform, 0, 0f, this.m_hits, true); this.m_rayOrigin = translation; this.m_rayDirection = forward; this.m_hits.Sort(new Comparison <MyPhysics.HitInfo>(this.CompareHits)); if (this.m_hits.Count <= 0) { goto TR_0012; } else { flag2 = false; flag3 = false; num = 0; } goto TR_002F; TR_0017: num++; TR_002F: while (true) { if (num >= this.m_hits.Count) { break; } HkRigidBody hkEntity = this.m_hits[num].HkHitInfo.Body; IMyEntity hitEntity = this.m_hits[num].HkHitInfo.GetHitEntity(); if (!ReferenceEquals(hitEntity, base.Character)) { int num1; if (hitEntity is MyEntitySubpart) { hitEntity = hitEntity.Parent; } if (((hkEntity == null) || (hitEntity == null)) || ReferenceEquals(hitEntity, base.Character)) { num1 = 0; } else { num1 = (int)!hkEntity.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT); } flag2 = (bool)num1; flag3 = (hitEntity != null) && (hitEntity.Physics != null); if (ReferenceEquals(objA, null) & flag2) { objA = hitEntity; base.ShapeKey = this.m_hits[num].HkHitInfo.GetShapeKey(0); } if (hitEntity is MyCubeGrid) { List <MyCube> list = (hitEntity as MyCubeGrid).RayCastBlocksAllOrdered(translation, to); if ((list != null) && (list.Count > 0)) { MySlimBlock cubeBlock = list[0].CubeBlock; if (cubeBlock.FatBlock != null) { flag3 = true; objA = cubeBlock.FatBlock; base.ShapeKey = 0; } } } if (!((base.HitMaterial.Equals(MyStringHash.NullOrEmpty) & flag2) & flag3)) { if (hkEntity == null) { num++; goto TR_0017; } else { zero = this.m_hits[num].GetFixedPosition(); } } else { base.HitBody = hkEntity; base.HitNormal = this.m_hits[num].HkHitInfo.Normal; base.HitPosition = this.m_hits[num].GetFixedPosition(); base.HitMaterial = hkEntity.GetBody().GetMaterialAt(base.HitPosition); zero = (Vector3)base.HitPosition; } break; } goto TR_0017; } } finally { shape.RemoveReference(); } TR_0012: flag = false; IMyUseObject interactive = objA as IMyUseObject; base.DetectedEntity = objA; if (objA != null) { MyUseObjectsComponentBase component = null; objA.Components.TryGet <MyUseObjectsComponentBase>(out component); if (component != null) { interactive = component.GetInteractiveObject(base.ShapeKey); } if (doModelIntersection) { LineD line = new LineD(translation, to); MyCharacter character = objA as MyCharacter; if (character == null) { MyIntersectionResultLineTriangleEx?nullable; if (objA.GetIntersectionWithLine(ref line, out nullable, IntersectionFlags.ALL_TRIANGLES)) { base.HitPosition = nullable.Value.IntersectionPointInWorldSpace; base.HitNormal = nullable.Value.NormalInWorldSpace; } } else if (character.GetIntersectionWithLine(ref line, ref base.CharHitInfo, IntersectionFlags.ALL_TRIANGLES)) { base.HitPosition = base.CharHitInfo.Triangle.IntersectionPointInWorldSpace; base.HitNormal = base.CharHitInfo.Triangle.NormalInWorldSpace; base.HitTag = base.CharHitInfo; } } } if (((interactive != null) && ((interactive.SupportedActions != UseActionEnum.None) && (Vector3D.Distance(translation, zero) < interactive.InteractiveDistance))) && ReferenceEquals(base.Character, MySession.Static.ControlledEntity)) { HandleInteractiveObject(interactive); base.UseObject = interactive; flag = true; } if (!flag) { base.UseObject = null; } base.DisableDetectors(); }
private void UpdateInput() { if (MyAPIGateway.Session == null) { return; } IMyPlayer player = MyAPIGateway.Session.Player; if (player == null) { return; } IMyCharacter character = player.Character; if (character == null) { return; } IMyUseObject useObject = character.Components?.Get <MyCharacterDetectorComponent>()?.UseObject; if (useObject == null) { return; } bool isUsePressed = MyAPIGateway.Input.GetGameControl(MyControlsSpace.USE).IsNewPressed(); bool isUsePressed2 = MyAPIGateway.Input.GetGameControl(MyControlsSpace.PRIMARY_TOOL_ACTION).IsNewPressed(); IMyModelDummy dummy = useObject.Dummy; if (dummy == null) { return; } string detectorName = dummy.Name; // ... only if the detector is not a Spawndoor, in this case make Terminal available again and return; if (detectorName.Contains(DUMMY_SUFFIX) || detectorName.Contains(DUMMY_SUFFIX2)) { IMyEntity owner = useObject.Owner; if (owner == null || owner != m_block) { return; } if ((isUsePressed || isUsePressed2) && CheckReadynessClient()) { try { ShowMessageInGameAndLog("UpdateInput", "isUsePressed:[ " + isUsePressed.ToString() + "]" + "isUsePressed2:[" + isUsePressed2.ToString() + "]"); // slot already has a weapon -> remove it and add to players inventory MyRelationsBetweenPlayerAndBlock blockrelationttoplayer = ((IMyCubeBlock)Entity).GetUserRelationToOwner(MyAPIGateway.Session.Player.IdentityId); bool b = (blockrelationttoplayer == MyRelationsBetweenPlayerAndBlock.Enemies) || (blockrelationttoplayer == MyRelationsBetweenPlayerAndBlock.Neutral); ShowMessageInGameAndLog("MyRelationsBetweenPlayerAndBlock", "NotFriendly = " + b); if (b) { // ShowMessageInGameAndLog("UpdateInput", " ReplaceOwner before!"); // ReplaceOwner(player.IdentityId); ShowMessageInGameAndLog("UpdateInput", "Try send msg to server "); SendMessage_ReplaceDoor(MyAPIGateway.Session.Player.IdentityId, true, m_block.CubeGrid.CustomName); //(m_block as IMyAdvancedDoor).OpenDoor(); NeedsUpdate = MyEntityUpdateEnum.NONE; Destuctscript(); var timer3 = new Timer(10000); timer3.AutoReset = false; timer3.Elapsed += (a12, b12) => MyAPIGateway.Utilities.InvokeOnGameThread(() => { sendrefreshmsgtoserver(); }); timer3.Start(); } else { (m_block as IMyAdvancedDoor).OpenDoor(); } } catch (Exception tmp) { ShowMessageInGameAndLog("UpdateInput", "EXEPTION! " + tmp?.ToString()); } } } }