/// <summary> /// Check to see if this docking port can capture another given the position, angle and velocity limits /// specified. /// </summary> /// <param name="matePort"></param> /// <returns></returns> public bool Capture(DockingPort matePort) { float deltaPos = Vector3.Distance(transform.position, matePort.gameObject.transform.position); Vector3 mateDirection = matePort.gameObject.transform.rotation * Vector3.forward; Vector3 myDirection = transform.rotation * Vector3.forward; float deltaAngle = Vector3.Angle(mateDirection, myDirection); float dV = (shipRigidbody.velocity - matePort.GetRigidbody().velocity).magnitude; if (deltaPos > captureDeltaPos) { return(false); } if (deltaAngle > captureDeltaAngleDeg) { return(false); } // velocity limit if (dV > velocityLimit) { return(false); } Debug.Log("Capture"); return(true); }
public Status ApproachFindDockingPort(double distance) { if (approach_target_stage_ != ApproachTargetStage.SHIP) { return(Status.FINISHED); } if (distance > TARGET_HAS_DETAILS_DISTANCE_THRESHOLD) { return(Status.UNFINISHED); } var ports = approach_vessel_.Parts.DockingPorts.Where(p => p.Part.Tag == approach_dock_tag_); if (ports.Count() == 0) { return(Status.UNFINISHED); } DockingPort port = ports.First(); approach_tar_pos_stream_.Remove(); approach_tar_vel_stream_.Remove(); SpaceCenter.TargetDockingPort = port; approach_tar_pos_stream_ = Conn.AddStream(() => port.Position(OrbitBodyFrame)); approach_tar_vel_stream_ = Conn.AddStream(() => port.Part.Velocity(OrbitBodyFrame)); approach_tar_dir_stream_ = Conn.AddStream(() => port.Direction(OrbitBodyFrame)); approach_target_stage_ = ApproachTargetStage.PORT; return(Status.SUCCESS); }
private void GenerateOutpost(Submarine submarine) { Submarine outpost = OutpostGenerator.Generate(OutpostParams ?? OutpostGenerationParams.Params.GetRandom(), OutpostType ?? LocationType.List.GetRandom()); outpost.SetPosition(Vector2.Zero); float closestDistance = 0.0f; DockingPort myPort = null, outPostPort = null; foreach (DockingPort port in DockingPort.List) { if (port.IsHorizontal || port.Docked) { continue; } if (port.Item.Submarine == outpost) { outPostPort = port; continue; } if (port.Item.Submarine != submarine) { continue; } //the submarine port has to be at the top of the sub if (port.Item.WorldPosition.Y < submarine.WorldPosition.Y) { continue; } float dist = Vector2.DistanceSquared(port.Item.WorldPosition, outpost.WorldPosition); if ((myPort == null || dist < closestDistance || port.MainDockingPort) && !(myPort?.MainDockingPort ?? false)) { myPort = port; closestDistance = dist; } } if (myPort != null && outPostPort != null) { Vector2 portDiff = myPort.Item.WorldPosition - submarine.WorldPosition; Vector2 spawnPos = (outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance; submarine.SetPosition(spawnPos); myPort.Dock(outPostPort); myPort.Lock(true); } if (Character.Controlled != null) { Character.Controlled.TeleportTo(outpost.GetWaypoints(false).GetRandom(point => point.SpawnType == SpawnType.Human).WorldPosition); } }
public static bool ChangeTarget(string name, string tag) { DockingPort target = null; foreach (Vessel vesselTarget in connection.SpaceCenter().Vessels) { if (vesselTarget.Name.Equals(name) && vesselTarget.Type.Equals(VesselType.Station)) { Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WriteLine("Vessel found..."); Console.ResetColor(); try { target = vesselTarget.Parts.WithTag(tag)[0].DockingPort; connection.SpaceCenter().TargetDockingPort = target; break; } catch { } } } if (target == null) { Console.ForegroundColor = ConsoleColor.DarkRed; Console.WriteLine("Target not found"); Console.ResetColor(); return(false); } else { Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WriteLine("Target Found and Set !"); Console.ResetColor(); return(true); } }
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; }
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; }
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; }
public void StartRound(Level level, bool reloadSub = true, bool loadSecondSub = false, bool mirrorLevel = false) { #if CLIENT GameMain.LightManager.LosEnabled = GameMain.Client == null || GameMain.Client.CharacterInfo != null; if (GameMain.Client == null) { GameMain.LightManager.LosMode = GameMain.Config.LosMode; } #endif this.Level = level; if (Submarine == null) { DebugConsole.ThrowError("Couldn't start game session, submarine not selected"); return; } if (reloadSub || Submarine.MainSub != Submarine) { Submarine.Load(true); } Submarine.MainSub = Submarine; if (loadSecondSub) { if (Submarine.MainSubs[1] == null) { Submarine.MainSubs[1] = new Submarine(Submarine.MainSub.FilePath, Submarine.MainSub.MD5Hash.Hash, true); Submarine.MainSubs[1].Load(false); } else if (reloadSub) { Submarine.MainSubs[1].Load(false); } } if (level != null) { level.Generate(mirrorLevel); if (level.StartOutpost != null) { //start by placing the sub below the outpost Rectangle outpostBorders = Level.Loaded.StartOutpost.GetDockedBorders(); Rectangle subBorders = Submarine.GetDockedBorders(); Vector2 startOutpostSize = Vector2.Zero; if (Level.Loaded.StartOutpost != null) { startOutpostSize = Level.Loaded.StartOutpost.Borders.Size.ToVector2(); } Submarine.SetPosition( Level.Loaded.StartOutpost.WorldPosition - new Vector2(0.0f, outpostBorders.Height / 2 + subBorders.Height / 2)); //find the port that's the nearest to the outpost and dock if one is found float closestDistance = 0.0f; DockingPort myPort = null, outPostPort = null; foreach (DockingPort port in DockingPort.List) { if (port.IsHorizontal || port.Docked) { continue; } if (port.Item.Submarine == level.StartOutpost) { outPostPort = port; continue; } if (port.Item.Submarine != Submarine) { continue; } //the submarine port has to be at the top of the sub if (port.Item.WorldPosition.Y < Submarine.WorldPosition.Y) { continue; } float dist = Vector2.DistanceSquared(port.Item.WorldPosition, level.StartOutpost.WorldPosition); if (myPort == null || dist < closestDistance) { myPort = port; closestDistance = dist; } } if (myPort != null && outPostPort != null) { Vector2 portDiff = myPort.Item.WorldPosition - Submarine.WorldPosition; Submarine.SetPosition((outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance); myPort.Dock(outPostPort); myPort.Lock(true); } } else { Submarine.SetPosition(Submarine.FindSpawnPos(level.StartPosition)); } } Entity.Spawner = new EntitySpawner(); if (GameMode.Mission != null) { Mission = GameMode.Mission; } if (GameMode != null) { GameMode.Start(); } if (GameMode.Mission != null) { Mission.Start(Level.Loaded); } EventManager.StartRound(level); SteamAchievementManager.OnStartRound(); if (GameMode != null) { GameMode.MsgBox(); if (GameMode is MultiPlayerCampaign mpCampaign && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) { mpCampaign.CargoManager.CreateItems(); } } GameAnalyticsManager.AddDesignEvent("Submarine:" + Submarine.Name); GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(level.Seed)); GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start, GameMode.Preset.Identifier, (Mission == null ? "None" : Mission.GetType().ToString())); #if CLIENT if (GameMode is SinglePlayerCampaign) { SteamAchievementManager.OnBiomeDiscovered(level.Biome); } roundSummary = new RoundSummary(this); GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f); if (!(GameMode is TutorialMode)) { GUI.AddMessage("", Color.Transparent, 3.0f, playSound: false); GUI.AddMessage(level.Biome.Name, Color.Lerp(Color.CadetBlue, Color.DarkRed, level.Difficulty / 100.0f), 5.0f, playSound: false); GUI.AddMessage(TextManager.Get("Destination") + ": " + EndLocation.Name, Color.CadetBlue, playSound: false); GUI.AddMessage(TextManager.Get("Mission") + ": " + (Mission == null ? TextManager.Get("None") : Mission.Name), Color.CadetBlue, playSound: false); } #endif RoundStartTime = Timing.TotalTime; GameMain.ResetFrameTime(); }
public void Undock () { dockedWith.dockedWith = null; dockedWith = null; }
public void DockWith (DockingPort otherPort) { dockedWith = otherPort; otherPort.dockedWith = this; }
public void PlaceSubAtStart(Level level) { if (level == null) { Submarine.MainSub.SetPosition(Vector2.Zero); return; } var originalSubPos = Submarine.WorldPosition; if (level.StartOutpost != null) { //start by placing the sub below the outpost Rectangle outpostBorders = Level.Loaded.StartOutpost.GetDockedBorders(); Rectangle subBorders = Submarine.GetDockedBorders(); Submarine.SetPosition( Level.Loaded.StartOutpost.WorldPosition - new Vector2(0.0f, outpostBorders.Height / 2 + subBorders.Height / 2)); //find the port that's the nearest to the outpost and dock if one is found float closestDistance = 0.0f; DockingPort myPort = null, outPostPort = null; foreach (DockingPort port in DockingPort.List) { if (port.IsHorizontal || port.Docked) { continue; } if (port.Item.Submarine == level.StartOutpost) { if (port.DockingTarget == null) { outPostPort = port; } continue; } if (port.Item.Submarine != Submarine) { continue; } //the submarine port has to be at the top of the sub if (port.Item.WorldPosition.Y < Submarine.WorldPosition.Y) { continue; } float dist = Vector2.DistanceSquared(port.Item.WorldPosition, level.StartOutpost.WorldPosition); if ((myPort == null || dist < closestDistance || port.MainDockingPort) && !(myPort?.MainDockingPort ?? false)) { myPort = port; closestDistance = dist; } } if (myPort != null && outPostPort != null) { Vector2 portDiff = myPort.Item.WorldPosition - Submarine.WorldPosition; Vector2 spawnPos = (outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance; bool startDocked = level.Type == LevelData.LevelType.Outpost; #if CLIENT startDocked |= GameMode is TutorialMode; #endif if (startDocked) { Submarine.SetPosition(spawnPos); myPort.Dock(outPostPort); myPort.Lock(isNetworkMessage: true, applyEffects: false); } else { Submarine.SetPosition(spawnPos - Vector2.UnitY * 100.0f); Submarine.NeutralizeBallast(); Submarine.EnableMaintainPosition(); } } else { Submarine.NeutralizeBallast(); Submarine.EnableMaintainPosition(); } } else { Submarine.SetPosition(Submarine.FindSpawnPos(level.StartPosition)); Submarine.NeutralizeBallast(); Submarine.EnableMaintainPosition(); } // Make sure that linked subs which are NOT docked to the main sub // (but still close enough to NOT be considered as 'left behind') // are also moved to keep their relative position to the main sub var linkedSubs = MapEntity.mapEntityList.FindAll(me => me is LinkedSubmarine); foreach (LinkedSubmarine ls in linkedSubs) { if (ls.Sub == null || ls.Submarine != Submarine) { continue; } if (!ls.LoadSub || ls.Sub.DockedTo.Contains(Submarine)) { continue; } if (Submarine.Info.LeftBehindDockingPortIDs.Contains(ls.OriginalLinkedToID)) { continue; } if (ls.Sub.Info.SubmarineElement.Attribute("location") != null) { continue; } ls.Sub.SetPosition(ls.Sub.WorldPosition + (Submarine.WorldPosition - originalSubPos)); } }
public void StartRound(Level level, bool mirrorLevel = false) { //make sure no status effects have been carried on from the next round //(they should be stopped in EndRound, this is a safeguard against cases where the round is ended ungracefully) StatusEffect.StopAll(); #if CLIENT GameMain.LightManager.LosEnabled = GameMain.Client == null || GameMain.Client.CharacterInfo != null; if (GameMain.Client == null) { GameMain.LightManager.LosMode = GameMain.Config.LosMode; } #endif this.Level = level; if (SubmarineInfo == null) { DebugConsole.ThrowError("Couldn't start game session, submarine not selected."); return; } if (SubmarineInfo.IsFileCorrupted) { DebugConsole.ThrowError("Couldn't start game session, submarine file corrupted."); return; } Submarine.Unload(); Submarine = Submarine.MainSub = new Submarine(SubmarineInfo); Submarine.MainSub = Submarine; if (GameMode.Mission != null && GameMode.Mission.TeamCount > 1 && Submarine.MainSubs[1] == null) { Submarine.MainSubs[1] = new Submarine(SubmarineInfo, true); } if (level != null) { level.Generate(mirrorLevel); if (level.StartOutpost != null) { //start by placing the sub below the outpost Rectangle outpostBorders = Level.Loaded.StartOutpost.GetDockedBorders(); Rectangle subBorders = Submarine.GetDockedBorders(); Vector2 startOutpostSize = Vector2.Zero; if (Level.Loaded.StartOutpost != null) { startOutpostSize = Level.Loaded.StartOutpost.Borders.Size.ToVector2(); } Submarine.SetPosition( Level.Loaded.StartOutpost.WorldPosition - new Vector2(0.0f, outpostBorders.Height / 2 + subBorders.Height / 2)); //find the port that's the nearest to the outpost and dock if one is found float closestDistance = 0.0f; DockingPort myPort = null, outPostPort = null; foreach (DockingPort port in DockingPort.List) { if (port.IsHorizontal || port.Docked) { continue; } if (port.Item.Submarine == level.StartOutpost) { outPostPort = port; continue; } if (port.Item.Submarine != Submarine) { continue; } //the submarine port has to be at the top of the sub if (port.Item.WorldPosition.Y < Submarine.WorldPosition.Y) { continue; } float dist = Vector2.DistanceSquared(port.Item.WorldPosition, level.StartOutpost.WorldPosition); if (myPort == null || dist < closestDistance || (port.MainDockingPort && !myPort.MainDockingPort)) { myPort = port; closestDistance = dist; } } if (myPort != null && outPostPort != null) { Vector2 portDiff = myPort.Item.WorldPosition - Submarine.WorldPosition; Submarine.SetPosition((outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance); myPort.Dock(outPostPort); myPort.Lock(true); } } else { Submarine.SetPosition(Submarine.FindSpawnPos(level.StartPosition)); } } foreach (var sub in Submarine.Loaded) { if (sub.Info.IsOutpost) { sub.DisableObstructedWayPoints(); } } Entity.Spawner = new EntitySpawner(); if (GameMode.Mission != null) { Mission = GameMode.Mission; } if (GameMode != null) { GameMode.Start(); } if (GameMode.Mission != null) { int prevEntityCount = Entity.GetEntityList().Count; Mission.Start(Level.Loaded); if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient && Entity.GetEntityList().Count != prevEntityCount) { DebugConsole.ThrowError( "Entity count has changed after starting a mission as a client. " + "The clients should not instantiate entities themselves when starting the mission," + " but instead the server should inform the client of the spawned entities using Mission.ServerWriteInitial."); } } EventManager?.StartRound(level); SteamAchievementManager.OnStartRound(); if (GameMode != null) { GameMode.ShowStartMessage(); if (GameMain.NetworkMember == null) { //only place items and corpses here in single player //the server does this after loading the respawn shuttle Level?.SpawnCorpses(); AutoItemPlacer.PlaceIfNeeded(GameMode); } if (GameMode is MultiPlayerCampaign mpCampaign && GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) { mpCampaign.CargoManager.CreateItems(); } } GameAnalyticsManager.AddDesignEvent("Submarine:" + Submarine.Info.Name); GameAnalyticsManager.AddDesignEvent("Level", ToolBox.StringToInt(level?.Seed ?? "[NO_LEVEL]")); GameAnalyticsManager.AddProgressionEvent(GameAnalyticsSDK.Net.EGAProgressionStatus.Start, GameMode.Preset.Identifier, (Mission == null ? "None" : Mission.GetType().ToString())); #if CLIENT if (GameMode is SinglePlayerCampaign) { SteamAchievementManager.OnBiomeDiscovered(level.Biome); } if (!(GameMode is SubTestMode)) { RoundSummary = new RoundSummary(this); } GameMain.GameScreen.ColorFade(Color.Black, Color.TransparentBlack, 5.0f); if (!(GameMode is TutorialMode) && !(GameMode is SubTestMode)) { GUI.AddMessage("", Color.Transparent, 3.0f, playSound: false); GUI.AddMessage(level.Biome.DisplayName, Color.Lerp(Color.CadetBlue, Color.DarkRed, level.Difficulty / 100.0f), 5.0f, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Destination"), EndLocation.Name), Color.CadetBlue, playSound: false); GUI.AddMessage(TextManager.AddPunctuation(':', TextManager.Get("Mission"), (Mission == null ? TextManager.Get("None") : Mission.Name)), Color.CadetBlue, playSound: false); } #endif RoundStartTime = Timing.TotalTime; GameMain.ResetFrameTime(); }
public void PlaceSubAtStart(Level level) { if (level == null) { Submarine.MainSub.SetPosition(Vector2.Zero); return; } if (level.StartOutpost != null) { //start by placing the sub below the outpost Rectangle outpostBorders = Level.Loaded.StartOutpost.GetDockedBorders(); Rectangle subBorders = Submarine.GetDockedBorders(); Submarine.SetPosition( Level.Loaded.StartOutpost.WorldPosition - new Vector2(0.0f, outpostBorders.Height / 2 + subBorders.Height / 2)); //find the port that's the nearest to the outpost and dock if one is found float closestDistance = 0.0f; DockingPort myPort = null, outPostPort = null; foreach (DockingPort port in DockingPort.List) { if (port.IsHorizontal || port.Docked) { continue; } if (port.Item.Submarine == level.StartOutpost) { outPostPort = port; continue; } if (port.Item.Submarine != Submarine) { continue; } //the submarine port has to be at the top of the sub if (port.Item.WorldPosition.Y < Submarine.WorldPosition.Y) { continue; } float dist = Vector2.DistanceSquared(port.Item.WorldPosition, level.StartOutpost.WorldPosition); if ((myPort == null || dist < closestDistance || port.MainDockingPort) && !(myPort?.MainDockingPort ?? false)) { myPort = port; closestDistance = dist; } } if (myPort != null && outPostPort != null) { Vector2 portDiff = myPort.Item.WorldPosition - Submarine.WorldPosition; Vector2 spawnPos = (outPostPort.Item.WorldPosition - portDiff) - Vector2.UnitY * outPostPort.DockedDistance; bool startDocked = level.Type == LevelData.LevelType.Outpost; #if CLIENT startDocked |= GameMode is TutorialMode; #endif if (startDocked) { Submarine.SetPosition(spawnPos); myPort.Dock(outPostPort); myPort.Lock(true); } else { Submarine.SetPosition(spawnPos - Vector2.UnitY * 100.0f); Submarine.NeutralizeBallast(); Submarine.EnableMaintainPosition(); } } else { Submarine.NeutralizeBallast(); Submarine.EnableMaintainPosition(); } } else { Submarine.SetPosition(Submarine.FindSpawnPos(level.StartPosition, verticalMoveDir: 1)); Submarine.NeutralizeBallast(); Submarine.EnableMaintainPosition(); } }
// Update is called once per frame void FixedUpdate() { if (isDockedToGradle) { } else if (isDockedToPayload) { } else if (isAlignedWithPort) { // Move to dock if (MoveTowardsPoint(targetPort.transform.position + targetPort.transform.forward * 0.6f)) { dockingPorts [0].DockWith(targetPort); Joint joint = transform.gameObject.AddComponent <FixedJoint> (); joint.connectedBody = targetPort.GetComponentInParent <Rigidbody> (); if (dockingPorts [0].GetDockedObject().dockingPorts.Length == 1) { // Docked at wall Debug.Log("Docked at wall"); isDockedToGradle = true; } else { // Docked at payload Debug.Log("Docked with payload"); isDockedToPayload = true; // Reset isInFrontOfTargetPort = false; isAlignedWithPort = false; isOnHighway = false; } } } else if (isInFrontOfTargetPort) { // Align with target port Vector3 targetVector = targetPort.transform.position - transform.position; if (RotateToAlignWithForwardAndUp(targetVector, targetPort.transform.up)) { // Aligned with port isAlignedWithPort = true; Debug.Log("Aligned with port"); } } else if (isInRoomWithTarget) { // Move to port if (MoveTowardsPoint(targetPort.getDockingNearLocation())) { isInFrontOfTargetPort = true; Debug.Log("Arrived at target port"); } } else if (isOnHighway) { // Move along highway PathNode nextHighwayNode = highwayPath.GetCurrentNode(); if (MoveTowardsPoint(nextHighwayNode.transform.position)) { // Arrived at node highwayPath.AdvanceToNextNode(); nextHighwayNode = highwayPath.GetCurrentNode(); if (nextHighwayNode == null) { // Arrived in target room isInRoomWithTarget = true; targetPort = targetDock.GetFreeDockingPort(); Debug.Log("Arrived in target room"); } } } else { // Move to highway Vector3 highwayIntersection = game.GetClosestPathIntersection(transform.position); if (MoveTowardsPoint(highwayIntersection)) { // Arrived on highway, calculate highway path isOnHighway = true; PathNode exitNode = game.GetClosestPathNodeToTargetPosition(targetDock.transform.position); highwayPath = game.GetPathToNode(transform.position, exitNode); Debug.Log("Arrived at highway, nodes to go: " + highwayPath.nodes.Length + ", first node: " + highwayPath.GetCurrentNode()); } } }
/// <summary> /// Determine the separation distance between the docking ports in Unity scene units. /// </summary> /// <param name="matePort"></param> /// <returns></returns> public Vector3 SeparationDistance(DockingPort matePort) { return(transform.position - matePort.gameObject.transform.position); }