Example #1
0
        private bool ToggleCharacterMode(GUIButton button, object obj)
        {
            selectedTab = -1;

            characterMode = !characterMode;
            //button.Color = (characterMode) ? Color.Gold : Color.White;

            wiringMode = false;

            if (characterMode)
            {
                CreateDummyCharacter();
            }
            else if (dummyCharacter != null)
            {
                RemoveDummyCharacter();
            }

            foreach (MapEntity me in MapEntity.mapEntityList)
            {
                me.IsHighlighted = false;
            }

            MapEntity.DeselectAll();

            return(true);
        }
Example #2
0
        public override void Deselect()
        {
            base.Deselect();

            GUIComponent.ForceMouseOn(null);

            MapEntityPrefab.Selected = null;

            MapEntity.DeselectAll();

            if (characterMode)
            {
                ToggleCharacterMode();
            }

            if (wiringMode)
            {
                ToggleWiringMode();
            }

            SoundPlayer.OverrideMusicType = null;
            for (int i = 0; i < Sounds.SoundManager.DefaultSourceCount; i++)
            {
                Sounds.SoundManager.Resume(i);
            }

            if (dummyCharacter != null)
            {
                dummyCharacter.Remove();
                dummyCharacter = null;
                GameMain.World.ProcessChanges();
            }
        }
Example #3
0
 public static void RemoveSelection(MapEntity entity)
 {
     selectedList.Remove(entity);
     HandleDoorGapLinks(entity,
                        onGapFound: (door, gap) => selectedList.Remove(gap),
                        onDoorFound: (door, gap) => selectedList.Remove(door.Item));
 }
Example #4
0
        private bool ToggleWiringMode(GUIButton button, object obj)
        {
            wiringMode = !wiringMode;

            characterMode = false;

            if (wiringMode)
            {
                CreateDummyCharacter();

                var screwdriverPrefab = ItemPrefab.list.Find(ip => ip.Name == "Screwdriver") as ItemPrefab;

                var item = new Item(screwdriverPrefab, Vector2.Zero, null);

                dummyCharacter.Inventory.TryPutItem(item, null, new List <InvSlotType>()
                {
                    InvSlotType.RightHand
                });

                wiringToolPanel = CreateWiringPanel();
            }
            else
            {
                RemoveDummyCharacter();
            }

            MapEntity.DeselectAll();

            return(true);
        }
Example #5
0
        private static void UpdateHighlightedListBox(List <MapEntity> highlightedEntities)
        {
            if (highlightedEntities == null || highlightedEntities.Count < 2)
            {
                highlightedListBox = null;
                return;
            }
            if (highlightedListBox != null)
            {
                if (GUI.MouseOn == highlightedListBox || highlightedListBox.IsParentOf(GUI.MouseOn))
                {
                    return;
                }
                if (highlightedEntities.SequenceEqual(highlightedList))
                {
                    return;
                }
            }

            highlightedList = highlightedEntities;

            highlightedListBox = new GUIListBox(new RectTransform(new Point(180, highlightedEntities.Count * 18 + 5), GUI.Canvas)
            {
                ScreenSpaceOffset = PlayerInput.MousePosition.ToPoint() + new Point(15)
            }, style: "GUIToolTip");

            foreach (MapEntity entity in highlightedEntities)
            {
                var textBlock = new GUITextBlock(new RectTransform(new Point(highlightedListBox.Content.Rect.Width, 15), highlightedListBox.Content.RectTransform),
                                                 ToolBox.LimitString(entity.Name, GUI.SmallFont, 140), font: GUI.SmallFont)
                {
                    UserData = entity
                };
            }

            highlightedListBox.OnSelected = (GUIComponent component, object obj) =>
            {
                MapEntity entity = obj as MapEntity;

                if (PlayerInput.KeyDown(Keys.LeftControl) ||
                    PlayerInput.KeyDown(Keys.RightControl))
                {
                    if (selectedList.Contains(entity))
                    {
                        selectedList.Remove(entity);
                    }
                    else
                    {
                        selectedList.Add(entity);
                    }
                }
                else
                {
                    SelectEntity(entity);
                }

                return(true);
            };
        }
Example #6
0
        private static void UpdateHighlightedListBox(List <MapEntity> highlightedEntities)
        {
            if (highlightedEntities == null || highlightedEntities.Count < 2)
            {
                highlightedListBox = null;
                return;
            }
            if (highlightedListBox != null)
            {
                if (GUIComponent.MouseOn == highlightedListBox || highlightedListBox.IsParentOf(GUIComponent.MouseOn))
                {
                    return;
                }
                if (highlightedEntities.SequenceEqual(highlightedList))
                {
                    return;
                }
            }

            highlightedList = highlightedEntities;

            highlightedListBox = new GUIListBox(
                new Rectangle((int)PlayerInput.MousePosition.X + 15, (int)PlayerInput.MousePosition.Y + 15, 150, highlightedEntities.Count * 18 + 5),
                null, Alignment.TopLeft, "GUIToolTip", null, false);

            foreach (MapEntity entity in highlightedEntities)
            {
                var textBlock = new GUITextBlock(
                    new Rectangle(0, 0, highlightedListBox.Rect.Width, 18),
                    ToolBox.LimitString(entity.Name, GUI.SmallFont, 140), "", Alignment.TopLeft, Alignment.CenterLeft, highlightedListBox, false, GUI.SmallFont);

                textBlock.UserData = entity;
            }

            highlightedListBox.OnSelected = (GUIComponent component, object obj) =>
            {
                MapEntity entity = obj as MapEntity;

                if (PlayerInput.KeyDown(Keys.LeftControl) ||
                    PlayerInput.KeyDown(Keys.RightControl))
                {
                    if (selectedList.Contains(entity))
                    {
                        selectedList.Remove(entity);
                    }
                    else
                    {
                        selectedList.Add(entity);
                    }
                }
                else
                {
                    SelectEntity(entity);
                }

                return(true);
            };
        }
Example #7
0
        /// <summary>
        /// Update the linkedTo-lists of the entities based on the linkedToID-lists
        /// Has to be done after all the entities have been loaded (an entity can't
        /// be linked to some other entity that hasn't been loaded yet)
        /// </summary>
        public static void MapLoaded(Submarine sub)
        {
            foreach (MapEntity e in mapEntityList)
            {
                if (e.Submarine != sub)
                {
                    continue;
                }
                if (e.linkedToID == null)
                {
                    continue;
                }
                if (e.linkedToID.Count == 0)
                {
                    continue;
                }

                e.linkedTo.Clear();

                foreach (ushort i in e.linkedToID)
                {
                    MapEntity linked = FindEntityByID(i) as MapEntity;

                    if (linked != null)
                    {
                        e.linkedTo.Add(linked);
                    }
                }
            }

            List <LinkedSubmarine> linkedSubs = new List <LinkedSubmarine>();

            for (int i = 0; i < mapEntityList.Count; i++)
            {
                if (mapEntityList[i].Submarine != sub)
                {
                    continue;
                }

                if (mapEntityList[i] is LinkedSubmarine)
                {
                    linkedSubs.Add((LinkedSubmarine)mapEntityList[i]);
                    continue;
                }

                mapEntityList[i].OnMapLoaded();
            }

            Item.UpdateHulls();
            Gap.UpdateHulls();

            foreach (LinkedSubmarine linkedSub in linkedSubs)
            {
                linkedSub.OnMapLoaded();
            }
        }
Example #8
0
 public void RemoveLinked(MapEntity e)
 {
     if (linkedTo == null)
     {
         return;
     }
     if (linkedTo.Contains(e))
     {
         linkedTo.Remove(e);
     }
 }
Example #9
0
 public void RemoveEntity(MapEntity entity)
 {
     for (int x = 0; x < entities.GetLength(0); x++)
     {
         for (int y = 0; y < entities.GetLength(1); y++)
         {
             if (entities[x, y].Contains(entity))
             {
                 entities[x, y].Remove(entity);
             }
         }
     }
 }
        public static List <MapEntity> PasteEntities(Vector2 position, Submarine sub, XElement configElement, string filePath = null, bool selectInstance = false)
        {
            int idOffset = Entity.FindFreeID(1);

            if (MapEntity.mapEntityList.Any())
            {
                idOffset = MapEntity.mapEntityList.Max(e => e.ID);
            }
            List <MapEntity> entities = MapEntity.LoadAll(sub, configElement, filePath, idOffset);

            if (entities.Count == 0)
            {
                return(entities);
            }

            Vector2 offset = sub?.HiddenSubPosition ?? Vector2.Zero;

            foreach (MapEntity me in entities)
            {
                me.Move(position);
                me.Submarine = sub;
                if (!(me is Item item))
                {
                    continue;
                }
                Wire wire = item.GetComponent <Wire>();
                //Vector2 subPosition = Submarine == null ? Vector2.Zero : Submarine.HiddenSubPosition;
                if (wire != null)
                {
                    //fix wires that have been erroneously saved at the "hidden position"
                    if (sub != null && Vector2.Distance(me.Position, sub.HiddenSubPosition) > sub.HiddenSubPosition.Length() / 2)
                    {
                        me.Move(position);
                    }
                    wire.MoveNodes(position - offset);
                }
            }

            MapEntity.MapLoaded(entities, true);
#if CLIENT
            if (Screen.Selected == GameMain.SubEditorScreen && selectInstance)
            {
                MapEntity.SelectedList.Clear();
                entities.ForEach(MapEntity.AddSelection);
            }
#endif
            return(entities);
        }
        private void SetRects(IReadOnlyList <Rectangle> rects)
        {
            if (Receivers.Count != rects.Count)
            {
                DebugConsole.ThrowError($"Receivers.Count did not match Rects.Count ({Receivers.Count} vs {rects.Count}).");
                return;
            }

            for (int i = 0; i < rects.Count; i++)
            {
                MapEntity entity = Receivers[i].GetReplacementOrThis();
                Rectangle Rect   = rects[i];
                Vector2   diff   = Rect.Location.ToVector2() - entity.Rect.Location.ToVector2();
                entity.Move(diff);
                entity.Rect = Rect;
            }
        }
Example #12
0
 /// <summary>
 /// Gets all linked entities of specific type.
 /// </summary>
 private static void GetLinkedEntitiesRecursive <T>(MapEntity mapEntity, HashSet <T> linkedTargets, ref int depth, int?maxDepth = null, Func <T, bool> filter = null)
     where T : MapEntity
 {
     if (depth > maxDepth)
     {
         return;
     }
     foreach (var linkedEntity in mapEntity.linkedTo)
     {
         if (linkedEntity is T linkedTarget)
         {
             if (!linkedTargets.Contains(linkedTarget) && (filter == null || filter(linkedTarget)))
             {
                 linkedTargets.Add(linkedTarget);
                 depth++;
                 GetLinkedEntitiesRecursive(linkedEntity, linkedTargets, ref depth, maxDepth, filter);
             }
         }
     }
 }
Example #13
0
        public void InsertEntity(MapEntity entity)
        {
            Rectangle rect = entity.Rect;
            //if (Submarine.Loaded != null) rect.Offset(-Submarine.HiddenSubPosition);
            Rectangle indices = GetIndices(rect);

            if (indices.Width < 0 || indices.X >= entities.GetLength(0) ||
                indices.Height < 0 || indices.Y >= entities.GetLength(1))
            {
                DebugConsole.ThrowError("Error in EntityGrid.InsertEntity: " + entity + " is outside the grid");
                return;
            }

            for (int x = Math.Max(indices.X, 0); x <= Math.Min(indices.Width, entities.GetLength(0) - 1); x++)
            {
                for (int y = Math.Max(indices.Y, 0); y <= Math.Min(indices.Height, entities.GetLength(1) - 1); y++)
                {
                    entities[x, y].Add(entity);
                }
            }
        }
Example #14
0
 private static void HandleDoorGapLinks(MapEntity entity, Action <Door, Gap> onGapFound, Action <Door, Gap> onDoorFound)
 {
     if (entity is Item i)
     {
         var door = i.GetComponent <Door>();
         if (door != null)
         {
             var gap = door.LinkedGap;
             if (gap != null)
             {
                 onGapFound(door, gap);
             }
         }
     }
     else if (entity is Gap gap)
     {
         var door = gap.ConnectedDoor;
         if (door != null)
         {
             onDoorFound(door, gap);
         }
     }
 }
Example #15
0
        public List <MapEntity> CreateInstance(Vector2 position, Submarine sub)
        {
            List <MapEntity> entities = MapEntity.LoadAll(sub, configElement, configPath);

            if (entities.Count == 0)
            {
                return(entities);
            }

            Vector2 offset = sub == null ? Vector2.Zero : sub.HiddenSubPosition;

            foreach (MapEntity me in entities)
            {
                me.Move(position);
                Item item = me as Item;
                if (item == null)
                {
                    continue;
                }
                Wire wire = item.GetComponent <Wire>();
                if (wire != null)
                {
                    wire.MoveNodes(position - offset);
                }
            }

            MapEntity.MapLoaded(entities, true);
#if CLIENT
            if (Screen.Selected == GameMain.SubEditorScreen)
            {
                MapEntity.SelectedList.Clear();
                entities.ForEach(e => MapEntity.AddSelection(e));
            }
#endif
            return(entities);
        }
Example #16
0
 public static void AddSelection(MapEntity entity)
 {
     if (selectedList.Contains(entity))
     {
         return;
     }
     selectedList.Add(entity);
     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);
         }
     });
 }
Example #17
0
        /// <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);
                    return;
                }
            }

            if (MapEntityPrefab.Selected != null)
            {
                selectionPos = Vector2.Zero;
                selectedList.Clear();
                return;
            }

            if (PlayerInput.KeyDown(Keys.Delete))
            {
                selectedList.ForEach(e => e.Remove());
                selectedList.Clear();
            }

            if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
            {
                if (PlayerInput.KeyHit(Keys.C))
                {
                    CopyEntities(selectedList);
                }
                else if (PlayerInput.KeyHit(Keys.X))
                {
                    CopyEntities(selectedList);

                    selectedList.ForEach(e => e.Remove());
                    selectedList.Clear();
                }
                else if (copiedList.Count > 0 && PlayerInput.KeyHit(Keys.V))
                {
                    List <MapEntity> prevEntities = new List <MapEntity>(mapEntityList);
                    Clone(copiedList);

                    var clones = mapEntityList.Except(prevEntities).ToList();

                    Vector2 center = Vector2.Zero;
                    clones.ForEach(c => center += c.WorldPosition);
                    center = Submarine.VectorToWorldGrid(center / clones.Count);

                    Vector2 moveAmount = Submarine.VectorToWorldGrid(cam.WorldViewCenter - center);

                    selectedList = new List <MapEntity>(clones);
                    foreach (MapEntity clone in selectedList)
                    {
                        clone.Move(moveAmount);
                        clone.Submarine = Submarine.MainSub;
                    }
                }
                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;
                            }
                        }
                    }

                    if (PlayerInput.MouseSpeed.LengthSquared() > 10)
                    {
                        highlightTimer = 0.0f;
                    }
                    else
                    {
                        bool mouseNearHighlightBox = false;

                        if (highlightedListBox != null)
                        {
                            Rectangle expandedRect = highlightedListBox.Rect;
                            expandedRect.Inflate(20, 20);
                            mouseNearHighlightBox = expandedRect.Contains(PlayerInput.MousePosition);
                            if (!mouseNearHighlightBox)
                            {
                                highlightedListBox = null;
                            }
                        }

                        highlightTimer += (float)Timing.Step;
                        if (highlightTimer > 1.0f)
                        {
                            if (!mouseNearHighlightBox)
                            {
                                UpdateHighlightedListBox(highlightedEntities);
                                highlightTimer = 0.0f;
                            }
                        }
                    }
                }

                if (highLightedEntity != null)
                {
                    highLightedEntity.isHighlighted = true;
                }
            }

            Vector2 nudgeAmount = Vector2.Zero;

            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);
                }
            }

            //started moving selected entities
            if (startMovingPos != Vector2.Zero)
            {
                if (PlayerInput.LeftButtonReleased())
                {
                    //mouse released -> move the entities to the new position of the mouse

                    Vector2 moveAmount = position - startMovingPos;
                    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)
                    {
                        moveAmount = Submarine.VectorToWorldGrid(moveAmount);
                        //clone
                        if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
                        {
                            var clones = Clone(selectedList);
                            selectedList = clones;
                            selectedList.ForEach(c => c.Move(moveAmount));
                        }
                        else // move
                        {
                            foreach (MapEntity e in selectedList)
                            {
                                if (e.rectMemento == null)
                                {
                                    e.rectMemento = new Memento <Rectangle>();
                                    e.rectMemento.Store(e.Rect);
                                }
                                e.Move(moveAmount);
                                e.rectMemento.Store(e.Rect);
                            }
                        }
                    }
                    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.LeftButtonReleased())
                {
                    if (PlayerInput.KeyDown(Keys.LeftControl) ||
                        PlayerInput.KeyDown(Keys.RightControl))
                    {
                        foreach (MapEntity e in newSelection)
                        {
                            if (selectedList.Contains(e))
                            {
                                selectedList.Remove(e);
                            }
                            else
                            {
                                selectedList.Add(e);
                            }
                        }
                    }
                    else
                    {
                        selectedList = newSelection;
                    }

                    //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.LeftButtonHeld() &&
                    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();
                }
            }
        }
Example #18
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        public override void Update(double deltaTime)
        {
#if DEBUG
            if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null &&
                !DebugConsole.IsOpen)
            {
                var closestSub = Submarine.FindClosest(cam.WorldViewCenter);
                if (closestSub == null)
                {
                    closestSub = GameMain.GameSession.Submarine;
                }

                Vector2 targetMovement = Vector2.Zero;
                if (PlayerInput.KeyDown(Keys.I))
                {
                    targetMovement.Y += 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.K))
                {
                    targetMovement.Y -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.J))
                {
                    targetMovement.X -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.L))
                {
                    targetMovement.X += 1.0f;
                }

                if (targetMovement != Vector2.Zero)
                {
                    closestSub.ApplyForce(targetMovement * closestSub.SubBody.Body.Mass * 100.0f);
                }
            }
#endif

            foreach (MapEntity e in MapEntity.mapEntityList)
            {
                e.IsHighlighted = false;
            }

            if (GameMain.GameSession != null)
            {
                GameMain.GameSession.Update((float)deltaTime);
            }

            if (Level.Loaded != null)
            {
                Level.Loaded.Update((float)deltaTime);
            }

            if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null)
            {
                if (Character.Controlled.SelectedConstruction == Character.Controlled.ClosestItem)
                {
                    Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled);
                }
            }
            Character.UpdateAll(cam, (float)deltaTime);

            BackgroundCreatureManager.Update(cam, (float)deltaTime);

            GameMain.ParticleManager.Update((float)deltaTime);

            StatusEffect.UpdateAll((float)deltaTime);

            if (Character.Controlled != null && Lights.LightManager.ViewTarget != null)
            {
                cam.TargetPos = Lights.LightManager.ViewTarget.WorldPosition;
            }

            GameMain.LightManager.Update((float)deltaTime);
            cam.MoveCamera((float)deltaTime);

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.SetPrevTransform(sub.Position);
            }

            foreach (PhysicsBody pb in PhysicsBody.list)
            {
                pb.SetPrevTransform(pb.SimPosition, pb.Rotation);
            }

            MapEntity.UpdateAll(cam, (float)deltaTime);

            Character.UpdateAnimAll((float)deltaTime);

            Ragdoll.UpdateAll(cam, (float)deltaTime);

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.Update((float)deltaTime);
            }

            GameMain.World.Step((float)deltaTime);

            if (!PlayerInput.LeftButtonHeld())
            {
                Inventory.draggingSlot = null;
                Inventory.draggingItem = null;
            }
        }
Example #19
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        public override void Update(double deltaTime)
        {
#if RUN_PHYSICS_IN_SEPARATE_THREAD
            physicsTime += deltaTime;
            lock (updateLock)
            {
#endif


#if DEBUG && CLIENT
            if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null &&
                !DebugConsole.IsOpen && GUI.KeyboardDispatcher.Subscriber == null)
            {
                var closestSub = Submarine.FindClosest(cam.WorldViewCenter);
                if (closestSub == null)
                {
                    closestSub = GameMain.GameSession.Submarine;
                }

                Vector2 targetMovement = Vector2.Zero;
                if (PlayerInput.KeyDown(Keys.I))
                {
                    targetMovement.Y += 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.K))
                {
                    targetMovement.Y -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.J))
                {
                    targetMovement.X -= 1.0f;
                }
                if (PlayerInput.KeyDown(Keys.L))
                {
                    targetMovement.X += 1.0f;
                }

                if (targetMovement != Vector2.Zero)
                {
                    closestSub.ApplyForce(targetMovement * closestSub.SubBody.Body.Mass * 100.0f);
                }
            }
#endif

            GameTime += deltaTime;

            foreach (PhysicsBody body in PhysicsBody.List)
            {
                if (body.Enabled)
                {
                    body.Update();
                }
            }
            foreach (MapEntity e in MapEntity.mapEntityList)
            {
                e.IsHighlighted = false;
            }

            if (GameMain.GameSession != null)
            {
                GameMain.GameSession.Update((float)deltaTime);
            }
#if CLIENT
            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            GameMain.ParticleManager.Update((float)deltaTime);

            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("ParticleUpdate", sw.ElapsedTicks);
            sw.Restart();

            if (Level.Loaded != null)
            {
                Level.Loaded.Update((float)deltaTime, cam);
            }

            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("LevelUpdate", sw.ElapsedTicks);

            if (Character.Controlled != null)
            {
                if (Character.Controlled.SelectedConstruction != null && Character.Controlled.CanInteractWith(Character.Controlled.SelectedConstruction))
                {
                    Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled, (float)deltaTime);
                }
                if (Character.Controlled.Inventory != null)
                {
                    foreach (Item item in Character.Controlled.Inventory.Items)
                    {
                        if (item == null)
                        {
                            continue;
                        }
                        if (Character.Controlled.HasEquippedItem(item))
                        {
                            item.UpdateHUD(cam, Character.Controlled, (float)deltaTime);
                        }
                    }
                }
            }


            sw.Restart();

            Character.UpdateAll((float)deltaTime, cam);
#elif SERVER
            if (Level.Loaded != null)
            {
                Level.Loaded.Update((float)deltaTime, Camera.Instance);
            }
            Character.UpdateAll((float)deltaTime, Camera.Instance);
#endif


#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("CharacterUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

            StatusEffect.UpdateAll((float)deltaTime);

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("StatusEffectUpdate", sw.ElapsedTicks);
            sw.Restart();

            if (Character.Controlled != null &&
                Lights.LightManager.ViewTarget != null)
            {
                Vector2 targetPos = Lights.LightManager.ViewTarget.DrawPosition;
                if (Lights.LightManager.ViewTarget == Character.Controlled &&
                    (CharacterHealth.OpenHealthWindow != null || CrewManager.IsCommandInterfaceOpen))
                {
                    Vector2 screenTargetPos = new Vector2(0.0f, GameMain.GraphicsHeight * 0.5f);
                    if (CrewManager.IsCommandInterfaceOpen)
                    {
                        screenTargetPos.X = GameMain.GraphicsWidth * 0.5f;
                    }
                    else
                    {
                        screenTargetPos = CharacterHealth.OpenHealthWindow.Alignment == Alignment.Left ?
                                          new Vector2(GameMain.GraphicsWidth * 0.75f, GameMain.GraphicsHeight * 0.5f) :
                                          new Vector2(GameMain.GraphicsWidth * 0.25f, GameMain.GraphicsHeight * 0.5f);
                    }
                    Vector2 screenOffset = screenTargetPos - new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight / 2);
                    screenOffset.Y = -screenOffset.Y;
                    targetPos     -= screenOffset / cam.Zoom;
                }
                cam.TargetPos = targetPos;
            }

            cam.MoveCamera((float)deltaTime);
#endif

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.SetPrevTransform(sub.Position);
            }

            foreach (PhysicsBody body in PhysicsBody.List)
            {
                if (body.Enabled)
                {
                    body.SetPrevTransform(body.SimPosition, body.Rotation);
                }
            }

#if CLIENT
            MapEntity.UpdateAll((float)deltaTime, cam);
#elif SERVER
            MapEntity.UpdateAll((float)deltaTime, Camera.Instance);
#endif

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("MapEntityUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif
            Character.UpdateAnimAll((float)deltaTime);

#if CLIENT
            Ragdoll.UpdateAll((float)deltaTime, cam);
#elif SERVER
            Ragdoll.UpdateAll((float)deltaTime, Camera.Instance);
#endif

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("AnimUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.Update((float)deltaTime);
            }

#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("SubmarineUpdate", sw.ElapsedTicks);
            sw.Restart();
#endif

#if !RUN_PHYSICS_IN_SEPARATE_THREAD
            try
            {
                GameMain.World.Step((float)Timing.Step);
            }
            catch (WorldLockedException e)
            {
                string errorMsg = "Attempted to modify the state of the physics simulation while a time step was running.";
                DebugConsole.ThrowError(errorMsg, e);
                GameAnalyticsManager.AddErrorEventOnce("GameScreen.Update:WorldLockedException" + e.Message, GameAnalyticsSDK.Net.EGAErrorSeverity.Critical, errorMsg);
            }
#endif


#if CLIENT
            sw.Stop();
            GameMain.PerformanceCounter.AddElapsedTicks("Physics", sw.ElapsedTicks);
#endif

#if CLIENT
            if (!PlayerInput.PrimaryMouseButtonHeld())
            {
                Inventory.draggingSlot = null;
                Inventory.draggingItem = null;
            }
#endif


#if RUN_PHYSICS_IN_SEPARATE_THREAD
        }
#endif
        }
Example #20
0
        public void Generate(bool mirror = false)
        {
            if (backgroundSpriteManager == null)
            {
                var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.BackgroundSpritePrefabs);
                if (files.Count > 0)
                {
                    backgroundSpriteManager = new BackgroundSpriteManager(files);
                }
                else
                {
                    backgroundSpriteManager = new BackgroundSpriteManager("Content/BackgroundSprites/BackgroundSpritePrefabs.xml");
                }
            }
#if CLIENT
            if (backgroundCreatureManager == null)
            {
                var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.BackgroundCreaturePrefabs);
                if (files.Count > 0)
                {
                    backgroundCreatureManager = new BackgroundCreatureManager(files);
                }
                else
                {
                    backgroundCreatureManager = new BackgroundCreatureManager("Content/BackgroundSprites/BackgroundCreaturePrefabs.xml");
                }
            }
#endif

            Stopwatch sw = new Stopwatch();
            sw.Start();

            if (loaded != null)
            {
                loaded.Unload();
            }
            loaded = this;

            positionsOfInterest = new List <InterestingPosition>();

            Voronoi voronoi = new Voronoi(1.0);

            List <Vector2> sites = new List <Vector2>();

            bodies = new List <Body>();

            Rand.SetSyncedSeed(ToolBox.StringToInt(seed));

#if CLIENT
            renderer = new LevelRenderer(this);

            backgroundColor = generationParams.BackgroundColor;
            float avgValue = (backgroundColor.R + backgroundColor.G + backgroundColor.G) / 3;
            GameMain.LightManager.AmbientLight = new Color(backgroundColor * (10.0f / avgValue), 1.0f);
#endif

            SeaFloorTopPos = generationParams.SeaFloorDepth + generationParams.MountainHeightMax + generationParams.SeaFloorVariance;

            float minWidth = 6500.0f;
            if (Submarine.MainSub != null)
            {
                Rectangle dockedSubBorders = Submarine.MainSub.GetDockedBorders();
                minWidth = Math.Max(minWidth, Math.Max(dockedSubBorders.Width, dockedSubBorders.Height));
            }

            Rectangle pathBorders = borders;
            pathBorders.Inflate(-minWidth * 2, -minWidth * 2);

            startPosition = new Vector2(
                Rand.Range(minWidth, minWidth * 2, Rand.RandSync.Server),
                Rand.Range(borders.Height * 0.5f, borders.Height - minWidth * 2, Rand.RandSync.Server));

            endPosition = new Vector2(
                borders.Width - Rand.Range(minWidth, minWidth * 2, Rand.RandSync.Server),
                Rand.Range(borders.Height * 0.5f, borders.Height - minWidth * 2, Rand.RandSync.Server));

            //----------------------------------------------------------------------------------
            //generate the initial nodes for the main path and smaller tunnels
            //----------------------------------------------------------------------------------

            List <Vector2> pathNodes = new List <Vector2>();
            pathNodes.Add(new Vector2(startPosition.X, borders.Height));

            Vector2 nodeInterval = generationParams.MainPathNodeIntervalRange;

            for (float x = startPosition.X + nodeInterval.X;
                 x < endPosition.X - nodeInterval.X;
                 x += Rand.Range(nodeInterval.X, nodeInterval.Y, Rand.RandSync.Server))
            {
                pathNodes.Add(new Vector2(x, Rand.Range(pathBorders.Y, pathBorders.Bottom, Rand.RandSync.Server)));
            }

            pathNodes.Add(new Vector2(endPosition.X, borders.Height));

            if (pathNodes.Count <= 2)
            {
                pathNodes.Insert(1, borders.Center.ToVector2());
            }

            GenerateTunnels(pathNodes, minWidth);

            //----------------------------------------------------------------------------------
            //generate voronoi sites
            //----------------------------------------------------------------------------------

            Vector2 siteInterval = generationParams.VoronoiSiteInterval;
            Vector2 siteVariance = generationParams.VoronoiSiteVariance;
            for (float x = siteInterval.X / 2; x < borders.Width; x += siteInterval.X)
            {
                for (float y = siteInterval.Y / 2; y < borders.Height; y += siteInterval.Y)
                {
                    Vector2 site = new Vector2(
                        x + Rand.Range(-siteVariance.X, siteVariance.X, Rand.RandSync.Server),
                        y + Rand.Range(-siteVariance.Y, siteVariance.Y, Rand.RandSync.Server));

                    if (smallTunnels.Any(t => t.Any(node => Vector2.Distance(node, site) < siteInterval.Length())))
                    {
                        //add some more sites around the small tunnels to generate more small voronoi cells
                        if (x < borders.Width - siteInterval.X)
                        {
                            sites.Add(new Vector2(x, y) + Vector2.UnitX * siteInterval * 0.5f);
                        }
                        if (y < borders.Height - siteInterval.Y)
                        {
                            sites.Add(new Vector2(x, y) + Vector2.UnitY * siteInterval * 0.5f);
                        }
                        if (x < borders.Width - siteInterval.X && y < borders.Height - siteInterval.Y)
                        {
                            sites.Add(new Vector2(x, y) + Vector2.One * siteInterval * 0.5f);
                        }
                    }

                    if (mirror)
                    {
                        site.X = borders.Width - site.X;
                    }

                    sites.Add(site);
                }
            }


            //----------------------------------------------------------------------------------
            // construct the voronoi graph and cells
            //----------------------------------------------------------------------------------

            Stopwatch sw2 = new Stopwatch();
            sw2.Start();

            List <GraphEdge> graphEdges = voronoi.MakeVoronoiGraph(sites, borders.Width, borders.Height);

            Debug.WriteLine("MakeVoronoiGraph: " + sw2.ElapsedMilliseconds + " ms");
            sw2.Restart();

            //construct voronoi cells based on the graph edges
            cells = CaveGenerator.GraphEdgesToCells(graphEdges, borders, GridCellSize, out cellGrid);

            Debug.WriteLine("find cells: " + sw2.ElapsedMilliseconds + " ms");
            sw2.Restart();

            //----------------------------------------------------------------------------------
            // generate a path through the initial path nodes
            //----------------------------------------------------------------------------------

            List <VoronoiCell> mainPath = CaveGenerator.GeneratePath(pathNodes, cells, cellGrid, GridCellSize,
                                                                     new Rectangle(pathBorders.X, pathBorders.Y, pathBorders.Width, borders.Height), 0.5f, mirror);

            for (int i = 2; i < mainPath.Count; i += 3)
            {
                positionsOfInterest.Add(new InterestingPosition(mainPath[i].Center, PositionType.MainPath));
            }

            List <VoronoiCell> pathCells = new List <VoronoiCell>(mainPath);

            //make sure the path is wide enough to pass through
            EnlargeMainPath(pathCells, minWidth);

            foreach (InterestingPosition positionOfInterest in positionsOfInterest)
            {
                WayPoint wayPoint = new WayPoint(positionOfInterest.Position, SpawnType.Enemy, null);
                wayPoint.MoveWithLevel = true;
            }

            startPosition.X = pathCells[0].Center.X;

            //----------------------------------------------------------------------------------
            // tunnels through the tunnel nodes
            //----------------------------------------------------------------------------------

            foreach (List <Vector2> tunnel in smallTunnels)
            {
                if (tunnel.Count < 2)
                {
                    continue;
                }

                //find the cell which the path starts from
                int startCellIndex = CaveGenerator.FindCellIndex(tunnel[0], cells, cellGrid, GridCellSize, 1);
                if (startCellIndex < 0)
                {
                    continue;
                }

                //if it wasn't one of the cells in the main path, don't create a tunnel
                if (cells[startCellIndex].CellType != CellType.Path)
                {
                    continue;
                }

                var newPathCells = CaveGenerator.GeneratePath(tunnel, cells, cellGrid, GridCellSize, pathBorders);

                positionsOfInterest.Add(new InterestingPosition(tunnel.Last(), PositionType.Cave));

                if (tunnel.Count > 4)
                {
                    positionsOfInterest.Add(new InterestingPosition(tunnel[tunnel.Count / 2], PositionType.Cave));
                }

                pathCells.AddRange(newPathCells);
            }

            Debug.WriteLine("path: " + sw2.ElapsedMilliseconds + " ms");
            sw2.Restart();


            //----------------------------------------------------------------------------------
            // remove unnecessary cells and create some holes at the bottom of the level
            //----------------------------------------------------------------------------------

            cells = CleanCells(pathCells);
            pathCells.AddRange(CreateBottomHoles(generationParams.BottomHoleProbability, new Rectangle(
                                                     (int)(borders.Width * 0.2f), 0,
                                                     (int)(borders.Width * 0.6f), (int)(borders.Height * 0.8f))));

            foreach (VoronoiCell cell in cells)
            {
                if (cell.Center.Y < borders.Height / 2)
                {
                    continue;
                }
                cell.edges.ForEach(e => e.OutsideLevel = true);
            }

            //----------------------------------------------------------------------------------
            // initialize the cells that are still left and insert them into the cell grid
            //----------------------------------------------------------------------------------

            foreach (VoronoiCell cell in pathCells)
            {
                cell.edges.ForEach(e => e.OutsideLevel = false);

                cell.CellType = CellType.Path;
                cells.Remove(cell);
            }

            for (int x = 0; x < cellGrid.GetLength(0); x++)
            {
                for (int y = 0; y < cellGrid.GetLength(1); y++)
                {
                    cellGrid[x, y].Clear();
                }
            }

            foreach (VoronoiCell cell in cells)
            {
                int x = (int)Math.Floor(cell.Center.X / GridCellSize);
                int y = (int)Math.Floor(cell.Center.Y / GridCellSize);

                if (x < 0 || y < 0 || x >= cellGrid.GetLength(0) || y >= cellGrid.GetLength(1))
                {
                    continue;
                }

                cellGrid[x, y].Add(cell);
            }


            //----------------------------------------------------------------------------------
            // create some ruins
            //----------------------------------------------------------------------------------

            ruins = new List <Ruin>();
            for (int i = 0; i < generationParams.RuinCount; i++)
            {
                GenerateRuin(mainPath);
            }


            //----------------------------------------------------------------------------------
            // generate the bodies and rendered triangles of the cells
            //----------------------------------------------------------------------------------

            startPosition.Y = borders.Height;
            endPosition.Y   = borders.Height;

            List <VoronoiCell> cellsWithBody = new List <VoronoiCell>(cells);

            List <Vector2[]> triangles;
            bodies = CaveGenerator.GeneratePolygons(cellsWithBody, out triangles);

#if CLIENT
            renderer.SetBodyVertices(CaveGenerator.GenerateRenderVerticeList(triangles).ToArray(), generationParams.WallColor);
            renderer.SetWallVertices(CaveGenerator.GenerateWallShapes(cells), generationParams.WallColor);
#endif

            TopBarrier = BodyFactory.CreateEdge(GameMain.World,
                                                ConvertUnits.ToSimUnits(new Vector2(borders.X, 0)),
                                                ConvertUnits.ToSimUnits(new Vector2(borders.Right, 0)));

            TopBarrier.SetTransform(ConvertUnits.ToSimUnits(new Vector2(0.0f, borders.Height)), 0.0f);
            TopBarrier.BodyType            = BodyType.Static;
            TopBarrier.CollisionCategories = Physics.CollisionLevel;

            bodies.Add(TopBarrier);

            GenerateSeaFloor();

            backgroundSpriteManager.PlaceSprites(this, generationParams.BackgroundSpriteAmount);
#if CLIENT
            backgroundCreatureManager.SpawnSprites(80);
#endif

            foreach (VoronoiCell cell in cells)
            {
                foreach (GraphEdge edge in cell.edges)
                {
                    edge.cell1 = null;
                    edge.cell2 = null;
                    edge.site1 = null;
                    edge.site2 = null;
                }
            }

            //initialize MapEntities that aren't in any sub (e.g. items inside ruins)
            MapEntity.MapLoaded(null);

            Debug.WriteLine("Generatelevel: " + sw2.ElapsedMilliseconds + " ms");
            sw2.Restart();

            if (mirror)
            {
                Vector2 temp = startPosition;
                startPosition = endPosition;
                endPosition   = temp;
            }

            Debug.WriteLine("**********************************************************************************");
            Debug.WriteLine("Generated a map with " + sites.Count + " sites in " + sw.ElapsedMilliseconds + " ms");
            Debug.WriteLine("Seed: " + seed);
            Debug.WriteLine("**********************************************************************************");

            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("Generated level with the seed " + seed + " (type: " + generationParams.Name + ")", Color.White);
            }
        }
Example #21
0
        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;
        }
Example #22
0
        public override void OnMapLoaded()
        {
            if (!loadSub)
            {
                return;
            }

            SubmarineInfo info = new SubmarineInfo(Submarine.Info.FilePath, "", saveElement);

            if (!info.SubmarineElement.HasElements)
            {
                DebugConsole.ThrowError("Failed to load a linked submarine (empty XML element). The save file may be corrupted.");
                return;
            }
            if (!info.SubmarineElement.Elements().Any(e => e.Name.ToString().Equals("hull", StringComparison.OrdinalIgnoreCase)))
            {
                DebugConsole.ThrowError("Failed to load a linked submarine (the submarine contains no hulls).");
                return;
            }

            IdRemap parentRemap = new IdRemap(Submarine.Info.SubmarineElement, Submarine.IdOffset);

            sub = Submarine.Load(info, false, parentRemap);
            sub.Info.SubmarineClass = Submarine.Info.SubmarineClass;

            IdRemap childRemap = new IdRemap(saveElement, sub.IdOffset);

            Vector2 worldPos = saveElement.GetAttributeVector2("worldpos", Vector2.Zero);

            if (worldPos != Vector2.Zero)
            {
                if (GameMain.GameSession != null && GameMain.GameSession.MirrorLevel)
                {
                    worldPos.X = GameMain.GameSession.LevelData.Size.X - worldPos.X;
                }
                sub.SetPosition(worldPos);
            }
            else
            {
                sub.SetPosition(WorldPosition);
            }

            DockingPort linkedPort = null;
            DockingPort myPort     = null;

            MapEntity linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent <DockingPort>() != null);

            if (linkedItem == null)
            {
                linkedPort = DockingPort.List.FirstOrDefault(dp => dp.DockingTarget != null && dp.DockingTarget.Item.Submarine == sub);
            }
            else
            {
                linkedPort = ((Item)linkedItem).GetComponent <DockingPort>();
            }

            if (linkedPort == null)
            {
                if (purchasedLostShuttles)
                {
                    linkedPort = (FindEntityByID(originalLinkedToID) as Item)?.GetComponent <DockingPort>();
                }
                if (linkedPort == null)
                {
                    return;
                }
            }
            originalLinkedPort = linkedPort;

            ushort originalMyId = childRemap.GetOffsetId(originalMyPortID);

            myPort = (FindEntityByID(originalMyId) as Item)?.GetComponent <DockingPort>();
            if (myPort == null)
            {
                float closestDistance = 0.0f;
                foreach (DockingPort port in DockingPort.List)
                {
                    if (port.Item.Submarine != sub || port.IsHorizontal != linkedPort.IsHorizontal)
                    {
                        continue;
                    }
                    float dist = Vector2.Distance(port.Item.WorldPosition, linkedPort.Item.WorldPosition);
                    if (myPort == null || dist < closestDistance)
                    {
                        myPort          = port;
                        closestDistance = dist;
                    }
                }
            }

            if (myPort != null)
            {
                originalMyPortID = myPort.Item.ID;

                myPort.Undock(applyEffects: false);
                myPort.DockingDir = 0;

                //something else is already docked to the port this sub should be docked to
                //may happen if a shuttle is lost, another vehicle docked to where the shuttle used to be,
                //and the shuttle is then restored in the campaign mode
                //or if the user connects multiple subs to the same docking ports in the sub editor
                if (linkedPort.Docked && linkedPort.DockingTarget != null && linkedPort.DockingTarget != myPort)
                {
                    //just spawn below the main sub
                    sub.SetPosition(
                        linkedPort.Item.Submarine.WorldPosition -
                        new Vector2(0, linkedPort.Item.Submarine.GetDockedBorders().Height / 2 + sub.GetDockedBorders().Height / 2));
                }
                else
                {
                    Vector2 portDiff = myPort.Item.WorldPosition - sub.WorldPosition;
                    Vector2 offset   = myPort.IsHorizontal ?
                                       Vector2.UnitX * myPort.GetDir(linkedPort) :
                                       Vector2.UnitY * myPort.GetDir(linkedPort);
                    offset *= myPort.DockedDistance;

                    sub.SetPosition((linkedPort.Item.WorldPosition - portDiff) - offset);

                    myPort.Dock(linkedPort);
                    myPort.Lock(isNetworkMessage: true, applyEffects: false);
                }
            }

            if (GameMain.GameSession?.GameMode is CampaignMode campaign && campaign.PurchasedLostShuttles)
            {
                foreach (Structure wall in Structure.WallList)
                {
                    if (wall.Submarine != sub)
                    {
                        continue;
                    }
                    for (int i = 0; i < wall.SectionCount; i++)
                    {
                        wall.SetDamage(i, 0, createNetworkEvent: false);
                    }
                }
                foreach (Hull hull in Hull.hullList)
                {
                    if (hull.Submarine != sub)
                    {
                        continue;
                    }
                    hull.WaterVolume      = 0.0f;
                    hull.OxygenPercentage = 100.0f;
                }
            }

            sub.SetPosition(sub.WorldPosition - Submarine.WorldPosition, forceUndockFromStaticSubmarines: false);
            sub.Submarine = Submarine;
        }
Example #23
0
        public static XElement Save(List <MapEntity> entities, string name, string description, bool hideInMenus = false)
        {
            XElement element = new XElement("ItemAssembly",
                                            new XAttribute("name", name),
                                            new XAttribute("description", description),
                                            new XAttribute("hideinmenus", hideInMenus));


            //move the entities so that their "center of mass" is at {0,0}
            var assemblyEntities = MapEntity.CopyEntities(entities);

            //find wires and items that are contained inside another item
            //place them at {0,0} to prevent them from messing up the origin of the prefab and to hide them in preview
            List <MapEntity> disabledEntities = new List <MapEntity>();

            foreach (MapEntity mapEntity in assemblyEntities)
            {
                if (mapEntity is Item item)
                {
                    var wire = item.GetComponent <Wire>();
                    if (item.ParentInventory != null ||
                        (wire != null && wire.Connections.Any(c => c != null)))
                    {
                        item.SetTransform(Vector2.Zero, 0.0f);
                        disabledEntities.Add(mapEntity);
                    }
                }
            }

            float minX = int.MaxValue, maxX = int.MinValue;
            float minY = int.MaxValue, maxY = int.MinValue;

            foreach (MapEntity mapEntity in assemblyEntities)
            {
                if (disabledEntities.Contains(mapEntity))
                {
                    continue;
                }
                minX = Math.Min(minX, mapEntity.WorldRect.X);
                maxX = Math.Max(maxX, mapEntity.WorldRect.Right);
                minY = Math.Min(minY, mapEntity.WorldRect.Y - mapEntity.WorldRect.Height);
                maxY = Math.Max(maxY, mapEntity.WorldRect.Y);
            }
            Vector2 center = new Vector2((minX + maxX) / 2.0f, (minY + maxY) / 2.0f);

            if (Submarine.MainSub != null)
            {
                center -= Submarine.MainSub.HiddenSubPosition;
            }
            center.X -= center.X % Submarine.GridSize.X;
            center.Y -= center.Y % Submarine.GridSize.Y;

            MapEntity.SelectedList.Clear();
            MapEntity.SelectedList.AddRange(assemblyEntities);

            foreach (MapEntity mapEntity in assemblyEntities)
            {
                mapEntity.Move(-center);
                mapEntity.Submarine = Submarine.MainSub;
                var entityElement = mapEntity.Save(element);
                if (disabledEntities.Contains(mapEntity))
                {
                    entityElement.Add(new XAttribute("hideinassemblypreview", "true"));
                }
            }

            return(element);
        }
Example #24
0
        public override void OnMapLoaded()
        {
            if (!loadSub)
            {
                return;
            }

            SubmarineInfo info = new SubmarineInfo(Submarine.Info.FilePath, "", saveElement);

            if (!info.SubmarineElement.HasElements)
            {
                DebugConsole.ThrowError("Failed to load a linked submarine (empty XML element). The save file may be corrupted.");
                return;
            }

            sub = Submarine.Load(info, false);

            Vector2 worldPos = saveElement.GetAttributeVector2("worldpos", Vector2.Zero);

            if (worldPos != Vector2.Zero)
            {
                sub.SetPosition(worldPos);
            }
            else
            {
                sub.SetPosition(WorldPosition);
            }

            DockingPort linkedPort = null;
            DockingPort myPort     = null;

            MapEntity linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent <DockingPort>() != null);

            if (linkedItem == null)
            {
                linkedPort = DockingPort.List.FirstOrDefault(dp => dp.DockingTarget != null && dp.DockingTarget.Item.Submarine == sub);
            }
            else
            {
                linkedPort = ((Item)linkedItem).GetComponent <DockingPort>();
            }

            if (linkedPort == null)
            {
                if (purchasedLostShuttles)
                {
                    linkedPort = (FindEntityByID(originalLinkedToID) as Item)?.GetComponent <DockingPort>();
                }
                if (linkedPort == null)
                {
                    return;
                }
            }
            originalLinkedPort = linkedPort;

            myPort = (FindEntityByID(originalMyPortID) as Item)?.GetComponent <DockingPort>();
            if (myPort == null)
            {
                float closestDistance = 0.0f;
                foreach (DockingPort port in DockingPort.List)
                {
                    if (port.Item.Submarine != sub || port.IsHorizontal != linkedPort.IsHorizontal)
                    {
                        continue;
                    }
                    float dist = Vector2.Distance(port.Item.WorldPosition, linkedPort.Item.WorldPosition);
                    if (myPort == null || dist < closestDistance)
                    {
                        myPort          = port;
                        closestDistance = dist;
                    }
                }
            }

            if (myPort != null)
            {
                originalMyPortID = myPort.Item.ID;

                myPort.Undock();

                //something else is already docked to the port this sub should be docked to
                //may happen if a shuttle is lost, another vehicle docked to where the shuttle used to be,
                //and the shuttle is then restored in the campaign mode
                //or if the user connects multiple subs to the same docking ports in the sub editor
                if (linkedPort.Docked && linkedPort.DockingTarget != null && linkedPort.DockingTarget != myPort)
                {
                    //just spawn below the main sub
                    sub.SetPosition(
                        linkedPort.Item.Submarine.WorldPosition -
                        new Vector2(0, linkedPort.Item.Submarine.GetDockedBorders().Height / 2 + sub.GetDockedBorders().Height / 2));
                }
                else
                {
                    Vector2 portDiff = myPort.Item.WorldPosition - sub.WorldPosition;
                    Vector2 offset   = myPort.IsHorizontal ?
                                       Vector2.UnitX * myPort.GetDir(linkedPort) :
                                       Vector2.UnitY * myPort.GetDir(linkedPort);
                    offset *= myPort.DockedDistance;

                    sub.SetPosition((linkedPort.Item.WorldPosition - portDiff) - offset);

                    myPort.Dock(linkedPort);
                    myPort.Lock(true);
                }
            }

            if (GameMain.GameSession?.GameMode is CampaignMode campaign && campaign.PurchasedLostShuttles)
            {
                foreach (Structure wall in Structure.WallList)
                {
                    if (wall.Submarine != sub)
                    {
                        continue;
                    }
                    for (int i = 0; i < wall.SectionCount; i++)
                    {
                        wall.AddDamage(i, -wall.MaxHealth);
                    }
                }
                foreach (Hull hull in Hull.hullList)
                {
                    if (hull.Submarine != sub)
                    {
                        continue;
                    }
                    hull.WaterVolume      = 0.0f;
                    hull.OxygenPercentage = 100.0f;
                }
            }

            sub.SetPosition(sub.WorldPosition - Submarine.WorldPosition);
            sub.Submarine = Submarine;
        }
Example #25
0
        public static void SelectEntity(MapEntity entity)
        {
            DeselectAll();

            selectedList.Add(entity);
        }
Example #26
0
        public override void OnMapLoaded()
        {
            if (!loadSub)
            {
                return;
            }

            sub = Submarine.Load(saveElement, false);

            Vector2 worldPos = saveElement.GetAttributeVector2("worldpos", Vector2.Zero);

            if (worldPos != Vector2.Zero)
            {
                sub.SetPosition(worldPos);
            }
            else
            {
                sub.SetPosition(WorldPosition);
            }


            DockingPort linkedPort = null;
            DockingPort myPort     = null;

            MapEntity linkedItem = linkedTo.FirstOrDefault(lt => (lt is Item) && ((Item)lt).GetComponent <DockingPort>() != null);

            if (linkedItem == null)
            {
                linkedPort = DockingPort.List.FirstOrDefault(dp => dp.DockingTarget != null && dp.DockingTarget.Item.Submarine == sub);
            }
            else
            {
                linkedPort = ((Item)linkedItem).GetComponent <DockingPort>();
            }

            if (linkedPort == null)
            {
                return;
            }

            float closestDistance = 0.0f;

            foreach (DockingPort port in DockingPort.List)
            {
                if (port.Item.Submarine != sub || port.IsHorizontal != linkedPort.IsHorizontal)
                {
                    continue;
                }

                float dist = Vector2.Distance(port.Item.WorldPosition, linkedPort.Item.WorldPosition);
                if (myPort == null || dist < closestDistance)
                {
                    myPort          = port;
                    closestDistance = dist;
                }
            }

            if (myPort != null)
            {
                myPort.Undock();

                Vector2 portDiff = myPort.Item.WorldPosition - sub.WorldPosition;
                Vector2 offset   = (myPort.IsHorizontal ?
                                    Vector2.UnitX * Math.Sign(linkedPort.Item.WorldPosition.X - myPort.Item.WorldPosition.X) :
                                    Vector2.UnitY * Math.Sign(linkedPort.Item.WorldPosition.Y - myPort.Item.WorldPosition.Y));
                offset *= myPort.DockedDistance;

                sub.SetPosition((linkedPort.Item.WorldPosition - portDiff) - offset);

                myPort.Dock(linkedPort);
                myPort.Lock(true);
            }

            sub.SetPosition(sub.WorldPosition - Submarine.WorldPosition);
            sub.Submarine = Submarine;
        }
Example #27
0
        private static void InitProjectSpecific()
        {
            commands.Add(new Command("autohull", "", (string[] args) =>
            {
                if (Screen.Selected != GameMain.SubEditorScreen)
                {
                    return;
                }

                if (MapEntity.mapEntityList.Any(e => e is Hull || e is Gap))
                {
                    ShowQuestionPrompt("This submarine already has hulls and/or gaps. This command will delete them. Do you want to continue? Y/N",
                                       (option) => {
                        if (option.ToLower() == "y")
                        {
                            GameMain.SubEditorScreen.AutoHull();
                        }
                    });
                }
                else
                {
                    GameMain.SubEditorScreen.AutoHull();
                }
            }));

            commands.Add(new Command("startclient", "", (string[] args) =>
            {
                if (args.Length == 0)
                {
                    return;
                }

                if (GameMain.Client == null)
                {
                    GameMain.NetworkMember = new GameClient("Name");
                    GameMain.Client.ConnectToServer(args[0]);
                }
            }));

            commands.Add(new Command("mainmenuscreen|mainmenu|menu", "mainmenu/menu: Go to the main menu.", (string[] args) =>
            {
                GameMain.GameSession = null;

                List <Character> characters = new List <Character>(Character.CharacterList);
                foreach (Character c in characters)
                {
                    c.Remove();
                }

                GameMain.MainMenuScreen.Select();
            }));

            commands.Add(new Command("gamescreen|game", "gamescreen/game: Go to the \"in-game\" view.", (string[] args) =>
            {
                GameMain.GameScreen.Select();
            }));

            commands.Add(new Command("editsubscreen|editsub|subeditor", "editsub/subeditor: Switch to the submarine editor.", (string[] args) =>
            {
                if (args.Length > 0)
                {
                    Submarine.Load(string.Join(" ", args), true);
                }
                GameMain.SubEditorScreen.Select();
            }));

            commands.Add(new Command("editcharacter", "", (string[] args) =>
            {
                GameMain.CharacterEditorScreen.Select();
            }));

            commands.Add(new Command("editparticles", "", (string[] args) =>
            {
                GameMain.ParticleEditorScreen.Select();
            }));


            commands.Add(new Command("control|controlcharacter", "control [character name]: Start controlling the specified character.", (string[] args) =>
            {
                if (args.Length < 1)
                {
                    return;
                }

                var character = FindMatchingCharacter(args, true);

                if (character != null)
                {
                    Character.Controlled = character;
                }
            },
                                     () =>
            {
                return(new string[][]
                {
                    Character.CharacterList.Select(c => c.Name).Distinct().ToArray()
                });
            }));

            commands.Add(new Command("shake", "", (string[] args) =>
            {
                GameMain.GameScreen.Cam.Shake = 10.0f;
            }));

            commands.Add(new Command("los", "los: Toggle the line of sight effect on/off.", (string[] args) =>
            {
                GameMain.LightManager.LosEnabled = !GameMain.LightManager.LosEnabled;
                NewMessage("Line of sight effect " + (GameMain.LightManager.LosEnabled ? "enabled" : "disabled"), Color.White);
            }));

            commands.Add(new Command("lighting|lights", "Toggle lighting on/off.", (string[] args) =>
            {
                GameMain.LightManager.LightingEnabled = !GameMain.LightManager.LightingEnabled;
                NewMessage("Lighting " + (GameMain.LightManager.LightingEnabled ? "enabled" : "disabled"), Color.White);
            }));

            commands.Add(new Command("tutorial", "", (string[] args) =>
            {
                TutorialMode.StartTutorial(Tutorials.TutorialType.TutorialTypes[0]);
            }));

            commands.Add(new Command("lobby|lobbyscreen", "", (string[] args) =>
            {
                GameMain.LobbyScreen.Select();
            }));

            commands.Add(new Command("save|savesub", "save [submarine name]: Save the currently loaded submarine using the specified name.", (string[] args) =>
            {
                if (args.Length < 1)
                {
                    return;
                }

                if (GameMain.SubEditorScreen.CharacterMode)
                {
                    GameMain.SubEditorScreen.ToggleCharacterMode();
                }

                string fileName = string.Join(" ", args);
                if (fileName.Contains("../"))
                {
                    ThrowError("Illegal symbols in filename (../)");
                    return;
                }

                if (Submarine.SaveCurrent(System.IO.Path.Combine(Submarine.SavePath, fileName + ".sub")))
                {
                    NewMessage("Sub saved", Color.Green);
                }
            }));

            commands.Add(new Command("load|loadsub", "load [submarine name]: Load a submarine.", (string[] args) =>
            {
                if (args.Length == 0)
                {
                    return;
                }
                Submarine.Load(string.Join(" ", args), true);
            }));

            commands.Add(new Command("cleansub", "", (string[] args) =>
            {
                for (int i = MapEntity.mapEntityList.Count - 1; i >= 0; i--)
                {
                    MapEntity me = MapEntity.mapEntityList[i];

                    if (me.SimPosition.Length() > 2000.0f)
                    {
                        NewMessage("Removed " + me.Name + " (simposition " + me.SimPosition + ")", Color.Orange);
                        MapEntity.mapEntityList.RemoveAt(i);
                    }
                    else if (!me.ShouldBeSaved)
                    {
                        NewMessage("Removed " + me.Name + " (!ShouldBeSaved)", Color.Orange);
                        MapEntity.mapEntityList.RemoveAt(i);
                    }
                    else if (me is Item)
                    {
                        Item item = me as Item;
                        var wire  = item.GetComponent <Wire>();
                        if (wire == null)
                        {
                            continue;
                        }

                        if (wire.GetNodes().Count > 0 && !wire.Connections.Any(c => c != null))
                        {
                            wire.Item.Drop(null);
                            NewMessage("Dropped wire (ID: " + wire.Item.ID + ") - attached on wall but no connections found", Color.Orange);
                        }
                    }
                }
            }));

            commands.Add(new Command("messagebox", "", (string[] args) =>
            {
                new GUIMessageBox("", string.Join(" ", args));
            }));

            commands.Add(new Command("debugdraw", "debugdraw: Toggle the debug drawing mode on/off.", (string[] args) =>
            {
                GameMain.DebugDraw = !GameMain.DebugDraw;
                NewMessage("Debug draw mode " + (GameMain.DebugDraw ? "enabled" : "disabled"), Color.White);
            }));
            commands.Add(new Command("fpscounter", "fpscounter: Toggle the FPS counter.", (string[] args) =>
            {
                GameMain.ShowFPS = !GameMain.ShowFPS;
                NewMessage("FPS counter " + (GameMain.DebugDraw ? "enabled" : "disabled"), Color.White);
            }));

            commands.Add(new Command("togglehud|hud", "togglehud/hud: Toggle the character HUD (inventories, icons, buttons, etc) on/off.", (string[] args) =>
            {
                GUI.DisableHUD = !GUI.DisableHUD;
                GameMain.Instance.IsMouseVisible = !GameMain.Instance.IsMouseVisible;
                NewMessage(GUI.DisableHUD ? "Disabled HUD" : "Enabled HUD", Color.White);
            }));

            commands.Add(new Command("followsub", "followsub: Toggle whether the camera should follow the nearest submarine.", (string[] args) =>
            {
                Camera.FollowSub = !Camera.FollowSub;
                NewMessage(Camera.FollowSub ? "Set the camera to follow the closest submarine" : "Disabled submarine following.", Color.White);
            }));

            commands.Add(new Command("toggleaitargets|aitargets", "toggleaitargets/aitargets: Toggle the visibility of AI targets (= targets that enemies can detect and attack/escape from).", (string[] args) =>
            {
                AITarget.ShowAITargets = !AITarget.ShowAITargets;
                NewMessage(AITarget.ShowAITargets ? "Enabled AI target drawing" : "Disabled AI target drawing", Color.White);
            }));
#if DEBUG
            commands.Add(new Command("spamchatmessages", "", (string[] args) =>
            {
                int msgCount = 1000;
                if (args.Length > 0)
                {
                    int.TryParse(args[0], out msgCount);
                }
                int msgLength = 50;
                if (args.Length > 1)
                {
                    int.TryParse(args[1], out msgLength);
                }

                for (int i = 0; i < msgCount; i++)
                {
                    if (GameMain.Server != null)
                    {
                        GameMain.Server.SendChatMessage(ToolBox.RandomSeed(msgLength), ChatMessageType.Default);
                    }
                    else if (GameMain.Client != null)
                    {
                        GameMain.Client.SendChatMessage(ToolBox.RandomSeed(msgLength));
                    }
                }
            }));
#endif
            commands.Add(new Command("cleanbuild", "", (string[] args) =>
            {
                GameMain.Config.MusicVolume = 0.5f;
                GameMain.Config.SoundVolume = 0.5f;
                NewMessage("Music and sound volume set to 0.5", Color.Green);

                GameMain.Config.GraphicsWidth  = 0;
                GameMain.Config.GraphicsHeight = 0;
                GameMain.Config.WindowMode     = WindowMode.Fullscreen;
                NewMessage("Resolution set to 0 x 0 (screen resolution will be used)", Color.Green);
                NewMessage("Fullscreen enabled", Color.Green);

                GameSettings.ShowUserStatisticsPrompt = true;

                GameSettings.VerboseLogging = false;

                if (GameMain.Config.MasterServerUrl != "http://www.undertowgames.com/baromaster")
                {
                    ThrowError("MasterServerUrl \"" + GameMain.Config.MasterServerUrl + "\"!");
                }

                GameMain.Config.Save("config.xml");

                var saveFiles = System.IO.Directory.GetFiles(SaveUtil.SaveFolder);

                foreach (string saveFile in saveFiles)
                {
                    System.IO.File.Delete(saveFile);
                    NewMessage("Deleted " + saveFile, Color.Green);
                }

                if (System.IO.Directory.Exists(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp")))
                {
                    System.IO.Directory.Delete(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp"), true);
                    NewMessage("Deleted temp save folder", Color.Green);
                }

                if (System.IO.Directory.Exists(ServerLog.SavePath))
                {
                    var logFiles = System.IO.Directory.GetFiles(ServerLog.SavePath);

                    foreach (string logFile in logFiles)
                    {
                        System.IO.File.Delete(logFile);
                        NewMessage("Deleted " + logFile, Color.Green);
                    }
                }

                if (System.IO.File.Exists("filelist.xml"))
                {
                    System.IO.File.Delete("filelist.xml");
                    NewMessage("Deleted filelist", Color.Green);
                }

                if (System.IO.File.Exists("Data/bannedplayers.txt"))
                {
                    System.IO.File.Delete("Data/bannedplayers.txt");
                    NewMessage("Deleted bannedplayers.txt", Color.Green);
                }

                if (System.IO.File.Exists("Submarines/TutorialSub.sub"))
                {
                    System.IO.File.Delete("Submarines/TutorialSub.sub");

                    NewMessage("Deleted TutorialSub from the submarine folder", Color.Green);
                }

                if (System.IO.File.Exists(GameServer.SettingsFile))
                {
                    System.IO.File.Delete(GameServer.SettingsFile);
                    NewMessage("Deleted server settings", Color.Green);
                }

                if (System.IO.File.Exists(GameServer.ClientPermissionsFile))
                {
                    System.IO.File.Delete(GameServer.ClientPermissionsFile);
                    NewMessage("Deleted client permission file", Color.Green);
                }

                if (System.IO.File.Exists("crashreport.txt"))
                {
                    System.IO.File.Delete("crashreport.txt");
                    NewMessage("Deleted crashreport.txt", Color.Green);
                }

                if (!System.IO.File.Exists("Content/Map/TutorialSub.sub"))
                {
                    ThrowError("TutorialSub.sub not found!");
                }
            }));
        }
Example #28
0
        /// <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 (GUIComponent.MouseOn != null || !PlayerInput.MouseInsideWindow)
            {
                if (highlightedListBox == null ||
                    (GUIComponent.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUIComponent.MouseOn)))
                {
                    UpdateHighlightedListBox(null);
                    return;
                }
            }

            if (MapEntityPrefab.Selected != null)
            {
                selectionPos = Vector2.Zero;
                selectedList.Clear();
                return;
            }

            if (PlayerInput.KeyDown(Keys.Delete))
            {
                selectedList.ForEach(e => e.Remove());
                selectedList.Clear();
            }

            if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
            {
                if (PlayerInput.GetKeyboardState.IsKeyDown(Keys.C) &&
                    PlayerInput.GetOldKeyboardState.IsKeyUp(Keys.C))
                {
                    CopyEntities(selectedList);
                }
                else if (PlayerInput.GetKeyboardState.IsKeyDown(Keys.X) &&
                         PlayerInput.GetOldKeyboardState.IsKeyUp(Keys.X))
                {
                    CopyEntities(selectedList);

                    selectedList.ForEach(e => e.Remove());
                    selectedList.Clear();
                }
                else if (copiedList.Count > 0 &&
                         PlayerInput.GetKeyboardState.IsKeyDown(Keys.V) &&
                         PlayerInput.GetOldKeyboardState.IsKeyUp(Keys.V))
                {
                    var clones = Clone(copiedList);

                    Vector2 center = Vector2.Zero;
                    clones.ForEach(c => center += c.WorldPosition);
                    center = Submarine.VectorToWorldGrid(center / clones.Count);

                    Vector2 moveAmount = Submarine.VectorToWorldGrid(cam.WorldViewCenter - center);

                    selectedList = new List <MapEntity>(clones);
                    foreach (MapEntity clone in selectedList)
                    {
                        clone.Move(moveAmount);
                        clone.Submarine = Submarine.MainSub;
                    }
                }
            }

            Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);

            MapEntity highLightedEntity = null;

            if (startMovingPos == Vector2.Zero)
            {
                List <MapEntity> highlightedEntities = new List <MapEntity>();
                if (highlightedListBox != null && highlightedListBox.IsParentOf(GUIComponent.MouseOn))
                {
                    highLightedEntity = GUIComponent.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].Sprite.Depth < e.Sprite.Depth))
                            {
                                i++;
                            }

                            highlightedEntities.Insert(i, e);

                            if (i == 0)
                            {
                                highLightedEntity = e;
                            }
                        }
                    }

                    if (PlayerInput.MouseSpeed.LengthSquared() > 10)
                    {
                        highlightTimer = 0.0f;
                    }
                    else
                    {
                        bool mouseNearHighlightBox = false;

                        if (highlightedListBox != null)
                        {
                            Rectangle expandedRect = highlightedListBox.Rect;
                            expandedRect.Inflate(20, 20);
                            mouseNearHighlightBox = expandedRect.Contains(PlayerInput.MousePosition);
                            if (!mouseNearHighlightBox)
                            {
                                highlightedListBox = null;
                            }
                        }

                        highlightTimer += (float)Timing.Step;
                        if (highlightTimer > 1.0f)
                        {
                            if (!mouseNearHighlightBox)
                            {
                                UpdateHighlightedListBox(highlightedEntities);
                                highlightTimer = 0.0f;
                            }
                        }
                    }
                }

                if (highLightedEntity != null)
                {
                    highLightedEntity.isHighlighted = true;
                }
            }

            Vector2 nudgeAmount = Vector2.Zero;

            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);
                }
            }

            //started moving selected entities
            if (startMovingPos != Vector2.Zero)
            {
                if (PlayerInput.LeftButtonReleased())
                {
                    //mouse released -> move the entities to the new position of the mouse

                    Vector2 moveAmount = position - startMovingPos;
                    moveAmount = Submarine.VectorToWorldGrid(moveAmount);

                    if (moveAmount != Vector2.Zero)
                    {
                        //clone
                        if (PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl))
                        {
                            var clones = Clone(selectedList);
                            selectedList = clones;
                            selectedList.ForEach(c => c.Move(moveAmount));
                        }
                        else // move
                        {
                            foreach (MapEntity e in selectedList)
                            {
                                e.Move(moveAmount);
                            }
                        }
                    }

                    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)
                    {
                        newSelection.Add(highLightedEntity);
                    }
                }

                if (PlayerInput.LeftButtonReleased())
                {
                    if (PlayerInput.KeyDown(Keys.LeftControl) ||
                        PlayerInput.KeyDown(Keys.RightControl))
                    {
                        foreach (MapEntity e in newSelection)
                        {
                            if (selectedList.Contains(e))
                            {
                                selectedList.Remove(e);
                            }
                            else
                            {
                                selectedList.Add(e);
                            }
                        }
                    }
                    else
                    {
                        selectedList = newSelection;
                    }

                    //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.LeftButtonHeld() &&
                    PlayerInput.KeyUp(Keys.Space) &&
                    (highlightedListBox == null || (GUIComponent.MouseOn != highlightedListBox && !highlightedListBox.IsParentOf(GUIComponent.MouseOn))))
                {
                    //if clicking a selected entity, start moving it
                    foreach (MapEntity e in selectedList)
                    {
                        if (e.IsMouseOn(position))
                        {
                            startMovingPos = position;
                        }
                    }

                    selectionPos = position;
                }
            }
        }
Example #29
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        public override void Update(double deltaTime)
        {
#if CLIENT
            if (Character.Spied != null)
            {
                if ((PlayerInput.KeyDown(InputType.Up) || PlayerInput.KeyDown(InputType.Down) || PlayerInput.KeyDown(InputType.Left) || PlayerInput.KeyDown(InputType.Right)) && !DebugConsole.IsOpen)
                {
                    if (GameMain.NetworkMember != null && !GameMain.NetworkMember.chatMsgBox.Selected)
                    {
                        if (Character.Controlled != null)
                        {
                            cam.Position = Character.Controlled.WorldPosition;
                        }
                        else
                        {
                            cam.Position = Character.Spied.WorldPosition;
                        }
                        Character.Spied = null;
                        cam.UpdateTransform(true);
                    }
                }
            }
#endif

#if DEBUG && CLIENT
            if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null &&
                !DebugConsole.IsOpen && GUIComponent.KeyboardDispatcher.Subscriber == null)
            {
                /*
                 * var closestSub = Submarine.FindClosest(cam.WorldViewCenter);
                 * if (closestSub == null) closestSub = GameMain.GameSession.Submarine;
                 *
                 * Vector2 targetMovement = Vector2.Zero;
                 * if (PlayerInput.KeyDown(Keys.I)) targetMovement.Y += 1.0f;
                 * if (PlayerInput.KeyDown(Keys.K)) targetMovement.Y -= 1.0f;
                 * if (PlayerInput.KeyDown(Keys.J)) targetMovement.X -= 1.0f;
                 * if (PlayerInput.KeyDown(Keys.L)) targetMovement.X += 1.0f;
                 *
                 * if (targetMovement != Vector2.Zero)
                 *  closestSub.ApplyForce(targetMovement * closestSub.SubBody.Body.Mass * 100.0f);
                 */
            }
#endif

#if CLIENT
            GameMain.NilModProfiler.SWMapEntityUpdate.Start();
#endif

            foreach (MapEntity e in MapEntity.mapEntityList)
            {
                e.IsHighlighted = false;
            }

#if CLIENT
            GameMain.NilModProfiler.SWMapEntityUpdate.Stop();

            if (GameMain.GameSession != null)
            {
                GameMain.NilModProfiler.SWGameSessionUpdate.Start();
                GameMain.GameSession.Update((float)deltaTime);
                GameMain.NilModProfiler.RecordGameSessionUpdate();
            }

            GameMain.NilModProfiler.SWParticleManager.Start();

            GameMain.ParticleManager.Update((float)deltaTime);

            GameMain.NilModProfiler.RecordParticleManager();
            GameMain.NilModProfiler.SWLightManager.Start();

            GameMain.LightManager.Update((float)deltaTime);

            GameMain.NilModProfiler.RecordLightManager();
#endif

            if (Level.Loaded != null)
            {
#if CLIENT
                GameMain.NilModProfiler.SWLevelUpdate.Start();
#endif
                Level.Loaded.Update((float)deltaTime, cam);
#if CLIENT
                GameMain.NilModProfiler.RecordLevelUpdate();
#endif
            }

#if CLIENT
            if (Character.Controlled != null && Character.Controlled.SelectedConstruction != null && Character.Controlled.CanInteractWith(Character.Controlled.SelectedConstruction))
            {
                Character.Controlled.SelectedConstruction.UpdateHUD(cam, Character.Controlled);
            }
            GameMain.NilModProfiler.SWCharacterUpdate.Start();
#endif

            Character.UpdateAll((float)deltaTime, cam);

#if CLIENT
            //NilMod spy Code
            if (Character.Spied != null)
            {
                Character.ViewSpied((float)deltaTime, Cam, true);
                Lights.LightManager.ViewTarget = Character.Spied;
                CharacterHUD.Update((float)deltaTime, Character.Spied);

                foreach (HUDProgressBar progressBar in Character.Spied.HUDProgressBars.Values)
                {
                    progressBar.Update((float)deltaTime);
                }

                foreach (var pb in Character.Spied.HUDProgressBars)
                {
                    if (pb.Value.FadeTimer <= 0.0f)
                    {
                        Character.Spied.HUDProgressBars.Remove(pb.Key);
                    }
                }
            }

            GameMain.NilModProfiler.SWCharacterUpdate.Stop();
            GameMain.NilModProfiler.RecordCharacterUpdate();
            GameMain.NilModProfiler.SWStatusEffect.Start();
#endif
            StatusEffect.UpdateAll((float)deltaTime);

#if CLIENT
            GameMain.NilModProfiler.RecordStatusEffect();
            if ((Character.Controlled != null && Lights.LightManager.ViewTarget != null) || (Character.Spied != null && Lights.LightManager.ViewTarget != null))
            {
                cam.TargetPos = Lights.LightManager.ViewTarget.WorldPosition;
            }
#endif

            cam.MoveCamera((float)deltaTime);
#if CLIENT
            GameMain.NilModProfiler.SWSetTransforms.Start();
#endif
            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.SetPrevTransform(sub.Position);
            }

            foreach (PhysicsBody pb in PhysicsBody.List)
            {
                pb.SetPrevTransform(pb.SimPosition, pb.Rotation);
            }
#if CLIENT
            GameMain.NilModProfiler.RecordSetTransforms();
            GameMain.NilModProfiler.SWMapEntityUpdate.Start();
#endif
            MapEntity.UpdateAll((float)deltaTime, cam);
#if CLIENT
            GameMain.NilModProfiler.RecordMapEntityUpdate();
            GameMain.NilModProfiler.SWCharacterAnimUpdate.Start();
#endif
            Character.UpdateAnimAll((float)deltaTime);
#if CLIENT
            GameMain.NilModProfiler.RecordCharacterAnimUpdate();
            GameMain.NilModProfiler.SWRagdollUpdate.Start();
#endif
            Ragdoll.UpdateAll((float)deltaTime, cam);
#if CLIENT
            GameMain.NilModProfiler.RecordRagdollUpdate();
            GameMain.NilModProfiler.SWSubmarineUpdate.Start();
#endif
            foreach (Submarine sub in Submarine.Loaded)
            {
                sub.Update((float)deltaTime);
            }

#if CLIENT
            GameMain.NilModProfiler.RecordSubmarineUpdate();
            GameMain.NilModProfiler.SWCharacterUpdate.Start();
#endif

#if CLIENT
            GameMain.NilModProfiler.RecordCharacterUpdate();
            GameMain.NilModProfiler.SWPhysicsWorldStep.Start();
#endif
            GameMain.World.Step((float)deltaTime);
#if CLIENT
            GameMain.NilModProfiler.RecordPhysicsWorldStep();

            if (!PlayerInput.LeftButtonHeld())
            {
                Inventory.draggingSlot = null;
                Inventory.draggingItem = null;
            }
#endif
        }
Example #30
0
        public void Load(bool unloadPrevious, XElement submarineElement = null)
        {
            if (unloadPrevious)
            {
                Unload();
            }

            Loading = true;

            if (submarineElement == null)
            {
                XDocument doc = OpenFile(filePath);
                if (doc == null || doc.Root == null)
                {
                    return;
                }

                submarineElement = doc.Root;
            }

            Description = submarineElement.GetAttributeString("description", "");
            Enum.TryParse(submarineElement.GetAttributeString("tags", ""), out tags);

            //place the sub above the top of the level
            HiddenSubPosition = HiddenSubStartPosition;
            if (GameMain.GameSession != null && GameMain.GameSession.Level != null)
            {
                HiddenSubPosition += Vector2.UnitY * GameMain.GameSession.Level.Size.Y;
            }

            foreach (Submarine sub in Submarine.loaded)
            {
                HiddenSubPosition += Vector2.UnitY * (sub.Borders.Height + 5000.0f);
            }

            IdOffset = 0;
            foreach (MapEntity me in MapEntity.mapEntityList)
            {
                IdOffset = Math.Max(IdOffset, me.ID);
            }

            foreach (XElement element in submarineElement.Elements())
            {
                string typeName = element.Name.ToString();

                Type t;
                try
                {
                    t = Type.GetType("Barotrauma." + typeName, true, true);
                    if (t == null)
                    {
                        DebugConsole.ThrowError("Error in " + filePath + "! Could not find a entity of the type \"" + typeName + "\".");
                        continue;
                    }
                }
                catch (Exception e)
                {
                    DebugConsole.ThrowError("Error in " + filePath + "! Could not find a entity of the type \"" + typeName + "\".", e);
                    continue;
                }

                try
                {
                    MethodInfo loadMethod = t.GetMethod("Load");
                    loadMethod.Invoke(t, new object[] { element, this });
                }
                catch (Exception e)
                {
                    DebugConsole.ThrowError("Could not find the method \"Load\" in " + t + ".", e);
                }
            }

            Vector2 center = Vector2.Zero;

            var matchingHulls = Hull.hullList.FindAll(h => h.Submarine == this);

            if (matchingHulls.Any())
            {
                Vector2 topLeft     = new Vector2(matchingHulls[0].Rect.X, matchingHulls[0].Rect.Y);
                Vector2 bottomRight = new Vector2(matchingHulls[0].Rect.X, matchingHulls[0].Rect.Y);
                foreach (Hull hull in matchingHulls)
                {
                    if (hull.Rect.X < topLeft.X)
                    {
                        topLeft.X = hull.Rect.X;
                    }
                    if (hull.Rect.Y > topLeft.Y)
                    {
                        topLeft.Y = hull.Rect.Y;
                    }

                    if (hull.Rect.Right > bottomRight.X)
                    {
                        bottomRight.X = hull.Rect.Right;
                    }
                    if (hull.Rect.Y - hull.Rect.Height < bottomRight.Y)
                    {
                        bottomRight.Y = hull.Rect.Y - hull.Rect.Height;
                    }
                }

                center    = (topLeft + bottomRight) / 2.0f;
                center.X -= center.X % GridSize.X;
                center.Y -= center.Y % GridSize.Y;

                if (center != Vector2.Zero)
                {
                    foreach (Item item in Item.ItemList)
                    {
                        if (item.Submarine != this)
                        {
                            continue;
                        }

                        var wire = item.GetComponent <Items.Components.Wire>();
                        if (wire != null)
                        {
                            wire.MoveNodes(-center);
                        }
                    }

                    for (int i = 0; i < MapEntity.mapEntityList.Count; i++)
                    {
                        if (MapEntity.mapEntityList[i].Submarine != this)
                        {
                            continue;
                        }

                        MapEntity.mapEntityList[i].Move(-center);
                    }
                }
            }

            subBody = new SubmarineBody(this);
            subBody.SetPosition(HiddenSubPosition);

            loaded.Add(this);

            if (entityGrid != null)
            {
                Hull.EntityGrids.Remove(entityGrid);
                entityGrid = null;
            }
            entityGrid = Hull.GenerateEntityGrid(this);

            for (int i = 0; i < MapEntity.mapEntityList.Count; i++)
            {
                if (MapEntity.mapEntityList[i].Submarine != this)
                {
                    continue;
                }
                MapEntity.mapEntityList[i].Move(HiddenSubPosition);
            }

            Loading = false;

            MapEntity.MapLoaded(this);

            //WayPoint.GenerateSubWaypoints();

#if CLIENT
            GameMain.LightManager.OnMapLoaded();
#endif

            ID = (ushort)(ushort.MaxValue - Submarine.loaded.IndexOf(this));
        }