Exemple #1
0
    public void Lock()
    {
        if (m_locked)
        {
            throw new Exception("Bitmap already locked.");
        }

        // https://stackoverflow.com/questions/1563038/fast-work-with-bitmaps-in-c-sharp

        Rectangle rect = new Rectangle(0, 0, Width, Height);

        m_bitmapData = BitmapRef.LockBits(rect, ImageLockMode.ReadWrite, BitmapRef.PixelFormat);

        //int rgbValueLength = IsAlphaBitmap ? 4 : 3;
        int rgbValueLength = 4;  // TODO fix this

        m_bitmapSizeBytes = (Width * Height) * rgbValueLength;

#if !USE_UNSAFE_FUNCTIONS
        m_bitmapPtr = m_bitmapData.Scan0;

        if (m_bitmapDataCopy == null || m_bitmapDataCopy.Length != m_bitmapSizeBytes)
        {
            m_bitmapDataCopy = new byte [m_bitmapSizeBytes];
        }

        Marshal.Copy(m_bitmapPtr, m_bitmapDataCopy, 0, m_bitmapDataCopy.Length);
#endif

        m_locked = true;
    }
Exemple #2
0
    public void Lock()
    {
        if (m_locked)
        {
            throw new Exception("Bitmap already locked.");
        }

        // https://stackoverflow.com/questions/1563038/fast-work-with-bitmaps-in-c-sharp

        Rectangle rect = new Rectangle(0, 0, Width, Height);

        m_bitmapData = BitmapRef.LockBits(rect, ImageLockMode.ReadWrite, BitmapRef.PixelFormat);
        m_bitmapPtr  = m_bitmapData.Scan0;

        int rgbValueLength = IsAlphaBitmap ? 4 : 3;

        int bytes = (Width * Height) * rgbValueLength;

        if (m_rgbValues == null || m_rgbValues.Length != (bytes - 1))
        {
            m_rgbValues = new byte [bytes - 1];
        }

        Marshal.Copy(m_bitmapPtr, m_rgbValues, 0, m_rgbValues.Length);

        m_locked = true;
    }
Exemple #3
0
    public void Unlock(bool writePixels = true)
    {
        if (!m_locked)
        {
            throw new Exception("Bitmap not locked.");
        }

#if !USE_UNSAFE_FUNCTIONS
        // Write the color values back to the bitmap
        if (writePixels)
        {
            Marshal.Copy(m_bitmapDataCopy, 0, m_bitmapPtr, m_bitmapDataCopy.Length);
        }
#endif

        // Unlock the bitmap
        BitmapRef.UnlockBits(m_bitmapData);

        m_bitmapData      = null;
        m_bitmapSizeBytes = 0;
#if !USE_UNSAFE_FUNCTIONS
        //m_rgbValues = null;  // don't null this, keep this memory around for re-use
        m_bitmapPtr = (IntPtr)0;
#endif

        m_locked = false;
    }
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                if (contentTextPos == null)
                {
                    int textureSubId;

                    textureSubId = ObjectCacheUtil.GetOrCreate <int>(capi, "contenttexture-" + contentTexture.ToString() + "-" + contentTexture.Alpha, () =>
                    {
                        TextureAtlasPosition texPos;
                        int id = 0;

                        BitmapRef bmp = capi.Assets.TryGet(contentTexture.Base.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi);
                        if (bmp != null)
                        {
                            if (contentTexture.Alpha != 255)
                            {
                                bmp.MulAlpha(contentTexture.Alpha);
                            }
                            capi.BlockTextureAtlas.InsertTexture(bmp, out id, out texPos);
                            bmp.Dispose();
                        }

                        return(id);
                    });

                    contentTextPos = capi.BlockTextureAtlas.Positions[textureSubId];
                }

                return(contentTextPos);
            }
        }
Exemple #5
0
        public static int LoadTextureArray(this ClientMain game, AssetLocation[] locations, int width, int height)
        {
            var Platform = game.GetField <ClientPlatformWindows>("Platform");

            BitmapRef[] bmps = new BitmapRef[locations.Length];

            for (int i = 0; i < locations.Length; i++)
            {
                var name = locations[i].WithPathPrefixOnce("textures/");

                byte[] assetData = Platform.AssetManager.TryGet(name)?.Data;

                if (assetData == null)
                {
                    return(0);
                }

                bmps[i] = Platform.BitmapCreateFromPng(assetData, assetData.Length);
            }

            int id = Platform.LoadTextureArray(bmps, width, height);

            for (int i = 0; i < bmps.Length; i++)
            {
                bmps[i].Dispose();
            }

            return(id);
        }
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                AssetLocation        texturePath = textureLocation;
                TextureAtlasPosition texpos;
                if (texturePath == null)
                {
                    texpos = this.texPos;
                }
                else
                {
                    texpos = api.BlockTextureAtlas[texturePath];
                }


                if (texpos == null)
                {
                    IAsset texAsset = api.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                    if (texAsset != null)
                    {
                        BitmapRef bmp = texAsset.ToBitmap(api);
                        api.BlockTextureAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos);
                    }
                    else
                    {
                        texpos = api.BlockTextureAtlas.UnknownTexturePosition;
                    }
                }

                return(texpos);
            }
        }
Exemple #7
0
        private void OnDraw(Context ctx, ImageSurface surface, ElementBounds currentBounds)
        {
            BitmapRef bmp = capi.Assets.Get("alchemy:textures/hud/alchemyhud.png").ToBitmap(capi);

            if (inactive)
            {
                bmp.MulAlpha(30);
            }
            Vintagestory.API.Common.SurfaceDrawImage.Image(surface, ((Vintagestory.API.Common.BitmapExternal)bmp), (int)currentBounds.drawX, (int)currentBounds.drawY, (int)currentBounds.InnerWidth, (int)currentBounds.InnerHeight);
            bmp.Dispose();
        }
Exemple #8
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                AssetLocation textureLoc = null;
                if (curContProps.Textures != null)
                {
                    CompositeTexture compTex;
                    if (curContProps.Textures.TryGetValue(textureCode, out compTex))
                    {
                        textureLoc = compTex.Base;
                    }
                }

                if (textureLoc == null && shapeTextures != null)
                {
                    shapeTextures.TryGetValue(textureCode, out textureLoc);
                }

                if (textureLoc != null)
                {
                    TextureAtlasPosition texPos = capi.BlockTextureAtlas[textureLoc];
                    if (texPos == null)
                    {
                        BitmapRef bmp = capi.Assets.TryGet(textureLoc.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi);
                        if (bmp != null)
                        {
                            capi.BlockTextureAtlas.InsertTextureCached(textureLoc, bmp, out _, out texPos);
                            bmp.Dispose();
                        }
                    }

                    return(texPos);
                }

                ItemStack content = GetContents();
                if (content.Class == EnumItemClass.Item)
                {
                    TextureAtlasPosition texPos;
                    textureLoc = content.Item.Textures[textureCode].Base;
                    BitmapRef bmp = capi.Assets.TryGet(textureLoc.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi);
                    if (bmp != null)
                    {
                        capi.BlockTextureAtlas.InsertTextureCached(textureLoc, bmp, out _, out texPos);
                        bmp.Dispose();
                        return(texPos);
                    }
                }

                return(contentTexSource[textureCode]);
            }
        }
        private void loadTexture(Shape entityShape, string code, AssetLocation location, int textureWidth, int textureHeight, string shapePathForLogging)
        {
            ICoreClientAPI api = entity.World.Api as ICoreClientAPI;

            CompositeTexture ctex = new CompositeTexture()
            {
                Base = location
            };

            entityShape.TextureSizes[code] = new int[] { textureWidth, textureHeight };

            AssetLocation shapeTexloc = location;

            // Weird backreference to the shaperenderer. Should be refactored.
            var texturesByLoc  = (entity as EntityAgent).extraTextureByLocation;
            var texturesByName = (entity as EntityAgent).extraTexturesByTextureName;

            BakedCompositeTexture bakedCtex;


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

                IAsset texAsset = api.Assets.TryGet(location.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                if (texAsset != null)
                {
                    BitmapRef bmp = texAsset.ToBitmap(api);
                    api.EntityTextureAtlas.InsertTexture(bmp, out textureSubId, out texpos, -1);
                }
                else
                {
                    api.World.Logger.Warning("Skin part shape {0} defined texture {1}, no such texture found.", shapePathForLogging, location);
                }

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

                texturesByName[code]       = ctex;
                texturesByLoc[shapeTexloc] = ctex.Baked;
            }
            else
            {
                ctex.Baked           = bakedCtex;
                texturesByName[code] = ctex;
            }
        }
Exemple #10
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                AssetLocation    texturePath = null;
                CompositeTexture tex;
                if (nowTesselatingItem.Textures.TryGetValue(textureCode, out tex))
                {
                    texturePath = tex.Baked.BakedName;
                }
                else
                {
                    if (nowTesselatingItem.Textures.TryGetValue("all", out tex))
                    {
                        texturePath = tex.Baked.BakedName;
                    }
                    else
                    {
                        nowTesselatingShape?.Textures.TryGetValue(textureCode, out texturePath);
                    }
                }

                if (texturePath == null)
                {
                    texturePath = new AssetLocation(textureCode);
                }

                TextureAtlasPosition texpos = capi.BlockTextureAtlas[texturePath];



                if (texpos == null)
                {
                    IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                    if (texAsset != null)
                    {
                        BitmapRef bmp = texAsset.ToBitmap(capi);
                        capi.BlockTextureAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos);
                    }
                    else
                    {
                        capi.World.Logger.Warning("For render in block " + Block.Code + ", item {0} defined texture {1}, not no such texture found.", nowTesselatingItem.Code, texturePath);
                    }
                }

                return(texpos);
            }
        }
        bool RuntimeInsert(ICoreClientAPI capi, ITextureAtlasAPI intoAtlas, BakedCompositeTexture btex)
        {
            BitmapRef bmp = capi.Assets.Get(btex.BakedName).ToBitmap(capi);

            int textureSubId;
            TextureAtlasPosition texpos;

            if (intoAtlas.InsertTexture(bmp, out textureSubId, out texpos))
            {
                btex.TextureSubId = textureSubId;
                capi.Render.RemoveTexture(btex.BakedName);
                return(true);
            }

            bmp.Dispose();
            return(false);
        }
        protected TextureAtlasPosition getOrCreateTexPos(AssetLocation texturePath)
        {
            TextureAtlasPosition texpos = capi.BlockTextureAtlas[texturePath];

            if (texpos == null)
            {
                IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                if (texAsset != null)
                {
                    BitmapRef bmp = texAsset.ToBitmap(capi);
                    capi.BlockTextureAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos);
                }
                else
                {
                    capi.World.Logger.Warning("For render in block " + Block.Code + ", item {0} defined texture {1}, not no such texture found.", nowTesselatingObj.Code, texturePath);
                }
            }

            return(texpos);
        }
Exemple #13
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                if (textureCode == "topper" && corkTextPos != null)
                {
                    return(corkTextPos);
                }
                if (textureCode == "glass" && blockTextPos != null)
                {
                    return(blockTextPos);
                }
                if (textureCode == "bracing" && bracingTextPos != null)
                {
                    return(bracingTextPos);
                }
                if (contentTextPos == null)
                {
                    int textureSubId;

                    textureSubId = ObjectCacheUtil.GetOrCreate <int>(capi, "contenttexture-" + contentTexture.ToString(), () =>
                    {
                        TextureAtlasPosition texPos;
                        int id = 0;

                        BitmapRef bmp = capi.Assets.TryGet(contentTexture.Base.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi);
                        if (bmp != null)
                        {
                            capi.BlockTextureAtlas.InsertTexture(bmp, out id, out texPos);
                            bmp.Dispose();
                        }

                        return(id);
                    });

                    contentTextPos = capi.BlockTextureAtlas.Positions[textureSubId];
                }

                return(contentTextPos);
            }
        }
Exemple #14
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                AssetLocation texturePath = crustTextureLoc;
                if (textureCode == "filling")
                {
                    texturePath = fillingTextureLoc;
                }
                if (textureCode == "topcrust")
                {
                    texturePath = topCrustTextureLoc;
                }

                if (texturePath == null)
                {
                    capi.World.Logger.Warning("Missing texture path for pie mesh texture code {0}, seems like a missing texture definition or invalid pie block.", textureCode);
                    return(capi.BlockTextureAtlas.UnknownTexturePosition);
                }

                TextureAtlasPosition texpos = capi.BlockTextureAtlas[texturePath];

                if (texpos == null)
                {
                    IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                    if (texAsset != null)
                    {
                        BitmapRef bmp = texAsset.ToBitmap(capi);
                        capi.BlockTextureAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos);
                    }
                    else
                    {
                        capi.World.Logger.Warning("Pie mesh texture {1} not found.", nowTesselatingBlock.Code, texturePath);
                        texpos = capi.BlockTextureAtlas.UnknownTexturePosition;
                    }
                }


                return(texpos);
            }
        }
        protected TextureAtlasPosition getOrCreateTexPos(AssetLocation texturePath)
        {
            var capi = api as ICoreClientAPI;
            TextureAtlasPosition texpos = curAtlas[texturePath];

            if (texpos == null)
            {
                IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                if (texAsset != null)
                {
                    BitmapRef bmp = texAsset.ToBitmap(capi);
                    curAtlas.InsertTextureCached(texturePath, bmp, out _, out texpos, 0.1f);
                }
                else
                {
                    capi.World.Logger.Warning("Item {0} defined texture {1}, not no such texture found.", Code, texturePath);
                }
            }

            return(texpos);
        }
Exemple #16
0
    public void Unlock(bool writePixels)
    {
        if (!m_locked)
        {
            throw new Exception("Bitmap not locked.");
        }

        // Write the color values back to the bitmap
        if (writePixels)
        {
            Marshal.Copy(m_rgbValues, 0, m_bitmapPtr, m_rgbValues.Length);
        }

        // Unlock the bitmap
        BitmapRef.UnlockBits(m_bitmapData);

        //m_rgbValues = null;  // keep this memory around for re-use
        m_bitmapData = null;
        m_bitmapPtr  = (IntPtr)0;

        m_locked = false;
    }
Exemple #17
0
        public override void reloadSkin()
        {
            if (skinTexPos == null)
            {
                GetTextureSource();
            }

            TextureAtlasPosition origTexPos = capi.EntityTextureAtlas.Positions[entity.Properties.Client.FirstTexture.Baked.TextureSubId];

            LoadedTexture entityAtlas = new LoadedTexture(null)
            {
                TextureId = origTexPos.atlasTextureId,
                Width     = capi.EntityTextureAtlas.Size.Width,
                Height    = capi.EntityTextureAtlas.Size.Height
            };

            capi.Render.GlToggleBlend(true, EnumBlendMode.Overlay);

            string componentPath = "characters:textures/entity/skin/";

            string[] skinParts = Enum.GetNames(typeof(EnumSkinPart));
            for (int x = 0; x < skinParts.Length; x++)
            {
                AssetLocation componentLoc;
                string        skinProperty = skinParts[x];
                float         alphaTest    = 0.005f;

                if (skinProperty == "hairtype" || skinProperty == "facialhair")
                {
                    if (entity.WatchedAttributes.GetString(skinProperty, "none") == "none")
                    {
                        continue;
                    }
                }

                switch (skinProperty)
                {
                case "skincolor":
                    componentLoc = new AssetLocation(
                        componentPath +
                        "skins/" +
                        entity.WatchedAttributes.GetString("sex", "male") +
                        "/" +
                        entity.WatchedAttributes.GetString("skincolor", "tan") +
                        ".png"
                        );
                    alphaTest = -1f;
                    break;

                case "eyecolor":
                    componentLoc = new AssetLocation(
                        componentPath +
                        "eyes/" +
                        entity.WatchedAttributes.GetString("eyecolor", "brown") +
                        ".png"
                        );
                    break;

                case "facialhair":
                    componentLoc = new AssetLocation(
                        componentPath +
                        "facialhairs/" +
                        entity.WatchedAttributes.GetString("facialhair", "full") +
                        "-" +
                        entity.WatchedAttributes.GetString("haircolor", "brown") +
                        ".png"
                        );
                    break;

                case "hairtype":
                    componentLoc = new AssetLocation(
                        componentPath +
                        "hairs/" +
                        entity.WatchedAttributes.GetString("hairtype", "m") +
                        "-" +
                        entity.WatchedAttributes.GetString("haircolor", "brown") +
                        ".png"
                        );
                    break;

                default:
                    componentLoc = new AssetLocation(
                        componentPath +
                        "hairs/" +
                        entity.WatchedAttributes.GetString("hairtype", "m") +
                        "-" +
                        entity.WatchedAttributes.GetString("haircolor", "brown") +
                        ".png"
                        );
                    break;
                }

                LoadedTexture componentTexture = new LoadedTexture(capi);
                BitmapRef     bitMap           = capi.Assets.Get(componentLoc).ToBitmap(capi);
                capi.Render.GetOrLoadTexture(componentLoc, bitMap, ref componentTexture);

                capi.Render.GlToggleBlend(false);

                capi.EntityTextureAtlas.RenderTextureIntoAtlas(
                    componentTexture,
                    0,
                    0,
                    128,
                    128,
                    skinTexPos.x1 * capi.EntityTextureAtlas.Size.Width,
                    skinTexPos.y1 * capi.EntityTextureAtlas.Size.Height, alphaTest
                    );

                capi.Render.GlToggleBlend(true, EnumBlendMode.Overlay);
            }

            // Standard

            int[] renderOrder = new int[]
            {
                (int)EnumCharacterDressType.LowerBody,
                (int)EnumCharacterDressType.Foot,
                (int)EnumCharacterDressType.UpperBody,
                (int)EnumCharacterDressType.UpperBodyOver,
                (int)EnumCharacterDressType.Waist,
                (int)EnumCharacterDressType.Shoulder,
                (int)EnumCharacterDressType.Emblem,
                (int)EnumCharacterDressType.Neck,
                (int)EnumCharacterDressType.Head,
                (int)EnumCharacterDressType.Hand,
                (int)EnumCharacterDressType.Arm,
                (int)EnumCharacterDressType.Face
            };

            if (gearInv == null && (eagent != null && eagent.GearInventory != null))
            {
                eagent.GearInventory.SlotModified += gearSlotModified;
                gearInv = eagent.GearInventory;
            }

            if (gearInv == null)
            {
                return;
            }

            for (int i = 0; i < renderOrder.Length; i++)
            {
                int slotid = renderOrder[i];

                if (gearInv[slotid] == null)
                {
                    continue;
                }
                ItemStack stack = gearInv[slotid].Itemstack;
                if (stack == null)
                {
                    continue;
                }

                int itemTextureSubId = stack.Item.FirstTexture.Baked.TextureSubId;

                TextureAtlasPosition itemTexPos = capi.ItemTextureAtlas.Positions[itemTextureSubId];

                LoadedTexture itemAtlas = new LoadedTexture(null)
                {
                    TextureId = itemTexPos.atlasTextureId,
                    Width     = capi.ItemTextureAtlas.Size.Width,
                    Height    = capi.ItemTextureAtlas.Size.Height
                };

                capi.EntityTextureAtlas.RenderTextureIntoAtlas(
                    itemAtlas,
                    itemTexPos.x1 * capi.ItemTextureAtlas.Size.Width,
                    itemTexPos.y1 * capi.ItemTextureAtlas.Size.Height,
                    (itemTexPos.x2 - itemTexPos.x1) * capi.ItemTextureAtlas.Size.Width,
                    (itemTexPos.y2 - itemTexPos.y1) * capi.ItemTextureAtlas.Size.Height,
                    skinTexPos.x1 * capi.EntityTextureAtlas.Size.Width,
                    skinTexPos.y1 * capi.EntityTextureAtlas.Size.Height
                    );
            }

            capi.Render.GlToggleBlend(true);
            capi.Render.BindTexture2d(skinTexPos.atlasTextureId);
            capi.Render.GlGenerateTex2DMipmaps();
        }
Exemple #18
0
        private Shape addGearToShape(ItemSlot slot, Shape entityShape, string shapePathForLogging)
        {
            if (slot.Empty)
            {
                return(entityShape);
            }
            ItemStack  stack   = slot.Itemstack;
            JsonObject attrObj = stack.Collectible.Attributes;

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

            if (!hasArmorExtras)
            {
                // So we don't affect other players models
                Shape newShape = new Shape()
                {
                    Elements               = entityShape.CloneElements(),
                    Animations             = entityShape.Animations,
                    AnimationsByCrc32      = entityShape.AnimationsByCrc32,
                    AttachmentPointsByCode = entityShape.AttachmentPointsByCode,
                    JointsById             = entityShape.JointsById,
                    TextureWidth           = entityShape.TextureWidth,
                    TextureHeight          = entityShape.TextureHeight,
                    TextureSizes           = entityShape.TextureSizes,
                    Textures               = entityShape.Textures,
                };

                newShape.ResolveAndLoadJoints("head");

                entityShape = newShape;
            }

            hasArmorExtras = true;

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

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

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

            if (asset == null)
            {
                capi.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)
            {
                capi.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)
                    {
                        capi.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 {3}. Will not be visible.", compArmorShape.Base, slot.Itemstack.Class, slot.Itemstack.Collectible.Code, val.StepParentName, shapePathForLogging);
                        continue;
                    }
                }
                else
                {
                    capi.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
                    };
                    //ctex.Bake(capi.Assets);

                    /*if (ctex.Baked.BakedVariants != null)
                     * {
                     *  for (int i = 0; i < ctex.Baked.BakedVariants.Length; i++)
                     *  {
                     *      AddTextureLocation(new AssetLocationAndSource(ctex.Baked.BakedVariants[i].BakedName, "Shape file " + clientConf.Shape.Base));
                     *  }
                     *  continue;
                     * }*/

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

                    AssetLocation         armorTexLoc    = val.Value;
                    var                   texturesByLoc  = extraTextureByLocation;
                    var                   texturesByName = extraTexturesByTextureName;
                    BakedCompositeTexture bakedCtex;

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

                        IAsset texAsset = capi.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);
        }
        public override void Initialize(EntityProperties properties, JsonObject attributes)
        {
            base.Initialize(properties, attributes);

            skintree = entity.WatchedAttributes.GetTreeAttribute("skinConfig");
            if (skintree == null)
            {
                entity.WatchedAttributes["skinConfig"] = skintree = new TreeAttribute();
            }

            entity.WatchedAttributes.RegisterModifiedListener("skinConfig", onSkinConfigChanged);

            AvailableSkinParts = properties.Attributes["skinnableParts"].AsObject <SkinnablePart[]>();
            foreach (var val in AvailableSkinParts)
            {
                string partCode = val.Code;
                val.VariantsByCode = new Dictionary <string, SkinnablePartVariant>();

                AvailableSkinPartsByCode[val.Code] = val;

                if (val.Type == EnumSkinnableType.Texture && entity.Api.Side == EnumAppSide.Client)
                {
                    ICoreClientAPI capi = entity.Api as ICoreClientAPI;

                    LoadedTexture texture = new LoadedTexture(capi);
                    foreach (var variant in val.Variants)
                    {
                        AssetLocation textureLoc;

                        if (val.TextureTemplate != null)
                        {
                            textureLoc      = val.TextureTemplate.Clone();
                            textureLoc.Path = textureLoc.Path.Replace("{code}", variant.Code);
                        }
                        else
                        {
                            textureLoc = variant.Texture;
                        }

                        IAsset asset = capi.Assets.TryGet(textureLoc.Clone().WithPathAppendixOnce(".png").WithPathPrefixOnce("textures/"), true);

                        int   r = 0, g = 0, b = 0;
                        float c = 0;

                        BitmapRef bmp = asset.ToBitmap(capi);
                        for (int i = 0; i < 8; i++)
                        {
                            Vec2d vec  = GameMath.R2Sequence2D(i);
                            Color col2 = bmp.GetPixelRel((float)vec.X, (float)vec.Y);
                            if (col2.A > 0.5)
                            {
                                r += col2.R;
                                g += col2.G;
                                b += col2.B;
                                c++;
                            }
                        }

                        bmp.Dispose();

                        c             = Math.Max(1, c);
                        variant.Color = ColorUtil.ColorFromRgba((int)(r / c), (int)(g / c), (int)(b / c), 255);
                        val.VariantsByCode[variant.Code] = variant;
                    }
                }
                else
                {
                    foreach (var variant in val.Variants)
                    {
                        val.VariantsByCode[variant.Code] = variant;
                    }
                }
            }

            if (entity.Api.Side == EnumAppSide.Server && AppliedSkinParts.Count == 0)
            {
                foreach (var val in AvailableSkinParts)
                {
                    string partCode    = val.Code;
                    string variantCode = val.Variants[entity.World.Rand.Next(val.Variants.Length)].Code;
                    selectSkinPart(partCode, variantCode, false);
                }
            }
        }
Exemple #20
0
        public TextureAtlasPosition this[string textureCode]
        {
            get
            {
                AssetLocation texturePath;

                if (textureCode == "ropedcloth" || type == null || type == "")
                {
                    texturePath = new AssetLocation("block/cloth/ropedcloth");
                }
                else
                {
                    texturePath = new AssetLocation("block/cloth/tapestry/" + type);
                }

                AssetLocation cachedPath = texturePath.Clone();

                AssetLocation rotLoc = null;

                if (rotten)
                {
                    rotLoc           = new AssetLocation("block/cloth/tapestryoverlay/rotten" + rotVariant);
                    cachedPath.Path += "++" + rotLoc.Path;
                }

                TextureAtlasPosition texpos = capi.BlockTextureAtlas[cachedPath];

                if (texpos == null)
                {
                    IAsset texAsset = capi.Assets.TryGet(texturePath.Clone().WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"));
                    if (texAsset != null)
                    {
                        BitmapRef bmp = texAsset.ToBitmap(capi);

                        if (rotten)
                        {
                            BakedBitmap bakedBmp = new BakedBitmap()
                            {
                                Width = bmp.Width, Height = bmp.Height
                            };
                            bakedBmp.TexturePixels = bmp.Pixels;

                            int[] texturePixelsOverlay = capi.Assets.TryGet(rotLoc.WithPathPrefixOnce("textures/").WithPathAppendixOnce(".png"))?.ToBitmap(capi)?.Pixels;
                            if (texturePixelsOverlay == null)
                            {
                                throw new Exception("Texture file " + rotLoc + " is missing");
                            }

                            for (int p = 0; p < bakedBmp.TexturePixels.Length; p++)
                            {
                                bakedBmp.TexturePixels[p] = ColorUtil.ColorOver(texturePixelsOverlay[p], bakedBmp.TexturePixels[p]);
                            }

                            capi.BlockTextureAtlas.InsertTextureCached(cachedPath, bakedBmp, out _, out texpos);
                        }
                        else
                        {
                            capi.BlockTextureAtlas.InsertTextureCached(cachedPath, bmp, out _, out texpos);
                        }
                    }
                    else
                    {
                        capi.World.Logger.Warning("Tapestry type '{0}' defined texture '{1}', but no such texture found.", type, texturePath);
                    }
                }

                if (texpos == null)
                {
                    return(capi.BlockTextureAtlas.UnknownTexturePosition);
                }

                return(texpos);
            }
        }