Ejemplo n.º 1
0
 public Hull(MapEntityPrefab prefab, Rectangle rectangle)
     : this(prefab, rectangle, Submarine.MainSub)
 {
 }
Ejemplo n.º 2
0
        protected override void StartMissionSpecific(Level level)
        {
            if (items.Any())
            {
#if DEBUG
                throw new Exception($"items.Count > 0 ({items.Count})");
#else
                DebugConsole.AddWarning("Item list was not empty at the start of a nest mission. The mission instance may not have been ended correctly on previous rounds.");
                items.Clear();
#endif
            }

            if (!IsClient)
            {
                //ruin/cave/wreck items are allowed to spawn close to the sub
                float minDistance = spawnPositionType == Level.PositionType.Ruin || spawnPositionType == Level.PositionType.Cave || spawnPositionType == Level.PositionType.Wreck ?
                                    0.0f : Level.Loaded.Size.X * 0.3f;
                nestPosition = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, minDistance, 30.0f);
                List <GraphEdge> spawnEdges = new List <GraphEdge>();
                if (spawnPositionType == Level.PositionType.Cave)
                {
                    Level.Cave closestCave     = null;
                    float      closestCaveDist = float.PositiveInfinity;
                    foreach (var cave in Level.Loaded.Caves)
                    {
                        float dist = Vector2.DistanceSquared(nestPosition, cave.Area.Center.ToVector2());
                        if (dist < closestCaveDist)
                        {
                            closestCave     = cave;
                            closestCaveDist = dist;
                        }
                    }
                    if (closestCave != null)
                    {
                        closestCave.DisplayOnSonar = true;
                        SpawnNestObjects(level, closestCave);
#if SERVER
                        selectedCave = closestCave;
#endif
                    }
                    var nearbyCells = Level.Loaded.GetCells(nestPosition, searchDepth: 3);
                    if (nearbyCells.Any())
                    {
                        List <GraphEdge> validEdges = new List <GraphEdge>();
                        foreach (var edge in nearbyCells.SelectMany(c => c.Edges))
                        {
                            if (!edge.NextToCave || !edge.IsSolid)
                            {
                                continue;
                            }
                            if (Level.Loaded.ExtraWalls.Any(w => w.IsPointInside(edge.Center + edge.GetNormal(edge.Cell1 ?? edge.Cell2) * 100.0f)))
                            {
                                continue;
                            }
                            validEdges.Add(edge);
                        }

                        if (validEdges.Any())
                        {
                            spawnEdges.AddRange(validEdges.Where(e => MathUtils.LineSegmentToPointDistanceSquared(e.Point1.ToPoint(), e.Point2.ToPoint(), nestPosition.ToPoint()) < itemSpawnRadius * itemSpawnRadius).Distinct());
                        }
                        //no valid edges found close enough to the nest position, find the closest one
                        if (!spawnEdges.Any())
                        {
                            GraphEdge closestEdge = null;
                            float     closestDist = float.PositiveInfinity;
                            foreach (var edge in nearbyCells.SelectMany(c => c.Edges))
                            {
                                if (!edge.NextToCave || !edge.IsSolid)
                                {
                                    continue;
                                }
                                float dist = Vector2.DistanceSquared(edge.Center, nestPosition);
                                if (dist < closestDist)
                                {
                                    closestEdge = edge;
                                    closestDist = dist;
                                }
                            }
                            if (closestEdge != null)
                            {
                                spawnEdges.Add(closestEdge);
                            }
                        }
                    }
                }

                foreach (XElement subElement in itemConfig.Elements())
                {
                    string itemIdentifier = subElement.GetAttributeString("identifier", "");
                    if (!(MapEntityPrefab.Find(null, itemIdentifier) is ItemPrefab itemPrefab))
                    {
                        DebugConsole.ThrowError("Couldn't spawn item for nest mission: item prefab \"" + itemIdentifier + "\" not found");
                        continue;
                    }

                    Vector2 spawnPos = nestPosition;
                    float   rotation = 0.0f;
                    if (spawnEdges.Any())
                    {
                        var edge = spawnEdges.GetRandom(Rand.RandSync.Server);
                        spawnPos = Vector2.Lerp(edge.Point1, edge.Point2, Rand.Range(0.1f, 0.9f, Rand.RandSync.Server));
                        Vector2 normal = Vector2.UnitY;
                        if (edge.Cell1 != null && edge.Cell1.CellType == CellType.Solid)
                        {
                            normal = edge.GetNormal(edge.Cell1);
                        }
                        else if (edge.Cell2 != null && edge.Cell2.CellType == CellType.Solid)
                        {
                            normal = edge.GetNormal(edge.Cell2);
                        }
                        spawnPos += normal * 10.0f;
                        rotation  = MathUtils.VectorToAngle(normal) - MathHelper.PiOver2;
                    }

                    var item = new Item(itemPrefab, spawnPos, null);
                    item.body.FarseerBody.BodyType = BodyType.Kinematic;
                    item.body.SetTransformIgnoreContacts(item.body.SimPosition, rotation);
                    item.FindHull();
                    items.Add(item);

                    var statusEffectElement = subElement.Element("StatusEffectOnApproach") ?? subElement.Element("statuseffectonapproach");
                    if (statusEffectElement != null)
                    {
                        statusEffectOnApproach.Add(item, StatusEffect.Load(statusEffectElement, Prefab.Identifier));
                    }
                }
            }
        }
Ejemplo n.º 3
0
 private bool IsThalamus(MapEntityPrefab entityPrefab) => IsThalamus(entityPrefab, Config.Entity);
Ejemplo n.º 4
0
        private void LoadItemAsChild(XElement element, Item parent)
        {
            ItemPrefab itemPrefab;

            if (element.Attribute("name") != null)
            {
                DebugConsole.ThrowError("Error in cargo mission \"" + Name + "\" - use item identifiers instead of names to configure the items.");
                string itemName = element.GetAttributeString("name", "");
                itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
                if (itemPrefab == null)
                {
                    DebugConsole.ThrowError("Couldn't spawn item for cargo mission: item prefab \"" + itemName + "\" not found");
                    return;
                }
            }
            else
            {
                string itemIdentifier = element.GetAttributeString("identifier", "");
                itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab;
                if (itemPrefab == null)
                {
                    DebugConsole.ThrowError("Couldn't spawn item for cargo mission: item prefab \"" + itemIdentifier + "\" not found");
                    return;
                }
            }

            if (itemPrefab == null)
            {
                DebugConsole.ThrowError("Couldn't spawn item for cargo mission: item prefab \"" + element.Name.ToString() + "\" not found");
                return;
            }

            WayPoint cargoSpawnPos = WayPoint.GetRandom(SpawnType.Cargo, null, Submarine.MainSub, useSyncedRand: true);

            if (cargoSpawnPos == null)
            {
                DebugConsole.ThrowError("Couldn't spawn items for cargo mission, cargo spawnpoint not found");
                return;
            }

            var cargoRoom = cargoSpawnPos.CurrentHull;

            if (cargoRoom == null)
            {
                DebugConsole.ThrowError("A waypoint marked as Cargo must be placed inside a room!");
                return;
            }

            Vector2 position = new Vector2(
                cargoSpawnPos.Position.X + Rand.Range(-20.0f, 20.0f, Rand.RandSync.Server),
                cargoRoom.Rect.Y - cargoRoom.Rect.Height + itemPrefab.Size.Y / 2);

            var item = new Item(itemPrefab, position, cargoRoom.Submarine);

            item.FindHull();
            items.Add(item);

            if (parent != null && parent.GetComponent <ItemContainer>() != null)
            {
                parentInventoryIDs.Add(item, parent.ID);
                parentItemContainerIndices.Add(item, (byte)parent.GetComponentIndex(parent.GetComponent <ItemContainer>()));
                parent.Combine(item, user: null);
            }

            foreach (XElement subElement in element.Elements())
            {
                int amount = subElement.GetAttributeInt("amount", 1);
                for (int i = 0; i < amount; i++)
                {
                    LoadItemAsChild(subElement, item);
                }
            }
        }
Ejemplo n.º 5
0
        public SalvageMission(MissionPrefab prefab, Location[] locations)
            : base(prefab, locations)
        {
            containerTag = prefab.ConfigElement.GetAttributeString("containertag", "");

            if (prefab.ConfigElement.Attribute("itemname") != null)
            {
                DebugConsole.ThrowError("Error in SalvageMission - use item identifier instead of the name of the item.");
                string itemName = prefab.ConfigElement.GetAttributeString("itemname", "");
                itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
                if (itemPrefab == null)
                {
                    DebugConsole.ThrowError("Error in SalvageMission: couldn't find an item prefab with the name " + itemName);
                }
            }
            else
            {
                string itemIdentifier = prefab.ConfigElement.GetAttributeString("itemidentifier", "");
                itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab;
                if (itemPrefab == null)
                {
                    DebugConsole.ThrowError("Error in SalvageMission - couldn't find an item prefab with the identifier " + itemIdentifier);
                }
            }

            existingItemTag         = prefab.ConfigElement.GetAttributeString("existingitemtag", "");
            showMessageWhenPickedUp = prefab.ConfigElement.GetAttributeBool("showmessagewhenpickedup", false);

            string spawnPositionTypeStr = prefab.ConfigElement.GetAttributeString("spawntype", "");

            if (string.IsNullOrWhiteSpace(spawnPositionTypeStr) ||
                !Enum.TryParse(spawnPositionTypeStr, true, out spawnPositionType))
            {
                spawnPositionType = Level.PositionType.Cave | Level.PositionType.Ruin;
            }

            foreach (XElement element in prefab.ConfigElement.Elements())
            {
                switch (element.Name.ToString().ToLowerInvariant())
                {
                case "statuseffect":
                {
                    var newEffect = StatusEffect.Load(element, parentDebugName: prefab.Name);
                    if (newEffect == null)
                    {
                        continue;
                    }
                    statusEffects.Add(new List <StatusEffect> {
                            newEffect
                        });
                    break;
                }

                case "chooserandom":
                    statusEffects.Add(new List <StatusEffect>());
                    foreach (XElement subElement in element.Elements())
                    {
                        var newEffect = StatusEffect.Load(subElement, parentDebugName: prefab.Name);
                        if (newEffect == null)
                        {
                            continue;
                        }
                        statusEffects.Last().Add(newEffect);
                    }
                    break;
                }
            }
        }
Ejemplo n.º 6
0
        private IEnumerable <object> Load()
        {
            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime);
            }
            GUI.GraphicsDevice = base.GraphicsDevice;
            GUI.Init(Content);

            InitUserStats();

            GUIComponent.Init(Window);
            DebugConsole.Init(Window);
            DebugConsole.Log(SelectedPackage == null ? "No content package selected" : "Content package \"" + SelectedPackage.Name + "\" selected");
            yield return(CoroutineStatus.Running);

            LightManager = new Lights.LightManager(base.GraphicsDevice, Content);

            Hull.renderer         = new WaterRenderer(base.GraphicsDevice, Content);
            TitleScreen.LoadState = 1.0f;
            yield return(CoroutineStatus.Running);

            GUI.LoadContent();
            TitleScreen.LoadState = 2.0f;
            yield return(CoroutineStatus.Running);

            MissionPrefab.Init();
            MapEntityPrefab.Init();
            LevelGenerationParams.LoadPresets();
            TitleScreen.LoadState = 10.0f;
            yield return(CoroutineStatus.Running);

            JobPrefab.LoadAll(SelectedPackage.GetFilesOfType(ContentType.Jobs));
            // Add any missing jobs from the prefab into Config.JobNamePreferences.
            foreach (JobPrefab job in JobPrefab.List)
            {
                if (!Config.JobNamePreferences.Contains(job.Name))
                {
                    Config.JobNamePreferences.Add(job.Name);
                }
            }
            StructurePrefab.LoadAll(SelectedPackage.GetFilesOfType(ContentType.Structure));
            TitleScreen.LoadState = 20.0f;
            yield return(CoroutineStatus.Running);

            ItemPrefab.LoadAll(SelectedPackage.GetFilesOfType(ContentType.Item));
            TitleScreen.LoadState = 30.0f;
            yield return(CoroutineStatus.Running);

            Debug.WriteLine("sounds");
            CoroutineManager.StartCoroutine(SoundPlayer.Init());

            int i = 0;

            while (!SoundPlayer.Initialized)
            {
                i++;
                TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ?
                                        30.0f :
                                        Math.Min(30.0f + 40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 70.0f);
                yield return(CoroutineStatus.Running);
            }

            TitleScreen.LoadState = 70.0f;
            yield return(CoroutineStatus.Running);

            GameModePreset.Init();

            Submarine.RefreshSavedSubs();
            TitleScreen.LoadState = 80.0f;
            yield return(CoroutineStatus.Running);

            GameScreen            = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content);
            TitleScreen.LoadState = 90.0f;
            yield return(CoroutineStatus.Running);

            MainMenuScreen = new MainMenuScreen(this);
            LobbyScreen    = new LobbyScreen();

            ServerListScreen = new ServerListScreen();

            SubEditorScreen       = new SubEditorScreen(Content);
            CharacterEditorScreen = new CharacterEditorScreen();
            ParticleEditorScreen  = new ParticleEditorScreen();

            yield return(CoroutineStatus.Running);

            ParticleManager = new ParticleManager(GameScreen.Cam);
            ParticleManager.LoadPrefabs();
            DecalManager = new DecalManager();
            yield return(CoroutineStatus.Running);

            LocationType.Init();
            MainMenuScreen.Select();

            TitleScreen.LoadState = 100.0f;
            hasLoaded             = true;
            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime);
            }
            yield return(CoroutineStatus.Success);
        }
Ejemplo n.º 7
0
        private void GiveTreatment(float deltaTime)
        {
            if (treatmentTimer > 0.0f)
            {
                treatmentTimer -= deltaTime;
            }
            treatmentTimer = TreatmentDelay;

            var allAfflictions = targetCharacter.CharacterHealth.GetAllAfflictions()
                                 .Where(a => a.GetVitalityDecrease(targetCharacter.CharacterHealth) > 0)
                                 .ToList();

            allAfflictions.Sort((a1, a2) =>
            {
                return(Math.Sign(a2.GetVitalityDecrease(targetCharacter.CharacterHealth) - a1.GetVitalityDecrease(targetCharacter.CharacterHealth)));
            });

            //check if we already have a suitable treatment for any of the afflictions
            foreach (Affliction affliction in allAfflictions)
            {
                foreach (KeyValuePair <string, float> treatmentSuitability in affliction.Prefab.TreatmentSuitability)
                {
                    if (treatmentSuitability.Value > 0.0f)
                    {
                        Item matchingItem = character.Inventory.FindItemByIdentifier(treatmentSuitability.Key);
                        if (matchingItem == null)
                        {
                            continue;
                        }
                        ApplyTreatment(affliction, matchingItem);
                        return;
                    }
                }
            }

            //didn't have any suitable treatments available, try to find some medical items
            HashSet <string> suitableItemIdentifiers = new HashSet <string>();

            foreach (Affliction affliction in allAfflictions)
            {
                foreach (KeyValuePair <string, float> treatmentSuitability in affliction.Prefab.TreatmentSuitability)
                {
                    if (treatmentSuitability.Value > 0.0f)
                    {
                        suitableItemIdentifiers.Add(treatmentSuitability.Key);
                    }
                }
            }
            if (suitableItemIdentifiers.Count > 0)
            {
                List <string> itemNameList = new List <string>();
                foreach (string itemIdentifier in suitableItemIdentifiers)
                {
                    if (MapEntityPrefab.Find(null, itemIdentifier, showErrorMessages: false) is ItemPrefab itemPrefab)
                    {
                        itemNameList.Add(itemPrefab.Name);
                    }
                    //only list the first 4 items
                    if (itemNameList.Count >= 4)
                    {
                        break;
                    }
                }

                if (itemNameList.Count > 0)
                {
                    string itemListStr = "";
                    if (itemNameList.Count == 1)
                    {
                        itemListStr = itemNameList[0];
                    }
                    else
                    {
                        itemListStr = string.Join(" or ", string.Join(", ", itemNameList.Take(itemNameList.Count - 1)), itemNameList.Last());
                    }
                    character?.Speak(TextManager.Get("DialogListRequiredTreatments")
                                     .Replace("[targetname]", targetCharacter.Name)
                                     .Replace("[treatmentlist]", itemListStr),
                                     null, 2.0f, "listrequiredtreatments" + targetCharacter.Name, 60.0f);
                }

                character.DeselectCharacter();
                AddSubObjective(new AIObjectiveGetItem(character, suitableItemIdentifiers.ToArray(), true));
            }

            character.AnimController.Anim = AnimController.Animation.CPR;
        }
Ejemplo n.º 8
0
        public ItemAssemblyPrefab(string filePath)
        {
            FilePath = filePath;
            XDocument doc = XMLExtensions.TryLoadXml(filePath);

            if (doc == null)
            {
                return;
            }

            XElement element = doc.Root;

            if (element.IsOverride())
            {
                element = element.Elements().First();
            }

            originalName  = element.GetAttributeString("name", "");
            identifier    = element.GetAttributeString("identifier", null) ?? originalName.ToLowerInvariant().Replace(" ", "");
            configElement = element;

            Category = MapEntityCategory.ItemAssembly;

            SerializableProperty.DeserializeProperties(this, configElement);

            name        = TextManager.Get("EntityName." + identifier, returnNull: true) ?? originalName;
            Description = TextManager.Get("EntityDescription." + identifier, returnNull: true) ?? Description;

            List <ushort> containedItemIDs = new List <ushort>();

            foreach (XElement entityElement in element.Elements())
            {
                var containerElement = entityElement.Elements().FirstOrDefault(e => e.Name.LocalName.Equals("itemcontainer", StringComparison.OrdinalIgnoreCase));
                if (containerElement == null)
                {
                    continue;
                }

                var itemIds = containerElement.GetAttributeIntArray("contained", new int[0]);
                containedItemIDs.AddRange(itemIds.Select(id => (ushort)id));
            }

            int minX = int.MaxValue, minY = int.MaxValue;
            int maxX = int.MinValue, maxY = int.MinValue;

            DisplayEntities = new List <Pair <MapEntityPrefab, Rectangle> >();
            foreach (XElement entityElement in element.Elements())
            {
                ushort id = (ushort)entityElement.GetAttributeInt("ID", 0);
                if (id > 0 && containedItemIDs.Contains(id))
                {
                    continue;
                }

                string          identifier = entityElement.GetAttributeString("identifier", entityElement.Name.ToString().ToLowerInvariant());
                MapEntityPrefab mapEntity  = List.FirstOrDefault(p => p.Identifier == identifier);
                if (mapEntity == null)
                {
                    string entityName = entityElement.GetAttributeString("name", "");
                    mapEntity = List.FirstOrDefault(p => p.Name == entityName);
                }

                Rectangle rect = entityElement.GetAttributeRect("rect", Rectangle.Empty);
                if (mapEntity != null && !entityElement.Elements().Any(e => e.Name.LocalName.Equals("wire", StringComparison.OrdinalIgnoreCase)))
                {
                    if (!entityElement.GetAttributeBool("hideinassemblypreview", false))
                    {
                        DisplayEntities.Add(new Pair <MapEntityPrefab, Rectangle>(mapEntity, rect));
                    }
                    minX = Math.Min(minX, rect.X);
                    minY = Math.Min(minY, rect.Y - rect.Height);
                    maxX = Math.Max(maxX, rect.Right);
                    maxY = Math.Max(maxY, rect.Y);
                }
            }

            Bounds = minX == int.MaxValue ?
                     new Rectangle(0, 0, 1, 1) :
                     new Rectangle(minX, minY, maxX - minX, maxY - minY);

            Prefabs.Add(this, doc.Root.IsOverride());
        }
Ejemplo n.º 9
0
        private void InitializeJobItem(Character character, WayPoint spawnPoint, XElement itemElement, Item parentItem = null)
        {
            string itemName = itemElement.GetAttributeString("name", "");

            ItemPrefab itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;

            if (itemPrefab == null)
            {
                DebugConsole.ThrowError("Tried to spawn \"" + Name + "\" with the item \"" + itemName + "\". Matching item prefab not found.");
                return;
            }

            Item item = new Item(itemPrefab, character.Position, null);

            if (GameMain.Server != null && Entity.Spawner != null)
            {
                Entity.Spawner.CreateNetworkEvent(item, false);
            }

            if (itemElement.GetAttributeBool("equip", false))
            {
                List <InvSlotType> allowedSlots = new List <InvSlotType>(item.AllowedSlots);
                allowedSlots.Remove(InvSlotType.Any);

                character.Inventory.TryPutItem(item, null, allowedSlots);
            }
            else
            {
                character.Inventory.TryPutItem(item, null, item.AllowedSlots);
            }

            if (item.Prefab.NameMatches("ID Card") && spawnPoint != null)
            {
                foreach (string s in spawnPoint.IdCardTags)
                {
                    item.AddTag(s);
                }
                item.AddTag("name:" + character.Name);
                item.AddTag("job:" + Name);
                if (!string.IsNullOrWhiteSpace(spawnPoint.IdCardDesc))
                {
                    item.Description = spawnPoint.IdCardDesc;
                }
            }

            item.AddTag("Starter_Item");

            foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>())
            {
                wifiComponent.TeamID = character.TeamID;
            }

            if (parentItem != null)
            {
                parentItem.Combine(item);
            }

            foreach (XElement childItemElement in itemElement.Elements())
            {
                InitializeJobItem(character, spawnPoint, childItemElement, item);
            }
        }
Ejemplo n.º 10
0
        static DebugConsole()
        {
            commands.Add(new Command("help", "", (string[] args) =>
            {
                if (args.Length == 0)
                {
                    foreach (Command c in commands)
                    {
                        if (string.IsNullOrEmpty(c.help))
                        {
                            continue;
                        }
                        NewMessage(c.help, Color.Cyan);
                    }
                }
                else
                {
                    var matchingCommand = commands.Find(c => c.names.Any(name => name == args[0]));
                    if (matchingCommand == null)
                    {
                        NewMessage("Command " + args[0] + " not found.", Color.Red);
                    }
                    else
                    {
                        NewMessage(matchingCommand.help, Color.Cyan);
                    }
                }
            }));

            commands.Add(new Command("clientlist", "clientlist: List all the clients connected to the server.", (string[] args) =>
            {
                if (GameMain.Server == null)
                {
                    return;
                }
                NewMessage("***************", Color.Cyan);
                foreach (Client c in GameMain.Server.ConnectedClients)
                {
                    NewMessage("- " + c.ID.ToString() + ": " + c.Name + ", " + c.Connection.RemoteEndPoint.Address.ToString(), Color.Cyan);
                }
                NewMessage("***************", Color.Cyan);
            }));


            commands.Add(new Command("createfilelist", "", (string[] args) =>
            {
                UpdaterUtil.SaveFileList("filelist.xml");
            }));

            commands.Add(new Command("spawn|spawncharacter", "spawn [creaturename] [near/inside/outside]: Spawn a creature at a random spawnpoint (use the second parameter to only select spawnpoints near/inside/outside the submarine).", (string[] args) =>
            {
                if (args.Length == 0)
                {
                    return;
                }

                Character spawnedCharacter = null;

                Vector2 spawnPosition = Vector2.Zero;
                WayPoint spawnPoint   = null;

                if (args.Length > 1)
                {
                    switch (args[1].ToLowerInvariant())
                    {
                    case "inside":
                        spawnPoint = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub);
                        break;

                    case "outside":
                        spawnPoint = WayPoint.GetRandom(SpawnType.Enemy);
                        break;

                    case "near":
                    case "close":
                        float closestDist = -1.0f;
                        foreach (WayPoint wp in WayPoint.WayPointList)
                        {
                            if (wp.Submarine != null)
                            {
                                continue;
                            }

                            //don't spawn inside hulls
                            if (Hull.FindHull(wp.WorldPosition, null) != null)
                            {
                                continue;
                            }

                            float dist = Vector2.Distance(wp.WorldPosition, GameMain.GameScreen.Cam.WorldViewCenter);

                            if (closestDist < 0.0f || dist < closestDist)
                            {
                                spawnPoint  = wp;
                                closestDist = dist;
                            }
                        }
                        break;

                    case "cursor":
                        spawnPosition = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
                        break;

                    default:
                        spawnPoint = WayPoint.GetRandom(args[0].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy);
                        break;
                    }
                }
                else
                {
                    spawnPoint = WayPoint.GetRandom(args[0].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy);
                }

                if (string.IsNullOrWhiteSpace(args[0]))
                {
                    return;
                }

                if (spawnPoint != null)
                {
                    spawnPosition = spawnPoint.WorldPosition;
                }

                if (args[0].ToLowerInvariant() == "human")
                {
                    spawnedCharacter = Character.Create(Character.HumanConfigFile, spawnPosition);

#if CLIENT
                    if (GameMain.GameSession != null)
                    {
                        SinglePlayerCampaign mode = GameMain.GameSession.GameMode as SinglePlayerCampaign;
                        if (mode != null)
                        {
                            Character.Controlled = spawnedCharacter;
                            GameMain.GameSession.CrewManager.AddCharacter(Character.Controlled);
                            GameMain.GameSession.CrewManager.SelectCharacter(null, Character.Controlled);
                        }
                    }
#endif
                }
                else
                {
                    List <string> characterFiles = GameMain.Config.SelectedContentPackage.GetFilesOfType(ContentType.Character);

                    foreach (string characterFile in characterFiles)
                    {
                        if (Path.GetFileNameWithoutExtension(characterFile).ToLowerInvariant() == args[0].ToLowerInvariant())
                        {
                            Character.Create(characterFile, spawnPosition);
                            return;
                        }
                    }

                    ThrowError("No character matching the name \"" + args[0] + "\" found in the selected content package.");

                    //attempt to open the config from the default path (the file may still be present even if it isn't included in the content package)
                    string configPath = "Content/Characters/"
                                        + args[0].First().ToString().ToUpper() + args[0].Substring(1)
                                        + "/" + args[0].ToLower() + ".xml";
                    Character.Create(configPath, spawnPosition);
                }
            }));

            commands.Add(new Command("spawnitem", "spawnitem [itemname] [cursor/inventory]: Spawn an item at the position of the cursor, in the inventory of the controlled character or at a random spawnpoint if the last parameter is omitted.", (string[] args) =>
            {
                if (args.Length < 1)
                {
                    return;
                }

                Vector2?spawnPos         = null;
                Inventory spawnInventory = null;

                int extraParams = 0;
                switch (args.Last())
                {
                case "cursor":
                    extraParams = 1;
                    spawnPos    = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
                    break;

                case "inventory":
                    extraParams    = 1;
                    spawnInventory = Character.Controlled == null ? null : Character.Controlled.Inventory;
                    break;

                default:
                    extraParams = 0;
                    break;
                }

                string itemName = string.Join(" ", args.Take(args.Length - extraParams)).ToLowerInvariant();

                var itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
                if (itemPrefab == null)
                {
                    ThrowError("Item \"" + itemName + "\" not found!");
                    return;
                }

                if (spawnPos == null && spawnInventory == null)
                {
                    var wp   = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub);
                    spawnPos = wp == null ? Vector2.Zero : wp.WorldPosition;
                }

                if (spawnPos != null)
                {
                    Entity.Spawner.AddToSpawnQueue(itemPrefab, (Vector2)spawnPos);
                }
                else if (spawnInventory != null)
                {
                    Entity.Spawner.AddToSpawnQueue(itemPrefab, spawnInventory);
                }
            }));

            commands.Add(new Command("disablecrewai", "disablecrewai: Disable the AI of the NPCs in the crew.", (string[] args) =>
            {
                HumanAIController.DisableCrewAI = true;
                NewMessage("Crew AI disabled", Color.White);
            }));

            commands.Add(new Command("enablecrewai", "enablecrewai: Enable the AI of the NPCs in the crew.", (string[] args) =>
            {
                HumanAIController.DisableCrewAI = false;
                NewMessage("Crew AI enabled", Color.White);
            }));

            commands.Add(new Command("autorestartinterval", "autorestartinterval [seconds]: Set how long the server waits between rounds before automatically starting a new one.", (string[] args) =>
            {
                if (GameMain.Server == null)
                {
                    return;
                }
                if (args.Length > 0)
                {
                    int parsedInt = 0;
                    if (int.TryParse(args[0], out parsedInt) && parsedInt >= 0)
                    {
                        GameMain.Server.AutoRestartInterval = parsedInt;
                        NewMessage("Autorestart interval set to " + GameMain.Server.AutoRestartInterval + " seconds.", Color.White);
                    }
                }
            }));


            commands.Add(new Command("autorestarttimer", "autorestarttimer [seconds]: Set the current autorestart countdown to the specified value.", (string[] args) =>
            {
                if (GameMain.Server == null)
                {
                    return;
                }
                if (args.Length > 0)
                {
                    int parsedInt = 0;
                    if (int.TryParse(args[0], out parsedInt) && parsedInt >= 0)
                    {
                        GameMain.Server.AutoRestartTimer = parsedInt;
                        GameMain.NetLobbyScreen.LastUpdateID++;
                        NewMessage("Autorestart timer set to " + GameMain.Server.AutoRestartTimer + " seconds.", Color.White);
                    }
                }
            }));

            commands.Add(new Command("kick", "kick [name]: Kick a player out of the server.", (string[] args) =>
            {
                if (GameMain.NetworkMember == null || args.Length == 0)
                {
                    return;
                }

                string playerName = string.Join(" ", args);

                ShowQuestionPrompt("Reason for kicking \"" + playerName + "\"?", (reason) =>
                {
                    GameMain.NetworkMember.KickPlayer(playerName, reason);
                });
            }));

            commands.Add(new Command("kickid", "kickid [id]: Kick the player with the specified client ID out of the server.", (string[] args) =>
            {
                if (GameMain.Server == null || args.Length == 0)
                {
                    return;
                }

                int id = 0;
                int.TryParse(args[0], out id);
                var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
                if (client == null)
                {
                    ThrowError("Client id \"" + id + "\" not found.");
                    return;
                }

                ShowQuestionPrompt("Reason for kicking \"" + client.Name + "\"?", (reason) =>
                {
                    GameMain.Server.KickPlayer(client.Name, reason);
                });
            }));

            commands.Add(new Command("ban", "ban [name]: Kick and ban the player from the server.", (string[] args) =>
            {
                if (GameMain.NetworkMember == null || args.Length == 0)
                {
                    return;
                }

                string clientName = string.Join(" ", args);
                ShowQuestionPrompt("Reason for banning \"" + clientName + "\"?", (reason) =>
                {
                    ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
                    {
                        TimeSpan?banDuration = null;
                        if (!string.IsNullOrWhiteSpace(duration))
                        {
                            TimeSpan parsedBanDuration;
                            if (!TryParseTimeSpan(duration, out parsedBanDuration))
                            {
                                ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
                                return;
                            }
                            banDuration = parsedBanDuration;
                        }

                        GameMain.NetworkMember.BanPlayer(clientName, reason, false, banDuration);
                    });
                });
            }));

            commands.Add(new Command("banid", "banid [id]: Kick and ban the player with the specified client ID from the server.", (string[] args) =>
            {
                if (GameMain.Server == null || args.Length == 0)
                {
                    return;
                }

                int id = 0;
                int.TryParse(args[0], out id);
                var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
                if (client == null)
                {
                    ThrowError("Client id \"" + id + "\" not found.");
                    return;
                }

                ShowQuestionPrompt("Reason for banning \"" + client.Name + "\"?", (reason) =>
                {
                    ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
                    {
                        TimeSpan?banDuration = null;
                        if (!string.IsNullOrWhiteSpace(duration))
                        {
                            TimeSpan parsedBanDuration;
                            if (!TryParseTimeSpan(duration, out parsedBanDuration))
                            {
                                ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
                                return;
                            }
                            banDuration = parsedBanDuration;
                        }

                        GameMain.Server.BanPlayer(client.Name, reason, false, banDuration);
                    });
                });
            }));


            commands.Add(new Command("banip", "banip [ip]: Ban the IP address from the server.", (string[] args) =>
            {
                if (GameMain.Server == null || args.Length == 0)
                {
                    return;
                }

                ShowQuestionPrompt("Reason for banning the ip \"" + commands[1] + "\"?", (reason) =>
                {
                    ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
                    {
                        TimeSpan?banDuration = null;
                        if (!string.IsNullOrWhiteSpace(duration))
                        {
                            TimeSpan parsedBanDuration;
                            if (!TryParseTimeSpan(duration, out parsedBanDuration))
                            {
                                ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
                                return;
                            }
                            banDuration = parsedBanDuration;
                        }

                        var client = GameMain.Server.ConnectedClients.Find(c => c.Connection.RemoteEndPoint.Address.ToString() == args[0]);
                        if (client == null)
                        {
                            GameMain.Server.BanList.BanPlayer("Unnamed", args[0], reason, banDuration);
                        }
                        else
                        {
                            GameMain.Server.KickClient(client, reason);
                        }
                    });
                });
            }));

            commands.Add(new Command("teleportcharacter|teleport", "teleport [character name]: Teleport the specified character to the position of the cursor. If the name parameter is omitted, the controlled character will be teleported.", (string[] args) =>
            {
                Character tpCharacter = null;

                if (args.Length == 0)
                {
                    tpCharacter = Character.Controlled;
                }
                else
                {
                    tpCharacter = FindMatchingCharacter(args, false);
                }

                if (tpCharacter == null)
                {
                    return;
                }

                var cam = GameMain.GameScreen.Cam;
                tpCharacter.AnimController.CurrentHull = null;
                tpCharacter.Submarine = null;
                tpCharacter.AnimController.SetPosition(ConvertUnits.ToSimUnits(cam.ScreenToWorld(PlayerInput.MousePosition)));
                tpCharacter.AnimController.FindHull(cam.ScreenToWorld(PlayerInput.MousePosition), true);
            }));

            commands.Add(new Command("godmode", "godmode: Toggle submarine godmode. Makes the main submarine invulnerable to damage.", (string[] args) =>
            {
                if (Submarine.MainSub == null)
                {
                    return;
                }

                Submarine.MainSub.GodMode = !Submarine.MainSub.GodMode;
                NewMessage(Submarine.MainSub.GodMode ? "Godmode on" : "Godmode off", Color.White);
            }));

            commands.Add(new Command("lockx", "lockx: Lock horizontal movement of the main submarine.", (string[] args) =>
            {
                Submarine.LockX = !Submarine.LockX;
            }));

            commands.Add(new Command("locky", "loxky: Lock vertical movement of the main submarine.", (string[] args) =>
            {
                Submarine.LockY = !Submarine.LockY;
            }));

            commands.Add(new Command("dumpids", "", (string[] args) =>
            {
                try
                {
                    int count = args.Length == 0 ? 10 : int.Parse(args[0]);
                    Entity.DumpIds(count);
                }
                catch (Exception e)
                {
                    ThrowError("Failed to dump ids", e);
                }
            }));

            commands.Add(new Command("heal", "heal [character name]: Restore the specified character to full health. If the name parameter is omitted, the controlled character will be healed.", (string[] args) =>
            {
                Character healedCharacter = null;
                if (args.Length == 0)
                {
                    healedCharacter = Character.Controlled;
                }
                else
                {
                    healedCharacter = FindMatchingCharacter(args);
                }

                if (healedCharacter != null)
                {
                    healedCharacter.AddDamage(CauseOfDeath.Damage, -healedCharacter.MaxHealth, null);
                    healedCharacter.Oxygen   = 100.0f;
                    healedCharacter.Bleeding = 0.0f;
                    healedCharacter.SetStun(0.0f, true);
                }
            }));

            commands.Add(new Command("revive", "revive [character name]: Bring the specified character back from the dead. If the name parameter is omitted, the controlled character will be revived.", (string[] args) =>
            {
                Character revivedCharacter = null;
                if (args.Length == 0)
                {
                    revivedCharacter = Character.Controlled;
                }
                else
                {
                    revivedCharacter = FindMatchingCharacter(args);
                }

                if (revivedCharacter == null)
                {
                    return;
                }

                revivedCharacter.Revive(false);
                if (GameMain.Server != null)
                {
                    foreach (Client c in GameMain.Server.ConnectedClients)
                    {
                        if (c.Character != revivedCharacter)
                        {
                            continue;
                        }

                        //clients stop controlling the character when it dies, force control back
                        GameMain.Server.SetClientCharacter(c, revivedCharacter);
                        break;
                    }
                }
            }));

            commands.Add(new Command("freeze", "", (string[] args) =>
            {
                if (Character.Controlled != null)
                {
                    Character.Controlled.AnimController.Frozen = !Character.Controlled.AnimController.Frozen;
                }
            }));

            commands.Add(new Command("freecamera|freecam", "freecam: Detach the camera from the controlled character.", (string[] args) =>
            {
                Character.Controlled = null;
                GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
            }));

            commands.Add(new Command("water|editwater", "water/editwater: Toggle water editing. Allows adding water into rooms by holding the left mouse button and removing it by holding the right mouse button.", (string[] args) =>
            {
                if (GameMain.Client == null)
                {
                    Hull.EditWater = !Hull.EditWater;
                    NewMessage(Hull.EditWater ? "Water editing on" : "Water editing off", Color.White);
                }
            }));

            commands.Add(new Command("fire|editfire", "fire/editfire: Allows putting up fires by left clicking.", (string[] args) =>
            {
                if (GameMain.Client == null)
                {
                    Hull.EditFire = !Hull.EditFire;
                    NewMessage(Hull.EditFire ? "Fire spawning on" : "Fire spawning off", Color.White);
                }
            }));

            commands.Add(new Command("explosion", "explosion [range] [force] [damage] [structuredamage]: Creates an explosion at the position of the cursor.", (string[] args) =>
            {
                Vector2 explosionPos = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
                float range          = 500, force = 10, damage = 50, structureDamage = 10;
                if (args.Length > 0)
                {
                    float.TryParse(args[0], out range);
                }
                if (args.Length > 1)
                {
                    float.TryParse(args[1], out force);
                }
                if (args.Length > 2)
                {
                    float.TryParse(args[2], out damage);
                }
                if (args.Length > 3)
                {
                    float.TryParse(args[3], out structureDamage);
                }
                new Explosion(range, force, damage, structureDamage).Explode(explosionPos);
            }));

            commands.Add(new Command("fixitems", "fixitems: Repairs all items and restores them to full condition.", (string[] args) =>
            {
                foreach (Item it in Item.ItemList)
                {
                    it.Condition = it.Prefab.Health;
                }
            }));

            commands.Add(new Command("fixhulls|fixwalls", "fixwalls/fixhulls: Fixes all walls.", (string[] args) =>
            {
                foreach (Structure w in Structure.WallList)
                {
                    for (int i = 0; i < w.SectionCount; i++)
                    {
                        w.AddDamage(i, -100000.0f);
                    }
                }
            }));

            commands.Add(new Command("power", "power [temperature]: Immediately sets the temperature of the nuclear reactor to the specified value.", (string[] args) =>
            {
                Item reactorItem = Item.ItemList.Find(i => i.GetComponent <Reactor>() != null);
                if (reactorItem == null)
                {
                    return;
                }

                float power = 5000.0f;
                if (args.Length > 0)
                {
                    float.TryParse(args[0], out power);
                }

                var reactor          = reactorItem.GetComponent <Reactor>();
                reactor.ShutDownTemp = power == 0 ? 0 : 7000.0f;
                reactor.AutoTemp     = true;
                reactor.Temperature  = power;

                if (GameMain.Server != null)
                {
                    reactorItem.CreateServerEvent(reactor);
                }
            }));

            commands.Add(new Command("oxygen|air", "oxygen/air: Replenishes the oxygen levels in every room to 100%.", (string[] args) =>
            {
                foreach (Hull hull in Hull.hullList)
                {
                    hull.OxygenPercentage = 100.0f;
                }
            }));

            commands.Add(new Command("killmonsters", "killmonsters: Immediately kills all AI-controlled enemies in the level.", (string[] args) =>
            {
                foreach (Character c in Character.CharacterList)
                {
                    if (!(c.AIController is EnemyAIController))
                    {
                        continue;
                    }
                    c.AddDamage(CauseOfDeath.Damage, 10000.0f, null);
                }
            }));

            commands.Add(new Command("netstats", "netstats: Toggles the visibility of the network statistics UI.", (string[] args) =>
            {
                if (GameMain.Server == null)
                {
                    return;
                }
                GameMain.Server.ShowNetStats = !GameMain.Server.ShowNetStats;
            }));

            commands.Add(new Command("setclientcharacter", "setclientcharacter [client name] ; [character name]: Gives the client control of the specified character.", (string[] args) =>
            {
                if (GameMain.Server == null)
                {
                    return;
                }

                int separatorIndex = Array.IndexOf(args, ";");

                if (separatorIndex == -1 || args.Length < 3)
                {
                    ThrowError("Invalid parameters. The command should be formatted as \"setclientcharacter [client] ; [character]\"");
                    return;
                }

                string[] argsLeft  = args.Take(separatorIndex).ToArray();
                string[] argsRight = args.Skip(separatorIndex + 1).ToArray();

                string clientName = String.Join(" ", argsLeft);

                var client = GameMain.Server.ConnectedClients.Find(c => c.Name == clientName);
                if (client == null)
                {
                    ThrowError("Client \"" + clientName + "\" not found.");
                }

                var character = FindMatchingCharacter(argsRight, false);
                GameMain.Server.SetClientCharacter(client, character);
            }));

            commands.Add(new Command("campaigninfo|campaignstatus", "campaigninfo: Display information about the state of the currently active campaign.", (string[] args) =>
            {
                var campaign = GameMain.GameSession?.GameMode as CampaignMode;
                if (campaign == null)
                {
                    ThrowError("No campaign active!");
                    return;
                }

                campaign.LogState();
            }));

            commands.Add(new Command("campaigndestination|setcampaigndestination", "campaigndestination [index]: Set the location to head towards in the currently active campaign.", (string[] args) =>
            {
                var campaign = GameMain.GameSession?.GameMode as CampaignMode;
                if (campaign == null)
                {
                    ThrowError("No campaign active!");
                    return;
                }

                if (args.Length == 0)
                {
                    int i = 0;
                    foreach (LocationConnection connection in campaign.Map.CurrentLocation.Connections)
                    {
                        NewMessage("     " + i + ". " + connection.OtherLocation(campaign.Map.CurrentLocation).Name, Color.White);
                        i++;
                    }
                    ShowQuestionPrompt("Select a destination (0 - " + (campaign.Map.CurrentLocation.Connections.Count - 1) + "):", (string selectedDestination) =>
                    {
                        int destinationIndex = -1;
                        if (!int.TryParse(selectedDestination, out destinationIndex))
                        {
                            return;
                        }
                        if (destinationIndex < 0 || destinationIndex >= campaign.Map.CurrentLocation.Connections.Count)
                        {
                            NewMessage("Index out of bounds!", Color.Red);
                            return;
                        }
                        Location location = campaign.Map.CurrentLocation.Connections[destinationIndex].OtherLocation(campaign.Map.CurrentLocation);
                        campaign.Map.SelectLocation(location);
                        NewMessage(location.Name + " selected.", Color.White);
                    });
                }
                else
                {
                    int destinationIndex = -1;
                    if (!int.TryParse(args[0], out destinationIndex))
                    {
                        return;
                    }
                    if (destinationIndex < 0 || destinationIndex >= campaign.Map.CurrentLocation.Connections.Count)
                    {
                        NewMessage("Index out of bounds!", Color.Red);
                        return;
                    }
                    Location location = campaign.Map.CurrentLocation.Connections[destinationIndex].OtherLocation(campaign.Map.CurrentLocation);
                    campaign.Map.SelectLocation(location);
                    NewMessage(location.Name + " selected.", Color.White);
                }
            }));

#if DEBUG
            commands.Add(new Command("spamevents", "A debug command that immediately creates entity events for all items, characters and structures.", (string[] args) =>
            {
                foreach (Item item in Item.ItemList)
                {
                    for (int i = 0; i < item.components.Count; i++)
                    {
                        if (item.components[i] is IServerSerializable)
                        {
                            GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, i });
                        }
                        var itemContainer = item.GetComponent <ItemContainer>();
                        if (itemContainer != null)
                        {
                            GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.InventoryState });
                        }

                        GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status });

                        item.NeedsPositionUpdate = true;
                    }
                }

                foreach (Character c in Character.CharacterList)
                {
                    GameMain.Server.CreateEntityEvent(c, new object[] { NetEntityEvent.Type.Status });
                }

                foreach (Structure wall in Structure.WallList)
                {
                    GameMain.Server.CreateEntityEvent(wall);
                }
            }));
#endif
            InitProjectSpecific();

            commands.Sort((c1, c2) => c1.names[0].CompareTo(c2.names[0]));
        }
Ejemplo n.º 11
0
        private void BakeMapEntity(XElement element)
        {
            string identifier = element.GetAttributeString("identifier", "");

            if (string.IsNullOrEmpty(identifier))
            {
                return;
            }
            Rectangle rect = element.GetAttributeRect("rect", Rectangle.Empty);

            if (rect.Equals(Rectangle.Empty))
            {
                return;
            }

            float depth    = element.GetAttributeFloat("spritedepth", 1f);
            bool  flippedX = element.GetAttributeBool("flippedx", false);
            bool  flippedY = element.GetAttributeBool("flippedy", false);

            float scale = element.GetAttributeFloat("scale", 1f);
            Color color = element.GetAttributeColor("spritecolor", Color.White);

            float rotation = element.GetAttributeFloat("rotation", 0f);

            MapEntityPrefab prefab = MapEntityPrefab.List.FirstOrDefault(p => p.Identifier.Equals(identifier, StringComparison.OrdinalIgnoreCase));

            if (prefab == null)
            {
                return;
            }

            var texture = prefab.sprite.Texture;
            var srcRect = prefab.sprite.SourceRect;

            SpriteEffects spriteEffects = SpriteEffects.None;

            if (flippedX)
            {
                spriteEffects |= SpriteEffects.FlipHorizontally;
            }
            if (flippedY)
            {
                spriteEffects |= SpriteEffects.FlipVertically;
            }

            var prevEffects = prefab.sprite.effects;

            prefab.sprite.effects ^= spriteEffects;

            bool            overrideSprite  = false;
            ItemPrefab      itemPrefab      = prefab as ItemPrefab;
            StructurePrefab structurePrefab = prefab as StructurePrefab;

            if (itemPrefab != null)
            {
                BakeItemComponents(itemPrefab, rect, color, scale, rotation, depth, out overrideSprite);
            }

            if (!overrideSprite)
            {
                if (structurePrefab != null)
                {
                    ParseUpgrades(structurePrefab.ConfigElement, ref scale);

                    if (!prefab.ResizeVertical)
                    {
                        rect.Height = (int)(rect.Height * scale / prefab.Scale);
                    }
                    if (!prefab.ResizeHorizontal)
                    {
                        rect.Width = (int)(rect.Width * scale / prefab.Scale);
                    }
                    var textureScale = element.GetAttributeVector2("texturescale", Vector2.One);

                    Vector2 backGroundOffset = Vector2.Zero;

                    Vector2 textureOffset = element.GetAttributeVector2("textureoffset", Vector2.Zero);
                    if (flippedX)
                    {
                        textureOffset.X = -textureOffset.X;
                    }
                    if (flippedY)
                    {
                        textureOffset.Y = -textureOffset.Y;
                    }

                    backGroundOffset = new Vector2(
                        MathUtils.PositiveModulo((int)-textureOffset.X, prefab.sprite.SourceRect.Width),
                        MathUtils.PositiveModulo((int)-textureOffset.Y, prefab.sprite.SourceRect.Height));

                    prefab.sprite.DrawTiled(
                        spriteRecorder,
                        rect.Location.ToVector2() * new Vector2(1f, -1f),
                        rect.Size.ToVector2(),
                        color: color,
                        startOffset: backGroundOffset,
                        textureScale: textureScale * scale,
                        depth: depth);
                }
                else if (itemPrefab != null)
                {
                    bool usePrefabValues = element.GetAttributeBool("isoverride", false) != itemPrefab.IsOverride;
                    if (usePrefabValues)
                    {
                        scale = itemPrefab.ConfigElement.GetAttributeFloat(scale, "scale", "Scale");
                    }

                    ParseUpgrades(itemPrefab.ConfigElement, ref scale);

                    if (prefab.ResizeVertical || prefab.ResizeHorizontal)
                    {
                        if (!prefab.ResizeHorizontal)
                        {
                            rect.Width = (int)(prefab.sprite.size.X * scale);
                        }
                        if (!prefab.ResizeVertical)
                        {
                            rect.Height = (int)(prefab.sprite.size.Y * scale);
                        }

                        var spritePos = rect.Center.ToVector2();
                        //spritePos.Y = rect.Height - spritePos.Y;

                        prefab.sprite.DrawTiled(
                            spriteRecorder,
                            rect.Location.ToVector2() * new Vector2(1f, -1f),
                            rect.Size.ToVector2(),
                            color: color,
                            textureScale: Vector2.One * scale,
                            depth: depth);

                        foreach (var decorativeSprite in itemPrefab.DecorativeSprites)
                        {
                            float   offsetState = 0f;
                            Vector2 offset      = decorativeSprite.GetOffset(ref offsetState, Vector2.Zero) * scale;
                            if (flippedX && itemPrefab.CanSpriteFlipX)
                            {
                                offset.X = -offset.X;
                            }
                            if (flippedY && itemPrefab.CanSpriteFlipY)
                            {
                                offset.Y = -offset.Y;
                            }
                            decorativeSprite.Sprite.DrawTiled(spriteRecorder,
                                                              new Vector2(spritePos.X + offset.X - rect.Width / 2, -(spritePos.Y + offset.Y + rect.Height / 2)),
                                                              rect.Size.ToVector2(), color: color,
                                                              textureScale: Vector2.One * scale,
                                                              depth: Math.Min(depth + (decorativeSprite.Sprite.Depth - prefab.sprite.Depth), 0.999f));
                        }
                    }
                    else
                    {
                        rect.Width  = (int)(rect.Width * scale / prefab.Scale);
                        rect.Height = (int)(rect.Height * scale / prefab.Scale);

                        var spritePos = rect.Center.ToVector2();
                        spritePos.Y -= rect.Height;
                        //spritePos.Y = rect.Height - spritePos.Y;

                        prefab.sprite.Draw(
                            spriteRecorder,
                            spritePos * new Vector2(1f, -1f),
                            color,
                            prefab.sprite.Origin,
                            rotation,
                            scale,
                            prefab.sprite.effects, depth);

                        foreach (var decorativeSprite in itemPrefab.DecorativeSprites)
                        {
                            float   rotationState = 0f; float offsetState = 0f;
                            float   rot    = decorativeSprite.GetRotation(ref rotationState, 0f);
                            Vector2 offset = decorativeSprite.GetOffset(ref offsetState, Vector2.Zero) * scale;
                            if (flippedX && itemPrefab.CanSpriteFlipX)
                            {
                                offset.X = -offset.X;
                            }
                            if (flippedY && itemPrefab.CanSpriteFlipY)
                            {
                                offset.Y = -offset.Y;
                            }
                            decorativeSprite.Sprite.Draw(spriteRecorder, new Vector2(spritePos.X + offset.X, -(spritePos.Y + offset.Y)), color,
                                                         MathHelper.ToRadians(rotation) + rot, decorativeSprite.GetScale(0f) * scale, prefab.sprite.effects,
                                                         depth: Math.Min(depth + (decorativeSprite.Sprite.Depth - prefab.sprite.Depth), 0.999f));
                        }
                    }
                }
            }

            prefab.sprite.effects = prevEffects;
        }
Ejemplo n.º 12
0
        private IEnumerable <object> Load(bool isSeparateThread)
        {
            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime);
            }

            while (TitleScreen.WaitForLanguageSelection)
            {
                yield return(CoroutineStatus.Running);
            }

            SoundManager = new Sounds.SoundManager();
            SoundManager.SetCategoryGainMultiplier("default", Config.SoundVolume, 0);
            SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume, 0);
            SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume, 0);
            SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume, 0);
            SoundManager.SetCategoryGainMultiplier("voip", Math.Min(Config.VoiceChatVolume, 1.0f), 0);

            if (Config.EnableSplashScreen && !ConsoleArguments.Contains("-skipintro"))
            {
                var   pendingSplashScreens = TitleScreen.PendingSplashScreens;
                float baseVolume           = MathHelper.Clamp(Config.SoundVolume * 2.0f, 0.0f, 1.0f);
                pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_UTG.webm", baseVolume * 0.5f));
                pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_FF.webm", baseVolume));
                pendingSplashScreens?.Enqueue(new LoadingScreen.PendingSplashScreen("Content/SplashScreens/Splash_Daedalic.webm", baseVolume * 0.1f));
            }

            //if not loading in a separate thread, wait for the splash screens to finish before continuing the loading
            //otherwise the videos will look extremely choppy
            if (!isSeparateThread)
            {
                while (TitleScreen.PlayingSplashScreen || TitleScreen.PendingSplashScreens.Count > 0)
                {
                    yield return(CoroutineStatus.Running);
                }
            }

            GUI.Init(Window, Config.AllEnabledPackages, GraphicsDevice);
            DebugConsole.Init();

            if (Config.AutoUpdateWorkshopItems)
            {
                Config.WaitingForAutoUpdate = true;
                TaskPool.Add("AutoUpdateWorkshopItemsAsync",
                             SteamManager.AutoUpdateWorkshopItemsAsync(), (task) =>
                {
                    bool result = ((Task <bool>)task).Result;

                    Config.WaitingForAutoUpdate = false;
                });

                while (Config.WaitingForAutoUpdate)
                {
                    yield return(CoroutineStatus.Running);
                }
            }


            if (Config.AllEnabledPackages.None())
            {
                DebugConsole.Log("No content packages selected");
            }
            else
            {
                DebugConsole.Log("Selected content packages: " + string.Join(", ", Config.AllEnabledPackages.Select(cp => cp.Name)));
            }

#if DEBUG
            GameSettings.ShowUserStatisticsPrompt = false;
            GameSettings.SendUserStatistics       = false;
#endif

            InitUserStats();

            yield return(CoroutineStatus.Running);

            Debug.WriteLine("sounds");

            int i = 0;
            foreach (object crObj in SoundPlayer.Init())
            {
                CoroutineStatus status = (CoroutineStatus)crObj;
                if (status == CoroutineStatus.Success)
                {
                    break;
                }

                i++;
                TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ?
                                        1.0f :
                                        Math.Min(40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 40.0f);

                yield return(CoroutineStatus.Running);
            }

            TitleScreen.LoadState = 40.0f;
            yield return(CoroutineStatus.Running);

            LightManager = new Lights.LightManager(base.GraphicsDevice, Content);

            TitleScreen.LoadState = 41.0f;
            yield return(CoroutineStatus.Running);

            GUI.LoadContent();
            TitleScreen.LoadState = 42.0f;

            yield return(CoroutineStatus.Running);

            TaskPool.Add("InitRelayNetworkAccess", SteamManager.InitRelayNetworkAccess(), (t) => { });

            FactionPrefab.LoadFactions();
            NPCSet.LoadSets();
            CharacterPrefab.LoadAll();
            MissionPrefab.Init();
            TraitorMissionPrefab.Init();
            MapEntityPrefab.Init();
            Tutorials.Tutorial.Init();
            MapGenerationParams.Init();
            LevelGenerationParams.LoadPresets();
            CaveGenerationParams.LoadPresets();
            OutpostGenerationParams.LoadPresets();
            WreckAIConfig.LoadAll();
            EventSet.LoadPrefabs();
            ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item));
            AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions));
            SkillSettings.Load(GetFilesOfType(ContentType.SkillSettings));
            Order.Init();
            EventManagerSettings.Init();
            BallastFloraPrefab.LoadAll(GetFilesOfType(ContentType.MapCreature));
            TitleScreen.LoadState = 50.0f;
            yield return(CoroutineStatus.Running);

            StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure));
            TitleScreen.LoadState = 55.0f;
            yield return(CoroutineStatus.Running);

            UpgradePrefab.LoadAll(GetFilesOfType(ContentType.UpgradeModules));
            TitleScreen.LoadState = 56.0f;
            yield return(CoroutineStatus.Running);

            JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs));
            CorpsePrefab.LoadAll(GetFilesOfType(ContentType.Corpses));

            NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations));

            ItemAssemblyPrefab.LoadAll();
            TitleScreen.LoadState = 60.0f;
            yield return(CoroutineStatus.Running);

            GameModePreset.Init();

            SaveUtil.DeleteDownloadedSubs();
            SubmarineInfo.RefreshSavedSubs();

            TitleScreen.LoadState = 65.0f;
            yield return(CoroutineStatus.Running);

            GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content);

            TitleScreen.LoadState = 68.0f;
            yield return(CoroutineStatus.Running);

            MainMenuScreen   = new MainMenuScreen(this);
            ServerListScreen = new ServerListScreen();

            TitleScreen.LoadState = 70.0f;
            yield return(CoroutineStatus.Running);

#if USE_STEAM
            SteamWorkshopScreen = new SteamWorkshopScreen();
            if (SteamManager.IsInitialized)
            {
                Steamworks.SteamFriends.OnGameRichPresenceJoinRequested += OnInvitedToGame;
                Steamworks.SteamFriends.OnGameLobbyJoinRequested        += OnLobbyJoinRequested;
            }
#endif

            SubEditorScreen = new SubEditorScreen();

            TitleScreen.LoadState = 75.0f;
            yield return(CoroutineStatus.Running);

            ParticleEditorScreen = new ParticleEditorScreen();

            TitleScreen.LoadState = 80.0f;
            yield return(CoroutineStatus.Running);

            LevelEditorScreen     = new LevelEditorScreen();
            SpriteEditorScreen    = new SpriteEditorScreen();
            EventEditorScreen     = new EventEditorScreen();
            CharacterEditorScreen = new CharacterEditor.CharacterEditorScreen();
            CampaignEndScreen     = new CampaignEndScreen();

            yield return(CoroutineStatus.Running);

            TitleScreen.LoadState = 85.0f;
            ParticleManager       = new ParticleManager(GameScreen.Cam);
            ParticleManager.LoadPrefabs();
            TitleScreen.LoadState = 88.0f;
            LevelObjectPrefab.LoadAll();

            TitleScreen.LoadState = 90.0f;
            yield return(CoroutineStatus.Running);

            DecalManager = new DecalManager();
            LocationType.Init();
            MainMenuScreen.Select();

            foreach (string steamError in SteamManager.InitializationErrors)
            {
                new GUIMessageBox(TextManager.Get("Error"), TextManager.Get(steamError));
            }

            TitleScreen.LoadState = 100.0f;
            hasLoaded             = true;
            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime);
            }
            yield return(CoroutineStatus.Success);
        }
Ejemplo n.º 13
0
        public void CancelItemSwap(Item itemToRemove, bool force = false)
        {
            if (!CanUpgradeSub())
            {
                DebugConsole.ThrowError("Cannot swap items when switching to another submarine.");
                return;
            }

            if (itemToRemove?.PendingItemSwap == null && string.IsNullOrEmpty(itemToRemove?.Prefab.SwappableItem?.ReplacementOnUninstall))
            {
                DebugConsole.ThrowError($"Cannot uninstall item \"{itemToRemove?.Name}\" (no replacement item configured).");
                return;
            }

            SwappableItem?swappableItem = itemToRemove.Prefab.SwappableItem;

            if (swappableItem == null)
            {
                DebugConsole.ThrowError($"Failed to uninstall item \"{itemToRemove.Name}\" (not configured as a swappable item).");
                return;
            }

            if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)
            {
                // only make the NPC speak if more than 5 minutes have passed since the last purchased service
                if (lastUpgradeSpeak == DateTime.MinValue || lastUpgradeSpeak.AddMinutes(5) < DateTime.Now)
                {
                    UpgradeNPCSpeak(TextManager.Get("Dialog.UpgradePurchased"), Campaign.IsSinglePlayer);
                    lastUpgradeSpeak = DateTime.Now;
                }
            }

            var linkedItems = GetLinkedItemsToSwap(itemToRemove);

            foreach (Item itemToCancel in linkedItems)
            {
                if (itemToCancel.PendingItemSwap == null)
                {
                    var replacement = MapEntityPrefab.Find("", swappableItem.ReplacementOnUninstall) as ItemPrefab;
                    if (replacement == null)
                    {
                        DebugConsole.ThrowError($"Failed to uninstall item \"{itemToCancel.Name}\". Could not find the replacement item \"{swappableItem.ReplacementOnUninstall}\".");
                        return;
                    }
                    PurchasedItemSwaps.RemoveAll(p => p.ItemToRemove == itemToCancel);
                    PurchasedItemSwaps.Add(new PurchasedItemSwap(itemToCancel, replacement));
                    DebugLog($"Uninstalled item item \"{itemToCancel.Name}\".", Color.Orange);
                    itemToCancel.PendingItemSwap = replacement;
                }
                else
                {
                    PurchasedItemSwaps.RemoveAll(p => p.ItemToRemove == itemToCancel);
                    DebugLog($"Cancelled swapping the item \"{itemToCancel.Name}\" with \"{itemToCancel.PendingItemSwap.Name}\".", Color.Orange);
                    itemToCancel.PendingItemSwap = null;
                }
            }

#if CLIENT
            OnUpgradesChanged?.Invoke();
#endif
        }
Ejemplo n.º 14
0
 public Gap(MapEntityPrefab prefab, Rectangle rectangle)
     : this(rectangle, Submarine.MainSub)
 {
 }
Ejemplo n.º 15
0
        private IEnumerable <object> Load()
        {
            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime);
            }

            SoundManager = new Sounds.SoundManager();
            SoundManager.SetCategoryGainMultiplier("default", Config.SoundVolume);
            SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume);
            SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume);
            SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume);
            SoundManager.SetCategoryGainMultiplier("voip", Config.VoiceChatVolume);
            if (Config.EnableSplashScreen)
            {
                (TitleScreen as LoadingScreen).SplashScreen = new Video(base.GraphicsDevice, SoundManager, "Content/splashscreen.mp4", 1280, 720);
            }

            GUI.Init(Window, Config.SelectedContentPackages, GraphicsDevice);
            DebugConsole.Init();

            SteamManager.Initialize();
            if (Config.AutoUpdateWorkshopItems)
            {
                if (SteamManager.AutoUpdateWorkshopItems())
                {
                    ContentPackage.LoadAll(ContentPackage.Folder);
                    Config.ReloadContentPackages();
                }
            }

            if (SelectedPackages.Count == 0)
            {
                DebugConsole.Log("No content packages selected");
            }
            else
            {
                DebugConsole.Log("Selected content packages: " + string.Join(", ", SelectedPackages.Select(cp => cp.Name)));
            }

#if DEBUG
            GameSettings.ShowUserStatisticsPrompt = false;
            GameSettings.SendUserStatistics       = false;
#endif

            InitUserStats();

            yield return(CoroutineStatus.Running);


            LightManager = new Lights.LightManager(base.GraphicsDevice, Content);

            WaterRenderer.Instance = new WaterRenderer(base.GraphicsDevice, Content);
            TitleScreen.LoadState  = 1.0f;
            yield return(CoroutineStatus.Running);

            GUI.LoadContent();
            TitleScreen.LoadState = 2.0f;

            yield return(CoroutineStatus.Running);

            MissionPrefab.Init();
            MapEntityPrefab.Init();
            Tutorials.Tutorial.Init();
            MapGenerationParams.Init();
            LevelGenerationParams.LoadPresets();
            ScriptedEventSet.LoadPrefabs();
            AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions));
            TitleScreen.LoadState = 10.0f;
            yield return(CoroutineStatus.Running);

            StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure));
            TitleScreen.LoadState = 15.0f;
            yield return(CoroutineStatus.Running);

            ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item));
            TitleScreen.LoadState = 25.0f;
            yield return(CoroutineStatus.Running);

            JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs));
            // Add any missing jobs from the prefab into Config.JobNamePreferences.
            foreach (JobPrefab job in JobPrefab.List)
            {
                if (!Config.JobPreferences.Contains(job.Identifier))
                {
                    Config.JobPreferences.Add(job.Identifier);
                }
            }

            NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations));

            ItemAssemblyPrefab.LoadAll();
            TitleScreen.LoadState = 30.0f;
            yield return(CoroutineStatus.Running);

            Debug.WriteLine("sounds");

            int i = 0;
            foreach (object crObj in SoundPlayer.Init())
            {
                CoroutineStatus status = (CoroutineStatus)crObj;
                if (status == CoroutineStatus.Success)
                {
                    break;
                }

                i++;
                TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ?
                                        30.0f :
                                        Math.Min(30.0f + 40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 70.0f);

                yield return(CoroutineStatus.Running);
            }

            TitleScreen.LoadState = 70.0f;
            yield return(CoroutineStatus.Running);

            GameModePreset.Init();

            Submarine.RefreshSavedSubs();

            TitleScreen.LoadState = 80.0f;

            yield return(CoroutineStatus.Running);

            GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content);

            TitleScreen.LoadState = 90.0f;

            yield return(CoroutineStatus.Running);

            MainMenuScreen   = new MainMenuScreen(this);
            LobbyScreen      = new LobbyScreen();
            ServerListScreen = new ServerListScreen();

            if (SteamManager.USE_STEAM)
            {
                SteamWorkshopScreen = new SteamWorkshopScreen();
            }

            SubEditorScreen       = new SubEditorScreen();
            ParticleEditorScreen  = new ParticleEditorScreen();
            LevelEditorScreen     = new LevelEditorScreen();
            SpriteEditorScreen    = new SpriteEditorScreen();
            CharacterEditorScreen = new CharacterEditorScreen();

            yield return(CoroutineStatus.Running);

            TitleScreen.LoadState = 95.0f;
            ParticleManager       = new ParticleManager(GameScreen.Cam);
            ParticleManager.LoadPrefabs();
            TitleScreen.LoadState = 97.0f;
            LevelObjectPrefab.LoadAll();
            DecalManager          = new DecalManager();
            TitleScreen.LoadState = 99.0f;
            yield return(CoroutineStatus.Running);

            LocationType.Init();
            MainMenuScreen.Select();

            CheckContentPackage();

            TitleScreen.LoadState = 100.0f;
            hasLoaded             = true;
            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime);
            }
            yield return(CoroutineStatus.Success);
        }
Ejemplo n.º 16
0
        private void InitializeJobItem(Character character, XElement itemElement, WayPoint spawnPoint = null, Item parentItem = null)
        {
            ItemPrefab itemPrefab;

            if (itemElement.Attribute("name") != null)
            {
                string itemName = itemElement.Attribute("name").Value;
                DebugConsole.ThrowError("Error in Job config (" + Name + ") - use item identifiers instead of names to configure the items.");
                itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
                if (itemPrefab == null)
                {
                    DebugConsole.ThrowError("Tried to spawn \"" + Name + "\" with the item \"" + itemName + "\". Matching item prefab not found.");
                    return;
                }
            }
            else
            {
                string itemIdentifier = itemElement.GetAttributeString("identifier", "");
                itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab;
                if (itemPrefab == null)
                {
                    DebugConsole.ThrowError("Tried to spawn \"" + Name + "\" with the item \"" + itemIdentifier + "\". Matching item prefab not found.");
                    return;
                }
            }

            Item item = new Item(itemPrefab, character.Position, null);

#if SERVER
            if (GameMain.Server != null && Entity.Spawner != null)
            {
                if (GameMain.Server.EntityEventManager.UniqueEvents.Any(ev => ev.Entity == item))
                {
                    string errorMsg = $"Error while spawning job items. Item {item.Name} created network events before the spawn event had been created.";
                    DebugConsole.ThrowError(errorMsg);
                    GameAnalyticsManager.AddErrorEventOnce("Job.InitializeJobItem:EventsBeforeSpawning", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
                    GameMain.Server.EntityEventManager.UniqueEvents.RemoveAll(ev => ev.Entity == item);
                    GameMain.Server.EntityEventManager.Events.RemoveAll(ev => ev.Entity == item);
                }

                Entity.Spawner.CreateNetworkEvent(item, false);
            }
#endif

            if (itemElement.GetAttributeBool("equip", false))
            {
                List <InvSlotType> allowedSlots = new List <InvSlotType>(item.AllowedSlots);
                allowedSlots.Remove(InvSlotType.Any);

                character.Inventory.TryPutItem(item, null, allowedSlots);
            }
            else
            {
                character.Inventory.TryPutItem(item, null, item.AllowedSlots);
            }

            Wearable wearable = ((List <ItemComponent>)item.Components)?.Find(c => c is Wearable) as Wearable;
            if (wearable != null)
            {
                if (Variant > 0 && Variant <= wearable.Variants)
                {
                    wearable.Variant = Variant;
                }
                else
                {
                    wearable.Variant = wearable.Variant; //force server event
                    if (wearable.Variants > 0 && Variant == 0)
                    {
                        //set variant to the same as the wearable to get the rest of the character's gear
                        //to use the same variant (if possible)
                        Variant = wearable.Variant;
                    }
                }
            }

            if (item.Prefab.Identifier == "idcard" && spawnPoint != null)
            {
                foreach (string s in spawnPoint.IdCardTags)
                {
                    item.AddTag(s);
                }
                item.AddTag("name:" + character.Name);
                item.AddTag("job:" + Name);
                if (!string.IsNullOrWhiteSpace(spawnPoint.IdCardDesc))
                {
                    item.Description = spawnPoint.IdCardDesc;
                }
            }

            foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>())
            {
                wifiComponent.TeamID = character.TeamID;
            }

            if (parentItem != null)
            {
                parentItem.Combine(item, user: null);
            }

            foreach (XElement childItemElement in itemElement.Elements())
            {
                InitializeJobItem(character, childItemElement, spawnPoint, item);
            }
        }
        public FabricationRecipe(XElement element, ItemPrefab itemPrefab)
        {
            TargetItem = itemPrefab;
            string displayName = element.GetAttributeString("displayname", "");

            DisplayName = string.IsNullOrEmpty(displayName) ? itemPrefab.Name : TextManager.Get($"DisplayName.{displayName}");

            SuitableFabricatorIdentifiers = element.GetAttributeStringArray("suitablefabricators", new string[0]);

            RequiredSkills = new List <Skill>();
            RequiredTime   = element.GetAttributeFloat("requiredtime", 1.0f);
            OutCondition   = element.GetAttributeFloat("outcondition", 1.0f);
            RequiredItems  = new List <RequiredItem>();
            Amount         = element.GetAttributeInt("amount", 1);

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "requiredskill":
                    if (subElement.Attribute("name") != null)
                    {
                        DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! Use skill identifiers instead of names.");
                        continue;
                    }

                    RequiredSkills.Add(new Skill(
                                           subElement.GetAttributeString("identifier", ""),
                                           subElement.GetAttributeInt("level", 0)));
                    break;

                case "item":
                case "requireditem":
                    string requiredItemIdentifier = subElement.GetAttributeString("identifier", "");
                    string requiredItemTag        = subElement.GetAttributeString("tag", "");
                    if (string.IsNullOrWhiteSpace(requiredItemIdentifier) && string.IsNullOrEmpty(requiredItemTag))
                    {
                        DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! One of the required items has no identifier or tag.");
                        continue;
                    }

                    float minCondition = subElement.GetAttributeFloat("mincondition", 1.0f);
                    //Substract mincondition from required item's condition or delete it regardless?
                    bool useCondition = subElement.GetAttributeBool("usecondition", true);
                    int  count        = subElement.GetAttributeInt("count", 1);

                    if (!string.IsNullOrEmpty(requiredItemIdentifier))
                    {
                        if (!(MapEntityPrefab.Find(null, requiredItemIdentifier.Trim()) is ItemPrefab requiredItem))
                        {
                            DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! Required item \"" + requiredItemIdentifier + "\" not found.");
                            continue;
                        }

                        var existing = RequiredItems.Find(r => r.ItemPrefabs.Count == 1 && r.ItemPrefabs[0] == requiredItem && MathUtils.NearlyEqual(r.MinCondition, minCondition));
                        if (existing == null)
                        {
                            RequiredItems.Add(new RequiredItem(requiredItem, count, minCondition, useCondition));
                        }
                        else
                        {
                            existing.Amount += count;
                        }
                    }
                    else
                    {
                        var matchingItems = ItemPrefab.Prefabs.Where(ip => ip.Tags.Any(t => t.Equals(requiredItemTag, StringComparison.OrdinalIgnoreCase)));
                        if (!matchingItems.Any())
                        {
                            DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! Could not find any items with the tag \"" + requiredItemTag + "\".");
                            continue;
                        }

                        var existing = RequiredItems.Find(r => r.ItemPrefabs.SequenceEqual(matchingItems) && MathUtils.NearlyEqual(r.MinCondition, minCondition));
                        if (existing == null)
                        {
                            RequiredItems.Add(new RequiredItem(matchingItems, count, minCondition, useCondition));
                        }
                        else
                        {
                            existing.Amount += count;
                        }
                    }
                    break;
                }
            }
        }
Ejemplo n.º 18
0
        private IEnumerable <object> Load(bool isSeparateThread)
        {
            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime);
            }

            while (TitleScreen.WaitForLanguageSelection)
            {
                yield return(CoroutineStatus.Running);
            }

            SoundManager = new Sounds.SoundManager();
            SoundManager.SetCategoryGainMultiplier("default", Config.SoundVolume, 0);
            SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume, 0);
            SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume, 0);
            SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume, 0);
            SoundManager.SetCategoryGainMultiplier("voip", Config.VoiceChatVolume * 20.0f, 0);

            if (ConsoleArguments.Contains("-skipintro"))
            {
                Config.EnableSplashScreen = false;
            }

            if (Config.EnableSplashScreen)
            {
                var   pendingSplashScreens = TitleScreen.PendingSplashScreens;
                float baseVolume           = MathHelper.Clamp(Config.SoundVolume * 2.0f, 0.0f, 1.0f);
                pendingSplashScreens?.Enqueue(new Triplet <string, Point, float>("Content/Splash_UTG.mp4", new Point(1280, 720), baseVolume * 0.5f));
                pendingSplashScreens?.Enqueue(new Triplet <string, Point, float>("Content/Splash_FF.mp4", new Point(1280, 720), baseVolume));
                pendingSplashScreens?.Enqueue(new Triplet <string, Point, float>("Content/Splash_Daedalic.mp4", new Point(1920, 1080), baseVolume * 0.15f));
            }

            //if not loading in a separate thread, wait for the splash screens to finish before continuing the loading
            //otherwise the videos will look extremely choppy
            if (!isSeparateThread)
            {
                while (TitleScreen.PlayingSplashScreen || TitleScreen.PendingSplashScreens.Count > 0)
                {
                    yield return(CoroutineStatus.Running);
                }
            }

            GUI.Init(Window, Config.SelectedContentPackages, GraphicsDevice);
            DebugConsole.Init();

            CrossThread.RequestExecutionOnMainThread(() =>
            {
                if (Config.AutoUpdateWorkshopItems)
                {
                    if (SteamManager.AutoUpdateWorkshopItems())
                    {
                        ContentPackage.LoadAll();
                        Config.ReloadContentPackages();
                    }
                }
            });


            if (SelectedPackages.None())
            {
                DebugConsole.Log("No content packages selected");
            }
            else
            {
                DebugConsole.Log("Selected content packages: " + string.Join(", ", SelectedPackages.Select(cp => cp.Name)));
            }

#if DEBUG
            GameSettings.ShowUserStatisticsPrompt = false;
            GameSettings.SendUserStatistics       = false;
#endif

            InitUserStats();

            yield return(CoroutineStatus.Running);

            Debug.WriteLine("sounds");

            int i = 0;
            foreach (object crObj in SoundPlayer.Init())
            {
                CoroutineStatus status = (CoroutineStatus)crObj;
                if (status == CoroutineStatus.Success)
                {
                    break;
                }

                i++;
                TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ?
                                        1.0f :
                                        Math.Min(40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 40.0f);

                yield return(CoroutineStatus.Running);
            }

            TitleScreen.LoadState = 40.0f;
            yield return(CoroutineStatus.Running);

            LightManager = new Lights.LightManager(base.GraphicsDevice, Content);

            TitleScreen.LoadState = 41.0f;
            yield return(CoroutineStatus.Running);

            GUI.LoadContent();
            TitleScreen.LoadState = 42.0f;

            yield return(CoroutineStatus.Running);

            Character.LoadAllConfigFiles();
            MissionPrefab.Init();
            TraitorMissionPrefab.Init();
            MapEntityPrefab.Init();
            Tutorials.Tutorial.Init();
            MapGenerationParams.Init();
            LevelGenerationParams.LoadPresets();
            ScriptedEventSet.LoadPrefabs();
            AfflictionPrefab.LoadAll(GetFilesOfType(ContentType.Afflictions));
            TitleScreen.LoadState = 50.0f;
            yield return(CoroutineStatus.Running);

            StructurePrefab.LoadAll(GetFilesOfType(ContentType.Structure));
            TitleScreen.LoadState = 53.0f;
            yield return(CoroutineStatus.Running);

            ItemPrefab.LoadAll(GetFilesOfType(ContentType.Item));
            TitleScreen.LoadState = 55.0f;
            yield return(CoroutineStatus.Running);

            JobPrefab.LoadAll(GetFilesOfType(ContentType.Jobs));

            NPCConversation.LoadAll(GetFilesOfType(ContentType.NPCConversations));

            ItemAssemblyPrefab.LoadAll();
            TitleScreen.LoadState = 60.0f;
            yield return(CoroutineStatus.Running);

            GameModePreset.Init();

            Submarine.RefreshSavedSubs();

            TitleScreen.LoadState = 65.0f;
            yield return(CoroutineStatus.Running);

            GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content);

            TitleScreen.LoadState = 68.0f;
            yield return(CoroutineStatus.Running);

            MainMenuScreen   = new MainMenuScreen(this);
            LobbyScreen      = new LobbyScreen();
            ServerListScreen = new ServerListScreen();

            TitleScreen.LoadState = 70.0f;
            yield return(CoroutineStatus.Running);

            if (SteamManager.USE_STEAM)
            {
                SteamWorkshopScreen = new SteamWorkshopScreen();
                if (SteamManager.IsInitialized)
                {
                    SteamManager.Instance.Friends.OnInvitedToGame    += OnInvitedToGame;
                    SteamManager.Instance.Lobby.OnLobbyJoinRequested += OnLobbyJoinRequested;
                }
            }
            SubEditorScreen = new SubEditorScreen();

            TitleScreen.LoadState = 75.0f;
            yield return(CoroutineStatus.Running);

            ParticleEditorScreen = new ParticleEditorScreen();

            TitleScreen.LoadState = 80.0f;
            yield return(CoroutineStatus.Running);

            LevelEditorScreen     = new LevelEditorScreen();
            SpriteEditorScreen    = new SpriteEditorScreen();
            CharacterEditorScreen = new CharacterEditor.CharacterEditorScreen();

            yield return(CoroutineStatus.Running);

            TitleScreen.LoadState = 85.0f;
            ParticleManager       = new ParticleManager(GameScreen.Cam);
            ParticleManager.LoadPrefabs();
            TitleScreen.LoadState = 88.0f;
            LevelObjectPrefab.LoadAll();

            TitleScreen.LoadState = 90.0f;
            yield return(CoroutineStatus.Running);

            DecalManager = new DecalManager();
            LocationType.Init();
            MainMenuScreen.Select();

            CheckContentPackage();

            foreach (string steamError in SteamManager.InitializationErrors)
            {
                new GUIMessageBox(TextManager.Get("Error"), TextManager.Get(steamError));
            }

            TitleScreen.LoadState = 100.0f;
            hasLoaded             = true;
            if (GameSettings.VerboseLogging)
            {
                DebugConsole.NewMessage("LOADING COROUTINE FINISHED", Color.Lime);
            }
            yield return(CoroutineStatus.Success);
        }
Ejemplo n.º 19
0
        private void GiveTreatment(float deltaTime)
        {
            if (targetCharacter == null)
            {
                string errorMsg = $"{character.Name}: Attempted to update a Rescue objective with no target!";
                DebugConsole.ThrowError(errorMsg);
                Abandon = true;
                return;
            }

            SteeringManager?.Reset();

            if (!targetCharacter.IsPlayer)
            {
                // If the target is a bot, don't let it move
                targetCharacter.AIController?.SteeringManager?.Reset();
            }
            if (treatmentTimer > 0.0f)
            {
                treatmentTimer -= deltaTime;
                return;
            }
            treatmentTimer = TreatmentDelay;

            //find which treatments are the most suitable to treat the character's current condition
            targetCharacter.CharacterHealth.GetSuitableTreatments(currentTreatmentSuitabilities, normalize: false);

            //check if we already have a suitable treatment for any of the afflictions
            foreach (Affliction affliction in GetSortedAfflictions(targetCharacter))
            {
                if (affliction == null)
                {
                    throw new Exception("Affliction was null");
                }
                if (affliction.Prefab == null)
                {
                    throw new Exception("Affliction prefab was null");
                }
                foreach (KeyValuePair <string, float> treatmentSuitability in affliction.Prefab.TreatmentSuitability)
                {
                    if (currentTreatmentSuitabilities.ContainsKey(treatmentSuitability.Key) && currentTreatmentSuitabilities[treatmentSuitability.Key] > 0.0f)
                    {
                        Item matchingItem = character.Inventory.FindItemByIdentifier(treatmentSuitability.Key, true);
                        if (matchingItem == null)
                        {
                            continue;
                        }
                        ApplyTreatment(affliction, matchingItem);
                        //wait a bit longer after applying a treatment to wait for potential side-effects to manifest
                        treatmentTimer = TreatmentDelay * 4;
                        return;
                    }
                }
            }
            // Find treatments outside of own inventory only if inside the own sub.
            if (character.Submarine != null && character.Submarine.TeamID == character.TeamID)
            {
                float cprSuitability = targetCharacter.Oxygen < 0.0f ? -targetCharacter.Oxygen * 100.0f : 0.0f;
                //didn't have any suitable treatments available, try to find some medical items
                if (currentTreatmentSuitabilities.Any(s => s.Value > cprSuitability))
                {
                    itemNameList.Clear();
                    suitableItemIdentifiers.Clear();
                    foreach (KeyValuePair <string, float> treatmentSuitability in currentTreatmentSuitabilities)
                    {
                        if (treatmentSuitability.Value <= cprSuitability)
                        {
                            continue;
                        }
                        if (MapEntityPrefab.Find(null, treatmentSuitability.Key, showErrorMessages: false) is ItemPrefab itemPrefab)
                        {
                            if (!Item.ItemList.Any(it => it.prefab.Identifier == treatmentSuitability.Key))
                            {
                                continue;
                            }
                            suitableItemIdentifiers.Add(treatmentSuitability.Key);
                            //only list the first 4 items
                            if (itemNameList.Count < 4)
                            {
                                itemNameList.Add(itemPrefab.Name);
                            }
                        }
                    }
                    if (itemNameList.Count > 0)
                    {
                        string itemListStr = "";
                        if (itemNameList.Count == 1)
                        {
                            itemListStr = itemNameList[0];
                        }
                        else
                        {
                            itemListStr = string.Join(" or ", string.Join(", ", itemNameList.Take(itemNameList.Count - 1)), itemNameList.Last());
                        }
                        if (targetCharacter != character)
                        {
                            character.Speak(TextManager.GetWithVariables("DialogListRequiredTreatments", new string[2] {
                                "[targetname]", "[treatmentlist]"
                            },
                                                                         new string[2] {
                                targetCharacter.Name, itemListStr
                            }, new bool[2] {
                                false, true
                            }),
                                            null, 2.0f, "listrequiredtreatments" + targetCharacter.Name, 60.0f);
                        }
                        character.DeselectCharacter();
                        RemoveSubObjective(ref getItemObjective);
                        TryAddSubObjective(ref getItemObjective,
                                           constructor: () => new AIObjectiveGetItem(character, suitableItemIdentifiers.ToArray(), objectiveManager, equip: true, spawnItemIfNotFound: character.TeamID == Character.TeamType.FriendlyNPC),
                                           onCompleted: () => RemoveSubObjective(ref getItemObjective),
                                           onAbandon: () => RemoveSubObjective(ref getItemObjective));
                    }
                }
            }
            if (character != targetCharacter)
            {
                character.AnimController.Anim = AnimController.Animation.CPR;
            }
        }
Ejemplo n.º 20
0
 public WayPoint(Rectangle newRect, Submarine submarine)
     : this(MapEntityPrefab.Find(null, "waypoint"), newRect, submarine)
 {
 }
Ejemplo n.º 21
0
 private static bool IsThalamus(MapEntityPrefab entityPrefab, string tag) => entityPrefab.Category == MapEntityCategory.Thalamus || entityPrefab.Tags.Contains(tag);
Ejemplo n.º 22
0
        private void InitializeItems(Character character, XElement itemElement, Submarine submarine, Item parentItem = null)
        {
            ItemPrefab itemPrefab;
            string     itemIdentifier = itemElement.GetAttributeString("identifier", "");

            itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab;
            if (itemPrefab == null)
            {
                DebugConsole.ThrowError("Tried to spawn \"" + Identifier + "\" with the item \"" + itemIdentifier + "\". Matching item prefab not found.");
                return;
            }
            Item item = new Item(itemPrefab, character.Position, null);

#if SERVER
            if (GameMain.Server != null && Entity.Spawner != null)
            {
                if (GameMain.Server.EntityEventManager.UniqueEvents.Any(ev => ev.Entity == item))
                {
                    string errorMsg = $"Error while spawning job items. Item {item.Name} created network events before the spawn event had been created.";
                    DebugConsole.ThrowError(errorMsg);
                    GameAnalyticsManager.AddErrorEventOnce("Job.InitializeJobItem:EventsBeforeSpawning", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
                    GameMain.Server.EntityEventManager.UniqueEvents.RemoveAll(ev => ev.Entity == item);
                    GameMain.Server.EntityEventManager.Events.RemoveAll(ev => ev.Entity == item);
                }

                Entity.Spawner.CreateNetworkEvent(item, false);
            }
#endif
            if (itemElement.GetAttributeBool("equip", false))
            {
                List <InvSlotType> allowedSlots = new List <InvSlotType>(item.AllowedSlots);
                allowedSlots.Remove(InvSlotType.Any);

                character.Inventory.TryPutItem(item, null, allowedSlots);
            }
            else
            {
                character.Inventory.TryPutItem(item, null, item.AllowedSlots);
            }
            if (item.Prefab.Identifier == "idcard" || item.Prefab.Identifier == "idcardwreck")
            {
                item.AddTag("name:" + character.Name);
                item.ReplaceTag("wreck_id", Level.Loaded.GetWreckIDTag("wreck_id", submarine));
                var job = character.Info?.Job;
                if (job != null)
                {
                    item.AddTag("job:" + job.Name);
                }
            }
            foreach (WifiComponent wifiComponent in item.GetComponents <WifiComponent>())
            {
                wifiComponent.TeamID = character.TeamID;
            }
            if (parentItem != null)
            {
                parentItem.Combine(item, user: null);
            }
            foreach (XElement childItemElement in itemElement.Elements())
            {
                InitializeItems(character, childItemElement, submarine, item);
            }
        }
Ejemplo n.º 23
0
        public ItemPrefab(XElement element, string filePath)
        {
            configFile    = filePath;
            ConfigElement = element;

            OriginalName = element.GetAttributeString("name", "");
            identifier   = element.GetAttributeString("identifier", "");

            //nameidentifier can be used to make multiple items use the same names and descriptions
            string nameIdentifier = element.GetAttributeString("nameidentifier", "");

            if (string.IsNullOrEmpty(nameIdentifier))
            {
                name = TextManager.Get("EntityName." + identifier, true) ?? OriginalName;
            }
            else
            {
                name = TextManager.Get("EntityName." + nameIdentifier, true) ?? OriginalName;
            }

            if (name == "")
            {
                DebugConsole.ThrowError("Unnamed item in " + filePath + "!");
            }

            DebugConsole.Log("    " + name);

            Aliases = new HashSet <string>
                          (element.GetAttributeStringArray("aliases", null, convertToLowerInvariant: true) ??
                          element.GetAttributeStringArray("Aliases", new string[0], convertToLowerInvariant: true));
            Aliases.Add(OriginalName.ToLowerInvariant());

            if (!Enum.TryParse(element.GetAttributeString("category", "Misc"), true, out MapEntityCategory category))
            {
                category = MapEntityCategory.Misc;
            }
            Category = category;

            Triggers           = new List <Rectangle>();
            DeconstructItems   = new List <DeconstructItem>();
            FabricationRecipes = new List <FabricationRecipe>();
            DeconstructTime    = 1.0f;

            Tags = new HashSet <string>(element.GetAttributeStringArray("tags", new string[0], convertToLowerInvariant: true));
            if (!Tags.Any())
            {
                Tags = new HashSet <string>(element.GetAttributeStringArray("Tags", new string[0], convertToLowerInvariant: true));
            }

            if (element.Attribute("cargocontainername") != null)
            {
                DebugConsole.ThrowError("Error in item prefab \"" + name + "\" - cargo container should be configured using the item's identifier, not the name.");
            }

            SerializableProperty.DeserializeProperties(this, element);

            string translatedDescription = "";

            if (string.IsNullOrEmpty(nameIdentifier))
            {
                translatedDescription = TextManager.Get("EntityDescription." + identifier, true);
            }
            else
            {
                translatedDescription = TextManager.Get("EntityDescription." + nameIdentifier, true);
            }
            if (!string.IsNullOrEmpty(translatedDescription))
            {
                Description = translatedDescription;
            }

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "sprite":
                    string spriteFolder = "";
                    if (!subElement.GetAttributeString("texture", "").Contains("/"))
                    {
                        spriteFolder = Path.GetDirectoryName(filePath);
                    }

                    canSpriteFlipX = subElement.GetAttributeBool("canflipx", true);
                    canSpriteFlipY = subElement.GetAttributeBool("canflipy", true);

                    sprite = new Sprite(subElement, spriteFolder, lazyLoad: true);
                    if (subElement.Attribute("sourcerect") == null)
                    {
                        DebugConsole.ThrowError("Warning - sprite sourcerect not configured for item \"" + Name + "\"!");
                    }
                    size = sprite.size;

                    if (subElement.Attribute("name") == null && !string.IsNullOrWhiteSpace(Name))
                    {
                        sprite.Name = Name;
                    }
                    sprite.EntityID = identifier;
                    break;

                case "price":
                    string locationType = subElement.GetAttributeString("locationtype", "");
                    if (prices == null)
                    {
                        prices = new Dictionary <string, PriceInfo>();
                    }
                    prices[locationType.ToLowerInvariant()] = new PriceInfo(subElement);
                    break;

#if CLIENT
                case "inventoryicon":
                    string iconFolder = "";
                    if (!subElement.GetAttributeString("texture", "").Contains("/"))
                    {
                        iconFolder = Path.GetDirectoryName(filePath);
                    }
                    InventoryIcon = new Sprite(subElement, iconFolder, lazyLoad: true);
                    break;

                case "brokensprite":
                    string brokenSpriteFolder = "";
                    if (!subElement.GetAttributeString("texture", "").Contains("/"))
                    {
                        brokenSpriteFolder = Path.GetDirectoryName(filePath);
                    }

                    var brokenSprite = new BrokenItemSprite(
                        new Sprite(subElement, brokenSpriteFolder, lazyLoad: true),
                        subElement.GetAttributeFloat("maxcondition", 0.0f),
                        subElement.GetAttributeBool("fadein", false));

                    int spriteIndex = 0;
                    for (int i = 0; i < BrokenSprites.Count && BrokenSprites[i].MaxCondition < brokenSprite.MaxCondition; i++)
                    {
                        spriteIndex = i;
                    }
                    BrokenSprites.Insert(spriteIndex, brokenSprite);
                    break;

                case "decorativesprite":
                    string decorativeSpriteFolder = "";
                    if (!subElement.GetAttributeString("texture", "").Contains("/"))
                    {
                        decorativeSpriteFolder = Path.GetDirectoryName(filePath);
                    }

                    int groupID = 0;
                    DecorativeSprite decorativeSprite = null;
                    if (subElement.Attribute("texture") == null)
                    {
                        groupID = subElement.GetAttributeInt("randomgroupid", 0);
                    }
                    else
                    {
                        decorativeSprite = new DecorativeSprite(subElement, decorativeSpriteFolder, lazyLoad: true);
                        DecorativeSprites.Add(decorativeSprite);
                        groupID = decorativeSprite.RandomGroupID;
                    }
                    if (!DecorativeSpriteGroups.ContainsKey(groupID))
                    {
                        DecorativeSpriteGroups.Add(groupID, new List <DecorativeSprite>());
                    }
                    DecorativeSpriteGroups[groupID].Add(decorativeSprite);

                    break;

                case "containedsprite":
                    string containedSpriteFolder = "";
                    if (!subElement.GetAttributeString("texture", "").Contains("/"))
                    {
                        containedSpriteFolder = Path.GetDirectoryName(filePath);
                    }
                    var containedSprite = new ContainedItemSprite(subElement, containedSpriteFolder, lazyLoad: true);
                    if (containedSprite.Sprite != null)
                    {
                        ContainedSprites.Add(containedSprite);
                    }
                    break;
#endif
                case "deconstruct":
                    DeconstructTime = subElement.GetAttributeFloat("time", 1.0f);

                    foreach (XElement deconstructItem in subElement.Elements())
                    {
                        if (deconstructItem.Attribute("name") != null)
                        {
                            DebugConsole.ThrowError("Error in item config \"" + Name + "\" - use item identifiers instead of names to configure the deconstruct items.");
                            continue;
                        }

                        DeconstructItems.Add(new DeconstructItem(deconstructItem));
                    }

                    break;

                case "fabricate":
                case "fabricable":
                case "fabricableitem":
                    fabricationRecipeElements.Add(subElement);
                    break;

                case "trigger":
                    Rectangle trigger = new Rectangle(0, 0, 10, 10)
                    {
                        X      = subElement.GetAttributeInt("x", 0),
                        Y      = subElement.GetAttributeInt("y", 0),
                        Width  = subElement.GetAttributeInt("width", 0),
                        Height = subElement.GetAttributeInt("height", 0)
                    };

                    Triggers.Add(trigger);

                    break;

                case "levelresource":
                    foreach (XElement levelCommonnessElement in subElement.Elements())
                    {
                        string levelName = levelCommonnessElement.GetAttributeString("levelname", "").ToLowerInvariant();
                        if (!LevelCommonness.ContainsKey(levelName))
                        {
                            LevelCommonness.Add(levelName, levelCommonnessElement.GetAttributeFloat("commonness", 0.0f));
                        }
                    }
                    break;

                case "suitabletreatment":
                    if (subElement.Attribute("name") != null)
                    {
                        DebugConsole.ThrowError("Error in item prefab \"" + Name + "\" - suitable treatments should be defined using item identifiers, not item names.");
                    }

                    string treatmentIdentifier = subElement.GetAttributeString("identifier", "").ToLowerInvariant();

                    List <AfflictionPrefab> matchingAfflictions = AfflictionPrefab.List.FindAll(a => a.Identifier == treatmentIdentifier || a.AfflictionType == treatmentIdentifier);
                    if (matchingAfflictions.Count == 0)
                    {
                        DebugConsole.ThrowError("Error in item prefab \"" + Name + "\" - couldn't define as a treatment, no treatments with the identifier or type \"" + treatmentIdentifier + "\" were found.");
                        continue;
                    }

                    float suitability = subElement.GetAttributeFloat("suitability", 0.0f);
                    foreach (AfflictionPrefab matchingAffliction in matchingAfflictions)
                    {
                        if (matchingAffliction.TreatmentSuitability.ContainsKey(identifier))
                        {
                            matchingAffliction.TreatmentSuitability[identifier] =
                                Math.Max(matchingAffliction.TreatmentSuitability[identifier], suitability);
                        }
                        else
                        {
                            matchingAffliction.TreatmentSuitability.Add(identifier, suitability);
                        }
                    }
                    break;
                }
            }

            if (sprite == null)
            {
                DebugConsole.ThrowError("Item \"" + Name + "\" has no sprite!");
#if SERVER
                sprite            = new Sprite("", Vector2.Zero);
                sprite.SourceRect = new Rectangle(0, 0, 32, 32);
#else
                sprite = new Sprite(TextureLoader.PlaceHolderTexture, null, null)
                {
                    Origin = TextureLoader.PlaceHolderTexture.Bounds.Size.ToVector2() / 2
                };
#endif
                size            = sprite.size;
                sprite.EntityID = identifier;
            }

            if (!category.HasFlag(MapEntityCategory.Legacy) && string.IsNullOrEmpty(identifier))
            {
                DebugConsole.ThrowError(
                    "Item prefab \"" + name + "\" has no identifier. All item prefabs have a unique identifier string that's used to differentiate between items during saving and loading.");
            }
            if (!string.IsNullOrEmpty(identifier))
            {
                MapEntityPrefab existingPrefab = List.Find(e => e.Identifier == identifier);
                if (existingPrefab != null)
                {
                    DebugConsole.ThrowError(
                        "Map entity prefabs \"" + name + "\" and \"" + existingPrefab.Name + "\" have the same identifier!");
                }
            }

            AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList();

            List.Add(this);
        }
Ejemplo n.º 24
0
 private static bool IsThalamus(MapEntityPrefab entityPrefab, string tag) => entityPrefab.HasSubCategory("thalamus") || entityPrefab.Tags.Contains(tag);
Ejemplo n.º 25
0
        public FabricationRecipe(XElement element, ItemPrefab itemPrefab)
        {
            TargetItem = itemPrefab;
            string displayName = element.GetAttributeString("displayname", "");

            DisplayName = string.IsNullOrEmpty(displayName) ? itemPrefab.Name : TextManager.Get($"DisplayName.{displayName}");

            SuitableFabricatorIdentifiers = element.GetAttributeStringArray("suitablefabricators", new string[0]);

            RequiredSkills = new List <Skill>();
            RequiredTime   = element.GetAttributeFloat("requiredtime", 1.0f);
            OutCondition   = element.GetAttributeFloat("outcondition", 1.0f);
            RequiredItems  = new List <RequiredItem>();

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "requiredskill":
                    if (subElement.Attribute("name") != null)
                    {
                        DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! Use skill identifiers instead of names.");
                        continue;
                    }

                    RequiredSkills.Add(new Skill(
                                           subElement.GetAttributeString("identifier", ""),
                                           subElement.GetAttributeInt("level", 0)));
                    break;

                case "item":
                case "requireditem":
                    string requiredItemIdentifier = subElement.GetAttributeString("identifier", "");
                    if (string.IsNullOrWhiteSpace(requiredItemIdentifier))
                    {
                        DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! One of the required items has no identifier.");
                        continue;
                    }

                    float minCondition = subElement.GetAttributeFloat("mincondition", 1.0f);
                    //Substract mincondition from required item's condition or delete it regardless?
                    bool useCondition = subElement.GetAttributeBool("usecondition", true);
                    int  count        = subElement.GetAttributeInt("count", 1);


                    ItemPrefab requiredItem = MapEntityPrefab.Find(null, requiredItemIdentifier.Trim()) as ItemPrefab;
                    if (requiredItem == null)
                    {
                        DebugConsole.ThrowError("Error in fabricable item " + itemPrefab.Name + "! Required item \"" + requiredItemIdentifier + "\" not found.");
                        continue;
                    }

                    var existing = RequiredItems.Find(r => r.ItemPrefab == requiredItem);
                    if (existing == null)
                    {
                        RequiredItems.Add(new RequiredItem(requiredItem, count, minCondition, useCondition));
                    }
                    else
                    {
                        RequiredItems.Remove(existing);
                        RequiredItems.Add(new RequiredItem(requiredItem, existing.Amount + count, minCondition, useCondition));
                    }

                    break;
                }
            }
        }
Ejemplo n.º 26
0
 public MapEntity(MapEntityPrefab prefab, Submarine submarine) : base(submarine)
 {
     this.prefab = prefab;
 }
Ejemplo n.º 27
0
 public MapEntity(MapEntityPrefab prefab, Submarine submarine, ushort id) : base(submarine, id)
 {
     this.prefab = prefab;
     Scale       = prefab != null ? prefab.Scale : 1;
 }
Ejemplo n.º 28
0
 public override MapEntity Clone()
 {
     return(new Hull(MapEntityPrefab.Find(null, "hull"), rect, Submarine));
 }
Ejemplo n.º 29
0
        public static StructurePrefab Load(XElement element)
        {
            StructurePrefab sp = new StructurePrefab
            {
                name = element.GetAttributeString("name", "")
            };

            sp.ConfigElement = element;
            if (string.IsNullOrEmpty(sp.name))
            {
                sp.name = element.Name.ToString();
            }
            sp.identifier = element.GetAttributeString("identifier", "");

            string translatedName = TextManager.Get("EntityName." + sp.identifier, true);

            if (!string.IsNullOrEmpty(translatedName))
            {
                sp.name = translatedName;
            }

            sp.Tags = new HashSet <string>();
            string joinedTags = element.GetAttributeString("tags", "");

            if (string.IsNullOrEmpty(joinedTags))
            {
                joinedTags = element.GetAttributeString("Tags", "");
            }
            foreach (string tag in joinedTags.Split(','))
            {
                sp.Tags.Add(tag.Trim().ToLowerInvariant());
            }

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString())
                {
                case "sprite":
                    sp.sprite = new Sprite(subElement, lazyLoad: true);
                    if (subElement.Attribute("sourcerect") == null)
                    {
                        DebugConsole.ThrowError("Warning - sprite sourcerect not configured for structure \"" + sp.name + "\"!");
                    }

                    if (subElement.GetAttributeBool("fliphorizontal", false))
                    {
                        sp.sprite.effects = SpriteEffects.FlipHorizontally;
                    }
                    if (subElement.GetAttributeBool("flipvertical", false))
                    {
                        sp.sprite.effects = SpriteEffects.FlipVertically;
                    }

                    sp.canSpriteFlipX = subElement.GetAttributeBool("canflipx", true);
                    sp.canSpriteFlipY = subElement.GetAttributeBool("canflipy", true);

                    if (subElement.Attribute("name") == null && !string.IsNullOrWhiteSpace(sp.Name))
                    {
                        sp.sprite.Name = sp.Name;
                    }
                    sp.sprite.EntityID = sp.identifier;
                    break;

                case "backgroundsprite":
                    sp.BackgroundSprite = new Sprite(subElement, lazyLoad: true);
                    if (subElement.Attribute("sourcerect") == null && sp.sprite != null)
                    {
                        sp.BackgroundSprite.SourceRect     = sp.sprite.SourceRect;
                        sp.BackgroundSprite.size           = sp.sprite.size;
                        sp.BackgroundSprite.size.X        *= sp.sprite.SourceRect.Width;
                        sp.BackgroundSprite.size.Y        *= sp.sprite.SourceRect.Height;
                        sp.BackgroundSprite.RelativeOrigin = subElement.GetAttributeVector2("origin", new Vector2(0.5f, 0.5f));
                    }
                    if (subElement.GetAttributeBool("fliphorizontal", false))
                    {
                        sp.BackgroundSprite.effects = SpriteEffects.FlipHorizontally;
                    }
                    if (subElement.GetAttributeBool("flipvertical", false))
                    {
                        sp.BackgroundSprite.effects = SpriteEffects.FlipVertically;
                    }

                    break;
                }
            }

            if (!Enum.TryParse(element.GetAttributeString("category", "Structure"), true, out MapEntityCategory category))
            {
                category = MapEntityCategory.Structure;
            }
            sp.Category = category;

            string aliases = element.GetAttributeString("aliases", "");

            if (!string.IsNullOrWhiteSpace(aliases))
            {
                sp.Aliases = aliases.Split(',');
            }

            SerializableProperty.DeserializeProperties(sp, element);
            if (sp.Body)
            {
                sp.Tags.Add("wall");
            }
            string translatedDescription = TextManager.Get("EntityDescription." + sp.identifier, true);

            if (!string.IsNullOrEmpty(translatedDescription))
            {
                sp.Description = translatedDescription;
            }

            //backwards compatibility
            if (element.Attribute("size") == null)
            {
                sp.size = Vector2.Zero;
                if (element.Attribute("width") == null && element.Attribute("height") == null)
                {
                    sp.size.X = sp.sprite.SourceRect.Width;
                    sp.size.Y = sp.sprite.SourceRect.Height;
                }
                else
                {
                    sp.size.X = element.GetAttributeFloat("width", 0.0f);
                    sp.size.Y = element.GetAttributeFloat("height", 0.0f);
                }
            }

            if (!category.HasFlag(MapEntityCategory.Legacy) && string.IsNullOrEmpty(sp.identifier))
            {
                DebugConsole.ThrowError(
                    "Structure prefab \"" + sp.name + "\" has no identifier. All structure prefabs have a unique identifier string that's used to differentiate between items during saving and loading.");
            }
            if (!string.IsNullOrEmpty(sp.identifier))
            {
                MapEntityPrefab existingPrefab = List.Find(e => e.Identifier == sp.identifier);
                if (existingPrefab != null)
                {
                    DebugConsole.ThrowError(
                        "Map entity prefabs \"" + sp.name + "\" and \"" + existingPrefab.Name + "\" have the same identifier!");
                }
            }

            return(sp);
        }