public override void UpdatePlacing(Camera cam) { if (PlayerInput.SecondaryMouseButtonClicked()) { selected = null; return; } Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); Vector2 size = ScaledSize; Rectangle newRect = new Rectangle((int)position.X, (int)position.Y, (int)size.X, (int)size.Y); if (placePosition == Vector2.Zero) { if (PlayerInput.PrimaryMouseButtonHeld()) { placePosition = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); } newRect.X = (int)position.X; newRect.Y = (int)position.Y; } else { Vector2 placeSize = size; if (ResizeHorizontal) { placeSize.X = position.X - placePosition.X; } if (ResizeVertical) { placeSize.Y = placePosition.Y - position.Y; } //don't allow resizing width/height to less than the grid size if (ResizeHorizontal && Math.Abs(placeSize.X) < Submarine.GridSize.X) { placeSize.X = Submarine.GridSize.X; } if (ResizeVertical && Math.Abs(placeSize.Y) < Submarine.GridSize.Y) { placeSize.Y = Submarine.GridSize.Y; } newRect = Submarine.AbsRect(placePosition, placeSize); if (PlayerInput.PrimaryMouseButtonReleased()) { newRect.Location -= MathUtils.ToPoint(Submarine.MainSub.Position); new Structure(newRect, this, Submarine.MainSub) { Submarine = Submarine.MainSub }; selected = null; return; } } }
public virtual void UpdatePlacing(Camera cam) { if (PlayerInput.SecondaryMouseButtonClicked()) { selected = null; return; } Vector2 placeSize = Submarine.GridSize; if (placePosition == Vector2.Zero) { Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); if (PlayerInput.PrimaryMouseButtonHeld()) { placePosition = position; } } else { Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); if (ResizeHorizontal) { placeSize.X = position.X - placePosition.X; } if (ResizeVertical) { placeSize.Y = placePosition.Y - position.Y; } Rectangle newRect = Submarine.AbsRect(placePosition, placeSize); newRect.Width = (int)Math.Max(newRect.Width, Submarine.GridSize.X); newRect.Height = (int)Math.Max(newRect.Height, Submarine.GridSize.Y); if (Submarine.MainSub != null) { newRect.Location -= MathUtils.ToPoint(Submarine.MainSub.Position); } if (PlayerInput.PrimaryMouseButtonReleased()) { CreateInstance(newRect); placePosition = Vector2.Zero; if (!PlayerInput.IsShiftDown()) { selected = null; } } newRect.Y = -newRect.Y; } }
public override void UpdatePlacing(Camera cam) { Vector2 position = Submarine.MouseToWorldGrid(cam, Submarine.MainSub); if (PlayerInput.SecondaryMouseButtonClicked()) { selected = null; return; } var potentialContainer = MapEntity.GetPotentialContainer(position); if (!ResizeHorizontal && !ResizeVertical) { if (PlayerInput.PrimaryMouseButtonClicked()) { var item = new Item(new Rectangle((int)position.X, (int)position.Y, (int)(sprite.size.X * Scale), (int)(sprite.size.Y * Scale)), this, Submarine.MainSub) { Submarine = Submarine.MainSub }; item.SetTransform(ConvertUnits.ToSimUnits(Submarine.MainSub == null ? item.Position : item.Position - Submarine.MainSub.Position), 0.0f); item.FindHull(); item.Submarine = Submarine.MainSub; if (PlayerInput.IsShiftDown()) { if (potentialContainer?.OwnInventory?.TryPutItem(item, Character.Controlled) ?? false) { SoundPlayer.PlayUISound(GUISoundType.PickItem); } } SubEditorScreen.StoreCommand(new AddOrDeleteCommand(new List <MapEntity> { item }, false)); placePosition = Vector2.Zero; return; } } else { Vector2 placeSize = size * Scale; if (placePosition == Vector2.Zero) { if (PlayerInput.PrimaryMouseButtonHeld()) { placePosition = position; } } else { if (ResizeHorizontal) { placeSize.X = Math.Max(position.X - placePosition.X, size.X); } if (ResizeVertical) { placeSize.Y = Math.Max(placePosition.Y - position.Y, size.Y); } if (PlayerInput.PrimaryMouseButtonReleased()) { var item = new Item(new Rectangle((int)placePosition.X, (int)placePosition.Y, (int)placeSize.X, (int)placeSize.Y), this, Submarine.MainSub); placePosition = Vector2.Zero; item.Submarine = Submarine.MainSub; item.SetTransform(ConvertUnits.ToSimUnits(Submarine.MainSub == null ? item.Position : item.Position - Submarine.MainSub.Position), 0.0f); item.FindHull(); //selected = null; return; } position = placePosition; } } if (potentialContainer != null) { potentialContainer.IsHighlighted = true; } //if (PlayerInput.GetMouseState.RightButton == ButtonState.Pressed) selected = null; }
/// <summary> /// Update the selection logic in submarine editor /// </summary> public static void UpdateSelecting(Camera cam) { if (resizing) { if (selectedList.Count == 0) { resizing = false; } return; } foreach (MapEntity e in mapEntityList) { e.isHighlighted = false; } if (DisableSelect) { DisableSelect = false; return; } if (GUI.MouseOn != null || !PlayerInput.MouseInsideWindow) { if (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))) { UpdateHighlightedListBox(null, false); return; } } if (MapEntityPrefab.Selected != null) { selectionPos = Vector2.Zero; selectedList.Clear(); return; } if (GUI.KeyboardDispatcher.Subscriber == null) { if (PlayerInput.KeyDown(Keys.Delete)) { selectedList.ForEach(e => { //orphaned wires may already have been removed if (!e.Removed) { e.Remove(); } }); selectedList.Clear(); } if (PlayerInput.IsCtrlDown()) { if (PlayerInput.KeyHit(Keys.C)) { Copy(selectedList); } else if (PlayerInput.KeyHit(Keys.X)) { Cut(selectedList); } else if (PlayerInput.KeyHit(Keys.V)) { Paste(cam.WorldViewCenter); } else if (PlayerInput.KeyHit(Keys.G)) { if (selectedList.Any()) { if (SelectionGroups.ContainsKey(selectedList.Last())) { // Ungroup all selected selectedList.ForEach(e => SelectionGroups.Remove(e)); } else { foreach (var entity in selectedList) { // Remove the old group, if any SelectionGroups.Remove(entity); // Create a group that can be accessed with any member SelectionGroups.Add(entity, selectedList); } } } } else if (PlayerInput.KeyHit(Keys.Z)) { SetPreviousRects(e => e.rectMemento.Undo()); } else if (PlayerInput.KeyHit(Keys.R)) { SetPreviousRects(e => e.rectMemento.Redo()); } void SetPreviousRects(Func <MapEntity, Rectangle> memoryMethod) { foreach (var e in SelectedList) { if (e.rectMemento != null) { Point diff = memoryMethod(e).Location - e.Rect.Location; // We have to call the move method, because there's a lot more than just storing the rect (in some cases) // We also have to reassign the rect, because the move method does not set the width and height. They might have changed too. // The Rect property is virtual and it's overridden for structs. Setting the rect via the property should automatically recreate the sections for resizable structures. e.Move(diff.ToVector2()); e.Rect = e.rectMemento.Current; } } } } } Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); MapEntity highLightedEntity = null; if (startMovingPos == Vector2.Zero) { List <MapEntity> highlightedEntities = new List <MapEntity>(); if (highlightedListBox != null && highlightedListBox.IsParentOf(GUI.MouseOn)) { highLightedEntity = GUI.MouseOn.UserData as MapEntity; } else { foreach (MapEntity e in mapEntityList) { if (!e.SelectableInEditor) { continue; } if (e.IsMouseOn(position)) { int i = 0; while (i < highlightedEntities.Count && e.Sprite != null && (highlightedEntities[i].Sprite == null || highlightedEntities[i].SpriteDepth < e.SpriteDepth)) { i++; } highlightedEntities.Insert(i, e); if (i == 0) { highLightedEntity = e; } } } UpdateHighlighting(highlightedEntities); } if (highLightedEntity != null) { highLightedEntity.isHighlighted = true; } } if (GUI.KeyboardDispatcher.Subscriber == null) { int up = PlayerInput.KeyDown(Keys.Up) ? 1 : 0, down = PlayerInput.KeyDown(Keys.Down) ? -1 : 0, left = PlayerInput.KeyDown(Keys.Left) ? -1 : 0, right = PlayerInput.KeyDown(Keys.Right) ? 1 : 0; int xKeysDown = (left + right); int yKeysDown = (up + down); if (xKeysDown != 0 || yKeysDown != 0) { keyDelay += (float)Timing.Step; } else { keyDelay = 0; } Vector2 nudgeAmount = Vector2.Zero; if (keyDelay >= 0.5f) { nudgeAmount.Y = yKeysDown; nudgeAmount.X = xKeysDown; } if (PlayerInput.KeyHit(Keys.Up)) { nudgeAmount.Y = 1f; } if (PlayerInput.KeyHit(Keys.Down)) { nudgeAmount.Y = -1f; } if (PlayerInput.KeyHit(Keys.Left)) { nudgeAmount.X = -1f; } if (PlayerInput.KeyHit(Keys.Right)) { nudgeAmount.X = 1f; } if (nudgeAmount != Vector2.Zero) { foreach (MapEntity entityToNudge in selectedList) { entityToNudge.Move(nudgeAmount); } } } else { keyDelay = 0; } bool isShiftDown = PlayerInput.IsShiftDown(); //started moving selected entities if (startMovingPos != Vector2.Zero) { Item targetContainer = GetPotentialContainer(position, selectedList); if (targetContainer != null) { targetContainer.IsHighlighted = true; } if (PlayerInput.PrimaryMouseButtonReleased()) { //mouse released -> move the entities to the new position of the mouse Vector2 moveAmount = position - startMovingPos; if (!isShiftDown) { moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X; moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y; } if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y || isShiftDown) { if (!isShiftDown) { moveAmount = Submarine.VectorToWorldGrid(moveAmount); } //clone if (PlayerInput.IsCtrlDown()) { var clones = Clone(selectedList); selectedList = clones; selectedList.ForEach(c => c.Move(moveAmount)); } else // move { List <MapEntity> deposited = new List <MapEntity>(); foreach (MapEntity e in selectedList) { if (e.rectMemento == null) { e.rectMemento = new Memento <Rectangle>(); e.rectMemento.Store(e.Rect); } e.Move(moveAmount); if (isShiftDown && e is Item item && targetContainer != null) { if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled)) { GUI.PlayUISound(GUISoundType.DropItem); deposited.Add(item); } else { GUI.PlayUISound(GUISoundType.PickItemFail); } } e.rectMemento.Store(e.Rect); } deposited.ForEach(entity => { selectedList.Remove(entity); }); } } startMovingPos = Vector2.Zero; } } //started dragging a "selection rectangle" else if (selectionPos != Vector2.Zero) { selectionSize.X = position.X - selectionPos.X; selectionSize.Y = selectionPos.Y - position.Y; List <MapEntity> newSelection = new List <MapEntity>();// FindSelectedEntities(selectionPos, selectionSize); if (Math.Abs(selectionSize.X) > Submarine.GridSize.X || Math.Abs(selectionSize.Y) > Submarine.GridSize.Y) { newSelection = FindSelectedEntities(selectionPos, selectionSize); } else { if (highLightedEntity != null) { if (SelectionGroups.TryGetValue(highLightedEntity, out List <MapEntity> group)) { newSelection.AddRange(group); } else { newSelection.Add(highLightedEntity); } } } if (PlayerInput.PrimaryMouseButtonReleased()) { if (PlayerInput.IsCtrlDown()) { foreach (MapEntity e in newSelection) { if (selectedList.Contains(e)) { RemoveSelection(e); } else { AddSelection(e); } } } else { selectedList = new List <MapEntity>(newSelection); //selectedList.Clear(); //newSelection.ForEach(e => AddSelection(e)); foreach (var entity in newSelection) { HandleDoorGapLinks(entity, onGapFound: (door, gap) => { door.RefreshLinkedGap(); if (!selectedList.Contains(gap)) { selectedList.Add(gap); } }, onDoorFound: (door, gap) => { if (!selectedList.Contains(door.Item)) { selectedList.Add(door.Item); } }); } } //select wire if both items it's connected to are selected var selectedItems = selectedList.Where(e => e is Item).Cast <Item>().ToList(); foreach (Item item in selectedItems) { if (item.Connections == null) { continue; } foreach (Connection c in item.Connections) { foreach (Wire w in c.Wires) { if (w == null || selectedList.Contains(w.Item)) { continue; } if (w.OtherConnection(c) != null && selectedList.Contains(w.OtherConnection(c).Item)) { selectedList.Add(w.Item); } } } } selectionPos = Vector2.Zero; selectionSize = Vector2.Zero; } } //default, not doing anything specific yet else { if (PlayerInput.PrimaryMouseButtonHeld() && PlayerInput.KeyUp(Keys.Space) && (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn)))) { //if clicking a selected entity, start moving it foreach (MapEntity e in selectedList) { if (e.IsMouseOn(position)) { startMovingPos = position; } } selectionPos = position; //stop camera movement to prevent accidental dragging or rect selection Screen.Selected.Cam.StopMovement(); } } }
/// <summary> /// Update the selection logic in submarine editor /// </summary> public static void UpdateSelecting(Camera cam) { if (resizing) { if (selectedList.Count == 0) { resizing = false; } return; } foreach (MapEntity e in mapEntityList) { e.isHighlighted = false; } if (DisableSelect) { DisableSelect = false; return; } if (GUI.MouseOn != null || !PlayerInput.MouseInsideWindow) { if (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn))) { UpdateHighlightedListBox(null, false); return; } } if (MapEntityPrefab.Selected != null) { selectionPos = Vector2.Zero; selectedList.Clear(); return; } if (GUI.KeyboardDispatcher.Subscriber == null) { if (PlayerInput.KeyHit(Keys.Delete)) { if (selectedList.Any()) { SubEditorScreen.StoreCommand(new AddOrDeleteCommand(selectedList, true)); } selectedList.ForEach(e => { if (!e.Removed) { e.Remove(); } }); selectedList.Clear(); } if (PlayerInput.IsCtrlDown()) { #if DEBUG if (PlayerInput.KeyHit(Keys.D)) { bool terminate = false; foreach (MapEntity entity in selectedList) { if (entity is Item item && item.GetComponent <Planter>() is { } planter) { planter.Update(1.0f, cam); for (var i = 0; i < planter.GrowableSeeds.Length; i++) { Growable seed = planter.GrowableSeeds[i]; PlantSlot slot = planter.PlantSlots.ContainsKey(i) ? planter.PlantSlots[i] : Planter.NullSlot; if (seed == null) { continue; } seed.CreateDebugHUD(planter, slot); terminate = true; break; } } if (terminate) { break; } } } #endif if (PlayerInput.KeyHit(Keys.C)) { Copy(selectedList); } else if (PlayerInput.KeyHit(Keys.X)) { Cut(selectedList); } else if (PlayerInput.KeyHit(Keys.V)) { Paste(cam.WorldViewCenter); } else if (PlayerInput.KeyHit(Keys.G)) { if (selectedList.Any()) { if (SelectionGroups.ContainsKey(selectedList.Last())) { // Ungroup all selected selectedList.ForEach(e => SelectionGroups.Remove(e)); } else { foreach (var entity in selectedList) { // Remove the old group, if any SelectionGroups.Remove(entity); // Create a group that can be accessed with any member SelectionGroups.Add(entity, selectedList); } } } } } } Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition); MapEntity highLightedEntity = null; if (startMovingPos == Vector2.Zero) { List <MapEntity> highlightedEntities = new List <MapEntity>(); if (highlightedListBox != null && highlightedListBox.IsParentOf(GUI.MouseOn)) { highLightedEntity = GUI.MouseOn.UserData as MapEntity; } else { foreach (MapEntity e in mapEntityList) { if (!e.SelectableInEditor) { continue; } if (e.IsMouseOn(position)) { int i = 0; while (i < highlightedEntities.Count && e.Sprite != null && (highlightedEntities[i].Sprite == null || highlightedEntities[i].SpriteDepth < e.SpriteDepth)) { i++; } highlightedEntities.Insert(i, e); if (i == 0) { highLightedEntity = e; } } } UpdateHighlighting(highlightedEntities); } if (highLightedEntity != null) { highLightedEntity.isHighlighted = true; } } if (GUI.KeyboardDispatcher.Subscriber == null) { int up = PlayerInput.KeyDown(Keys.Up) ? 1 : 0, down = PlayerInput.KeyDown(Keys.Down) ? -1 : 0, left = PlayerInput.KeyDown(Keys.Left) ? -1 : 0, right = PlayerInput.KeyDown(Keys.Right) ? 1 : 0; int xKeysDown = (left + right); int yKeysDown = (up + down); if (xKeysDown != 0 || yKeysDown != 0) { keyDelay += (float)Timing.Step; } else { keyDelay = 0; } Vector2 nudgeAmount = Vector2.Zero; if (keyDelay >= 0.5f) { nudgeAmount.Y = yKeysDown; nudgeAmount.X = xKeysDown; } if (PlayerInput.KeyHit(Keys.Up)) { nudgeAmount.Y = 1f; } if (PlayerInput.KeyHit(Keys.Down)) { nudgeAmount.Y = -1f; } if (PlayerInput.KeyHit(Keys.Left)) { nudgeAmount.X = -1f; } if (PlayerInput.KeyHit(Keys.Right)) { nudgeAmount.X = 1f; } if (nudgeAmount != Vector2.Zero) { foreach (MapEntity entityToNudge in selectedList) { entityToNudge.Move(nudgeAmount); } } } else { keyDelay = 0; } bool isShiftDown = PlayerInput.IsShiftDown(); //started moving selected entities if (startMovingPos != Vector2.Zero) { Item targetContainer = GetPotentialContainer(position, selectedList); if (targetContainer != null) { targetContainer.IsHighlighted = true; } if (PlayerInput.PrimaryMouseButtonReleased()) { //mouse released -> move the entities to the new position of the mouse Vector2 moveAmount = position - startMovingPos; if (!isShiftDown) { moveAmount.X = (float)(moveAmount.X > 0.0f ? Math.Floor(moveAmount.X / Submarine.GridSize.X) : Math.Ceiling(moveAmount.X / Submarine.GridSize.X)) * Submarine.GridSize.X; moveAmount.Y = (float)(moveAmount.Y > 0.0f ? Math.Floor(moveAmount.Y / Submarine.GridSize.Y) : Math.Ceiling(moveAmount.Y / Submarine.GridSize.Y)) * Submarine.GridSize.Y; } if (Math.Abs(moveAmount.X) >= Submarine.GridSize.X || Math.Abs(moveAmount.Y) >= Submarine.GridSize.Y || isShiftDown) { if (!isShiftDown) { moveAmount = Submarine.VectorToWorldGrid(moveAmount); } //clone if (PlayerInput.IsCtrlDown()) { var clones = Clone(selectedList).Where(c => c != null).ToList(); selectedList = clones; SubEditorScreen.StoreCommand(new AddOrDeleteCommand(clones, false)); selectedList.ForEach(c => c.Move(moveAmount)); } else // move { var oldRects = selectedList.Select(e => e.Rect).ToList(); List <MapEntity> deposited = new List <MapEntity>(); foreach (MapEntity e in selectedList) { e.Move(moveAmount); if (isShiftDown && e is Item item && targetContainer != null) { if (targetContainer.OwnInventory.TryPutItem(item, Character.Controlled)) { SoundPlayer.PlayUISound(GUISoundType.DropItem); deposited.Add(item); } else { SoundPlayer.PlayUISound(GUISoundType.PickItemFail); } } } SubEditorScreen.StoreCommand(new TransformCommand(new List <MapEntity>(selectedList), selectedList.Select(entity => entity.Rect).ToList(), oldRects, false)); if (deposited.Any() && deposited.Any(entity => entity is Item)) { var depositedItems = deposited.Where(entity => entity is Item).Cast <Item>().ToList(); SubEditorScreen.StoreCommand(new InventoryPlaceCommand(targetContainer.OwnInventory, depositedItems, false)); } deposited.ForEach(entity => { selectedList.Remove(entity); }); } } startMovingPos = Vector2.Zero; } } //started dragging a "selection rectangle" else if (selectionPos != Vector2.Zero) { selectionSize.X = position.X - selectionPos.X; selectionSize.Y = selectionPos.Y - position.Y; List <MapEntity> newSelection = new List <MapEntity>();// FindSelectedEntities(selectionPos, selectionSize); if (Math.Abs(selectionSize.X) > Submarine.GridSize.X || Math.Abs(selectionSize.Y) > Submarine.GridSize.Y) { newSelection = FindSelectedEntities(selectionPos, selectionSize); } else { if (highLightedEntity != null) { if (SelectionGroups.TryGetValue(highLightedEntity, out List <MapEntity> group)) { newSelection.AddRange(group); } else { newSelection.Add(highLightedEntity); } } } if (PlayerInput.PrimaryMouseButtonReleased()) { if (PlayerInput.IsCtrlDown()) { foreach (MapEntity e in newSelection) { if (selectedList.Contains(e)) { RemoveSelection(e); } else { AddSelection(e); } } } else { selectedList = new List <MapEntity>(newSelection); //selectedList.Clear(); //newSelection.ForEach(e => AddSelection(e)); foreach (var entity in newSelection) { HandleDoorGapLinks(entity, onGapFound: (door, gap) => { door.RefreshLinkedGap(); if (!selectedList.Contains(gap)) { selectedList.Add(gap); } }, onDoorFound: (door, gap) => { if (!selectedList.Contains(door.Item)) { selectedList.Add(door.Item); } }); } } //select wire if both items it's connected to are selected var selectedItems = selectedList.Where(e => e is Item).Cast <Item>().ToList(); foreach (Item item in selectedItems) { if (item.Connections == null) { continue; } foreach (Connection c in item.Connections) { foreach (Wire w in c.Wires) { if (w == null || selectedList.Contains(w.Item)) { continue; } if (w.OtherConnection(c) != null && selectedList.Contains(w.OtherConnection(c).Item)) { selectedList.Add(w.Item); } } } } selectionPos = Vector2.Zero; selectionSize = Vector2.Zero; } } //default, not doing anything specific yet else { if (PlayerInput.PrimaryMouseButtonHeld() && PlayerInput.KeyUp(Keys.Space) && (highlightedListBox == null || (GUI.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUI.MouseOn)))) { //if clicking a selected entity, start moving it foreach (MapEntity e in selectedList) { if (e.IsMouseOn(position)) { startMovingPos = position; } } selectionPos = position; //stop camera movement to prevent accidental dragging or rect selection Screen.Selected.Cam.StopMovement(); } } }