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);
        }
예제 #3
0
        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();
            }
        }
예제 #4
0
 public void FireCharacter(CharacterInfo characterInfo)
 {
     CrewManager.RemoveCharacterInfo(characterInfo);
 }
예제 #5
0
        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();
            }
        }
예제 #6
0
        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);
        }