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