diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..eb28263 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +*.webm filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text +*.gif filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.jpeg filter=lfs diff=lfs merge=lfs -text +*.webp filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index 9b1c8b1..63ee02e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /dist +/scripts/node_modules diff --git a/README.md b/README.md index 23533d1..b7af667 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Replaces the default bed textures with yiff. Supports 1.12+ * [lime](https://e621.net/posts/1976008) * [green](https://e621.net/posts/2416598) * [cyan](https://e621.net/posts/2364029) -* [light_blue](https://e621.net/posts/2397890) +* [light_blue](https://e621.net/posts/2194206) * [blue](https://e621.net/posts/314664) * [purple](https://e621.net/posts/1957635) * [magenta](https://e621.net/posts/1933688) @@ -38,7 +38,7 @@ Replaces the default bed textures with yiff. Supports 1.12+ | Lime | ![Lime](examples/lime.png) | [Source](https://e621.net/posts/1976008) | | Green | ![Green](examples/green.png) | [Source](https://e621.net/posts/2416598) | | Cyan | ![Cyan](examples/cyan.png) | [Source](https://e621.net/posts/2364029) | -| Light Blue | ![Light Blue](examples/light_blue.png) | [Source](https://e621.net/posts/2397890) | +| Light Blue | ![Light Blue](examples/light_blue.png) | [Source](https://e621.net/posts/2194206) | | Blue | ![Blue](examples/blue.png) | [Source](https://e621.net/posts/314664) | | Purple | ![Purple](examples/purple.png) | [Source](https://e621.net/posts/1957635) | | Magenta | ![Magenta](examples/magenta.png) | [Source](https://e621.net/posts/1933688) | diff --git a/base.png b/base.png new file mode 100644 index 0000000..38a6740 --- /dev/null +++ b/base.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:51c5857625be3c9b14017300bfdd8e62c122ba4becfaa8b7a45c3228fa6c0984 +size 12307 diff --git a/common/assets/minecraft/textures/entity/bed/black.png b/common/assets/minecraft/textures/entity/bed/black.png deleted file mode 100644 index 1b9580e..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/black.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/blue.png b/common/assets/minecraft/textures/entity/bed/blue.png deleted file mode 100644 index 95ff6a5..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/blue.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/brown.png b/common/assets/minecraft/textures/entity/bed/brown.png deleted file mode 100644 index 348a05f..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/brown.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/cyan.png b/common/assets/minecraft/textures/entity/bed/cyan.png deleted file mode 100644 index 165eb73..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/cyan.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/gray.png b/common/assets/minecraft/textures/entity/bed/gray.png deleted file mode 100644 index 1ce9ad8..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/gray.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/green.png b/common/assets/minecraft/textures/entity/bed/green.png deleted file mode 100644 index 9ac9d78..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/green.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/light_blue.png b/common/assets/minecraft/textures/entity/bed/light_blue.png deleted file mode 100644 index 99d0167..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/light_blue.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/light_gray.png b/common/assets/minecraft/textures/entity/bed/light_gray.png deleted file mode 100644 index 97c929f..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/light_gray.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/lime.png b/common/assets/minecraft/textures/entity/bed/lime.png deleted file mode 100644 index 13097b1..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/lime.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/magenta.png b/common/assets/minecraft/textures/entity/bed/magenta.png deleted file mode 100644 index ecc0da2..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/magenta.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/orange.png b/common/assets/minecraft/textures/entity/bed/orange.png deleted file mode 100644 index 6d8d234..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/orange.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/pink.png b/common/assets/minecraft/textures/entity/bed/pink.png deleted file mode 100644 index 9013215..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/pink.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/purple.png b/common/assets/minecraft/textures/entity/bed/purple.png deleted file mode 100644 index 862536f..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/purple.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/red.png b/common/assets/minecraft/textures/entity/bed/red.png deleted file mode 100644 index 023c2c4..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/red.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/white.png b/common/assets/minecraft/textures/entity/bed/white.png deleted file mode 100644 index 5d2fb68..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/white.png and /dev/null differ diff --git a/common/assets/minecraft/textures/entity/bed/yellow.png b/common/assets/minecraft/textures/entity/bed/yellow.png deleted file mode 100644 index f24ea42..0000000 Binary files a/common/assets/minecraft/textures/entity/bed/yellow.png and /dev/null differ diff --git a/common/pack.png b/common/pack.png deleted file mode 100644 index 01b4635..0000000 Binary files a/common/pack.png and /dev/null differ diff --git a/crop.png b/crop.png new file mode 100644 index 0000000..fb40288 --- /dev/null +++ b/crop.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5860efb71bdf87f51c1f50e586075a67d029e69585067853f7f1416d007b380 +size 1032 diff --git a/data/assets/minecraft/textures/entity/bed/black.png b/data/assets/minecraft/textures/entity/bed/black.png new file mode 100644 index 0000000..9b36098 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/black.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae69736a9e9087e17fa25047f86589d18f9a8e9b5934b35ca75ed866d0c1c388 +size 1096844 diff --git a/data/assets/minecraft/textures/entity/bed/blue.png b/data/assets/minecraft/textures/entity/bed/blue.png new file mode 100644 index 0000000..42ac78a --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/blue.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e2eba5d191aecc1de9040d95883de3fe232fb2312597edc0b83d0608ec5fef4 +size 1141610 diff --git a/data/assets/minecraft/textures/entity/bed/brown.png b/data/assets/minecraft/textures/entity/bed/brown.png new file mode 100644 index 0000000..120847f --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/brown.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:422cac3a9bbde66b2aabdb7c9c39d045d9a667f267dc2cf37d4e8e4fc77ad361 +size 1356701 diff --git a/data/assets/minecraft/textures/entity/bed/cyan.png b/data/assets/minecraft/textures/entity/bed/cyan.png new file mode 100644 index 0000000..17c6512 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/cyan.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e6a13aaaa9911b33100b231a0de7ecbecc58cd2f16372d3b06fec16a208e6a8 +size 1009365 diff --git a/data/assets/minecraft/textures/entity/bed/gray.png b/data/assets/minecraft/textures/entity/bed/gray.png new file mode 100644 index 0000000..23e42c9 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/gray.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6827b3e6258ab3010163e7e76a116780fb03fc07887975319042d6812c7344ce +size 776351 diff --git a/data/assets/minecraft/textures/entity/bed/green.png b/data/assets/minecraft/textures/entity/bed/green.png new file mode 100644 index 0000000..5d1a906 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/green.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c78ea63373ac3ac727c6c77d55a5504edc4d0f683fc40e5a60bbfad87ca93038 +size 1207743 diff --git a/data/assets/minecraft/textures/entity/bed/light_blue.png b/data/assets/minecraft/textures/entity/bed/light_blue.png new file mode 100644 index 0000000..0285d92 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/light_blue.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c29ab28546d5681df695298ed78886462bfba0c4b0af73f392e80803f3ca2a69 +size 810106 diff --git a/data/assets/minecraft/textures/entity/bed/light_gray.png b/data/assets/minecraft/textures/entity/bed/light_gray.png new file mode 100644 index 0000000..10081df --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/light_gray.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e62ad39b05ffa0fa8adf1e002279c5b49e9138680a0511422c69657f565b91ea +size 1389418 diff --git a/data/assets/minecraft/textures/entity/bed/lime.png b/data/assets/minecraft/textures/entity/bed/lime.png new file mode 100644 index 0000000..0ac4e9f --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/lime.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62c7d8436d4d56750350e760851ccff84440a2562eeb5a8282d1cf538276dce2 +size 1396086 diff --git a/data/assets/minecraft/textures/entity/bed/magenta.png b/data/assets/minecraft/textures/entity/bed/magenta.png new file mode 100644 index 0000000..1d35a79 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/magenta.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4908273de4258da7773e8bc7fe647b23d295fa6662b8e4d7674f64e3b5406d79 +size 1372200 diff --git a/data/assets/minecraft/textures/entity/bed/orange.png b/data/assets/minecraft/textures/entity/bed/orange.png new file mode 100644 index 0000000..73edb55 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/orange.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0dc5395a64ca16ff47ab86cfd3d88322135956b46ca3c00c32498bbd6e3bf31 +size 1658221 diff --git a/data/assets/minecraft/textures/entity/bed/pink.png b/data/assets/minecraft/textures/entity/bed/pink.png new file mode 100644 index 0000000..4f5f653 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/pink.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e22537af853f0355ec23ce2c413138bed214ba8b0b2dfb1c4594033e6d233d1f +size 1175861 diff --git a/data/assets/minecraft/textures/entity/bed/purple.png b/data/assets/minecraft/textures/entity/bed/purple.png new file mode 100644 index 0000000..6b7b0f9 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/purple.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7feed36dcfa8dcc4ff082bd78ae54ca80bfd9ca5e617c67b2b83a03ac4b10bbb +size 1191358 diff --git a/data/assets/minecraft/textures/entity/bed/red.png b/data/assets/minecraft/textures/entity/bed/red.png new file mode 100644 index 0000000..70d4426 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/red.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd5286b3ad84f5fec58b6b430b7070f31915b30151165b4810aa4e6ee2ba0ae9 +size 1098229 diff --git a/data/assets/minecraft/textures/entity/bed/white.png b/data/assets/minecraft/textures/entity/bed/white.png new file mode 100644 index 0000000..eb413fe --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/white.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bbacef20ab551530fcf7f1b0c6b2b311df3ac871d5e2f4675342dcb2353c2b0 +size 1247345 diff --git a/data/assets/minecraft/textures/entity/bed/yellow.png b/data/assets/minecraft/textures/entity/bed/yellow.png new file mode 100644 index 0000000..2584cc5 --- /dev/null +++ b/data/assets/minecraft/textures/entity/bed/yellow.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:574fe8cf1eb9b3887ac508ab8385f349381587aebdda925015e283314d3efe26 +size 2052578 diff --git a/data/pack.png b/data/pack.png new file mode 100644 index 0000000..ede9ad5 --- /dev/null +++ b/data/pack.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90b97190b34b041a8ec3c642b98eba365db282267a00b2d78fa3b870d49a29ad +size 305055 diff --git a/examples/all.png b/examples/all.png index 07b4f17..ee75460 100644 Binary files a/examples/all.png and b/examples/all.png differ diff --git a/examples/black.png b/examples/black.png index c79352a..9b7bada 100644 Binary files a/examples/black.png and b/examples/black.png differ diff --git a/examples/blue.png b/examples/blue.png index 9161790..fb996e4 100644 Binary files a/examples/blue.png and b/examples/blue.png differ diff --git a/examples/brown.png b/examples/brown.png index 7d59937..20908a8 100644 Binary files a/examples/brown.png and b/examples/brown.png differ diff --git a/examples/cyan.png b/examples/cyan.png index ee07409..010408b 100644 Binary files a/examples/cyan.png and b/examples/cyan.png differ diff --git a/examples/gray.png b/examples/gray.png index d48978f..98eec3e 100644 Binary files a/examples/gray.png and b/examples/gray.png differ diff --git a/examples/green.png b/examples/green.png index f57f337..67de20a 100644 Binary files a/examples/green.png and b/examples/green.png differ diff --git a/examples/light_blue.png b/examples/light_blue.png index ed16d56..61577de 100644 Binary files a/examples/light_blue.png and b/examples/light_blue.png differ diff --git a/examples/light_gray.png b/examples/light_gray.png index f8a15c1..c6029e6 100644 Binary files a/examples/light_gray.png and b/examples/light_gray.png differ diff --git a/examples/lime.png b/examples/lime.png index e4fc24b..6b5b25c 100644 Binary files a/examples/lime.png and b/examples/lime.png differ diff --git a/examples/megenta.png b/examples/megenta.png index 6def8dc..8437fc7 100644 Binary files a/examples/megenta.png and b/examples/megenta.png differ diff --git a/examples/orange.png b/examples/orange.png index 1bd80f2..f7a65bc 100644 Binary files a/examples/orange.png and b/examples/orange.png differ diff --git a/examples/pink.png b/examples/pink.png index e9966ea..69c0f90 100644 Binary files a/examples/pink.png and b/examples/pink.png differ diff --git a/examples/purple.png b/examples/purple.png index 89293b3..e3abfb5 100644 Binary files a/examples/purple.png and b/examples/purple.png differ diff --git a/examples/red.png b/examples/red.png index 5be36ff..c6ab71d 100644 Binary files a/examples/red.png and b/examples/red.png differ diff --git a/examples/white.png b/examples/white.png index 869902b..a798655 100644 Binary files a/examples/white.png and b/examples/white.png differ diff --git a/examples/yellow.png b/examples/yellow.png index df71c6e..6423436 100644 Binary files a/examples/yellow.png and b/examples/yellow.png differ diff --git a/images/black.png b/images/black.png new file mode 100644 index 0000000..6ee0b37 --- /dev/null +++ b/images/black.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:950f23c9f1f2767c72924ae3c6b5bd923131b4e4b02fbb6e910adbdc0d98d991 +size 547045 diff --git a/images/blue.png b/images/blue.png new file mode 100644 index 0000000..4d38b56 --- /dev/null +++ b/images/blue.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fc7c6bf63d7602d77224a3c16acad0ee57b786f01abc2d795089832a420f360 +size 608743 diff --git a/images/brown.jpg b/images/brown.jpg new file mode 100644 index 0000000..11b12cb --- /dev/null +++ b/images/brown.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0cfd537654756ba8d6b7d653218133912797f2e2a4851c8e99a20e5832e4a108 +size 354959 diff --git a/images/cyan.png b/images/cyan.png new file mode 100644 index 0000000..8e69084 --- /dev/null +++ b/images/cyan.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53e2f1c8b74f99f042dd4767182c6dcc00a4d54fcc1c9943a3f170e98c66211a +size 5482756 diff --git a/images/gray.png b/images/gray.png new file mode 100644 index 0000000..479dfcd --- /dev/null +++ b/images/gray.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:396f19577cd05af2a5b1834f7cc4451525ac4f0d007b6af501b84c01e738b65b +size 771510 diff --git a/images/green.png b/images/green.png new file mode 100644 index 0000000..d841bfc --- /dev/null +++ b/images/green.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c21b0be320878d405b19f1b32333cbeed3659b7fabb94868182144419cb3689 +size 4513309 diff --git a/images/images.json b/images/images.json new file mode 100644 index 0000000..3bbb7a7 --- /dev/null +++ b/images/images.json @@ -0,0 +1,91 @@ +{ + "defaultSize": [512, 512], + "details": { + "top": { + "pos": [10, 117], + "size": [204, 59], + "cut": [0, 0] + }, + "middle": { + "pos": [10, 224], + "size": [204, 128], + "cut": [0, 59] + }, + "bottom": { + "pos": [176, 186], + "size": [128, 38], + "cut": [38, 187], + "flip": "horizontal" + } + }, + "images": [ + { + "name": "black", + "sizeMultiplier": 4 + }, + { + "name": "blue", + "sizeMultiplier": 4, + "rotate": -90 + }, + { + "name": "brown", + "sizeMultiplier": 4 + }, + { + "name": "cyan", + "sizeMultiplier": 4 + }, + { + "name": "gray", + "sizeMultiplier": 4 + }, + { + "name": "green", + "sizeMultiplier": 4 + }, + { + "name": "light_blue", + "sizeMultiplier": 4 + }, + { + "name": "light_gray", + "sizeMultiplier": 4 + }, + { + "name": "lime", + "sizeMultiplier": 4 + }, + { + "name": "magenta", + "sizeMultiplier": 4, + "rotate": -90, + "flip": "horizontal" + }, + { + "name": "orange", + "sizeMultiplier": 4, + "rotate": -90 + }, + { + "name": "pink", + "sizeMultiplier": 4 + }, + { + "name": "purple", + "sizeMultiplier": 4 + }, + { + "name": "red", + "sizeMultiplier": 4 + }, + { + "name": "white", + "sizeMultiplier": 4 + }, + { + "name": "yellow", + "sizeMultiplier": 4 + } + ] +} diff --git a/images/light_blue.png b/images/light_blue.png new file mode 100644 index 0000000..06b4d83 --- /dev/null +++ b/images/light_blue.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:546ea2c4ea941629f2f20e026e775c5f835c2e0a947b477aef3ff03b33df7cd5 +size 1415245 diff --git a/images/light_gray.jpg b/images/light_gray.jpg new file mode 100644 index 0000000..bb1f2a6 --- /dev/null +++ b/images/light_gray.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:beea33696d7f768c616a9c0668950ccdc59f3a135e0f660598cdfbf7539b4f65 +size 785319 diff --git a/images/lime.png b/images/lime.png new file mode 100644 index 0000000..fbba230 --- /dev/null +++ b/images/lime.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c75a4581f5640da5678ded032fb7e2a089eca796dbd26a1865f22aba794c18b1 +size 4226915 diff --git a/images/magenta.png b/images/magenta.png new file mode 100644 index 0000000..acf574d --- /dev/null +++ b/images/magenta.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2367b1c4deeadae3d4e13bf70d0d7906655499468f0a508a279dcdcef68ca189 +size 2188246 diff --git a/images/orange.jpg b/images/orange.jpg new file mode 100644 index 0000000..7ab9b68 --- /dev/null +++ b/images/orange.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0730b2089d53219984806bfd925c67edd2638a03fd067b9a61653888f58c5124 +size 199293 diff --git a/images/pink.png b/images/pink.png new file mode 100644 index 0000000..c1c21f0 --- /dev/null +++ b/images/pink.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7da73450d2a2eb009481fef88786bf009c6de4c33947b7b31fd9c47e82fc93d7 +size 1056794 diff --git a/images/purple.png b/images/purple.png new file mode 100644 index 0000000..741e8bb --- /dev/null +++ b/images/purple.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:30001c0cdfdb30d4364aa0186b14ac9e124696348b700cbb854a6e2afbce2b5e +size 985772 diff --git a/images/red.jpg b/images/red.jpg new file mode 100644 index 0000000..437be7b --- /dev/null +++ b/images/red.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0b1059e69f723f88dc64f7416d6df73c121a2b386d22708833d3e7c5808ef4c +size 376004 diff --git a/images/test.json b/images/test.json new file mode 100644 index 0000000..b4401d9 --- /dev/null +++ b/images/test.json @@ -0,0 +1,29 @@ +{ + "defaultSize": [512, 512], + "details": { + "top": { + "pos": [10, 117], + "size": [204, 59], + "cut": [0, 0] + }, + "middle": { + "pos": [10, 224], + "size": [204, 128], + "cut": [0, 59] + }, + "bottom": { + "pos": [176, 186], + "size": [128, 38], + "cut": [38, 187], + "flip": "horizontal" + } + }, + "images": [ + { + "name": "animated" + }, + { + "name": "orange" + } + ] +} diff --git a/images/white.png b/images/white.png new file mode 100644 index 0000000..3695e0f --- /dev/null +++ b/images/white.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01abe61c996a5bacc6a8dfab25de56280598899144c681ea5e0072e92b050c3e +size 824299 diff --git a/images/yellow.png b/images/yellow.png new file mode 100644 index 0000000..297a46e --- /dev/null +++ b/images/yellow.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9852ad149a2560d9e0572d06fcc61778a7a215c49bdfdf235e5620741b147d41 +size 4648427 diff --git a/info.json b/info.json index 78e33c9..5452275 100644 --- a/info.json +++ b/info.json @@ -3,19 +3,20 @@ "description": "Replaces bed textures with furry porn.", "url": "https://git.furry.cool/MCFurryPacks/YiffyBeds", "versions": [ - ["1.12", 3], - ["1.13", 4], - ["1.15", 5], - ["1.16", 6], - ["1.17", 7], - ["1.18", 8], - ["1.19", 9], + ["1.12", 3], + ["1.13", 4], + ["1.15", 5], + ["1.16", 6], + ["1.17", 7], + ["1.18", 8], + ["1.19", 9], ["1.19.3", 12], ["1.19.4", 13], - ["1.20", 15], + ["1.20", 15], ["1.20.2", 18], ["1.20.3", 26], - ["1.20.5", 32] + ["1.20.5", 32], + ["1.21", 34] ], "exports": [] } diff --git a/scripts/.eslintrc.json b/scripts/.eslintrc.json new file mode 100644 index 0000000..a78a956 --- /dev/null +++ b/scripts/.eslintrc.json @@ -0,0 +1,8 @@ +{ + "extends": ["@uwu-codes/eslint-config/esm"], + "rules": { + "unicorn/prevent-abbreviations": "off", + "unicorn/no-process-exit": "off", + "unicorn/import-style": "off" + } +} diff --git a/scripts/bun.lockb b/scripts/bun.lockb new file mode 100755 index 0000000..cb3b806 Binary files /dev/null and b/scripts/bun.lockb differ diff --git a/scripts/common.ts b/scripts/common.ts new file mode 100644 index 0000000..8076ad0 --- /dev/null +++ b/scripts/common.ts @@ -0,0 +1,292 @@ +import { randomBytes } from "crypto"; +import { fileTypeFromBuffer } from "file-type"; +import Ffmpeg from "fluent-ffmpeg"; +import { rm } from "fs/promises"; +import { readdir } from "fs/promises"; +import { mkdtemp } from "fs/promises"; +import { tmpdir } from "os"; +import { basename } from "path"; +import sharp, { type OverlayOptions, type Sharp } from "sharp"; +import type { Config, Detail, Image } from "./images"; + +async function makeComposite(image: string | Buffer, details: Detail, sizeMultiplier: number, offset = 0) { + let img = await sharp(image) + .extract({ + top: details.cut[1] * sizeMultiplier, + left: details.cut[0] * sizeMultiplier, + width: details.size[0] * sizeMultiplier, + height: details.size[1] * sizeMultiplier + }).toBuffer(); + if (details.rotate) { + img = await sharp(img).rotate(details.rotate).toBuffer(); + } + if (details.flip) { + img = await sharp(img).flip(details.flip === "horizontal").flop(details.flip === "vertical").toBuffer(); + } + return { + input: img, + top: (details.pos[1] * sizeMultiplier) + offset, + left: details.pos[0] * sizeMultiplier + } +} + +async function applyOptions(image: string | Buffer, options: Image, width: number, height: number) { + let img = await sharp(image).toBuffer() + if (options.rotate) { + img = await sharp(img).rotate(options.rotate).toBuffer(); + } + if (options.flip) { + img = await sharp(img).flip(options.flip === "horizontal").flop(options.flip === "vertical").toBuffer(); + } + img = await sharp(img).resize(width, height, { fit: "fill" }).toBuffer(); + return img; +} + +export async function formatImage(name: string, baseFile: string, config: Config, image: string | string[]) { + const options = config.images.find(img => img.name === name)!; + const isImage = !Array.isArray(image) && ["image/png", "image/jpeg"].includes((await fileTypeFromBuffer(Buffer.isBuffer(image) ? image : await Bun.file(image).arrayBuffer()))!.mime); + let result: Sharp; + const multplier = options.sizeMultiplier ?? 1; + const cropWidth = Math.max(config.details.top.size[0], config.details.middle.size[0], config.details.bottom.size[0]) * multplier, + cropHeight = (config.details.top.size[1] + config.details.middle.size[1] + config.details.bottom.size[1]) * multplier, + fullWidth = Math.floor(config.defaultSize[0] * multplier), + fullHeight = Math.floor(config.defaultSize[1] * multplier); + const base = sharp(baseFile); + if (multplier !== 1) { + base.resize(fullWidth, fullHeight, { + kernel: sharp.kernel.nearest + }); + } + const baseBuf = await base.toBuffer(); + if (isImage) { + const img = await applyOptions(image, options, cropWidth, cropHeight); + result = await sharp(baseBuf) + .composite([ + await makeComposite(img, config.details.top, multplier), + await makeComposite(img, config.details.middle, multplier), + await makeComposite(img, config.details.bottom, multplier) + ]); + } else { + let tmpDir: string | undefined; + + let files: string[] = []; + tmpDir = await mkdtemp(`${tmpdir()}/split-frames-`); + if (!Array.isArray(image)) { + let select = ""; + if (Array.isArray(options.frames)) { + select = options.frames.map(f => `eq(n\\,${f})`).join("+"); + } else if (options.frames) { + select = `gte(n\\, ${options.frames.start})${options.frames.end ? `*lte(n\\,${options.frames.end}` : ""})`; + } else { + select = "n"; + } + console.debug("Input file %s is not an image, assuming we need to extract frames.", name); + await new Promise((resolve) => { + Ffmpeg(image) + .videoFilter(`scale=${cropWidth}:${cropHeight},select='${select}'`) + .addOption("-vsync vfr") + .output(`${tmpDir}/frame%04d.png`) + .on("end", async() => { + files = (await readdir(tmpDir!)).filter(f => /frame\d+\.png/.test(f)).sort().map(f => `${tmpDir}/${f}`); + if (files.length === 0) { + console.error("No frames extracted for %s.", name); + if (tmpDir) { + await rm(tmpDir, { recursive: true }); + } + process.exit(1); + } + console.log("Frames extracted to %s, %d total for %s", tmpDir, files.length, name); + resolve(); + }) + .on("error", async(err) => { + if (tmpDir) { + await rm(tmpDir, { recursive: true }); + } + console.error("Failed to extract frames for %s.", name); + console.error(err); + process.exit(1); + }) + .run() + }); + } else { + for (const img of image) { + await sharp(await applyOptions(img, options, cropWidth, cropHeight)).toFile(`${tmpDir}/${basename(img)}`); + } + files = image.map(f => `${tmpDir}/${basename(f)}`).sort(); + } + + const parts: OverlayOptions[] = []; + for (const img of files) { + const i = files.indexOf(img); + console.log("Processing %s (%d/%d) for %s", img, i + 1, files.length, name); + parts.push( + { input: baseBuf, top: fullHeight * i, left: 0 }, + await makeComposite(img, config.details.top, multplier, fullHeight * i), + await makeComposite(img, config.details.middle, multplier, fullHeight * i), + await makeComposite(img, config.details.bottom, multplier, fullHeight * i) + ); + } + + result = await sharp({ + create: { + width: fullWidth, + height: fullHeight * files.length, + channels: 4, + background: { r: 0, g: 0, b: 0, alpha: 0 } + }, + limitInputPixels: false + }) + .composite(parts) + if (tmpDir) { + await rm(tmpDir, { recursive: true }); + } + } + return { isImage, result: result! }; +} + +const frameSizePercent = 0.1; +async function createFrame(colors: number[], percent: number, width: number, height: number) { + let frameW = width, frameH = height, i = 0; + const parts: OverlayOptions[] = []; + const frameVH = Math.floor(Math.min(width, height) * percent); + while (frameW > 0) { + if (i > colors.length - 1) { + i = 0; + } + const color = colors[i], r = (color >> 16) & 0xFF, g = (color >> 8) & 0xFF, b = color & 0xFF, + w = width * frameSizePercent, h = frameVH; + parts.push({ + input: { + create: { + width: w, + height: h, + channels: 4, + background: { r, g, b, alpha: 255 } + } + }, + top: 0, + // left to right + left: i * w + }, + { + input: { + create: { + width: w, + height: h, + channels: 4, + background: { r, g, b, alpha: 255 } + } + }, + top: frameH - h, + // right to left + left: width - (i + 1) * w + }); + frameW -= w; + i += 1; + } + i = 0; + colors = colors.toReversed(); + while (frameH > 0) { + if (i > colors.length - 1) { + i = 0; + } + const color = colors[i], r = (color >> 16) & 0xFF, g = (color >> 8) & 0xFF, b = color & 0xFF, + w = frameVH, h = height * frameSizePercent; + parts.push({ + input: { + create: { + width: w, + height: h, + channels: 4, + background: { r, g, b, alpha: 255 } + } + }, + top: i * h, + // top to bottom + left: 0 + }, + { + input: { + create: { + width: w, + height: h, + channels: 4, + background: { r, g, b, alpha: 255 } + } + }, + top: height - (i + 1) * h, + // bottom to top + left: width - w + }); + frameH -= h; + i += 1; + } + return sharp({ + create: { + width, + height, + channels: 4, + background: { r: 0, g: 0, b: 0, alpha: 0 } + }, + limitInputPixels: false + }).composite(parts).png().toBuffer(); +} + +export const rgb = (hex: number) => ({ r: (hex >> 16) & 0xFF, g: (hex >> 8) & 0xFF, b: hex & 0xFF }); +const kzBorderColor = rgb(0x6B3F7F) +const kzFillColor = rgb(0xD67FFF); +const plankSize = 4; +// the things I do to not have to make this a file +const plank = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH6AUfFCAKmCc95gAAATJJREFUKM9lUsFqwzAMlSXFXRYIYQRy6GX/tq/Zh/ZQGKUEOi9WpOyg1jWpL1Gen+X3/BS+vz6TCDxW2zQAoGZZ1et6JRF0UiSab1skUrMkklV9O4k4omZ+hv2TVfsuOC8SAQAh+paazbdtGu6/fLos9wrD4+a1aFht8+J0WZzAx4/Dq4ck0jZNEgEI820b+7sQQmRnF1TNXIyaubaxB5cKAKDK3rIdntTiyhtNQ2wrnM/XXGvd+Vlt25nkaYg19XzNfRdKGkV6yYFrxwAwDVHNPDhHXFWhcds0u05PiwCRaOyfD5BV+XzNq22urzjZZVLjew9VAlDdwz/z6kz0UfG3KsGVAStK+i74RDEhtojQiXetJ5QQk0gkotccAIBCWNQAlgPhosaYH1HI75+9v6F7+AdOcdbDy169/gAAAABJRU5ErkJggg==", "base64"); +export async function makeKZ(squareSize: number, gridSize = 16) { + const kzBorderSize = squareSize * 0.0625; + const kzPlank = await sharp(plank).resize(squareSize, squareSize).toBuffer(); + const plankStart = gridSize - plankSize; + const kzParts: OverlayOptions[] = []; + // i = top to bottom + // j = left to right + for (let i = 0; i < gridSize; i++) { + for (let j = 0; j < gridSize; j++) { + if (i < plankSize && j >= plankStart) { + kzParts.push({ + input: kzPlank, + top: squareSize * i, + left: squareSize * j + }); + } else { + kzParts.push({ + input: { + create: { + width: kzBorderSize, + height: squareSize, + channels: 3, + background: kzBorderColor + } + }, + top: squareSize * i, + left: squareSize * j + },{ + input: { + create: { + width: squareSize, + height: kzBorderSize, + channels: 3, + background: kzBorderColor + } + }, + top: squareSize * i, + left: squareSize * j + }); + } + } + } + return sharp({ + create: { + width: squareSize * 16, + height: squareSize * 16, + channels: 3, + background: kzFillColor + }, + limitInputPixels: false + }).composite(kzParts).png().toBuffer(); +} diff --git a/scripts/images.ts b/scripts/images.ts new file mode 100644 index 0000000..3263d38 --- /dev/null +++ b/scripts/images.ts @@ -0,0 +1,117 @@ +import type { PathLike } from "fs"; +import { access } from "fs/promises"; +import { dirname, resolve } from "path"; +import sharp, { type OverlayOptions } from "sharp"; +import { parseArgs } from "util"; +import { formatImage, makeKZ } from "./common"; +import { readFile } from "fs/promises"; +import { writeFile } from "fs/promises"; +import { rm } from "fs/promises"; +import { mkdir } from "fs/promises"; +import { stat } from "fs/promises"; +import { readdir } from "fs/promises"; + +const { values: args } = parseArgs({ + args: Bun.argv, + options: { + images: { + type: "string", + short: "i", + default: "images/images.json" + }, + imagedir: { + type: "string", + short: "d", + default: "images" + }, + outdir: { + type: "string", + short: "o", + default: "data" + }, + basefile: { + type: "string", + short: "b", + default: "base.png" + }, + throw: { + type: "boolean", + short: "t", + default: false + } + }, + strict: true, + allowPositionals: true +}); + +const dirExists = async(path: PathLike) => access(path).then(() => true, () => false); +const imagesPath = resolve(args.images ?? "images.json"); +const imageDir = resolve(args.imagedir ?? dirname(imagesPath)); +const baseFile = resolve(args.basefile ?? "base.png"); +const outDir = resolve(args.outdir ?? "data"); +const throwOnMissing = !!args.throw; +if (!await dirExists(imageDir)) { + console.error("Image directory %s does not exist.", imageDir); + process.exit(1); +} + +const ap = (p: string) => resolve(p, "assets/minecraft/textures/entity/bed"); +// const ap = (p: string) => resolve(p, "../img"); +await rm(`${outDir}/assets`, { recursive: true, force: true }); +await mkdir(ap(outDir), { recursive: true }); + +export interface Image { + animation?: { frametime?: number; }; + frames?: { start: number; end?: number; } | Array; + name: string; + sizeMultiplier?: number; + rotate?: number; + flip?: "horizontal" | "vertical"; +} + +export interface Detail { + pos: [number, number]; + size: [number, number]; + cut: [number, number]; + rotate?: number; + flip?: "horizontal" | "vertical"; +} + + +export interface Details { + top: Detail; + middle: Detail; + bottom: Detail; +} + +export interface Config { + defaultSize: [width: number, height: number]; + details: Details; + images: Array; +} + +const config = await Bun.file(imagesPath).json() as Config; + +for (const image of config.images) { + let img: string | Array; + if (await stat(`${imageDir}/${image.name}`).then(s => s.isDirectory(), () => false)) { + img = await readdir(`${imageDir}/${image.name}`).then(files => files.map(f => `${imageDir}/${image.name}/${f}`).sort()); + } else { + const [file] = await Array.fromAsync(new Bun.Glob(`${image.name}.*`).scan({ onlyFiles: true, cwd: imageDir })); + if (!file) { + console.error("Image %s does not exist.", image.name); + if (throwOnMissing) { + process.exit(1); + } + continue; + } + img = `${imageDir}/${file}` + } + console.log("Processing %s", image.name); + + const { isImage, result } = await formatImage(image.name, baseFile, config, img); + await result.toFile(`${ap(outDir)}/${image.name}.png`); + if (!isImage) { + await writeFile(`${ap(outDir)}/${image.name}.png.mcmeta`, JSON.stringify({ animation: image.animation ?? {} })); + } +} diff --git a/scripts/package.json b/scripts/package.json new file mode 100644 index 0000000..0e55735 --- /dev/null +++ b/scripts/package.json @@ -0,0 +1,26 @@ +{ + "name": "image-maker", + "module": "index.ts", + "type": "module", + "devDependencies": { + "@types/bun": "latest", + "@types/fluent-ffmpeg": "^2.1.24", + "@types/node": "^20.12.13", + "@uwu-codes/eslint-config": "^1.1.28", + "eslint": "^9.3.0" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "file-type": "^19.0.0", + "fluent-ffmpeg": "^2.1.3", + "sharp": "^0.33.4" + }, + "scripts": { + "compile": "bun build ./images.ts --compile --outfile bin/make-images" + }, + "bin": { + "make-images": "./images.ts" + } +} diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json new file mode 100644 index 0000000..dcd8fc5 --- /dev/null +++ b/scripts/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + /* Linting */ + "skipLibCheck": true, + "strict": true, + "noFallthroughCasesInSwitch": true, + "forceConsistentCasingInFileNames": true + } +}