/// <summary> /// Find the correct position to add a node. /// </summary> /// <param name="camera"></param> /// <param name="from"></param> /// <returns></returns> private Vector3 AddPosition(Camera camera, WayPoint.Node from) { bool asRoad = false; float height = from.RenderPosition(asRoad).Z; Vector3 hit = MouseEdit.FindAtHeight(camera, MouseInput.Position, height); return(hit); }
/// <summary> /// Drag the current node/edge/path by mouse movement. Includes raise/lower /// as well as horizontal drag. /// </summary> /// <param name="camera"></param> private void DoDrag(Camera camera) { Vector3 delta = Vector3.Zero; if (mode == Mode.Drag) { Vector3 oldPos = MouseEdit.FindAtHeight(camera, MouseInput.PrevPosition, height); Vector3 newPos = MouseEdit.FindAtHeight(camera, MouseInput.Position, height); delta = newPos - oldPos; } if (mode == Mode.Raise) { float dheight = MouseInput.Position.Y - MouseInput.PrevPosition.Y; float kUpDownSpeed = -0.002f; dheight *= kUpDownSpeed; Vector3 dragPos = camera.ActualFrom; bool asRoad = false; if (node != null) { dragPos = node.RenderPosition(asRoad); } if (edge != null) { dragPos = (edge.Node0.RenderPosition(asRoad) + edge.Node1.RenderPosition(asRoad)) * 0.5f; } float dist = Vector3.Distance(dragPos, camera.ActualFrom); dheight *= dist; delta.Z = dheight; } if ((delta != Vector3.Zero) && (Path != null)) { if (actOnPath) { MovePath(Path, delta); } else if (node != null) { MoveNode(node, delta); } else if (edge != null) { MoveEdge(edge, delta); } skeletonTimer = kSkeletonTime; } }
} // end of MaterialPicker c'tor /// <summary> /// Sample the type under the cursor and translate to a UISlot. /// Return -1 on no terrain. /// </summary> /// <returns></returns> public int SampleType() { Vector2 pos = InGame.inGame.Cursor3D.Position2d; if (MouseEdit.TriggerSample()) { Vector3 p = MouseEdit.HitInfo.TerrainPosition; pos = new Vector2(p.X, p.Y); } ushort t = Terrain.GetMaterialType(pos); return(TerrainMaterial.IsValid(t, false, false) ? Terrain.MaterialIndexToUISlot(t) : -1); }
} // end of OnActivate() public override void OnDeactivate() { //base.OnDeactivate(); if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { // Ensure that the selection highlight is off. TouchEdit touchEdit = Boku.InGame.inGame.TouchEdit; touchEdit.KillSelectionHighlight(); } else if (GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse) { // Ensure that the selection highlight is off. MouseEdit mouseEdit = Boku.InGame.inGame.MouseEdit; mouseEdit.KillSelectionHighlight(); } sliderActive = false; groundMenu.Deactivate(); nodeMenu.Deactivate(); edgeMenu.Deactivate(); //make sure the color palette doesn't stay up Boku.InGame.ColorPalette.Active = false; } // end of OnDeactivate()
/// <summary> /// Do a LOS check for a hypothetical node at given position with standard radius. /// </summary> /// <param name="camera"></param> /// <param name="objPos"></param> /// <returns></returns> private bool LOSCheck(Camera camera, Vector3 objPos) { return(MouseEdit.MouseOver(camera, objPos, WayPoint.Node.Radius)); }
private void UpdateKeyboardMouse() { Camera camera = Boku.InGame.inGame.shared.camera; MouseEdit mouseEdit = Boku.InGame.inGame.MouseEdit; MouseEdit.MouseHitInfo hitInfo = MouseEdit.HitInfo; // Don't update mouseOver if the menus are active. This way the focus state will be preserved. if (!MenusActive && !SliderActive) { mouseOver.ActOnPath = KeyboardInput.ShiftIsPressed; mouseOver.Update(inGame, camera); // If the user presses the left button while not over anything // start adding a plain path. if (!mouseOver.Adding && !mouseOver.Adjusting && MouseInput.Left.WasPressed) { Road.GenIndex = 0; mouseOver.NewPath(hitInfo.TerrainPosition, focusColorIndex); } } // Check for Escape to cancel adding. // Also allow clicking the right button to cancel. if (mouseOver.Adding && (Actions.Cancel.WasPressed || MouseInput.Right.WasPressed)) { Actions.Cancel.ClearAllWasPressedState(); MouseInput.Right.ClearAllWasPressedState(); if (mouseOver.Adding) { mouseOver.StopAdding(); } } // Check to see if any of the menus need activating. if (MouseInput.Right.WasPressed) { // The menus may change depending on whether or not the full path is selected. SetUpMenus(); if (mouseOver.Over) { if (mouseOver.node != null) { nodeMenu.Activate(new Vector2(MouseInput.Position.X, MouseInput.Position.Y)); } if (mouseOver.edge != null) { edgeMenu.Activate(new Vector2(MouseInput.Position.X, MouseInput.Position.Y)); } } else { groundMenu.Activate(new Vector2(MouseInput.Position.X, MouseInput.Position.Y)); menuPosition = hitInfo.TerrainPosition; } } groundMenu.Update(); nodeMenu.Update(); edgeMenu.Update(); // See if we've tried to change path types. if (mouseOver.Over && mouseOver.Path != null && mouseOver.node != null && !MenusActive && !sliderActive) { if (Actions.Up.WasPressedOrRepeat) { mouseOver.Path.Road.AdvanceGen(1); } if (Actions.Down.WasPressedOrRepeat) { mouseOver.Path.Road.AdvanceGen(-1); } } // Change edge direction? if (mouseOver.Over && mouseOver.Path != null && mouseOver.edge != null) { if (Actions.Up.WasPressedOrRepeat) { if (mouseOver.ActOnPath) { mouseOver.Path.IncDir(); } else { mouseOver.edge.IncDir(); } } if (Actions.Down.WasPressedOrRepeat) { if (mouseOver.ActOnPath) { mouseOver.Path.DecDir(); } else { mouseOver.edge.DecDir(); } } } // Color palette support. if (mouseOver.Over && mouseOver.Path != null && !MenusActive && !sliderActive) { focusColorIndex = ColorPalette.GetIndexFromColor(mouseOver.Path.Color); Boku.InGame.ColorPalette.Active = true; int numColors = Boku.InGame.ColorPalette.NumEntries; if (Actions.Left.WasPressedOrRepeat) { focusColorIndex = (focusColorIndex + numColors - 1) % numColors; mouseOver.Path.Color = ColorPalette.GetColorFromIndex(focusColorIndex); Foley.PlayColorChange(); Boku.InGame.IsLevelDirty = true; } if (Actions.Right.WasPressedOrRepeat) { focusColorIndex = (focusColorIndex + 1) % numColors; mouseOver.Path.Color = ColorPalette.GetColorFromIndex(focusColorIndex); Foley.PlayColorChange(); Boku.InGame.IsLevelDirty = true; } } else { Boku.InGame.ColorPalette.Active = false; } // // Set up correct HelpOverlay // if (mouseOver.Over) { if (mouseOver.ActOnPath) { HelpOverlay.ReplaceTop("MouseEditPathsFocusPath"); } else if (mouseOver.node != null) { HelpOverlay.ReplaceTop("MouseEditPathsFocusNode"); } else if (mouseOver.edge != null) { HelpOverlay.ReplaceTop("MouseEditPathsFocusEdge"); } } }
private void HandleMouseInput(Camera uicamera) { if (GamePadInput.ActiveMode != GamePadInput.InputMode.KeyboardMouse) { return; } // If the mouse took over from the touch, it should clear any // highlights the touch had going. Boku.InGame.inGame.TouchEdit.Clear(); Camera camera = Boku.InGame.inGame.shared.camera; MouseEdit mouseEdit = Boku.InGame.inGame.MouseEdit; MouseEdit.MouseHitInfo hitInfo = null; hitInfo = MouseEdit.HitInfo; mouseEdit.DoObject(camera); if (hitInfo.HaveActor) { FocusActor = hitInfo.ActorHit; focusColorIndex = ColorPalette.GetIndexFromColor(FocusActor.Classification.Color); Boku.InGame.ColorPalette.Active = true; } else { FocusActor = null; Boku.InGame.ColorPalette.Active = false; } if (MouseInput.Left.WasReleased) { selectedActor = null; } //don't add if we detected a paste if (MouseInput.Left.WasPressed && !MenusActive && (mouseEdit.MiddleAction != true)) { MouseInput.Left.ClearAllWasPressedState(); if (FocusActor != null) { // Start draggin if over actor. selectedActor = FocusActor; actorOffset = selectedActor.Movement.Position - hitInfo.TerrainPosition; } else if (!MenusActive && !SliderActive && inGame.editObjectUpdateObj.newItemSelectorShim.State != UIShim.States.Active) { // No actor in focus so activate AddItem menu. Vector2 position = new Vector2(hitInfo.TerrainPosition.X, hitInfo.TerrainPosition.Y); inGame.editObjectUpdateObj.ActivateNewItemSelector(position, true); } } if (MouseInput.Left.IsPressed && (selectedActor != null) && (hitInfo != null)) { Vector3 position = hitInfo.TerrainPosition + actorOffset; selectedActor.Movement.Position = Boku.InGame.SnapPosition(position); // Try and keep the bot directly under the mouse cursor while still being at the correct height. // A possible alternative would be to use the cursor's 2d position for the bot and just have the // bot float at the appropriate height over the cursor. This would allow more exact placement of // bots over terrain but it would mean a visual disconnect between where the cursor is and where // the bot is. There would also be a jump when the bot is first clicked on since the terrain // position of the cursor is most likely further back than the bot's current position. if (hitInfo.VerticalOffset == 0.0f) { Vector3 terrainToCameraDir = hitInfo.TerrainPosition - camera.From; terrainToCameraDir.Normalize(); position = hitInfo.TerrainPosition + terrainToCameraDir * (selectedActor.EditHeight / terrainToCameraDir.Z); selectedActor.Movement.Position = Boku.InGame.SnapPosition(position); } // If the actor is supposed to stay above water, try to enforce that. // This can have some strange visual effects since it forces the actor to // float above where the mouse cursor is but the alternative is to have // actor get dragged under water. if (selectedActor.StayAboveWater) { float waterAlt = Terrain.GetWaterBase(position); if (waterAlt != 0) { position.Z = waterAlt + selectedActor.EditHeight; selectedActor.Movement.Position = Boku.InGame.SnapPosition(position); } } Boku.InGame.IsLevelDirty = true; } if (MouseInput.Right.WasReleased) { menuActor = FocusActor; menuCursorPosition = hitInfo.TerrainPosition; // We need to do this repeatedly since the Paste option will // change depending on what's in the cut/paste buffer. SetUpMenus(); if (FocusActor == null) { actorMenu.Deactivate(); noActorMenu.Activate(new Vector2(MouseInput.Position.X, MouseInput.Position.Y)); } else { noActorMenu.Deactivate(); actorMenu.Activate(new Vector2(MouseInput.Position.X, MouseInput.Position.Y)); // Turn off any thought balloons so they don't clutter the menu. ThoughtBalloonManager.RemoveThoughts(FocusActor); } } noActorMenu.Update(); actorMenu.Update(); // Support for changing tree types via up/down arrow keys. if (FocusActor != null && FocusActor.Classification.name == "tree") { inGame.editObjectUpdateObj.MakeTreeChange(FocusActor); } // Color palette support. if (FocusActor != null && !MenusActive && !sliderActive) { int numColors = Boku.InGame.ColorPalette.NumEntries; if (Actions.Left.WasPressedOrRepeat) { focusColorIndex = (focusColorIndex + numColors - 1) % numColors; shared.curObjectColor = focusColorIndex; FocusActor.ClassColor = ColorPalette.GetColorFromIndex(focusColorIndex); Foley.PlayColorChange(); Boku.InGame.IsLevelDirty = true; } if (Actions.Right.WasPressedOrRepeat) { focusColorIndex = (focusColorIndex + 1) % numColors; shared.curObjectColor = focusColorIndex; FocusActor.ClassColor = ColorPalette.GetColorFromIndex(focusColorIndex); Foley.PlayColorChange(); Boku.InGame.IsLevelDirty = true; } } // Align NSEW if (FocusActor != null && !MenusActive && !sliderActive) { if (Actions.Up.WasPressedOrRepeat) { // Rotate clockwise. float targetRotation = MathHelper.PiOver2 * (int)((FocusActor.Movement.RotationZ + MathHelper.TwoPi - 0.0001f) / MathHelper.PiOver2); FocusActor.Movement.RotationZ = targetRotation; Foley.PlayClickUp(); Boku.InGame.IsLevelDirty = true; } if (Actions.Down.WasPressedOrRepeat) { // Rotate counter-clockwise. float targetRotation = MathHelper.PiOver2 * (int)((FocusActor.Movement.RotationZ + MathHelper.PiOver2 + 0.0001f) / MathHelper.PiOver2); FocusActor.Movement.RotationZ = targetRotation; Foley.PlayClickDown(); Boku.InGame.IsLevelDirty = true; } } // Cut/Copy/Paste via keyboard. if (Actions.Cut.WasPressed && FocusActor != null) { inGame.editObjectUpdateObj.CutAction(FocusActor); } if (Actions.Copy.WasPressed && FocusActor != null) { inGame.editObjectUpdateObj.CopyAction(FocusActor); } if (Actions.Paste.WasPressed) { inGame.editObjectUpdateObj.PasteAction(null, hitInfo.TerrainPosition); } // // Figure out help overlay mode. // if (inGame.editObjectUpdateObj.newItemSelectorShim.State == UIShim.States.Active) { // The pie menu is active. HelpOverlay.ReplaceTop("MouseObjectEditAddItemMenu"); } else if (hitInfo != null && hitInfo.HaveActor) { // We have an actor in focus. if (FocusActor != null && FocusActor.Classification.name == "tree") { HelpOverlay.ReplaceTop("MouseEditEditObjectFocusTree"); } else { HelpOverlay.ReplaceTop("MouseEditEditObjectFocus"); } } }
public void HandleMouseInput() { if (GamePadInput.ActiveMode != GamePadInput.InputMode.KeyboardMouse) { return; } // In eyedropper mode, show the pointy cursor. if (KeyboardInput.AltIsPressed) { inGame.Cursor3D.Rep = Cursor3D.Visual.Pointy; inGame.Cursor3D.Hidden = false; } else { inGame.Cursor3D.Hidden = true; } if (KeyboardInput.AltIsPressed) { // Sample the current terrain. if (MouseEdit.TriggerSample()) { MouseInput.Left.IgnoreUntilReleased = true; // Prevent terrain from being painted when Alt is being used to select material. editMode = Terrain.EditMode.Noop; Vector3 p = MouseEdit.HitInfo.TerrainPosition; Vector2 pos = new Vector2(p.X, p.Y); ushort matIdx = Terrain.GetMaterialType(pos); if (TerrainMaterial.IsValid(matIdx, false, false)) { Terrain.CurrentMaterialIndex = matIdx; Foley.PlayCut(); } } } else if (!PickerXInUse && !PickerYInUse) { if (DebouncePending) { return; } if (GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse) { // Set the mode based on whether or not // option keys are pressed. if (MouseInput.Left.WasPressed) { editMode = Terrain.EditMode.PaintAndAddMaterial; if (KeyboardInput.ShiftIsPressed) { editMode = Terrain.EditMode.PaintMaterial; } else if (KeyboardInput.CtrlIsPressed) { editMode = Terrain.EditMode.AddAtCenter; } } } } }
} // end of BasePicker RestorePreviousChoice() public virtual void Update(PerspectiveUICamera camera) { if (active) { if (hidden) { // Note, even though we're hidden we may still be rendering our fade out. double elapsedTime = Time.WallClockTotalSeconds - startFadeTime; if (elapsedTime >= fadeTime) { Alpha = 0.0f; } else { Alpha = 1.0f - (float)(elapsedTime / fadeTime); } } else { // Not hidden, so respond to user input. int scroll = MouseInput.ScrollWheel - MouseInput.PrevScrollWheel; if (Actions.PickerRight.WasPressedOrRepeat || scroll > 0) { Actions.PickerRight.ClearAllWasPressedState(); DecrementFocus(); } if (Actions.PickerLeft.WasPressedOrRepeat || scroll < 0) { Actions.PickerLeft.ClearAllWasPressedState(); IncrementFocus(); } if (Actions.Select.WasPressed) { Actions.Select.ClearAllWasPressedState(); SelectCurrentChoice(); Foley.PlayPressA(); } if (Actions.Cancel.WasPressedOrRepeat) { Actions.Cancel.ClearAllWasPressedState(); RestorePreviousChoice(); Foley.PlayBack(); } bool handled = false; if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch) { handled = HandleTouchInput(camera); } else if (GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse) { handled = HandleMouseInput(camera); } if (!handled) { // If the user clicked but didn't hit any of the picker elements, close the picker. // If alt is pressed, they must be in eyedropper mode. if ((MouseInput.Left.WasPressed && !KeyboardInput.AltIsPressed) || (TouchGestureManager.Get().TapGesture.WasRecognized)) { SelectCurrentChoice(); Foley.PlayPressA(); } else if (Actions.Sample.WasPressed || MouseEdit.TriggerSample() || TouchEdit.TriggerSample()) { Actions.Sample.ClearAllWasPressedState(); int t = OnSampleType(); if (t >= 0) { OnSetType(t); Point selection = grid.SelectionIndex; selection.X = t; grid.SelectionIndex = selection; Foley.PlayCut(); } else { Foley.PlayNoBudget(); } } } grid.Update(ref worldMatrix); } } // end if active } // end of BasePicker Update()
public void UpdateSensors(BrainCategories category) { UpdateUserControlled(); UpdateIsTurning(); UpdateMouseButtonPresence(); if (IsLeftMouseButtonPresent) { MouseEdit.DisableLeftDrag(); } if (IsRightMouseButtonPresent) { MouseEdit.DisableRightOrbit(); } for (int i = 0; i < reflexes.Count; i++) { Reflex reflex = reflexes[i] as Reflex; reflex.targetSet.Clear(); } if (reflexes.Count > 0) { UpdateGameThingSensors(category); for (int indentationLevel = 0; indentationLevel <= maxReflexIndentation; ++indentationLevel) { // After evaluating root-level reflexes, open up to all sensor categories. if (indentationLevel > 0) { category = BrainCategories.NotSpecified; } for (int i = 0; i < reflexes.Count; i++) { Reflex reflex = reflexes[i]; // Only evaluate reflexes at the current level of indentation. if (reflex.Indentation != indentationLevel) { continue; } // Only evaluate sub-reflexes of parents that evaluated true except // in the case where the reflex actuator is movement based. if (reflex.Parent != null && !reflex.Parent.targetSet.Action) { // Nested reflexes with once modifiers need to clear their "once" state. reflex.ResetOnceModifiers(); // Nested reflexes with active mouse targets should still be acted on // so create valid target and action sets for them. Note that this // only applies to reflexes with a movement actuator. This is so you // can have WHEN MouseLeft DO Move and the result will be that the // bot continues to move toward the target (position or bot) even // after the parent reflex goes false. bool mouseTarget = reflex.MousePosition != null || reflex.MouseActor != null; if (mouseTarget && reflex.IsMovement) { // Create a sensor target set if (reflex.MouseActor != null) { // We need to add the mouse actor to the targetSet. SensorTarget target = SensorTargetSpares.Alloc(); target.Init(reflex.Task.GameActor, reflex.MouseActor); reflex.targetSet.Add(target); } else if (reflex.MousePosition != null) { // We need to add the mouse position to the targetSet. SensorTarget target = SensorTargetSpares.Alloc(); target.GameThing = GameActor; target.Position = reflex.MousePosition.Value; target.Direction = target.Position - reflex.Task.GameActor.Movement.Position; target.Range = target.Direction.Length(); target.Direction /= target.Range; reflex.targetSet.Add(target); } reflex.targetSet.ActionMouseTarget = true; reflex.CreateActionSet(GameActor, 0); } continue; } // Don't evaluate reflexes that don't match the given categories, if any were specified. if ((category != BrainCategories.NotSpecified) && (reflex.Sensor == null || !reflex.Sensor.Categories.Get((int)category))) { continue; } reflex.Update(GameActor, i); } } } }