public override void Save(XElement element) { XElement modeElement = new XElement("SinglePlayerCampaign", new XAttribute("money", Money), new XAttribute("cheatsenabled", CheatsEnabled)); //save and remove all items that are in someone's inventory so they don't get included in the sub file as well foreach (Character c in Character.CharacterList) { if (c.Info == null) { continue; } if (c.IsDead) { CrewManager.RemoveCharacterInfo(c.Info); } c.Info.LastControlled = c == lastControlledCharacter; c.Info.HealthData = new XElement("health"); c.CharacterHealth.Save(c.Info.HealthData); if (c.Inventory != null) { c.Info.InventoryData = new XElement("inventory"); c.SaveInventory(c.Inventory, c.Info.InventoryData); c.Inventory?.DeleteAllItems(); } } CrewManager.Save(modeElement); CampaignMetadata.Save(modeElement); Map.Save(modeElement); CargoManager?.SavePurchasedItems(modeElement); UpgradeManager?.SavePendingUpgrades(modeElement, UpgradeManager?.PendingUpgrades); element.Add(modeElement); }
public override void Save(XElement element) { XElement modeElement = new XElement("SinglePlayerCampaign", new XAttribute("money", Money), new XAttribute("purchasedlostshuttles", PurchasedLostShuttles), new XAttribute("purchasedhullrepairs", PurchasedHullRepairs), new XAttribute("purchaseditemrepairs", PurchasedItemRepairs), new XAttribute("cheatsenabled", CheatsEnabled)); modeElement.Add(Settings.Save()); //save and remove all items that are in someone's inventory so they don't get included in the sub file as well foreach (Character c in Character.CharacterList) { if (c.Info == null) { continue; } if (c.IsDead) { CrewManager.RemoveCharacterInfo(c.Info); } c.Info.LastControlled = c == lastControlledCharacter; c.Info.HealthData = new XElement("health"); c.CharacterHealth.Save(c.Info.HealthData); if (c.Inventory != null) { c.Info.InventoryData = new XElement("inventory"); c.SaveInventory(); c.Inventory?.DeleteAllItems(); } c.Info.SaveOrderData(); } petsElement = new XElement("pets"); PetBehavior.SavePets(petsElement); modeElement.Add(petsElement); CrewManager.Save(modeElement); CampaignMetadata.Save(modeElement); Map.Save(modeElement); CargoManager?.SavePurchasedItems(modeElement); UpgradeManager?.Save(modeElement); element.Add(modeElement); }
public void SaveInventories() { List <CharacterCampaignData> prevCharacterData = new List <CharacterCampaignData>(characterData); //client character has spawned this round -> remove old data (and replace with an up-to-date one if the client still has a character) characterData.RemoveAll(cd => cd.HasSpawned); //refresh the character data of clients who are still in the server foreach (Client c in GameMain.Server.ConnectedClients) { if (c.Character?.Info == null) { continue; } if (c.Character.IsDead && c.Character.CauseOfDeath?.Type != CauseOfDeathType.Disconnected) { continue; } c.CharacterInfo = c.Character.Info; characterData.RemoveAll(cd => cd.MatchesClient(c)); characterData.Add(new CharacterCampaignData(c)); } //refresh the character data of clients who aren't in the server anymore foreach (CharacterCampaignData data in prevCharacterData) { if (data.HasSpawned && !characterData.Any(cd => cd.IsDuplicate(data))) { var character = Character.CharacterList.Find(c => c.Info == data.CharacterInfo && !c.IsHusk); if (character != null && (!character.IsDead || character.CauseOfDeath?.Type == CauseOfDeathType.Disconnected)) { data.Refresh(character); characterData.Add(data); } } } characterData.ForEach(cd => cd.HasSpawned = false); petsElement = new XElement("pets"); PetBehavior.SavePets(petsElement); //remove all items that are in someone's inventory foreach (Character c in Character.CharacterList) { if (c.Inventory == null) { continue; } if (Level.Loaded.Type == LevelData.LevelType.Outpost && c.Submarine != Level.Loaded.StartOutpost) { Map.CurrentLocation.RegisterTakenItems(c.Inventory.AllItems.Where(it => it.SpawnedInOutpost && it.OriginalModuleIndex > 0)); } if (c.Info != null && c.IsBot) { if (c.IsDead && c.CauseOfDeath?.Type != CauseOfDeathType.Disconnected) { CrewManager.RemoveCharacterInfo(c.Info); } c.Info.HealthData = new XElement("health"); c.CharacterHealth.Save(c.Info.HealthData); c.Info.InventoryData = new XElement("inventory"); c.SaveInventory(); c.Info.SaveOrderData(); } c.Inventory.DeleteAllItems(); } }
public void FireCharacter(CharacterInfo characterInfo) { CrewManager.RemoveCharacterInfo(characterInfo); }
public void SavePlayers() { //refresh the character data of clients who are still in the server foreach (Client c in GameMain.Server.ConnectedClients) { //ignore if the character is controlling a monster //(we'll just use the previously saved campaign data if there's any) if (c.Character != null && c.Character.Info == null) { c.Character = null; } if (c.HasSpawned && c.CharacterInfo != null && c.CharacterInfo.CauseOfDeath != null && c.CharacterInfo.CauseOfDeath.Type != CauseOfDeathType.Disconnected) { //the client has opted to spawn this round with Reaper's Tax if (c.WaitForNextRoundRespawn.HasValue && !c.WaitForNextRoundRespawn.Value) { c.CharacterInfo.StartItemsGiven = false; characterData.RemoveAll(cd => cd.MatchesClient(c)); characterData.Add(new CharacterCampaignData(c, giveRespawnPenaltyAffliction: true)); continue; } } //use the info of the character the client is currently controlling // or the previously saved info if not (e.g. if the client has been spectating or died) var characterInfo = c.Character?.Info ?? characterData.Find(d => d.MatchesClient(c))?.CharacterInfo; if (characterInfo == null) { continue; } //reduce skills if the character has died if (characterInfo.CauseOfDeath != null && characterInfo.CauseOfDeath.Type != CauseOfDeathType.Disconnected) { RespawnManager.ReduceCharacterSkills(characterInfo); } c.CharacterInfo = characterInfo; characterData.RemoveAll(cd => cd.MatchesClient(c)); characterData.Add(new CharacterCampaignData(c)); } //refresh the character data of clients who aren't in the server anymore List <CharacterCampaignData> prevCharacterData = new List <CharacterCampaignData>(characterData); foreach (CharacterCampaignData data in prevCharacterData) { if (data.HasSpawned && !GameMain.Server.ConnectedClients.Any(c => data.MatchesClient(c))) { var character = Character.CharacterList.Find(c => c.Info == data.CharacterInfo && !c.IsHusk); if (character != null && (!character.IsDead || character.CauseOfDeath?.Type == CauseOfDeathType.Disconnected)) { characterData.RemoveAll(cd => cd.IsDuplicate(data)); data.Refresh(character); characterData.Add(data); } } } characterData.ForEach(cd => cd.HasSpawned = false); petsElement = new XElement("pets"); PetBehavior.SavePets(petsElement); //remove all items that are in someone's inventory foreach (Character c in Character.CharacterList) { if (c.Inventory == null) { continue; } if (Level.Loaded.Type == LevelData.LevelType.Outpost && c.Submarine != Level.Loaded.StartOutpost) { Map.CurrentLocation.RegisterTakenItems(c.Inventory.AllItems.Where(it => it.SpawnedInOutpost && it.OriginalModuleIndex > 0)); } if (c.Info != null && c.IsBot) { if (c.IsDead && c.CauseOfDeath?.Type != CauseOfDeathType.Disconnected) { CrewManager.RemoveCharacterInfo(c.Info); } c.Info.HealthData = new XElement("health"); c.CharacterHealth.Save(c.Info.HealthData); c.Info.InventoryData = new XElement("inventory"); c.SaveInventory(); c.Info.SaveOrderData(); } c.Inventory.DeleteAllItems(); } }
protected override IEnumerable <object> DoLevelTransition(TransitionType transitionType, LevelData newLevel, Submarine leavingSub, bool mirror, List <TraitorMissionResult> traitorResults) { lastUpdateID++; switch (transitionType) { case TransitionType.None: throw new InvalidOperationException("Level transition failed (no transitions available)."); case TransitionType.ReturnToPreviousLocation: //deselect destination on map map.SelectLocation(-1); break; case TransitionType.ProgressToNextLocation: Map.MoveToNextLocation(); break; case TransitionType.End: EndCampaign(); IsFirstRound = true; break; } Map.ProgressWorld(transitionType, (float)(Timing.TotalTime - GameMain.GameSession.RoundStartTime)); bool success = GameMain.Server.ConnectedClients.Any(c => c.InGame && c.Character != null && !c.Character.IsDead); GameMain.GameSession.EndRound("", traitorResults, transitionType); //-------------------------------------- if (success) { List <CharacterCampaignData> prevCharacterData = new List <CharacterCampaignData>(characterData); //client character has spawned this round -> remove old data (and replace with an up-to-date one if the client still has a character) characterData.RemoveAll(cd => cd.HasSpawned); //refresh the character data of clients who are still in the server foreach (Client c in GameMain.Server.ConnectedClients) { if (c.Character?.Info == null) { continue; } if (c.Character.IsDead && c.Character.CauseOfDeath?.Type != CauseOfDeathType.Disconnected) { continue; } c.CharacterInfo = c.Character.Info; characterData.RemoveAll(cd => cd.MatchesClient(c)); characterData.Add(new CharacterCampaignData(c)); } //refresh the character data of clients who aren't in the server anymore foreach (CharacterCampaignData data in prevCharacterData) { if (data.HasSpawned && !characterData.Any(cd => cd.IsDuplicate(data))) { var character = Character.CharacterList.Find(c => c.Info == data.CharacterInfo && !c.IsHusk); if (character != null && (!character.IsDead || character.CauseOfDeath?.Type == CauseOfDeathType.Disconnected)) { data.Refresh(character); characterData.Add(data); } } } characterData.ForEach(cd => cd.HasSpawned = false); //remove all items that are in someone's inventory foreach (Character c in Character.CharacterList) { if (c.Inventory == null) { continue; } if (Level.Loaded.Type == LevelData.LevelType.Outpost && c.Submarine != Level.Loaded.StartOutpost) { Map.CurrentLocation.RegisterTakenItems(c.Inventory.Items.Where(it => it != null && it.SpawnedInOutpost && it.OriginalModuleIndex > 0).Distinct()); } if (c.Info != null && c.IsBot) { if (c.IsDead && c.CauseOfDeath?.Type != CauseOfDeathType.Disconnected) { CrewManager.RemoveCharacterInfo(c.Info); } c.Info.HealthData = new XElement("health"); c.CharacterHealth.Save(c.Info.HealthData); c.Info.InventoryData = new XElement("inventory"); c.SaveInventory(c.Inventory, c.Info.InventoryData); } c.Inventory.DeleteAllItems(); } yield return(CoroutineStatus.Running); if (leavingSub != Submarine.MainSub && !leavingSub.DockedTo.Contains(Submarine.MainSub)) { Submarine.MainSub = leavingSub; GameMain.GameSession.Submarine = leavingSub; var subsToLeaveBehind = GetSubsToLeaveBehind(leavingSub); foreach (Submarine sub in subsToLeaveBehind) { MapEntity.mapEntityList.RemoveAll(e => e.Submarine == sub && e is LinkedSubmarine); LinkedSubmarine.CreateDummy(leavingSub, sub); } } NextLevel = newLevel; GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine); if (PendingSubmarineSwitch != null) { SubmarineInfo previousSub = GameMain.GameSession.SubmarineInfo; GameMain.GameSession.SubmarineInfo = PendingSubmarineSwitch; PendingSubmarineSwitch = null; for (int i = 0; i < GameMain.GameSession.OwnedSubmarines.Count; i++) { if (GameMain.GameSession.OwnedSubmarines[i].Name == previousSub.Name) { GameMain.GameSession.OwnedSubmarines[i] = previousSub; break; } } } SaveUtil.SaveGame(GameMain.GameSession.SavePath); } else { PendingSubmarineSwitch = null; GameMain.Server.EndGame(TransitionType.None); LoadCampaign(GameMain.GameSession.SavePath); LastSaveID++; LastUpdateID++; yield return(CoroutineStatus.Success); } //-------------------------------------- GameMain.Server.EndGame(transitionType); ForceMapUI = false; NextLevel = newLevel; MirrorLevel = mirror; //give clients time to play the end cinematic before starting the next round if (transitionType == TransitionType.End) { yield return(new WaitForSeconds(EndCinematicDuration)); } else { yield return(new WaitForSeconds(EndTransitionDuration * 0.5f)); } GameMain.Server.StartGame(); yield return(CoroutineStatus.Success); }