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 #2
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 #3
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;
        }