diff --git a/build.gradle b/build.gradle index f8f01b0..1082b8c 100644 --- a/build.gradle +++ b/build.gradle @@ -3916,11 +3916,15 @@ project(":onlyfun") { "src/main/java/fr/koka99cab/sanctuary26/onlyfun/world/CobbleDungeonStructure.java").text def dungeonStructureSet = new JsonSlurper().parse(file( "src/main/resources/data/onlyfun/worldgen/structure_set/cobble_dungeons.json")) - def expectedItems = ["normal_lootbox", "cape_lootbox", "spawn_egg_lootbox", "anomaly_lootbox", "lucky_block", "nourra_firework"] + def fireworkIds = ["nourra", "chrism", "kaninscheun", "poupoutain", "lbeast", + "creveforest", "sacdchips", "vaselline", "duncan"] + def expectedItems = ["normal_lootbox", "cape_lootbox", "spawn_egg_lootbox", "anomaly_lootbox", "lucky_block"] + + fireworkIds.collect { "${it}_firework" } def missingModels = expectedItems.findAll { id -> !file("src/main/resources/assets/onlyfun/items/${id}.json").exists() } - def textureIds = ["normal_lootbox", "cape_lootbox", "spawn_egg_lootbox", "anomaly_lootbox", "nourra_firework"] + def textureIds = ["normal_lootbox", "cape_lootbox", "spawn_egg_lootbox", "anomaly_lootbox"] + + fireworkIds.collect { "${it}_firework" } def invalidTextures = textureIds.findAll { id -> def texture = file("src/main/resources/assets/onlyfun/textures/item/${id}.png") if (!texture.isFile()) return true @@ -4138,41 +4142,53 @@ project(":onlyfun") { || !shopCsvText.contains("TRUE,ITEM,iliketomoveit:magic_cloud,1,3072,192,") || !javaText.contains("MAGIC_CLOUD, MAGIC_CARPET") || !file("src/main/resources/assets/onlyfun/models/block/lucky_block.json").text.contains("onlyfun:block/lucky_block") - || !javaText.contains("class NourraFireworkItem extends FireworkRocketItem") - || !javaText.contains("class SkinFaceFireworkExplosions") - || !javaText.contains("FACE = {") - || !javaText.contains("HOOD = {") - || !javaText.contains("HOOD_TOP = {") - || !javaText.contains("0x4A9DFC") - || !javaText.contains("TRANSPARENT") - || !javaText.contains("class SkinFaceFireworkClient") - || !javaText.contains("DustParticleOptions") - || !javaText.contains("PIXEL = 1.85D") - || !javaText.contains("LARGE_PIXEL = 2.7D") - || !javaText.contains("LARGE_SPARK_SIZE = 5.15F") - || !javaText.contains("SPARK_LIFETIME_TICKS = 38") - || !javaText.contains("new Fireworks(3, List.of())") - || !javaText.contains("LIFETIME_TRIM_TICKS = 5") - || !javaText.contains("onlyfun\$midFlightLifetime") - || !javaText.contains("onlyfun\$drawSkinFace") - || !javaText.contains("output.accept(OnlyFunRegistries.NOURRA_FIREWORK)") - || !file("src/main/resources/onlyfun.mixins.json").text.contains("FireworkRocketLifetimeMixin") - || !file("src/main/resources/onlyfun.client.mixins.json").text.contains("FireworkRocketEntityMixin") - || !file("src/main/resources/onlyfun.client.mixins.json").text.contains("ParticleLifetimeAccessor") - || !file("src/main/resources/fabric.mod.json").text.contains("onlyfun.mixins.json") - || !file("src/main/resources/fabric.mod.json").text.contains("onlyfun.client.mixins.json") - || !file("src/main/resources/data/onlyfun/recipe/nourra_firework.json").text.contains("onlyfun:nourra_firework") - || ["fr_fr", "en_us", "ru_ru"].any { locale -> - def translations = new JsonSlurper().parse(file( - "src/main/resources/assets/onlyfun/lang/${locale}.json")) - !translations.containsKey("item.onlyfun.nourra_firework") - || !translations.containsKey("tooltip.onlyfun.nourra_firework") - } || !missingModels.isEmpty() || !invalidTextureHashes.isEmpty() || !invalidTextures.isEmpty()) { throw new GradleException("Only Fun natural-distribution contract is incomplete: models=${missingModels}, textures=${invalidTextures}, hashes=${invalidTextureHashes}") } + def fireworkFailures = [] + if (!javaText.contains("class SkinFaceFireworkItem extends FireworkRocketItem")) fireworkFailures << "SkinFaceFireworkItem" + if (!javaText.contains("enum SkinFacePortrait")) fireworkFailures << "SkinFacePortrait" + if (!javaText.contains("class SkinFaceFireworkExplosions")) fireworkFailures << "SkinFaceFireworkExplosions" + if (!javaText.contains("CHRISM(")) fireworkFailures << "CHRISM" + if (!javaText.contains("DUNCAN(")) fireworkFailures << "DUNCAN" + if (!javaText.contains("0x4A9DFC")) fireworkFailures << "nourraEyes" + if (!javaText.contains("TRANSPARENT")) fireworkFailures << "TRANSPARENT" + if (!javaText.contains("class SkinFaceFireworkClient")) fireworkFailures << "client" + if (!javaText.contains("DustParticleOptions")) fireworkFailures << "dust" + if (!javaText.contains("PIXEL = 1.85D")) fireworkFailures << "pixel" + if (!javaText.contains("LARGE_PIXEL = 2.7D")) fireworkFailures << "largePixel" + if (!javaText.contains("LARGE_SPARK_SIZE = 5.15F")) fireworkFailures << "largeSpark" + if (!javaText.contains("SPARK_LIFETIME_TICKS = 38")) fireworkFailures << "lifetime" + if (!javaText.contains("new Fireworks(3, List.of())")) fireworkFailures << "fireworks" + if (!javaText.contains("LIFETIME_TRIM_TICKS = 5")) fireworkFailures << "trim" + if (!javaText.contains("onlyfun\$midFlightLifetime")) fireworkFailures << "midFlight" + if (!javaText.contains("onlyfun\$drawSkinFace")) fireworkFailures << "drawSkinFace" + if (!javaText.contains("OnlyFunRegistries.skinFireworks()")) fireworkFailures << "tab" + if (!file("src/main/resources/onlyfun.mixins.json").text.contains("FireworkRocketLifetimeMixin")) fireworkFailures << "commonMixin" + if (!file("src/main/resources/onlyfun.client.mixins.json").text.contains("FireworkRocketEntityMixin")) fireworkFailures << "clientMixin" + if (!file("src/main/resources/onlyfun.client.mixins.json").text.contains("ParticleLifetimeAccessor")) fireworkFailures << "particleAccessor" + if (!file("src/main/resources/fabric.mod.json").text.contains("onlyfun.mixins.json")) fireworkFailures << "fabricCommon" + if (!file("src/main/resources/fabric.mod.json").text.contains("onlyfun.client.mixins.json")) fireworkFailures << "fabricClient" + fireworkIds.each { fireworkId -> + if (!file("src/main/resources/data/onlyfun/recipe/${fireworkId}_firework.json").text.contains("onlyfun:${fireworkId}_firework")) { + fireworkFailures << "recipe:${fireworkId}" + } + } + ["fr_fr", "en_us", "ru_ru"].each { locale -> + def translations = new JsonSlurper().parse(file( + "src/main/resources/assets/onlyfun/lang/${locale}.json")) + if (!translations.containsKey("tooltip.onlyfun.skin_face_firework")) fireworkFailures << "tooltip:${locale}" + fireworkIds.each { fireworkId -> + if (translations["item.onlyfun.${fireworkId}_firework"] == null) { + fireworkFailures << "lang:${locale}:${fireworkId}" + } + } + } + if (!fireworkFailures.isEmpty()) { + throw new GradleException("Only Fun firework contract is incomplete: ${fireworkFailures}") + } } } diff --git a/onlyfun/art/skins/bake_portraits.py b/onlyfun/art/skins/bake_portraits.py new file mode 100644 index 0000000..dbfb0ec --- /dev/null +++ b/onlyfun/art/skins/bake_portraits.py @@ -0,0 +1,174 @@ +from pathlib import Path + +from PIL import Image + +TRANSPARENT = -1 +PEOPLE = [ + ("chrism", "ChrisM", "red_dye"), + ("kaninscheun", "Kaninscheun", "yellow_dye"), + ("poupoutain", "Poupoutain", "light_gray_dye"), + ("lbeast", "lBeast", "brown_dye"), + ("creveforest", "CreveForest", "green_dye"), + ("sacdchips", "SacDChips", "orange_dye"), + ("vaselline", "Vaselline", "white_dye"), + ("duncan", "Duncan", "pink_dye"), +] +ROOT = Path(__file__).resolve().parents[2] + + +def rgb(pixel): + red, green, blue, _alpha = pixel + return (red << 16) | (green << 8) | blue + + +def extract(path): + image = Image.open(path).convert("RGBA") + face = [] + hood = [] + hood_top = [] + inner_top = [] + for y in range(8, 16): + for x in range(8, 16): + face.append(rgb(image.getpixel((x, y)))) + for y in range(8, 16): + for x in range(40, 48): + red, green, blue, alpha = image.getpixel((x, y)) + hood.append(TRANSPARENT if alpha < 128 else (red << 16) | (green << 8) | blue) + for y in range(6, 8): + for x in range(8, 16): + inner_top.append(rgb(image.getpixel((x, y)))) + for y in range(6, 8): + for x in range(40, 48): + red, green, blue, alpha = image.getpixel((x, y)) + if alpha < 128: + hood_top.append(inner_top[(y - 6) * 8 + (x - 40)]) + else: + hood_top.append((red << 16) | (green << 8) | blue) + return face, hood, hood_top + + +def fmt(values): + lines = [] + for index in range(0, len(values), 8): + chunk = values[index:index + 8] + parts = ["-1" if value == TRANSPARENT else f"0x{value:06X}" for value in chunk] + comma = "," if index + 8 < len(values) else "" + lines.append("\t\t" + ", ".join(parts) + comma) + return "\n".join(lines) + + +NOURRA_FACE = [ + 0x000000, 0x020202, 0x0A0A0A, 0x111111, 0x111111, 0x0A0A0A, 0x020202, 0x000000, + 0x020202, 0x0A0A0A, 0x111111, 0x181818, 0x181818, 0x111111, 0x0A0A0A, 0x020202, + 0x0A0A0A, 0x111111, 0x181818, 0x212121, 0x212121, 0x181818, 0x111111, 0x0A0A0A, + 0x111111, 0x181818, 0x212121, 0x2B2B2B, 0x2B2B2B, 0x212121, 0x181818, 0x111111, + 0x111111, 0x000000, 0x000000, 0xFFF0E1, 0xFFF0E1, 0x000000, 0x000000, 0x111111, + 0x0A0A0A, 0xFFFFFF, 0x4A9DFC, 0xFDE8D7, 0xFFF0E1, 0x4A9DFC, 0xFFFFFF, 0x0A0A0A, + 0x020202, 0xFFFFFF, 0x4A9DFC, 0xFDE8D7, 0xFDE8D7, 0x4A9DFC, 0xFFFFFF, 0x020202, + 0x000000, 0xF0C6A5, 0xF7D5B9, 0xFCE1CA, 0xFCE1CA, 0xF7D5B9, 0xF0C6A5, 0x000000, +] +NOURRA_HOOD = [ + 0x000000, 0x0D0D0D, 0xCBCBCB, 0xD8D8D8, 0xD8D8D8, 0xCBCBCB, 0x0D0D0D, 0x000000, + 0x0D0D0D, 0x707070, 0xD8D8D8, 0xE5E5E5, 0xE5E5E5, 0xD8D8D8, 0x707070, 0x0D0D0D, + 0xCBCBCB, 0xD8D8D8, 0xFFFFFF, 0x212121, 0x212121, 0x181818, 0xD8D8D8, 0xCBCBCB, + 0xD8D8D8, 0x181818, 0x212121, 0x2B2B2B, 0x2B2B2B, 0x212121, 0x181818, 0xD8D8D8, + 0x111111, 0x181818, 0x212121, 0x2B2B2B, TRANSPARENT, TRANSPARENT, TRANSPARENT, 0x111111, + 0x0A0A0A, 0x111111, 0x181818, TRANSPARENT, TRANSPARENT, TRANSPARENT, TRANSPARENT, TRANSPARENT, + 0x020202, 0x0A0A0A, TRANSPARENT, TRANSPARENT, TRANSPARENT, TRANSPARENT, TRANSPARENT, TRANSPARENT, + TRANSPARENT, 0x020202, TRANSPARENT, TRANSPARENT, TRANSPARENT, TRANSPARENT, TRANSPARENT, TRANSPARENT, +] +NOURRA_TOP = [ + 0xBEBEBE, 0xCBCBCB, 0xD8D8D8, 0xD8D8D8, 0xD8D8D8, 0xD8D8D8, 0xCBCBCB, 0xBEBEBE, + 0xB8B8B8, 0xB8B8B8, 0xCBCBCB, 0xD8D8D8, 0xD8D8D8, 0xCBCBCB, 0xB8B8B8, 0xB8B8B8, +] + + +def main(): + entries = [("nourra", NOURRA_FACE, NOURRA_HOOD, NOURRA_TOP)] + for ident, _display, _dye in PEOPLE: + face, hood, top = extract(ROOT / "art" / "skins" / f"{ident}.png") + entries.append((ident, face, hood, top)) + print(ident, "hood opaque", sum(1 for value in hood if value != TRANSPARENT)) + + out = ROOT / "src" / "main" / "java" / "fr" / "koka99cab" / "sanctuary26" / "onlyfun" / "item" / "SkinFacePortrait.java" + chunks = [ + "package fr.koka99cab.sanctuary26.onlyfun.item;\n\n", + "import net.minecraft.world.item.ItemStack;\n\n", + "/** Baked 8x8 inner face, hood overlay and hood-top strip for each skin firework. */\n", + "public enum SkinFacePortrait {\n", + ] + for index, (ident, face, hood, top) in enumerate(entries): + comma = "," if index + 1 < len(entries) else ";" + chunks.append( + f"\t{ident.upper()}(\"{ident}\", new int[] {{\n{fmt(face)}\n\t}}, new int[] {{\n{fmt(hood)}\n\t}}, new int[] {{\n{fmt(top)}\n\t}}){comma}\n" + ) + chunks.append(""" + public static final int WIDTH = 8; + public static final int HEIGHT = 8; + public static final int TRANSPARENT = -1; + + private final String id; + private final int[] face; + private final int[] hood; + private final int[] hoodTop; + + SkinFacePortrait(String id, int[] face, int[] hood, int[] hoodTop) { + this.id = id; + this.face = face; + this.hood = hood; + this.hoodTop = hoodTop; + } + + public String id() { + return id; + } + + public String itemId() { + return id + \"_firework\"; + } + + public int[] face() { + return face; + } + + public int[] hood() { + return hood; + } + + public int[] hoodTop() { + return hoodTop; + } + + public int opaqueHoodPixels() { + int count = 0; + for (int color : hood) { + if (color != TRANSPARENT) count++; + } + return count; + } + + public int[] portrait() { + int[] pixels = new int[WIDTH * (HEIGHT + 2)]; + System.arraycopy(hoodTop, 0, pixels, 0, hoodTop.length); + for (int index = 0; index < face.length; index++) { + pixels[hoodTop.length + index] = hood[index] == TRANSPARENT ? face[index] : hood[index]; + } + return pixels; + } + + public int portraitHeight() { + return HEIGHT + hoodTop.length / WIDTH; + } + + public static SkinFacePortrait of(ItemStack stack) { + if (stack.isEmpty() || !(stack.getItem() instanceof SkinFaceFireworkItem item)) return null; + return item.portrait(); + } +} +""") + out.write_text("".join(chunks), encoding="utf-8") + print("wrote", out) + + +if __name__ == "__main__": + main() diff --git a/onlyfun/art/skins/chrism.png b/onlyfun/art/skins/chrism.png new file mode 100644 index 0000000..d4539c7 Binary files /dev/null and b/onlyfun/art/skins/chrism.png differ diff --git a/onlyfun/art/skins/creveforest.png b/onlyfun/art/skins/creveforest.png new file mode 100644 index 0000000..46bdb8a Binary files /dev/null and b/onlyfun/art/skins/creveforest.png differ diff --git a/onlyfun/art/skins/duncan.png b/onlyfun/art/skins/duncan.png new file mode 100644 index 0000000..a94b4bf Binary files /dev/null and b/onlyfun/art/skins/duncan.png differ diff --git a/onlyfun/art/skins/kaninscheun.png b/onlyfun/art/skins/kaninscheun.png new file mode 100644 index 0000000..e9dc777 Binary files /dev/null and b/onlyfun/art/skins/kaninscheun.png differ diff --git a/onlyfun/art/skins/lbeast.png b/onlyfun/art/skins/lbeast.png new file mode 100644 index 0000000..63713c1 Binary files /dev/null and b/onlyfun/art/skins/lbeast.png differ diff --git a/onlyfun/art/skins/poupoutain.png b/onlyfun/art/skins/poupoutain.png new file mode 100644 index 0000000..242c107 Binary files /dev/null and b/onlyfun/art/skins/poupoutain.png differ diff --git a/onlyfun/art/skins/sacdchips.png b/onlyfun/art/skins/sacdchips.png new file mode 100644 index 0000000..4b9e053 Binary files /dev/null and b/onlyfun/art/skins/sacdchips.png differ diff --git a/onlyfun/art/skins/vaselline.png b/onlyfun/art/skins/vaselline.png new file mode 100644 index 0000000..c2c0295 Binary files /dev/null and b/onlyfun/art/skins/vaselline.png differ diff --git a/onlyfun/art/skins/write_firework_assets.py b/onlyfun/art/skins/write_firework_assets.py new file mode 100644 index 0000000..bcb4346 --- /dev/null +++ b/onlyfun/art/skins/write_firework_assets.py @@ -0,0 +1,47 @@ +from pathlib import Path + +IDS = [ + ("chrism", "red_dye"), + ("kaninscheun", "yellow_dye"), + ("poupoutain", "light_gray_dye"), + ("lbeast", "brown_dye"), + ("creveforest", "green_dye"), + ("sacdchips", "orange_dye"), + ("vaselline", "white_dye"), + ("duncan", "pink_dye"), +] +ROOT = Path(__file__).resolve().parents[2] / "src" / "main" / "resources" + + +def main(): + for ident, dye in IDS: + (ROOT / "assets" / "onlyfun" / "items" / f"{ident}_firework.json").write_text( + '{\n\t"model": {\n\t\t"type": "minecraft:model",\n\t\t"model": "onlyfun:item/%s_firework"\n\t}\n}\n' % ident, + encoding="utf-8", + ) + (ROOT / "assets" / "onlyfun" / "models" / "item" / f"{ident}_firework.json").write_text( + '{\n\t"parent": "minecraft:item/generated",\n\t"textures": {\n\t\t"layer0": "onlyfun:item/%s_firework"\n\t}\n}\n' % ident, + encoding="utf-8", + ) + (ROOT / "data" / "onlyfun" / "recipe" / f"{ident}_firework.json").write_text( + """{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:firework_rocket", + "minecraft:%s", + "minecraft:paper" + ], + "result": { + "count": 1, + "id": "onlyfun:%s_firework" + } +} +""" % (dye, ident), + encoding="utf-8", + ) + print("wrote", ident) + + +if __name__ == "__main__": + main() diff --git a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/client/SkinFaceFireworkClient.java b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/client/SkinFaceFireworkClient.java index de81930..5f1fa60 100644 --- a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/client/SkinFaceFireworkClient.java +++ b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/client/SkinFaceFireworkClient.java @@ -1,6 +1,6 @@ package fr.koka99cab.sanctuary26.onlyfun.client; -import fr.koka99cab.sanctuary26.onlyfun.item.SkinFaceFireworkExplosions; +import fr.koka99cab.sanctuary26.onlyfun.item.SkinFacePortrait; import fr.koka99cab.sanctuary26.onlyfun.mixin.client.ParticleLifetimeAccessor; import net.minecraft.client.Minecraft; import net.minecraft.client.particle.Particle; @@ -40,9 +40,11 @@ public final class SkinFaceFireworkClient { if (right.lengthSqr() < 1.0E-6D) right = new Vec3(1.0D, 0.0D, 0.0D); right = right.normalize(); Vec3 up = new Vec3(0.0D, 1.0D, 0.0D); - int[] pixels = SkinFaceFireworkExplosions.portrait(); - int width = SkinFaceFireworkExplosions.WIDTH; - int height = SkinFaceFireworkExplosions.portraitHeight(); + SkinFacePortrait portrait = SkinFacePortrait.of(rocket.getItem()); + if (portrait == null) return; + int[] pixels = portrait.portrait(); + int width = SkinFacePortrait.WIDTH; + int height = portrait.portraitHeight(); boolean large = largeBurst(rocket); double pixel = burstPixel(large); float sparkSize = burstSparkSize(large); diff --git a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkExplosions.java b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkExplosions.java index d8d4a9c..1884c50 100644 --- a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkExplosions.java +++ b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkExplosions.java @@ -1,13 +1,12 @@ package fr.koka99cab.sanctuary26.onlyfun.item; -import fr.koka99cab.sanctuary26.onlyfun.registry.OnlyFunRegistries; import java.util.List; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.Fireworks; /** * Baked Nourra head (NameMC 6166a439e9354904): inner face, hood overlay, hood top. - * The portrait is drawn client-side with firework sparks. + * Other skin fireworks reuse the same flight rules via {@link SkinFacePortrait}. */ public final class SkinFaceFireworkExplosions { public static final int WIDTH = 8; @@ -40,13 +39,12 @@ public final class SkinFaceFireworkExplosions { 0xBEBEBE, 0xCBCBCB, 0xD8D8D8, 0xD8D8D8, 0xD8D8D8, 0xD8D8D8, 0xCBCBCB, 0xBEBEBE, 0xB8B8B8, 0xB8B8B8, 0xCBCBCB, 0xD8D8D8, 0xD8D8D8, 0xCBCBCB, 0xB8B8B8, 0xB8B8B8 }; + /** Vanilla flight 3 minus half a gunpowder step, so the burst sits between 2 and 3. */ + public static final int LIFETIME_TRIM_TICKS = 5; private SkinFaceFireworkExplosions() { } - /** Vanilla flight 3 minus half a gunpowder step, so the burst sits between 2 and 3. */ - public static final int LIFETIME_TRIM_TICKS = 5; - public static Fireworks defaultFireworks() { return new Fireworks(3, List.of()); } @@ -56,7 +54,7 @@ public final class SkinFaceFireworkExplosions { } public static boolean isSkinFaceRocket(ItemStack stack) { - return !stack.isEmpty() && stack.is(OnlyFunRegistries.NOURRA_FIREWORK); + return SkinFacePortrait.of(stack) != null; } public static int opaqueHoodPixels() { @@ -69,15 +67,10 @@ public final class SkinFaceFireworkExplosions { /** Hood top (2 rows) then the 8×8 face with the hood overlay composited. */ public static int[] portrait() { - int[] pixels = new int[WIDTH * (HEIGHT + 2)]; - System.arraycopy(HOOD_TOP, 0, pixels, 0, HOOD_TOP.length); - for (int index = 0; index < FACE.length; index++) { - pixels[HOOD_TOP.length + index] = HOOD[index] == TRANSPARENT ? FACE[index] : HOOD[index]; - } - return pixels; + return SkinFacePortrait.NOURRA.portrait(); } public static int portraitHeight() { - return HEIGHT + HOOD_TOP.length / WIDTH; + return SkinFacePortrait.NOURRA.portraitHeight(); } } diff --git a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkItem.java b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkItem.java new file mode 100644 index 0000000..749b934 --- /dev/null +++ b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkItem.java @@ -0,0 +1,30 @@ +package fr.koka99cab.sanctuary26.onlyfun.item; + +import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.FireworkRocketItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipDisplay; + +/** Firework rocket that bursts into a baked skin face. */ +public final class SkinFaceFireworkItem extends FireworkRocketItem { + private final SkinFacePortrait portrait; + + public SkinFaceFireworkItem(SkinFacePortrait portrait, Properties properties) { + super(properties); + this.portrait = portrait; + } + + public SkinFacePortrait portrait() { + return portrait; + } + + @Override + public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay display, + Consumer tooltip, TooltipFlag flag) { + tooltip.accept(Component.translatable("tooltip.onlyfun.skin_face_firework").withStyle(ChatFormatting.AQUA)); + super.appendHoverText(stack, context, display, tooltip, flag); + } +} diff --git a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFacePortrait.java b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFacePortrait.java new file mode 100644 index 0000000..5159e0f --- /dev/null +++ b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFacePortrait.java @@ -0,0 +1,269 @@ +package fr.koka99cab.sanctuary26.onlyfun.item; + +import net.minecraft.world.item.ItemStack; + +/** Baked 8x8 inner face, hood overlay and hood-top strip for each skin firework. */ +public enum SkinFacePortrait { + NOURRA("nourra", new int[] { + 0x000000, 0x020202, 0x0A0A0A, 0x111111, 0x111111, 0x0A0A0A, 0x020202, 0x000000, + 0x020202, 0x0A0A0A, 0x111111, 0x181818, 0x181818, 0x111111, 0x0A0A0A, 0x020202, + 0x0A0A0A, 0x111111, 0x181818, 0x212121, 0x212121, 0x181818, 0x111111, 0x0A0A0A, + 0x111111, 0x181818, 0x212121, 0x2B2B2B, 0x2B2B2B, 0x212121, 0x181818, 0x111111, + 0x111111, 0x000000, 0x000000, 0xFFF0E1, 0xFFF0E1, 0x000000, 0x000000, 0x111111, + 0x0A0A0A, 0xFFFFFF, 0x4A9DFC, 0xFDE8D7, 0xFFF0E1, 0x4A9DFC, 0xFFFFFF, 0x0A0A0A, + 0x020202, 0xFFFFFF, 0x4A9DFC, 0xFDE8D7, 0xFDE8D7, 0x4A9DFC, 0xFFFFFF, 0x020202, + 0x000000, 0xF0C6A5, 0xF7D5B9, 0xFCE1CA, 0xFCE1CA, 0xF7D5B9, 0xF0C6A5, 0x000000 + }, new int[] { + 0x000000, 0x0D0D0D, 0xCBCBCB, 0xD8D8D8, 0xD8D8D8, 0xCBCBCB, 0x0D0D0D, 0x000000, + 0x0D0D0D, 0x707070, 0xD8D8D8, 0xE5E5E5, 0xE5E5E5, 0xD8D8D8, 0x707070, 0x0D0D0D, + 0xCBCBCB, 0xD8D8D8, 0xFFFFFF, 0x212121, 0x212121, 0x181818, 0xD8D8D8, 0xCBCBCB, + 0xD8D8D8, 0x181818, 0x212121, 0x2B2B2B, 0x2B2B2B, 0x212121, 0x181818, 0xD8D8D8, + 0x111111, 0x181818, 0x212121, 0x2B2B2B, -1, -1, -1, 0x111111, + 0x0A0A0A, 0x111111, 0x181818, -1, -1, -1, -1, -1, + 0x020202, 0x0A0A0A, -1, -1, -1, -1, -1, -1, + -1, 0x020202, -1, -1, -1, -1, -1, -1 + }, new int[] { + 0xBEBEBE, 0xCBCBCB, 0xD8D8D8, 0xD8D8D8, 0xD8D8D8, 0xD8D8D8, 0xCBCBCB, 0xBEBEBE, + 0xB8B8B8, 0xB8B8B8, 0xCBCBCB, 0xD8D8D8, 0xD8D8D8, 0xCBCBCB, 0xB8B8B8, 0xB8B8B8 + }), + CHRISM("chrism", new int[] { + 0xF59589, 0xF89C90, 0xFEA398, 0xFEA398, 0xFCA297, 0xF89B8F, 0xF2978B, 0xF49488, + 0xF59589, 0xFB9D91, 0xFA9D92, 0xFCA095, 0xFCA095, 0xFCA095, 0xF89B8F, 0xF49488, + 0xF59589, 0xFB9A8E, 0xFD9E93, 0xFDA196, 0xFDA196, 0xFD9E93, 0xFB9A8E, 0xFF988B, + 0xFE8B7E, 0xFE8B7E, 0xFE8B7E, 0xFE8B7E, 0xFE8B7E, 0xFE8B7E, 0xFE8B7E, 0xFE8B7E, + 0xFE8B7E, 0x000000, 0xFE8B7E, 0xFE8B7E, 0xFE8B7E, 0xFE8B7E, 0x000000, 0xFD8B7D, + 0xF67D70, 0xF68375, 0xFA897C, 0xFE8B7E, 0xFE8B7E, 0xFE8B7E, 0xF68375, 0xF67D70, + 0x000000, 0xFFFFFF, 0x000000, 0x000000, 0x000000, 0x000000, 0xFFFFFF, 0x000000, + 0xEE6858, 0x000000, 0x000000, 0xFF1408, 0xFC0C00, 0x000000, 0x000000, 0xEE6858 + }, new int[] { + 0xFF8071, 0xFF8274, 0xFF796A, 0xFA7B6C, 0xFE7E70, 0xF97769, 0xFB7F70, 0xFF7A6B, + 0xF56E5E, 0xFF9185, 0xFF8375, 0xFF9084, 0xFB8A7E, 0xFE9286, 0xFF8B7E, 0xF68274, + 0xFA7263, 0xFF9488, 0xFE9084, 0xFE8C80, 0xFF9286, 0xF77F72, 0xF89084, 0xF97465, + 0xFF8273, 0xFF8E82, 0xFA8D81, 0xF68477, 0xF69186, 0xFF8F83, 0xFD9286, 0xFF7767, + 0xFF8173, 0xFB887B, 0xFC9084, 0xFF9083, 0xFF978B, 0xFF8375, 0xF48A7E, 0xFF8173, + 0xFD7D6E, -1, 0xF5897D, 0xFF8C7F, 0xF3877A, 0xFF897C, -1, 0xFF7060, + 0xFC7667, 0xFF897B, 0xFF9488, -1, -1, 0xF37F72, 0xF89186, 0xFD7566, + 0xFF8375, 0xFF7F70, 0xF88072, 0xF88173, 0xFC7869, 0xFF8173, 0xFF8678, 0xFF7C6D + }, new int[] { + 0xF97566, 0xFF8C7F, 0xF4867A, 0xFF877A, 0xF4786A, 0xFF8678, 0xF97E70, 0xFF7F71, + 0xFF897B, 0xFB7566, 0xFF8C7F, 0xF77F72, 0xF77769, 0xFF7C6E, 0xF88578, 0xF87B6D + }), + KANINSCHEUN("kaninscheun", new int[] { + 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, + 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xFFCC66, 0xEAD900, 0xEDDF2D, + 0xEAD900, 0xEDDF2D, 0xEAD900, 0xFFCC66, 0xFFCC66, 0xFFCC66, 0xFFCC66, 0xEDDF2D, + 0xEAD900, 0x000000, 0xFFCC66, 0xFFCC66, 0xFFCC66, 0xFFCC66, 0x000000, 0xEDDF2D, + 0xEAD900, 0x000000, 0x000000, 0xFFCC66, 0xFFCC66, 0x000000, 0x000000, 0xEDDF2D, + 0xEAD900, 0xFFCC66, 0xFFCC66, 0xFFCC66, 0xFFCC66, 0xFFCC66, 0xFFCC66, 0xEDDF2D, + 0xEAD900, 0xFFCC66, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xFFCC66, 0xEDDF2D, + 0xEAD900, 0xEAD900, 0xEDDF2D, 0xFFCC66, 0xFFCC66, 0xEAD900, 0xEAD900, 0xEDDF2D + }, new int[] { + -1, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, -1, + 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, + 0xEDDF2D, 0xEAD900, 0xEDDF2D, -1, -1, -1, 0xEDDF2D, 0xEAD900, + 0xEDDF2D, 0xEAD900, -1, -1, -1, -1, -1, 0xEAD900, + 0xEDDF2D, -1, -1, -1, -1, -1, -1, 0xEAD900, + 0xEDDF2D, -1, -1, -1, -1, -1, -1, 0xEAD900, + 0xEDDF2D, -1, -1, -1, -1, -1, -1, 0xEAD900, + -1, 0xEAD900, -1, -1, -1, -1, 0xEDDF2D, -1 + }, new int[] { + 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, + 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900, 0xEDDF2D, 0xEAD900 + }), + POUPOUTAIN("poupoutain", new int[] { + 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, + 0x4B5456, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0x4B5456, + 0x4B5456, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0x342404, 0xE7E6E4, 0x4B5456, + 0x4B5456, 0xE7E6E4, 0x342404, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0x4B5456, + 0x4B5456, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0x4B5456, + 0x4B5456, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0x342404, 0xE0DFDE, 0xE7E6E4, 0x4B5456, + 0x4B5456, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0xE7E6E4, 0x4B5456, + 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456 + }, new int[] { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 + }, new int[] { + 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, 0x4B5456, + 0x414B4C, 0x414B4C, 0x414B4C, 0x414B4C, 0x414B4C, 0x414B4C, 0x414B4C, 0x414B4C + }), + LBEAST("lbeast", new int[] { + 0x8A6C30, 0x8A6B31, 0x644B1A, 0x5D4B1E, 0x896F37, 0x80672A, 0x614B1A, 0x4C3910, + 0x957538, 0x816C34, 0x6D5521, 0x715B20, 0xA88C44, 0x9C7E3B, 0x7F6625, 0x7D6325, + 0xB59F6D, 0xC1AC74, 0xC8B378, 0xD0BB7C, 0xD9C382, 0xE7CF8A, 0xD2BC7E, 0xC6A574, + 0xB39C6C, 0x2B2324, 0x2B2324, 0xD5BA80, 0xD7BE80, 0x2B2324, 0x2B2324, 0xCBA977, + 0xDCC285, 0xBAA0A6, 0x42597E, 0xF1D491, 0xD7BD7F, 0x42597E, 0xBAA0A6, 0xECC48B, + 0xEACC8C, 0xFAF3F5, 0x87A6D2, 0xFDDB98, 0xDCBE81, 0x87A6D2, 0xFAF3F5, 0xF1C88E, + 0xE4C082, 0xF6D695, 0xFBDD96, 0xFBE197, 0xFBE197, 0xFDDC95, 0xF6D695, 0xEBC288, + 0xE9C183, 0xEFC68A, 0xF6D695, 0xFDDC94, 0xFBE197, 0xF6D695, 0xF4C98C, 0xDFB67D + }, new int[] { + 0x7E652E, 0xC5A253, 0xC5A253, 0xBB984A, 0xD0A64E, 0xBB984A, 0xC5A253, 0x715B29, + 0x947438, 0xEAC269, 0x96772C, 0xB69045, 0xD0A64E, 0xBB984A, 0xC5A253, 0x7E652E, + 0xB49043, 0xD0A64E, -1, 0xD0A64E, 0xE4C368, 0xBB984A, 0xD0A64E, 0x8A6E32, + 0x96772C, -1, -1, -1, -1, 0xBB9853, 0xD1AD5C, 0xB18D46, + 0xD0A64E, -1, -1, -1, -1, -1, -1, 0x9C7D39, + -1, -1, -1, -1, -1, -1, -1, 0x9C7D39, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 + }, new int[] { + 0x846932, 0x907336, 0xA18340, 0xAE8E45, 0xAE8E45, 0x886F36, 0x7B6431, 0x6E5A2C, + 0x7A6029, 0x886F36, 0x95793B, 0xA18340, 0xA18340, 0x95793B, 0x886F36, 0x7B6431 + }), + CREVEFOREST("creveforest", new int[] { + 0x2D4C54, 0x2D4C54, 0x2D4C54, 0x2D4C54, 0x355C5E, 0x2D4C54, 0x2D4C54, 0x2D4C54, + 0x2D4C54, 0x2D4C54, 0x355C5E, 0x355C5E, 0x355C5E, 0x355C5E, 0x2D4C54, 0x2D4C54, + 0x2D4C54, 0x355C5E, 0x79A88F, 0x8FC49B, 0x79A88F, 0x79A88F, 0x355C5E, 0x2D4C54, + 0x355C5E, 0x79A88F, 0x8FC49B, 0x9ED69C, 0x8FC49B, 0x8FC49B, 0x79A88F, 0x355C5E, + 0x355C5E, 0x1E2E33, 0x1E2E33, 0xB7E8A9, 0x9ED69C, 0x1E2E33, 0x1E2E33, 0x355C5E, + 0x1E2E33, 0x9BB0AC, 0x344C46, 0xD3F5BA, 0xB7E8A9, 0x344C46, 0x9BB0AC, 0x1E2E33, + 0x2D4C54, 0xEBEBEB, 0x79B8AB, 0xD3F5BA, 0xB7E8A9, 0x79B8AB, 0xEBEBEB, 0x355C5E, + 0x2D4C54, 0x8FC49B, 0xB7E8A9, 0x9ED69C, 0xB7E8A9, 0xB7E8A9, 0x8FC49B, 0x355C5E + }, new int[] { + -1, 0x549C62, 0x4D8C64, 0x4D8C64, 0x549C62, 0x3D785D, 0x4D8C64, -1, + 0x549C62, 0x549C62, 0x4D8C64, 0x4D8C64, 0x4D8C64, 0x3D785D, 0x4D8C64, 0x549C62, + 0x4D8C64, 0x4D8C64, 0x3D785D, 0x3D785D, 0x3D785D, 0x355C5E, 0x3D785D, 0x4D8C64, + 0x3D785D, 0x3D785D, 0x355C5E, -1, 0x355C5E, 0x2D4C54, 0x355C5E, 0x3D785D, + 0x3D785D, -1, 0x2D4C54, -1, -1, -1, 0x355C5E, 0x3D785D, + 0x355C5E, -1, -1, -1, -1, -1, -1, 0x355C5E, + 0x2D4C54, -1, -1, -1, -1, -1, -1, 0x2D4C54, + -1, -1, -1, -1, -1, -1, -1, -1 + }, new int[] { + 0x355C5E, 0x355C5E, 0x355C5E, 0x355C5E, 0x3D785D, 0x355C5E, 0x2D4C54, 0x355C5E, + 0x2D4C54, 0x549C62, 0x4D8C64, 0x4D8C64, 0x549C62, 0x3D785D, 0x4D8C64, 0x355C5E + }), + SACDCHIPS("sacdchips", new int[] { + 0x3E1A05, 0x421D05, 0x391904, 0x421C06, 0x391904, 0x632C08, 0x3D1B05, 0x552607, + 0x421D05, 0x421D05, 0x391904, 0xF1DACD, 0xF2DDD1, 0xEFD7C9, 0xEED4C5, 0x632C08, + 0xEBCCBA, 0xECCFBE, 0xEDD1C1, 0xE7C3AE, 0xEDD1C1, 0xEED4C5, 0xF2DDD1, 0xECCFBE, + 0xECCFBE, 0x341704, 0x341704, 0xE7C3AE, 0xEBCCBA, 0x341704, 0x341704, 0xF1DACD, + 0xEBCCBA, 0xEEEEEE, 0x602F10, 0xEDD1C1, 0xF2DDD1, 0x602F10, 0xEEEEEE, 0xEDD1C1, + 0xE7C3AE, 0xEDD1C1, 0xE7C3AE, 0xF2DDD1, 0xF1DACD, 0xEDD1C1, 0xE7C3AE, 0xEDD1C1, + 0xE6C0AA, 0xECCFBE, 0xEBCCBA, 0x000000, 0x000000, 0xEDD1C1, 0xEAC9B6, 0xEBCCBA, + 0xEAC9B6, 0xECCFBE, 0xF2DDD1, 0xECCFBE, 0xEAC9B6, 0xF1DACD, 0xECCFBE, 0xF1DACD + }, new int[] { + -1, 0x180A02, 0x261003, 0x2B1204, 0x341604, 0x210E03, 0x2F1404, -1, + -1, -1, -1, 0x2B1204, 0x210E03, 0x471E06, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 0x261003, 0x180A02, 0x210E03, 0x1D0C02, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 + }, new int[] { + 0x3E1A05, 0x3E1A05, 0x210E03, 0x1D0C02, 0x341604, 0x180A02, 0x2F1404, 0x1D0C02, + 0x391805, 0x421C06, 0x421C06, 0x3E1A05, 0x471E06, 0x1D0C02, 0x341604, 0x341604 + }), + VASELLINE("vaselline", new int[] { + 0xEBE176, 0xEBE176, 0xEBE176, 0xE8DC5F, 0xE8DC5F, 0xE8DC5F, 0xEBE176, 0xEBE176, + 0xEBE176, 0xE8DC5F, 0xE8D7B1, 0xE8D7B1, 0xE8D7B1, 0xE8D7B1, 0xE8DC5F, 0xEBE176, + 0xE8DC5F, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xE8DC5F, + 0xE8DC5F, 0xFFFFFF, 0x6F9EE8, 0xE8D7B1, 0xE8D7B1, 0x6F9EE8, 0xFFFFFF, 0xE8DC5F, + 0xE8DC5F, 0xE8D7B1, 0xE8D7B1, 0xEEE1C5, 0xEEE1C5, 0xE8D7B1, 0xE8D7B1, 0xE8DC5F, + 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, + 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xE2CD9D, 0xE2CD9D, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, + 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5, 0xEEE1C5 + }, new int[] { + 0xEBE176, 0xEBE176, 0xE8DC5F, 0xE8DC5F, 0xE8DC5F, 0xE8DC5F, 0xEBE176, 0xEBE176, + 0xEBE176, 0xE8DC5F, -1, -1, -1, -1, 0xE8DC5F, 0xEBE176, + 0xEBE176, -1, -1, -1, -1, -1, -1, 0xE8DC5F, + 0xE8DC5F, -1, -1, -1, -1, -1, -1, 0xE8DC5F, + 0xE8DC5F, -1, -1, -1, -1, -1, -1, 0xE8DC5F, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 + }, new int[] { + 0xEBE176, 0xE8DC5F, 0xE8DC5F, 0xEBE176, 0xEBE176, 0xE8DC5F, 0xE8DC5F, 0xE8DC5F, + 0xEBE176, 0xEBE176, 0xEBE176, 0xEBE176, 0xEBE176, 0xEBE176, 0xEBE176, 0xEBE176 + }), + DUNCAN("duncan", new int[] { + 0x9D5330, 0x9D5330, 0x9D5330, 0x9D5330, 0x9D5330, 0x9D5330, 0x9D5330, 0x9D5330, + 0xFFD6AE, 0xFFD7AE, 0xFFD7AE, 0xFFD6AE, 0xFFD6AE, 0xFED7AE, 0xFFD7AF, 0xFFD7AE, + 0xFFD7AE, 0xAD3B11, 0xAC3A10, 0xFFD7AE, 0xFFD7AE, 0xAD3B10, 0xAC3B11, 0xFFD6AF, + 0xFED6AF, 0xFEFFFF, 0x783018, 0xFFD7AE, 0xFFD7AE, 0xFEFFFE, 0x793019, 0xFFD6AF, + 0xFFD6AE, 0x783018, 0x010000, 0xFFD7AF, 0xFED7AE, 0x010100, 0x783018, 0xFFD7AF, + 0xFED7AF, 0xFFD7AE, 0xFFD7AF, 0xFED6AF, 0xFED7AE, 0xFED7AE, 0xFED7AF, 0xFFD6AE, + 0xFED7AE, 0xFED7AF, 0xFED7AE, 0xCB97A0, 0xCB96A0, 0xFED7AE, 0xFFD7AE, 0xFFD6AE, + 0xFFD7AE, 0xFED7AE, 0xFFD7AE, 0xFFD7AF, 0xFFD7AE, 0xFFD7AE, 0xFFD7AE, 0xFED7AE + }, new int[] { + 0x9D5330, 0xBC5D30, 0x9D5330, 0x88492A, 0x9D5330, 0x9D5330, 0x88492A, 0x9D5330, + 0x9D5330, -1, 0x88492A, -1, -1, 0xBC5D30, -1, 0x9D5330, + -1, 0xE6AB35, 0xE7AA34, -1, -1, 0xE6AA34, 0xE7AA34, -1, + 0xE6AB34, -1, -1, 0xE7AB35, 0xE7AB35, -1, -1, 0xE6AB35, + 0xE7AB35, -1, -1, 0xE6AB35, 0xE6AA34, -1, -1, 0xE6AB35, + -1, 0xE6AB34, 0xE6AB35, -1, -1, 0xE6AB35, 0xE6AB34, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1 + }, new int[] { + 0x9D5330, 0x9D5330, 0x9D5330, 0x9D5330, 0x88492A, 0x9D5330, 0x9D5330, 0x88492A, + 0x9D5330, 0x9D5330, 0x9D5330, 0xBC5D30, 0x9D5330, 0x9D5330, 0x9D5330, 0x9D5330 + }); + + public static final int WIDTH = 8; + public static final int HEIGHT = 8; + public static final int TRANSPARENT = -1; + + private final String id; + private final int[] face; + private final int[] hood; + private final int[] hoodTop; + + SkinFacePortrait(String id, int[] face, int[] hood, int[] hoodTop) { + this.id = id; + this.face = face; + this.hood = hood; + this.hoodTop = hoodTop; + } + + public String id() { + return id; + } + + public String itemId() { + return id + "_firework"; + } + + public int[] face() { + return face; + } + + public int[] hood() { + return hood; + } + + public int[] hoodTop() { + return hoodTop; + } + + public int opaqueHoodPixels() { + int count = 0; + for (int color : hood) { + if (color != TRANSPARENT) count++; + } + return count; + } + + public int[] portrait() { + int[] pixels = new int[WIDTH * (HEIGHT + 2)]; + System.arraycopy(hoodTop, 0, pixels, 0, hoodTop.length); + for (int index = 0; index < face.length; index++) { + pixels[hoodTop.length + index] = hood[index] == TRANSPARENT ? face[index] : hood[index]; + } + return pixels; + } + + public int portraitHeight() { + return HEIGHT + hoodTop.length / WIDTH; + } + + public static SkinFacePortrait of(ItemStack stack) { + if (stack.isEmpty()) return null; + if (stack.getItem() instanceof SkinFaceFireworkItem item) return item.portrait(); + if (stack.getItem() instanceof NourraFireworkItem) return NOURRA; + return null; + } +} diff --git a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/registry/OnlyFunCreativeTab.java b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/registry/OnlyFunCreativeTab.java index 7116203..9bbbe3c 100644 --- a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/registry/OnlyFunCreativeTab.java +++ b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/registry/OnlyFunCreativeTab.java @@ -8,6 +8,7 @@ import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; public final class OnlyFunCreativeTab { @@ -29,6 +30,9 @@ public final class OnlyFunCreativeTab { output.accept(OnlyFunRegistries.SPAWN_EGG_LOOTBOX); output.accept(OnlyFunRegistries.ANOMALY_LOOTBOX); output.accept(OnlyFunRegistries.NOURRA_FIREWORK); + for (Item firework : OnlyFunRegistries.skinFireworks()) { + if (firework != OnlyFunRegistries.NOURRA_FIREWORK) output.accept(firework); + } output.accept(AbjectionRegistries.SHIT_BALL); output.accept(AbjectionRegistries.SHIT_CUBE_ITEM); }) diff --git a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/registry/OnlyFunRegistries.java b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/registry/OnlyFunRegistries.java index 289f2b1..7d913ee 100644 --- a/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/registry/OnlyFunRegistries.java +++ b/onlyfun/src/main/java/fr/koka99cab/sanctuary26/onlyfun/registry/OnlyFunRegistries.java @@ -3,8 +3,10 @@ package fr.koka99cab.sanctuary26.onlyfun.registry; import fr.koka99cab.sanctuary26.onlyfun.OnlyFunMod; import fr.koka99cab.sanctuary26.onlyfun.block.LuckyBlockBlock; import fr.koka99cab.sanctuary26.onlyfun.item.LootboxItem; -import fr.koka99cab.sanctuary26.onlyfun.item.SkinFaceFireworkExplosions; import fr.koka99cab.sanctuary26.onlyfun.item.NourraFireworkItem; +import fr.koka99cab.sanctuary26.onlyfun.item.SkinFaceFireworkExplosions; +import fr.koka99cab.sanctuary26.onlyfun.item.SkinFaceFireworkItem; +import fr.koka99cab.sanctuary26.onlyfun.item.SkinFacePortrait; import fr.koka99cab.sanctuary26.onlyfun.loot.OnlyFunGenerator; import fr.koka99cab.sanctuary26.onlyfun.loot.OnlyFunSource; import java.util.function.Function; @@ -37,6 +39,14 @@ public final class OnlyFunRegistries { public static final Item NOURRA_FIREWORK = registerItem("nourra_firework", properties -> new NourraFireworkItem(properties.stacksTo(64) .component(DataComponents.FIREWORKS, SkinFaceFireworkExplosions.defaultFireworks()))); + public static final Item CHRISM_FIREWORK = registerSkinFirework(SkinFacePortrait.CHRISM); + public static final Item KANINSCHEUN_FIREWORK = registerSkinFirework(SkinFacePortrait.KANINSCHEUN); + public static final Item POUPOUTAIN_FIREWORK = registerSkinFirework(SkinFacePortrait.POUPOUTAIN); + public static final Item LBEAST_FIREWORK = registerSkinFirework(SkinFacePortrait.LBEAST); + public static final Item CREVEFOREST_FIREWORK = registerSkinFirework(SkinFacePortrait.CREVEFOREST); + public static final Item SACDCHIPS_FIREWORK = registerSkinFirework(SkinFacePortrait.SACDCHIPS); + public static final Item VASELLINE_FIREWORK = registerSkinFirework(SkinFacePortrait.VASELLINE); + public static final Item DUNCAN_FIREWORK = registerSkinFirework(SkinFacePortrait.DUNCAN); private static boolean initialized; private OnlyFunRegistries() { @@ -52,6 +62,13 @@ public final class OnlyFunRegistries { }; } + public static Item[] skinFireworks() { + return new Item[] { + NOURRA_FIREWORK, CHRISM_FIREWORK, KANINSCHEUN_FIREWORK, POUPOUTAIN_FIREWORK, + LBEAST_FIREWORK, CREVEFOREST_FIREWORK, SACDCHIPS_FIREWORK, VASELLINE_FIREWORK, DUNCAN_FIREWORK + }; + } + public static void initialize() { if (initialized) { return; @@ -66,6 +83,11 @@ public final class OnlyFunRegistries { OnlyFunMod.LOGGER.debug("[{}] Item and block registries initialized.", OnlyFunMod.DISPLAY_NAME); } + private static Item registerSkinFirework(SkinFacePortrait portrait) { + return registerItem(portrait.itemId(), properties -> new SkinFaceFireworkItem(portrait, + properties.stacksTo(64).component(DataComponents.FIREWORKS, SkinFaceFireworkExplosions.defaultFireworks()))); + } + private static Item registerItem(String path, Function factory) { ResourceKey key = ResourceKey.create(Registries.ITEM, OnlyFunMod.id(path)); return Registry.register(BuiltInRegistries.ITEM, key, factory.apply(new Item.Properties().setId(key))); diff --git a/onlyfun/src/main/resources/assets/onlyfun/items/chrism_firework.json b/onlyfun/src/main/resources/assets/onlyfun/items/chrism_firework.json new file mode 100644 index 0000000..b4a5283 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/items/chrism_firework.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "onlyfun:item/chrism_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/items/creveforest_firework.json b/onlyfun/src/main/resources/assets/onlyfun/items/creveforest_firework.json new file mode 100644 index 0000000..e026644 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/items/creveforest_firework.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "onlyfun:item/creveforest_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/items/duncan_firework.json b/onlyfun/src/main/resources/assets/onlyfun/items/duncan_firework.json new file mode 100644 index 0000000..49bffe1 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/items/duncan_firework.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "onlyfun:item/duncan_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/items/kaninscheun_firework.json b/onlyfun/src/main/resources/assets/onlyfun/items/kaninscheun_firework.json new file mode 100644 index 0000000..8c01025 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/items/kaninscheun_firework.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "onlyfun:item/kaninscheun_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/items/lbeast_firework.json b/onlyfun/src/main/resources/assets/onlyfun/items/lbeast_firework.json new file mode 100644 index 0000000..46e8a00 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/items/lbeast_firework.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "onlyfun:item/lbeast_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/items/poupoutain_firework.json b/onlyfun/src/main/resources/assets/onlyfun/items/poupoutain_firework.json new file mode 100644 index 0000000..7161d34 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/items/poupoutain_firework.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "onlyfun:item/poupoutain_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/items/sacdchips_firework.json b/onlyfun/src/main/resources/assets/onlyfun/items/sacdchips_firework.json new file mode 100644 index 0000000..5f6a22d --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/items/sacdchips_firework.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "onlyfun:item/sacdchips_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/items/vaselline_firework.json b/onlyfun/src/main/resources/assets/onlyfun/items/vaselline_firework.json new file mode 100644 index 0000000..fb6d87f --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/items/vaselline_firework.json @@ -0,0 +1,6 @@ +{ + "model": { + "type": "minecraft:model", + "model": "onlyfun:item/vaselline_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/lang/en_us.json b/onlyfun/src/main/resources/assets/onlyfun/lang/en_us.json index 498b7d2..4125974 100644 --- a/onlyfun/src/main/resources/assets/onlyfun/lang/en_us.json +++ b/onlyfun/src/main/resources/assets/onlyfun/lang/en_us.json @@ -7,7 +7,16 @@ "item.onlyfun.spawn_egg_lootbox": "Spawn Egg Lootbox", "item.onlyfun.anomaly_lootbox": "Anomaly Lootbox", "item.onlyfun.nourra_firework": "Nourra Firework", + "item.onlyfun.chrism_firework": "ChrisM Firework", + "item.onlyfun.kaninscheun_firework": "Kaninscheun Firework", + "item.onlyfun.poupoutain_firework": "Poupoutain Firework", + "item.onlyfun.lbeast_firework": "lBeast Firework", + "item.onlyfun.creveforest_firework": "CreveForest Firework", + "item.onlyfun.sacdchips_firework": "SacDChips Firework", + "item.onlyfun.vaselline_firework": "Vaselline Firework", + "item.onlyfun.duncan_firework": "Duncan Firework", "tooltip.onlyfun.nourra_firework": "The burst paints the skin face, at normal or larger size.", + "tooltip.onlyfun.skin_face_firework": "The burst paints the skin face, at normal or larger size.", "item.onlyfun.quality_gear": "Quality Gear", "item.onlyfun.impossible_tool": "Impossible Tool", "item.onlyfun.impossible_book": "Impossible Book", diff --git a/onlyfun/src/main/resources/assets/onlyfun/lang/fr_fr.json b/onlyfun/src/main/resources/assets/onlyfun/lang/fr_fr.json index 98f2a21..968aabf 100644 --- a/onlyfun/src/main/resources/assets/onlyfun/lang/fr_fr.json +++ b/onlyfun/src/main/resources/assets/onlyfun/lang/fr_fr.json @@ -7,7 +7,16 @@ "item.onlyfun.spawn_egg_lootbox": "Lootbox d'œufs", "item.onlyfun.anomaly_lootbox": "Lootbox anomalie", "item.onlyfun.nourra_firework": "Feu d'artifice Nourra", + "item.onlyfun.chrism_firework": "Feu d'artifice ChrisM", + "item.onlyfun.kaninscheun_firework": "Feu d'artifice Kaninscheun", + "item.onlyfun.poupoutain_firework": "Feu d'artifice Poupoutain", + "item.onlyfun.lbeast_firework": "Feu d'artifice lBeast", + "item.onlyfun.creveforest_firework": "Feu d'artifice CreveForest", + "item.onlyfun.sacdchips_firework": "Feu d'artifice SacDChips", + "item.onlyfun.vaselline_firework": "Feu d'artifice Vaselline", + "item.onlyfun.duncan_firework": "Feu d'artifice Duncan", "tooltip.onlyfun.nourra_firework": "L'explosion dessine le visage, en taille normale ou plus grande.", + "tooltip.onlyfun.skin_face_firework": "L'explosion dessine le visage, en taille normale ou plus grande.", "item.onlyfun.quality_gear": "Équipement de qualité", "item.onlyfun.impossible_tool": "Outil impossible", "item.onlyfun.impossible_book": "Livre impossible", diff --git a/onlyfun/src/main/resources/assets/onlyfun/lang/ru_ru.json b/onlyfun/src/main/resources/assets/onlyfun/lang/ru_ru.json index 6eb8818..a8a0535 100644 --- a/onlyfun/src/main/resources/assets/onlyfun/lang/ru_ru.json +++ b/onlyfun/src/main/resources/assets/onlyfun/lang/ru_ru.json @@ -7,7 +7,16 @@ "item.onlyfun.spawn_egg_lootbox": "Лутбокс яиц призыва", "item.onlyfun.anomaly_lootbox": "Лутбокс-аномалия", "item.onlyfun.nourra_firework": "Фейерверк Нурры", + "item.onlyfun.chrism_firework": "Фейерверк ChrisM", + "item.onlyfun.kaninscheun_firework": "Фейерверк Kaninscheun", + "item.onlyfun.poupoutain_firework": "Фейерверк Poupoutain", + "item.onlyfun.lbeast_firework": "Фейерверк lBeast", + "item.onlyfun.creveforest_firework": "Фейерверк CreveForest", + "item.onlyfun.sacdchips_firework": "Фейерверк SacDChips", + "item.onlyfun.vaselline_firework": "Фейерверк Vaselline", + "item.onlyfun.duncan_firework": "Фейерверк Duncan", "tooltip.onlyfun.nourra_firework": "Взрыв рисует лицо скина обычного или увеличенного размера.", + "tooltip.onlyfun.skin_face_firework": "Взрыв рисует лицо скина обычного или увеличенного размера.", "item.onlyfun.quality_gear": "Качественное снаряжение", "item.onlyfun.impossible_tool": "Невозможный инструмент", "item.onlyfun.impossible_book": "Невозможная книга", diff --git a/onlyfun/src/main/resources/assets/onlyfun/models/item/chrism_firework.json b/onlyfun/src/main/resources/assets/onlyfun/models/item/chrism_firework.json new file mode 100644 index 0000000..b92d1d9 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/models/item/chrism_firework.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "onlyfun:item/chrism_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/models/item/creveforest_firework.json b/onlyfun/src/main/resources/assets/onlyfun/models/item/creveforest_firework.json new file mode 100644 index 0000000..038bbc7 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/models/item/creveforest_firework.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "onlyfun:item/creveforest_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/models/item/duncan_firework.json b/onlyfun/src/main/resources/assets/onlyfun/models/item/duncan_firework.json new file mode 100644 index 0000000..e605637 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/models/item/duncan_firework.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "onlyfun:item/duncan_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/models/item/kaninscheun_firework.json b/onlyfun/src/main/resources/assets/onlyfun/models/item/kaninscheun_firework.json new file mode 100644 index 0000000..e71b456 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/models/item/kaninscheun_firework.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "onlyfun:item/kaninscheun_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/models/item/lbeast_firework.json b/onlyfun/src/main/resources/assets/onlyfun/models/item/lbeast_firework.json new file mode 100644 index 0000000..1a6591a --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/models/item/lbeast_firework.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "onlyfun:item/lbeast_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/models/item/poupoutain_firework.json b/onlyfun/src/main/resources/assets/onlyfun/models/item/poupoutain_firework.json new file mode 100644 index 0000000..2b13a03 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/models/item/poupoutain_firework.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "onlyfun:item/poupoutain_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/models/item/sacdchips_firework.json b/onlyfun/src/main/resources/assets/onlyfun/models/item/sacdchips_firework.json new file mode 100644 index 0000000..62b283c --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/models/item/sacdchips_firework.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "onlyfun:item/sacdchips_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/models/item/vaselline_firework.json b/onlyfun/src/main/resources/assets/onlyfun/models/item/vaselline_firework.json new file mode 100644 index 0000000..3a81508 --- /dev/null +++ b/onlyfun/src/main/resources/assets/onlyfun/models/item/vaselline_firework.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "onlyfun:item/vaselline_firework" + } +} diff --git a/onlyfun/src/main/resources/assets/onlyfun/textures/item/chrism_firework.png b/onlyfun/src/main/resources/assets/onlyfun/textures/item/chrism_firework.png new file mode 100644 index 0000000..57e03d8 Binary files /dev/null and b/onlyfun/src/main/resources/assets/onlyfun/textures/item/chrism_firework.png differ diff --git a/onlyfun/src/main/resources/assets/onlyfun/textures/item/creveforest_firework.png b/onlyfun/src/main/resources/assets/onlyfun/textures/item/creveforest_firework.png new file mode 100644 index 0000000..5f1949f Binary files /dev/null and b/onlyfun/src/main/resources/assets/onlyfun/textures/item/creveforest_firework.png differ diff --git a/onlyfun/src/main/resources/assets/onlyfun/textures/item/duncan_firework.png b/onlyfun/src/main/resources/assets/onlyfun/textures/item/duncan_firework.png new file mode 100644 index 0000000..d710611 Binary files /dev/null and b/onlyfun/src/main/resources/assets/onlyfun/textures/item/duncan_firework.png differ diff --git a/onlyfun/src/main/resources/assets/onlyfun/textures/item/kaninscheun_firework.png b/onlyfun/src/main/resources/assets/onlyfun/textures/item/kaninscheun_firework.png new file mode 100644 index 0000000..71101eb Binary files /dev/null and b/onlyfun/src/main/resources/assets/onlyfun/textures/item/kaninscheun_firework.png differ diff --git a/onlyfun/src/main/resources/assets/onlyfun/textures/item/lbeast_firework.png b/onlyfun/src/main/resources/assets/onlyfun/textures/item/lbeast_firework.png new file mode 100644 index 0000000..083b352 Binary files /dev/null and b/onlyfun/src/main/resources/assets/onlyfun/textures/item/lbeast_firework.png differ diff --git a/onlyfun/src/main/resources/assets/onlyfun/textures/item/poupoutain_firework.png b/onlyfun/src/main/resources/assets/onlyfun/textures/item/poupoutain_firework.png new file mode 100644 index 0000000..5ea71b6 Binary files /dev/null and b/onlyfun/src/main/resources/assets/onlyfun/textures/item/poupoutain_firework.png differ diff --git a/onlyfun/src/main/resources/assets/onlyfun/textures/item/sacdchips_firework.png b/onlyfun/src/main/resources/assets/onlyfun/textures/item/sacdchips_firework.png new file mode 100644 index 0000000..23e14a3 Binary files /dev/null and b/onlyfun/src/main/resources/assets/onlyfun/textures/item/sacdchips_firework.png differ diff --git a/onlyfun/src/main/resources/assets/onlyfun/textures/item/vaselline_firework.png b/onlyfun/src/main/resources/assets/onlyfun/textures/item/vaselline_firework.png new file mode 100644 index 0000000..d24520b Binary files /dev/null and b/onlyfun/src/main/resources/assets/onlyfun/textures/item/vaselline_firework.png differ diff --git a/onlyfun/src/main/resources/data/onlyfun/recipe/chrism_firework.json b/onlyfun/src/main/resources/data/onlyfun/recipe/chrism_firework.json new file mode 100644 index 0000000..d6794c1 --- /dev/null +++ b/onlyfun/src/main/resources/data/onlyfun/recipe/chrism_firework.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:firework_rocket", + "minecraft:red_dye", + "minecraft:paper" + ], + "result": { + "count": 1, + "id": "onlyfun:chrism_firework" + } +} diff --git a/onlyfun/src/main/resources/data/onlyfun/recipe/creveforest_firework.json b/onlyfun/src/main/resources/data/onlyfun/recipe/creveforest_firework.json new file mode 100644 index 0000000..f569183 --- /dev/null +++ b/onlyfun/src/main/resources/data/onlyfun/recipe/creveforest_firework.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:firework_rocket", + "minecraft:green_dye", + "minecraft:paper" + ], + "result": { + "count": 1, + "id": "onlyfun:creveforest_firework" + } +} diff --git a/onlyfun/src/main/resources/data/onlyfun/recipe/duncan_firework.json b/onlyfun/src/main/resources/data/onlyfun/recipe/duncan_firework.json new file mode 100644 index 0000000..c4e832d --- /dev/null +++ b/onlyfun/src/main/resources/data/onlyfun/recipe/duncan_firework.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:firework_rocket", + "minecraft:pink_dye", + "minecraft:paper" + ], + "result": { + "count": 1, + "id": "onlyfun:duncan_firework" + } +} diff --git a/onlyfun/src/main/resources/data/onlyfun/recipe/kaninscheun_firework.json b/onlyfun/src/main/resources/data/onlyfun/recipe/kaninscheun_firework.json new file mode 100644 index 0000000..5e27fcb --- /dev/null +++ b/onlyfun/src/main/resources/data/onlyfun/recipe/kaninscheun_firework.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:firework_rocket", + "minecraft:yellow_dye", + "minecraft:paper" + ], + "result": { + "count": 1, + "id": "onlyfun:kaninscheun_firework" + } +} diff --git a/onlyfun/src/main/resources/data/onlyfun/recipe/lbeast_firework.json b/onlyfun/src/main/resources/data/onlyfun/recipe/lbeast_firework.json new file mode 100644 index 0000000..79fbd86 --- /dev/null +++ b/onlyfun/src/main/resources/data/onlyfun/recipe/lbeast_firework.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:firework_rocket", + "minecraft:brown_dye", + "minecraft:paper" + ], + "result": { + "count": 1, + "id": "onlyfun:lbeast_firework" + } +} diff --git a/onlyfun/src/main/resources/data/onlyfun/recipe/poupoutain_firework.json b/onlyfun/src/main/resources/data/onlyfun/recipe/poupoutain_firework.json new file mode 100644 index 0000000..8fe93b7 --- /dev/null +++ b/onlyfun/src/main/resources/data/onlyfun/recipe/poupoutain_firework.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:firework_rocket", + "minecraft:light_gray_dye", + "minecraft:paper" + ], + "result": { + "count": 1, + "id": "onlyfun:poupoutain_firework" + } +} diff --git a/onlyfun/src/main/resources/data/onlyfun/recipe/sacdchips_firework.json b/onlyfun/src/main/resources/data/onlyfun/recipe/sacdchips_firework.json new file mode 100644 index 0000000..590a627 --- /dev/null +++ b/onlyfun/src/main/resources/data/onlyfun/recipe/sacdchips_firework.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:firework_rocket", + "minecraft:orange_dye", + "minecraft:paper" + ], + "result": { + "count": 1, + "id": "onlyfun:sacdchips_firework" + } +} diff --git a/onlyfun/src/main/resources/data/onlyfun/recipe/vaselline_firework.json b/onlyfun/src/main/resources/data/onlyfun/recipe/vaselline_firework.json new file mode 100644 index 0000000..367942a --- /dev/null +++ b/onlyfun/src/main/resources/data/onlyfun/recipe/vaselline_firework.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "minecraft:firework_rocket", + "minecraft:white_dye", + "minecraft:paper" + ], + "result": { + "count": 1, + "id": "onlyfun:vaselline_firework" + } +} diff --git a/onlyfun/src/test/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkSmoke.java b/onlyfun/src/test/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkSmoke.java index f6f0f4f..8ec41cb 100644 --- a/onlyfun/src/test/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkSmoke.java +++ b/onlyfun/src/test/java/fr/koka99cab/sanctuary26/onlyfun/item/SkinFaceFireworkSmoke.java @@ -5,7 +5,7 @@ import net.minecraft.SharedConstants; import net.minecraft.server.Bootstrap; import net.minecraft.world.item.component.Fireworks; -/** Executable check for the baked Nourra face and hood firework contract. */ +/** Executable check for baked skin-face firework portraits. */ public final class SkinFaceFireworkSmoke { private SkinFaceFireworkSmoke() { } @@ -17,37 +17,47 @@ public final class SkinFaceFireworkSmoke { } public static void verify() { - require(SkinFaceFireworkExplosions.WIDTH == 8 && SkinFaceFireworkExplosions.HEIGHT == 8, + require(SkinFacePortrait.values().length == 9, "Skin firework roster drifted"); + require(SkinFacePortrait.WIDTH == 8 && SkinFacePortrait.HEIGHT == 8, "Face grid is no longer 8×8"); - require(SkinFaceFireworkExplosions.FACE.length == 64, "Face palette length drifted"); - require(SkinFaceFireworkExplosions.HOOD.length == 64, "Hood overlay length drifted"); - require(SkinFaceFireworkExplosions.HOOD_TOP.length == 16, "Hood top strip length drifted"); - require(SkinFaceFireworkExplosions.FACE[5 * 8 + 2] == 0x4A9DFC - && SkinFaceFireworkExplosions.FACE[5 * 8 + 5] == 0x4A9DFC, - "Blue eyes are missing from the inner face"); - require(SkinFaceFireworkExplosions.FACE[4 * 8 + 3] == 0xFFF0E1, - "Skin tone is missing from the baked face"); - require(SkinFaceFireworkExplosions.HOOD[2] == 0xCBCBCB, - "Hood overlay is missing from the top of the face"); - require(SkinFaceFireworkExplosions.HOOD[5 * 8 + 2] == 0x181818, - "Hood no longer covers the left eye"); - require(SkinFaceFireworkExplosions.HOOD[5 * 8 + 5] == SkinFaceFireworkExplosions.TRANSPARENT, - "Hood opening no longer leaves the right eye visible"); - require(SkinFaceFireworkExplosions.opaqueHoodPixels() == 43, - "Opaque hood pixel count drifted"); + for (SkinFacePortrait portrait : SkinFacePortrait.values()) { + require(portrait.face().length == 64, portrait.id() + " face palette length drifted"); + require(portrait.hood().length == 64, portrait.id() + " hood overlay length drifted"); + require(portrait.hoodTop().length == 16, portrait.id() + " hood top strip length drifted"); + int[] pixels = portrait.portrait(); + require(pixels.length == 80 && portrait.portraitHeight() == 10, + portrait.id() + " portrait grid drifted"); + require(portrait.itemId().equals(portrait.id() + "_firework"), + portrait.id() + " item id drifted"); + } + require(SkinFacePortrait.NOURRA.face()[5 * 8 + 2] == 0x4A9DFC + && SkinFacePortrait.NOURRA.face()[5 * 8 + 5] == 0x4A9DFC, + "Blue eyes are missing from the Nourra face"); + require(SkinFacePortrait.NOURRA.face()[4 * 8 + 3] == 0xFFF0E1, + "Skin tone is missing from the baked Nourra face"); + require(SkinFacePortrait.NOURRA.hood()[2] == 0xCBCBCB, + "Hood overlay is missing from the top of the Nourra face"); + require(SkinFacePortrait.NOURRA.hood()[5 * 8 + 2] == 0x181818, + "Nourra hood no longer covers the left eye"); + require(SkinFacePortrait.NOURRA.hood()[5 * 8 + 5] == SkinFacePortrait.TRANSPARENT, + "Nourra hood opening no longer leaves the right eye visible"); + require(SkinFacePortrait.NOURRA.opaqueHoodPixels() == 43, + "Opaque Nourra hood pixel count drifted"); + int[] nourra = SkinFacePortrait.NOURRA.portrait(); + require(nourra[16 + 5 * 8 + 5] == 0x4A9DFC, + "Right eye is missing from the composited Nourra portrait"); + require(nourra[2] == 0xD8D8D8, + "Hood top is missing from the Nourra portrait"); + require(SkinFacePortrait.CHRISM.face()[6 * 8 + 1] == 0xFFFFFF, + "ChrisM eyes are missing from the baked face"); + require(SkinFacePortrait.DUNCAN.face().length == 64, + "Duncan face is missing"); Fireworks fireworks = SkinFaceFireworkExplosions.defaultFireworks(); require(fireworks.flightDuration() == 3 && fireworks.explosions().isEmpty(), "Default firework burst contract changed"); require(SkinFaceFireworkExplosions.LIFETIME_TRIM_TICKS == 5 && SkinFaceFireworkExplosions.midFlightLifetime(45) == 40, "Mid-flight lifetime trim drifted"); - int[] portrait = SkinFaceFireworkExplosions.portrait(); - require(portrait.length == 80 && SkinFaceFireworkExplosions.portraitHeight() == 10, - "Portrait grid drifted"); - require(portrait[16 + 5 * 8 + 5] == 0x4A9DFC, - "Right eye is missing from the composited portrait"); - require(portrait[2] == 0xD8D8D8, - "Hood top is missing from the portrait"); require(SkinFaceFireworkClient.PIXEL == 1.85D, "Portrait scale drifted"); require(SkinFaceFireworkClient.LARGE_PIXEL == 2.7D, "Large portrait scale drifted"); require(SkinFaceFireworkClient.burstPixel(false) == SkinFaceFireworkClient.PIXEL @@ -57,7 +67,7 @@ public final class SkinFaceFireworkSmoke { && SkinFaceFireworkClient.burstSparkSize(true) == SkinFaceFireworkClient.LARGE_SPARK_SIZE, "Large burst scale drifted"); require(SkinFaceFireworkClient.SPARK_LIFETIME_TICKS == 38, "Spark lifetime drifted"); - System.out.println("Only Fun Nourra firework: 8×8 face with hood overlay ready."); + System.out.println("Only Fun skin fireworks: 9 baked faces with hood overlay ready."); } private static void require(boolean condition, String message) {