/// <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); }
public static void Image(this ImageSurface surface, BitmapRef bmp, int xPos, int yPos, int width, int height) { surface.Image(((BitmapExternal)bmp).bmp, xPos, yPos, width, height); }
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); }