示例#1
0
        public static WayPoint Load(XElement element, Submarine submarine, IdRemap idRemap)
        {
            Rectangle rect = new Rectangle(
                int.Parse(element.Attribute("x").Value),
                int.Parse(element.Attribute("y").Value),
                (int)Submarine.GridSize.X, (int)Submarine.GridSize.Y);


            Enum.TryParse(element.GetAttributeString("spawn", "Path"), out SpawnType spawnType);
            WayPoint w = new WayPoint(MapEntityPrefab.Find(null, spawnType == SpawnType.Path ? "waypoint" : "spawnpoint"), rect, submarine, idRemap.GetOffsetId(element));

            w.spawnType = spawnType;

            string idCardDescString = element.GetAttributeString("idcarddesc", "");

            if (!string.IsNullOrWhiteSpace(idCardDescString))
            {
                w.IdCardDesc = idCardDescString;
            }
            string idCardTagString = element.GetAttributeString("idcardtags", "");

            if (!string.IsNullOrWhiteSpace(idCardTagString))
            {
                w.IdCardTags = idCardTagString.Split(',');
            }

            w.tags = element.GetAttributeStringArray("tags", new string[0], convertToLowerInvariant: true).ToList();

            string jobIdentifier = element.GetAttributeString("job", "").ToLowerInvariant();

            if (!string.IsNullOrWhiteSpace(jobIdentifier))
            {
                w.AssignedJob =
                    JobPrefab.Get(jobIdentifier) ??
                    JobPrefab.Prefabs.Find(jp => jp.Name.Equals(jobIdentifier, StringComparison.OrdinalIgnoreCase));
            }

            w.linkedToID = new List <ushort>();
            w.ladderId   = idRemap.GetOffsetId(element.GetAttributeInt("ladders", 0));
            w.gapId      = idRemap.GetOffsetId(element.GetAttributeInt("gap", 0));

            int i = 0;

            while (element.Attribute("linkedto" + i) != null)
            {
                int srcId  = int.Parse(element.Attribute("linkedto" + i).Value);
                int destId = idRemap.GetOffsetId(srcId);
                if (destId > 0)
                {
                    w.linkedToID.Add((ushort)destId);
                }
                else
                {
                    w.unresolvedLinkedToID ??= new List <ushort>();
                    w.unresolvedLinkedToID.Add((ushort)srcId);
                }
                i += 1;
            }
            return(w);
        }
示例#2
0
        public static Gap Load(XElement element, Submarine submarine, IdRemap idRemap)
        {
            Rectangle rect = Rectangle.Empty;

            if (element.Attribute("rect") != null)
            {
                rect = element.GetAttributeRect("rect", Rectangle.Empty);
            }
            else
            {
                //backwards compatibility
                rect = new Rectangle(
                    int.Parse(element.Attribute("x").Value),
                    int.Parse(element.Attribute("y").Value),
                    int.Parse(element.Attribute("width").Value),
                    int.Parse(element.Attribute("height").Value));
            }

            bool isHorizontal = rect.Height > rect.Width;

            var horizontalAttribute = element.Attribute("horizontal");

            if (horizontalAttribute != null)
            {
                isHorizontal = horizontalAttribute.Value.ToString() == "true";
            }

            Gap g = new Gap(rect, isHorizontal, submarine, idRemap.GetOffsetId(element))
            {
                linkedToID = new List <ushort>(),
            };

            return(g);
        }
示例#3
0
        // LinkedSubmarine.Load() is called from MapEntity.LoadAll()
        public static LinkedSubmarine Load(XElement element, Submarine submarine, IdRemap idRemap)
        {
            Vector2         pos = element.GetAttributeVector2("pos", Vector2.Zero);
            LinkedSubmarine linkedSub;

            if (Screen.Selected == GameMain.SubEditorScreen)
            {
                linkedSub                       = CreateDummy(submarine, element, pos, idRemap.AssignMaxId());
                linkedSub.saveElement           = element;
                linkedSub.purchasedLostShuttles = false;
            }
            else
            {
                string    levelSeed = element.GetAttributeString("location", "");
                LevelData levelData = GameMain.GameSession?.Campaign?.NextLevel ?? GameMain.GameSession?.LevelData;
                linkedSub = new LinkedSubmarine(submarine, idRemap.AssignMaxId())
                {
                    purchasedLostShuttles = GameMain.GameSession?.GameMode is CampaignMode campaign && campaign.PurchasedLostShuttles,
                    saveElement           = element
                };

                if (!string.IsNullOrWhiteSpace(levelSeed) && levelData != null &&
                    levelData.Seed != levelSeed && !linkedSub.purchasedLostShuttles)
                {
                    linkedSub.loadSub = false;
                }
                else
                {
                    linkedSub.loadSub       = true;
                    linkedSub.rect.Location = MathUtils.ToPoint(pos);
                }
            }

            linkedSub.filePath = element.GetAttributeString("filepath", "");
            int[] linkedToIds = element.GetAttributeIntArray("linkedto", new int[0]);
            for (int i = 0; i < linkedToIds.Length; i++)
            {
                linkedSub.linkedToID.Add(idRemap.GetOffsetId(linkedToIds[i]));
            }
            linkedSub.originalLinkedToID = idRemap.GetOffsetId(element.GetAttributeInt("originallinkedto", 0));
            linkedSub.originalMyPortID   = (ushort)element.GetAttributeInt("originalmyport", 0);

            return(linkedSub.loadSub ? linkedSub : null);
        }
示例#4
0
        protected void ParseLinks(XElement element, IdRemap idRemap)
        {
            string linkedToString = element.GetAttributeString("linked", "");

            if (!string.IsNullOrEmpty(linkedToString))
            {
                string[] linkedToIds = linkedToString.Split(',');
                for (int i = 0; i < linkedToIds.Length; i++)
                {
                    int srcId    = int.Parse(linkedToIds[i]);
                    int targetId = idRemap.GetOffsetId(srcId);
                    if (targetId <= 0)
                    {
                        unresolvedLinkedToID ??= new List <ushort>();
                        unresolvedLinkedToID.Add((ushort)srcId);
                        continue;
                    }
                    linkedToID.Add((ushort)targetId);
                }
            }
        }
示例#5
0
 public void ResolveLinks(IdRemap childRemap)
 {
     if (unresolvedLinkedToID == null)
     {
         return;
     }
     for (int i = 0; i < unresolvedLinkedToID.Count; i++)
     {
         int srcId    = unresolvedLinkedToID[i];
         int targetId = childRemap.GetOffsetId(srcId);
         if (targetId > 0)
         {
             var otherEntity = FindEntityByID((ushort)targetId) as MapEntity;
             linkedTo.Add(otherEntity);
             if (otherEntity.Linkable && otherEntity.linkedTo != null)
             {
                 otherEntity.linkedTo.Add(this);
             }
             unresolvedLinkedToID.RemoveAt(i);
             i--;
         }
     }
 }
示例#6
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;
        }