Beispiel #1
0
        /// <summary>
        /// Deserializes the alloy
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="resolver"></param>
        public void FromBytes(BinaryReader reader, IWorldAccessor resolver)
        {
            Code        = reader.ReadString();
            Ingredients = new CookingRecipeIngredient[reader.ReadInt32()];

            for (int i = 0; i < Ingredients.Length; i++)
            {
                Ingredients[i] = new CookingRecipeIngredient();
                Ingredients[i].FromBytes(reader, resolver.ClassRegistry);
                Ingredients[i].Resolve(resolver, "[FromBytes]");
            }

            //NameComponentOrder = reader.ReadIntArray();

            if (!reader.ReadBoolean())
            {
                Shape = new CompositeShape()
                {
                    Base = new AssetLocation(reader.ReadString())
                };
            }

            PerishableProps = new TransitionableProperties();
            PerishableProps.FromBytes(reader, resolver.ClassRegistry);

            //     CanBeServedInto = new JsonItemStack();
            //     CanBeServedInto.FromBytes(reader, resolver.ClassRegistry);
            //     CanBeServedInto.Resolve(resolver, "[FromBytes]");
        }
Beispiel #2
0
        /// <summary>
        /// Creates a deep copy of the texture
        /// </summary>
        /// <returns></returns>
        public CompositeShape Clone()
        {
            CompositeShape[] alternatesClone = null;

            if (Alternates != null)
            {
                alternatesClone = new CompositeShape[Alternates.Length];
                for (int i = 0; i < alternatesClone.Length; i++)
                {
                    alternatesClone[i] = Alternates[i].CloneWithoutAlternates();
                }
            }

            CompositeShape[] overlaysClone = null;

            if (this.Overlays != null)
            {
                overlaysClone = new CompositeShape[Overlays.Length];
                for (int i = 0; i < overlaysClone.Length; i++)
                {
                    overlaysClone[i] = Overlays[i].CloneWithoutAlternates();
                }
            }

            CompositeShape ct = new CompositeShape()
            {
                Base                = Base?.Clone(),
                Alternates          = alternatesClone,
                Overlays            = overlaysClone,
                Format              = Format,
                VoxelizeTexture     = VoxelizeTexture,
                InsertBakedTextures = InsertBakedTextures,
                rotateX             = rotateX,
                rotateY             = rotateY,
                rotateZ             = rotateZ,
                offsetX             = offsetX,
                offsetY             = offsetY,
                offsetZ             = offsetZ,
                Scale               = Scale,
                QuantityElements    = QuantityElements,
                SelectiveElements   = (string[])SelectiveElements?.Clone()
            };

            return(ct);
        }
Beispiel #3
0
        internal CompositeShape CloneWithoutAlternates()
        {
            CompositeShape ct = new CompositeShape()
            {
                Base   = Base?.Clone(),
                Format = Format,
                InsertBakedTextures = InsertBakedTextures,
                rotateX             = rotateX,
                rotateY             = rotateY,
                rotateZ             = rotateZ,
                offsetX             = offsetX,
                offsetY             = offsetY,
                offsetZ             = offsetZ,
                VoxelizeTexture     = VoxelizeTexture,
                QuantityElements    = QuantityElements,
                SelectiveElements   = (string[])SelectiveElements?.Clone()
            };

            return(ct);
        }
Beispiel #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="code">Any unique Identifier</param>
        /// <param name="cshape"></param>
        /// <param name="entityShape"></param>
        /// <param name="shapePathForLogging"></param>
        /// <param name="disableElements"></param>
        /// <returns></returns>
        protected Shape addGearToShape(string code, CompositeShape cshape, Shape entityShape, string shapePathForLogging, string[] disableElements = null, Dictionary <string, AssetLocation> textureOverrides = null)
        {
            AssetLocation shapePath = shapePath = cshape.Base.CopyWithPath("shapes/" + cshape.Base.Path + ".json");

            if (disableElements != null)
            {
                foreach (var val in disableElements)
                {
                    entityShape.RemoveElementByName(val);
                }
            }

            IAsset asset = Api.Assets.TryGet(shapePath);

            if (asset == null)
            {
                Api.World.Logger.Warning("Compositshape {0} (code: {2}) defined but not found, was supposed to be at {1}. Part will be invisible.", cshape.Base, shapePath, code);
                return(null);
            }

            Shape armorShape;

            try
            {
                armorShape = asset.ToObject <Shape>();
            }
            catch (Exception e)
            {
                Api.World.Logger.Warning("Exception thrown when trying to load gear shape {0} (code: {2}) . Will be invisible. Exception: {1}", cshape.Base, e, code);
                return(null);
            }

            bool added = applyStepParents(null, armorShape.Elements, entityShape, code, cshape, shapePathForLogging);


            if (added && armorShape.Textures != null)
            {
                Dictionary <string, AssetLocation> newdict = new Dictionary <string, AssetLocation>();
                foreach (var val in armorShape.Textures)
                {
                    newdict[code + "-" + val.Key] = val.Value;
                }

                // Texture overrides
                if (textureOverrides != null)
                {
                    foreach (var val in textureOverrides)
                    {
                        newdict[code + "-" + val.Key] = val.Value;
                    }
                }

                armorShape.Textures = newdict;

                foreach (var val in armorShape.Textures)
                {
                    CompositeTexture ctex = new CompositeTexture()
                    {
                        Base = val.Value
                    };

                    entityShape.TextureSizes[val.Key] = new int[] { armorShape.TextureWidth, armorShape.TextureHeight };

                    AssetLocation armorTexLoc = val.Value;

                    // Weird backreference to the shaperenderer. Should be refactored.
                    var texturesByLoc  = extraTextureByLocation;
                    var texturesByName = extraTexturesByTextureName;

                    BakedCompositeTexture bakedCtex;

                    ICoreClientAPI capi = Api as ICoreClientAPI;

                    if (!texturesByLoc.TryGetValue(armorTexLoc, out bakedCtex))
                    {
                        int textureSubId = 0;
                        TextureAtlasPosition texpos;

                        IAsset texAsset = Api.Assets.TryGet(val.Value.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                        if (texAsset != null)
                        {
                            BitmapRef bmp = texAsset.ToBitmap(capi);
                            capi.EntityTextureAtlas.InsertTexture(bmp, out textureSubId, out texpos);
                        }
                        else
                        {
                            capi.World.Logger.Warning("Entity armor shape {0} defined texture {1}, not no such texture found.", shapePath, val.Value);
                        }

                        ctex.Baked = new BakedCompositeTexture()
                        {
                            BakedName = val.Value, TextureSubId = textureSubId
                        };

                        texturesByName[val.Key]    = ctex;
                        texturesByLoc[armorTexLoc] = ctex.Baked;
                    }
                    else
                    {
                        ctex.Baked = bakedCtex;
                        texturesByName[val.Key] = ctex;
                    }
                }

                foreach (var val in armorShape.TextureSizes)
                {
                    entityShape.TextureSizes[val.Key] = val.Value;
                }
            }

            return(entityShape);
        }
Beispiel #5
0
        protected Shape addGearToShape(ItemSlot slot, Shape entityShape, string shapePathForLogging)
        {
            if (slot.Empty)
            {
                return(entityShape);
            }
            ItemStack  stack   = slot.Itemstack;
            JsonObject attrObj = stack.Collectible.Attributes;


            string[] disableElements = attrObj?["disableElements"]?.AsArray <string>(null);
            if (disableElements != null)
            {
                foreach (var val in disableElements)
                {
                    entityShape.RemoveElementByName(val);
                }
            }

            if (attrObj?["wearableAttachment"].Exists != true)
            {
                return(entityShape);
            }

            CompositeShape compArmorShape = !attrObj["attachShape"].Exists ? (stack.Class == EnumItemClass.Item ? stack.Item.Shape : stack.Block.Shape) : attrObj["attachShape"].AsObject <CompositeShape>(null, stack.Collectible.Code.Domain);

            AssetLocation shapePath = shapePath = compArmorShape.Base.CopyWithPath("shapes/" + compArmorShape.Base.Path + ".json");



            IAsset asset = Api.Assets.TryGet(shapePath);

            if (asset == null)
            {
                Api.World.Logger.Warning("Entity armor shape {0} defined in {1} {2} not found, was supposed to be at {3}. Armor piece will be invisible.", compArmorShape.Base, stack.Class, stack.Collectible.Code, shapePath);
                return(null);
            }

            Shape armorShape;

            try
            {
                armorShape = asset.ToObject <Shape>();
            }
            catch (Exception e)
            {
                Api.World.Logger.Warning("Exception thrown when trying to load entity armor shape {0} defined in {1} {2}. Armor piece will be invisible. Exception: {3}", compArmorShape.Base, slot.Itemstack.Class, slot.Itemstack.Collectible.Code, e);
                return(null);
            }

            bool added = false;

            foreach (var val in armorShape.Elements)
            {
                ShapeElement elem;

                if (val.StepParentName != null)
                {
                    elem = entityShape.GetElementByName(val.StepParentName, StringComparison.InvariantCultureIgnoreCase);
                    if (elem == null)
                    {
                        Api.World.Logger.Warning("Entity armor shape {0} defined in {1} {2} requires step parent element with name {3}, but no such element was found in shape {4}. Will not be visible.", compArmorShape.Base, slot.Itemstack.Class, slot.Itemstack.Collectible.Code, val.StepParentName, shapePathForLogging);
                        continue;
                    }
                }
                else
                {
                    Api.World.Logger.Warning("Entity armor shape element {0} in shape {1} defined in {2} {3} did not define a step parent element. Will not be visible.", val.Name, compArmorShape.Base, slot.Itemstack.Class, slot.Itemstack.Collectible.Code);
                    continue;
                }

                if (elem.Children == null)
                {
                    elem.Children = new ShapeElement[] { val };
                }
                else
                {
                    elem.Children = elem.Children.Append(val);
                }

                val.SetJointIdRecursive(elem.JointId);
                val.WalkRecursive((el) =>
                {
                    foreach (var face in el.Faces)
                    {
                        face.Value.Texture = "#" + stack.Collectible.Code + "-" + face.Value.Texture.TrimStart('#');
                    }
                });

                added = true;
            }

            if (added && armorShape.Textures != null)
            {
                Dictionary <string, AssetLocation> newdict = new Dictionary <string, AssetLocation>();
                foreach (var val in armorShape.Textures)
                {
                    newdict[stack.Collectible.Code + "-" + val.Key] = val.Value;
                }

                // Item overrides
                var collDict = stack.Class == EnumItemClass.Block ? stack.Block.Textures : stack.Item.Textures;
                foreach (var val in collDict)
                {
                    newdict[stack.Collectible.Code + "-" + val.Key] = val.Value.Base;
                }

                armorShape.Textures = newdict;

                foreach (var val in armorShape.Textures)
                {
                    CompositeTexture ctex = new CompositeTexture()
                    {
                        Base = val.Value
                    };

                    entityShape.TextureSizes[val.Key] = new int[] { armorShape.TextureWidth, armorShape.TextureHeight };

                    AssetLocation armorTexLoc = val.Value;

                    // Weird backreference to the shaperenderer. Should be refactored.
                    var texturesByLoc  = extraTextureByLocation;
                    var texturesByName = extraTexturesByTextureName;

                    BakedCompositeTexture bakedCtex;

                    ICoreClientAPI capi = Api as ICoreClientAPI;

                    if (!texturesByLoc.TryGetValue(armorTexLoc, out bakedCtex))
                    {
                        int textureSubId = 0;
                        TextureAtlasPosition texpos;

                        IAsset texAsset = Api.Assets.TryGet(val.Value.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                        if (texAsset != null)
                        {
                            BitmapRef bmp = texAsset.ToBitmap(capi);
                            capi.EntityTextureAtlas.InsertTextureCached(val.Value, bmp, out textureSubId, out texpos);
                        }
                        else
                        {
                            capi.World.Logger.Warning("Entity armor shape {0} defined texture {1}, no such texture found.", shapePath, val.Value);
                        }

                        ctex.Baked = new BakedCompositeTexture()
                        {
                            BakedName = val.Value, TextureSubId = textureSubId
                        };

                        texturesByName[val.Key]    = ctex;
                        texturesByLoc[armorTexLoc] = ctex.Baked;
                    }
                    else
                    {
                        ctex.Baked = bakedCtex;
                        texturesByName[val.Key] = ctex;
                    }
                }

                foreach (var val in armorShape.TextureSizes)
                {
                    entityShape.TextureSizes[val.Key] = val.Value;
                }
            }

            return(entityShape);
        }
Beispiel #6
0
        private bool applyStepParents(ShapeElement parentElem, ShapeElement[] elements, Shape toShape, string code, CompositeShape cshape, string shapePathForLogging)
        {
            bool added = false;

            foreach (var cElem in elements)
            {
                ShapeElement refelem;

                if (cElem.Children != null)
                {
                    added |= applyStepParents(cElem, cElem.Children, toShape, code, cshape, shapePathForLogging);
                }

                if (cElem.StepParentName != null)
                {
                    refelem = toShape.GetElementByName(cElem.StepParentName, StringComparison.InvariantCultureIgnoreCase);
                    if (refelem == null)
                    {
                        Api.World.Logger.Warning("Shape {0} requires step parent element with name {1}, but no such element was found in shape {2}. Will not be visible.", cshape.Base, cElem.StepParentName, shapePathForLogging);
                        continue;
                    }
                }
                else
                {
                    if (parentElem == null)
                    {
                        Api.World.Logger.Warning("Entity armor shape element {0} in shape {1} did not define a step parent element. Will not be visible.", cElem.Name, cshape.Base);
                    }
                    continue;
                }

                if (parentElem != null)
                {
                    parentElem.Children = parentElem.Children.Remove(cElem);
                }

                if (refelem.Children == null)
                {
                    refelem.Children = new ShapeElement[] { cElem };
                }
                else
                {
                    refelem.Children = refelem.Children.Append(cElem);
                }

                cElem.SetJointIdRecursive(refelem.JointId);

                cElem.WalkRecursive((el) =>
                {
                    foreach (var face in el.Faces)
                    {
                        face.Value.Texture = "#" + code + "-" + face.Value.Texture.TrimStart('#');
                    }
                });

                added = true;
            }

            return(added);
        }
Beispiel #7
0
        /// <summary>
        /// Expands the Composite Texture to a texture atlas friendly version and populates the Baked field
        /// </summary>
        public void LoadAlternates(IAssetManager assetManager, ILogger logger)
        {
            if (Base.Path.EndsWith("*"))
            {
                List <IAsset> assets = assetManager.GetMany("shapes/" + Base.Path.Substring(0, Base.Path.Length - 1), Base.Domain);

                if (assets.Count == 0)
                {
                    Base = new AssetLocation("block/basic/cube");
                    logger.Warning("Could not find any variants for shape {0}, will use standard cube shape.", Base.Path);
                }

                if (assets.Count == 1)
                {
                    Base = assets[0].Location.CopyWithPath(assets[0].Location.Path.Substring("shapes/".Length));
                    Base.RemoveEnding();
                }

                if (assets.Count > 1)
                {
                    int origLength = (Alternates == null ? 0 : Alternates.Length);
                    CompositeShape[] alternates = new CompositeShape[origLength + assets.Count];
                    if (Alternates != null)
                    {
                        Array.Copy(Alternates, alternates, Alternates.Length);
                    }

                    int i = 0;
                    foreach (IAsset asset in assets)
                    {
                        AssetLocation newLocation = asset.Location.CopyWithPath(asset.Location.Path.Substring("shapes/".Length));
                        newLocation.RemoveEnding();

                        if (i == 0)
                        {
                            Base = newLocation.Clone();
                        }

                        alternates[origLength + i] = new CompositeShape()
                        {
                            Base = newLocation, rotateX = rotateX, rotateY = rotateY, rotateZ = rotateZ
                        };

                        i++;
                    }

                    Alternates = alternates;
                }
            }

            if (Alternates != null)
            {
                BakedAlternates               = new CompositeShape[Alternates.Length + 1];
                BakedAlternates[0]            = this.Clone();
                BakedAlternates[0].Alternates = null;

                for (int i = 0; i < Alternates.Length; i++)
                {
                    BakedAlternates[i + 1] = Alternates[i].Clone();

                    if (BakedAlternates[i + 1].Base == null)
                    {
                        BakedAlternates[i + 1].Base = Base.Clone();
                    }

                    if (BakedAlternates[i + 1].QuantityElements == null)
                    {
                        BakedAlternates[i + 1].QuantityElements = QuantityElements;
                    }

                    if (BakedAlternates[i + 1].SelectiveElements == null)
                    {
                        BakedAlternates[i + 1].SelectiveElements = SelectiveElements;
                    }
                }
            }
        }