Exemplo n.º 1
0
 public void RecreateSprites()
 {
     if (Sprite != null)
     {
         Sprite.Remove();
         var source = Sprite.SourceElement;
         Sprite = new Sprite(source, file: GetSpritePath(source, Params.normalSpriteParams));
     }
     if (_deformSprite != null)
     {
         _deformSprite.Remove();
         var source = _deformSprite.Sprite.SourceElement;
         _deformSprite = new DeformableSprite(source, filePath: GetSpritePath(source, Params.deformSpriteParams));
     }
     if (DamagedSprite != null)
     {
         DamagedSprite.Remove();
         var source = DamagedSprite.SourceElement;
         DamagedSprite = new Sprite(source, file: GetSpritePath(source, Params.damagedSpriteParams));
     }
     for (int i = 0; i < ConditionalSprites.Count; i++)
     {
         var conditionalSprite = ConditionalSprites[i];
         var source            = conditionalSprite.ActiveSprite.SourceElement;
         conditionalSprite.Remove();
         ConditionalSprites[i] = new ConditionalSprite(source, character, file: GetSpritePath(source, null));
     }
     for (int i = 0; i < DecorativeSprites.Count; i++)
     {
         var decorativeSprite = DecorativeSprites[i];
         decorativeSprite.Remove();
         var source = decorativeSprite.Sprite.SourceElement;
         DecorativeSprites[i] = new DecorativeSprite(source, file: GetSpritePath(source, Params.decorativeSpriteParams[i]));
     }
 }
Exemplo n.º 2
0
        public void UpdateSpriteStates(float deltaTime)
        {
            DecorativeSprite.UpdateSpriteStates(Prefab.DecorativeSpriteGroups, spriteAnimState, ID, deltaTime, ConditionalMatches);
            foreach (int spriteGroup in Prefab.DecorativeSpriteGroups.Keys)
            {
                for (int i = 0; i < Prefab.DecorativeSpriteGroups[spriteGroup].Count; i++)
                {
                    var decorativeSprite = Prefab.DecorativeSpriteGroups[spriteGroup][i];
                    if (decorativeSprite == null)
                    {
                        continue;
                    }
                    if (spriteGroup > 0)
                    {
                        int activeSpriteIndex = ID % Prefab.DecorativeSpriteGroups[spriteGroup].Count;
                        if (i != activeSpriteIndex)
                        {
                            spriteAnimState[decorativeSprite].IsActive = false;
                            continue;
                        }
                    }

                    //check if the sprite is active (whether it should be drawn or not)
                    var spriteState = spriteAnimState[decorativeSprite];
                    spriteState.IsActive = true;
                    foreach (PropertyConditional conditional in decorativeSprite.IsActiveConditionals)
                    {
                        if (!ConditionalMatches(conditional))
                        {
                            spriteState.IsActive = false;
                            break;
                        }
                    }
                    if (!spriteState.IsActive)
                    {
                        continue;
                    }

                    //check if the sprite should be animated
                    bool animate = true;
                    foreach (PropertyConditional conditional in decorativeSprite.AnimationConditionals)
                    {
                        if (!ConditionalMatches(conditional))
                        {
                            animate = false; break;
                        }
                    }
                    if (!animate)
                    {
                        continue;
                    }
                    spriteState.OffsetState   += deltaTime;
                    spriteState.RotationState += deltaTime;
                }
            }
        }
Exemplo n.º 3
0
        private static StructurePrefab Load(XElement element, bool allowOverride, ContentFile file)
        {
            StructurePrefab sp = new StructurePrefab
            {
                originalName   = element.GetAttributeString("name", ""),
                FilePath       = file.Path,
                ContentPackage = file.ContentPackage
            };

            sp.name          = sp.originalName;
            sp.ConfigElement = element;
            sp.identifier    = element.GetAttributeString("identifier", "");

            var parentType = element.Parent?.GetAttributeString("prefabtype", "") ?? string.Empty;

            string nameIdentifier        = element.GetAttributeString("nameidentifier", "");
            string descriptionIdentifier = element.GetAttributeString("descriptionidentifier", "");

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

            if (string.IsNullOrEmpty(sp.name))
            {
                sp.name = TextManager.Get("EntityName." + sp.identifier, returnNull: true) ?? $"Not defined ({sp.identifier})";
            }
            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());
            }

            if (element.Attribute("ishorizontal") != null)
            {
                sp.IsHorizontal = element.GetAttributeBool("ishorizontal", false);
            }

            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 CLIENT
                    if (subElement.GetAttributeBool("fliphorizontal", false))
                    {
                        sp.sprite.effects = SpriteEffects.FlipHorizontally;
                    }
                    if (subElement.GetAttributeBool("flipvertical", false))
                    {
                        sp.sprite.effects = SpriteEffects.FlipVertically;
                    }
#endif
                    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 CLIENT
                    if (subElement.GetAttributeBool("fliphorizontal", false))
                    {
                        sp.BackgroundSprite.effects = SpriteEffects.FlipHorizontally;
                    }
                    if (subElement.GetAttributeBool("flipvertical", false))
                    {
                        sp.BackgroundSprite.effects = SpriteEffects.FlipVertically;
                    }
                    sp.BackgroundSpriteColor = subElement.GetAttributeColor("color", Color.White);
#endif
                    break;

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

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

            if (string.Equals(parentType, "wrecked", StringComparison.OrdinalIgnoreCase))
            {
                if (!string.IsNullOrEmpty(sp.Name))
                {
                    sp.name = TextManager.GetWithVariable("wreckeditemformat", "[name]", sp.name);
                }
            }

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

            if (category.HasFlag(MapEntityCategory.Legacy))
            {
                if (string.IsNullOrWhiteSpace(sp.identifier))
                {
                    sp.identifier = "legacystructure_" + sp.name.ToLowerInvariant().Replace(" ", "");
                }
            }

            sp.Aliases =
                (element.GetAttributeStringArray("aliases", null) ??
                 element.GetAttributeStringArray("Aliases", new string[0])).ToHashSet();

            string nonTranslatedName = element.GetAttributeString("name", null) ?? element.Name.ToString();
            sp.Aliases.Add(nonTranslatedName.ToLowerInvariant());

            SerializableProperty.DeserializeProperties(sp, element);
            if (sp.Body)
            {
                sp.Tags.Add("wall");
            }

            if (string.IsNullOrEmpty(sp.Description))
            {
                if (!string.IsNullOrEmpty(descriptionIdentifier))
                {
                    sp.Description = TextManager.Get("EntityDescription." + descriptionIdentifier, returnNull: true) ?? string.Empty;
                }
                else if (string.IsNullOrEmpty(nameIdentifier))
                {
                    sp.Description = TextManager.Get("EntityDescription." + sp.identifier, returnNull: true) ?? string.Empty;
                }
                else
                {
                    sp.Description = TextManager.Get("EntityDescription." + nameIdentifier, true) ?? string.Empty;
                }
            }

            //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);
                }
            }

            //backwards compatibility
            if (categoryStr.Equals("Thalamus", StringComparison.OrdinalIgnoreCase))
            {
                sp.Category    = MapEntityCategory.Wrecked;
                sp.Subcategory = "Thalamus";
            }

            if (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.");
            }
            Prefabs.Add(sp, allowOverride);
            return(sp);
        }
Exemplo n.º 4
0
        public ItemPrefab(XElement element, string filePath, bool allowOverriding)
        {
            FilePath      = filePath;
            ConfigElement = element;

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

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

            var parentType = element.Parent?.GetAttributeString("itemtype", "") ?? string.Empty;

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

            //works the same as nameIdentifier, but just replaces the description
            string descriptionIdentifier = element.GetAttributeString("descriptionidentifier", "");

            if (string.IsNullOrEmpty(originalName))
            {
                if (string.IsNullOrEmpty(nameIdentifier))
                {
                    name = TextManager.Get("EntityName." + identifier, true) ?? string.Empty;
                }
                else
                {
                    name = TextManager.Get("EntityName." + nameIdentifier, true) ?? string.Empty;
                }
            }
            else if (Category.HasFlag(MapEntityCategory.Legacy))
            {
                // Legacy items use names as identifiers, so we have to define them in the xml. But we also want to support the translations. Therefore
                if (string.IsNullOrEmpty(nameIdentifier))
                {
                    name = TextManager.Get("EntityName." + identifier, true) ?? originalName;
                }
                else
                {
                    name = TextManager.Get("EntityName." + nameIdentifier, true) ?? originalName;
                }

                if (string.IsNullOrWhiteSpace(identifier))
                {
                    identifier = GenerateLegacyIdentifier(originalName);
                }
            }

            if (string.Equals(parentType, "wrecked", StringComparison.OrdinalIgnoreCase))
            {
                if (!string.IsNullOrEmpty(name))
                {
                    name = TextManager.GetWithVariable("wreckeditemformat", "[name]", name);
                }
            }

            if (string.IsNullOrEmpty(name))
            {
                DebugConsole.ThrowError($"Unnamed item ({identifier})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());

            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);

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

            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":
                    if (locationPrices == null)
                    {
                        locationPrices = new Dictionary <string, PriceInfo>();
                    }
                    if (subElement.Attribute("baseprice") != null)
                    {
                        foreach (Tuple <string, PriceInfo> priceInfo in PriceInfo.CreatePriceInfos(subElement, out defaultPrice))
                        {
                            if (priceInfo == null)
                            {
                                continue;
                            }
                            locationPrices.Add(priceInfo.Item1, priceInfo.Item2);
                        }
                    }
                    else if (subElement.Attribute("buyprice") != null)
                    {
                        string locationType = subElement.GetAttributeString("locationtype", "").ToLowerInvariant();
                        locationPrices.Add(locationType, new PriceInfo(subElement));
                    }
                    break;

                case "upgradeoverride":
                {
#if CLIENT
                    var sprites = new List <DecorativeSprite>();
                    foreach (XElement decorSprite in subElement.Elements())
                    {
                        if (decorSprite.Name.ToString().Equals("decorativesprite", StringComparison.OrdinalIgnoreCase))
                        {
                            sprites.Add(new DecorativeSprite(decorSprite));
                        }
                    }
                    UpgradeOverrideSprites.Add(subElement.GetAttributeString("identifier", ""), sprites);
#endif
                    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 "minimapicon":
                {
                    string iconFolder = "";
                    if (!subElement.GetAttributeString("texture", "").Contains("/"))
                    {
                        iconFolder = Path.GetDirectoryName(filePath);
                    }
                    MinimapIcon = 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),
                        subElement.GetAttributePoint("offset", Point.Zero));

                    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);
                    AllowDeconstruct = true;
                    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 "preferredcontainer":
                    var preferredContainer = new PreferredContainer(subElement);
                    if (preferredContainer.Primary.Count == 0 && preferredContainer.Secondary.Count == 0)
                    {
                        DebugConsole.ThrowError($"Error in item prefab {Name}: preferred container has no preferences defined ({subElement.ToString()}).");
                    }
                    else
                    {
                        PreferredContainers.Add(preferredContainer);
                    }
                    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();

                    float suitability = subElement.GetAttributeFloat("suitability", 0.0f);

                    treatmentSuitability.Add(treatmentIdentifier, suitability);
                    break;
                }
            }

            // Set the default price in case the prices are defined in the old way
            // with separate Price elements and there is no default price explicitly set
            if (locationPrices != null && locationPrices.Any())
            {
                defaultPrice ??= new PriceInfo(GetMinPrice() ?? 0, false);
            }

            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 (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.");
            }

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

            Prefabs.Add(this, allowOverriding);
        }
Exemplo n.º 5
0
        public ItemPrefab(XElement element, string filePath, bool allowOverriding)
        {
            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.");
            }

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

            if (HandleExisting(identifier, allowOverriding, filePath))
            {
                List.Add(this);
            }
        }
Exemplo n.º 6
0
        partial void InitProjSpecific(XElement element)
        {
            for (int i = 0; i < Params.decorativeSpriteParams.Count; i++)
            {
                var param            = Params.decorativeSpriteParams[i];
                var decorativeSprite = new DecorativeSprite(param.Element, file: GetSpritePath(param.Element, param));
                DecorativeSprites.Add(decorativeSprite);
                int groupID = decorativeSprite.RandomGroupID;
                if (!DecorativeSpriteGroups.ContainsKey(groupID))
                {
                    DecorativeSpriteGroups.Add(groupID, new List <DecorativeSprite>());
                }
                DecorativeSpriteGroups[groupID].Add(decorativeSprite);
                spriteAnimState.Add(decorativeSprite, new SpriteState());
            }
            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "sprite":
                    Sprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.normalSpriteParams));
                    break;

                case "damagedsprite":
                    DamagedSprite = new Sprite(subElement, file: GetSpritePath(subElement, Params.damagedSpriteParams));
                    break;

                case "conditionalsprite":
                    var conditionalSprite = new ConditionalSprite(subElement, character, file: GetSpritePath(subElement, null));
                    ConditionalSprites.Add(conditionalSprite);
                    if (conditionalSprite.DeformableSprite != null)
                    {
                        CreateDeformations(subElement.GetChildElement("deformablesprite"));
                    }
                    break;

                case "deformablesprite":
                    _deformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement, Params.deformSpriteParams));
                    CreateDeformations(subElement);
                    break;

                case "lightsource":
                    LightSource             = new LightSource(subElement);
                    InitialLightSourceColor = LightSource.Color;
                    break;
                }

                void CreateDeformations(XElement e)
                {
                    foreach (XElement animationElement in e.GetChildElements("spritedeformation"))
                    {
                        int sync = animationElement.GetAttributeInt("sync", -1);
                        SpriteDeformation deformation = null;
                        if (sync > -1)
                        {
                            // if the element is marked with the sync attribute, use a deformation of the same type with the same sync value, if there is one already.
                            string typeName = animationElement.GetAttributeString("type", "").ToLowerInvariant();
                            deformation = ragdoll.Limbs
                                          .Where(l => l != null)
                                          .SelectMany(l => l.Deformations)
                                          .Where(d => d.TypeName == typeName && d.Sync == sync)
                                          .FirstOrDefault();
                        }
                        if (deformation == null)
                        {
                            deformation = SpriteDeformation.Load(animationElement, character.SpeciesName);
                            if (deformation != null)
                            {
                                ragdoll.SpriteDeformations.Add(deformation);
                            }
                        }
                        if (deformation != null)
                        {
                            Deformations.Add(deformation);
                        }
                    }
                }
            }
        }