Ejemplo n.º 1
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();
            }
        }