From a3c1248e9f95fc99682e4a142cdad8123c4aa037 Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 22 Mar 2024 00:07:36 +0000 Subject: [PATCH 01/73] Move all remaining regular recipes to datagen --- .../com/minelittlepony/unicopia/UTags.java | 1 + .../unicopia/block/FancyBedBlock.java | 1 + .../entity/CloudBedBlockEntityRenderer.java | 2 +- .../datagen/CraftingMaterialHelper.java | 65 +++ .../unicopia/datagen/UBlockFamilies.java | 20 + .../BedSheetPatternRecipeBuilder.java | 83 +++ .../providers/UBlockStateModelGenerator.java | 2 +- .../datagen/providers/UItemTagProvider.java | 3 +- .../datagen/providers/URecipeProvider.java | 533 +++++++++++++++++- .../minelittlepony/unicopia/item/UItems.java | 1 + .../recipes/blocks/chiselled_chitin.json | 30 - .../recipes/blocks/chiselled_chitin_hull.json | 30 - .../recipes/blocks/chiselled_chitin_slab.json | 30 - .../blocks/chiselled_chitin_stairs.json | 30 - .../recipes/blocks/chitin_spikes.json | 30 - .../recipes/blocks/cloud_brick_slab.json | 30 - .../recipes/blocks/cloud_brick_stairs.json | 30 - .../recipes/blocks/cloud_pillar.json | 30 - .../recipes/blocks/cloud_plank_slab.json | 30 - .../recipes/blocks/cloud_plank_stairs.json | 30 - .../recipes/blocks/cloud_planks.json | 30 - .../recipes/blocks/cloud_slab.json | 30 - .../recipes/blocks/cloud_stairs.json | 30 - .../recipes/blocks/dense_cloud.json | 30 - .../recipes/blocks/dense_cloud_slab.json | 30 - .../recipes/blocks/dense_cloud_stairs.json | 30 - .../advancements/recipes/cloud_lump.json | 30 - .../advancements/recipes/crystal_heart.json | 30 - .../advancements/recipes/empty_jar.json | 30 - .../advancements/recipes/food/apple_pie.json | 30 - .../recipes/food/apple_pie_from_slices.json | 30 - .../recipes/food/burned_juice.json | 30 - .../recipes/food/burned_toast.json | 30 - .../recipes/food/candied_apple.json | 32 -- .../advancements/recipes/food/cider.json | 34 -- .../advancements/recipes/food/hay_fries.json | 30 - .../recipes/food/horse_shoe_fries.json | 30 - .../advancements/recipes/food/jam_toast.json | 31 - .../advancements/recipes/food/juice.json | 30 - .../advancements/recipes/food/muffin.json | 38 -- .../advancements/recipes/food/oatmeal.json | 30 - .../advancements/recipes/food/rock_candy.json | 31 - .../advancements/recipes/food/rock_stew.json | 30 - .../advancements/recipes/food/toast.json | 30 - .../recipes/food/zap_apple_jam_jar.json | 30 - .../recipes/friendship_bracelet.json | 30 - .../advancements/recipes/gemstone.json | 30 - .../advancements/recipes/golden_feather.json | 31 - .../advancements/recipes/golden_wing.json | 30 - .../recipes/meadowbrooks_staff.json | 30 - .../unicopia/advancements/recipes/mug.json | 30 - .../advancements/recipes/pegasus_amulet.json | 30 - .../advancements/recipes/pineapple_crown.json | 30 - .../unicopia/advancements/recipes/shelly.json | 30 - .../advancements/recipes/spellbook.json | 30 - .../recipes/tools/diamond_polearm.json | 30 - .../recipes/tools/golden_polearm.json | 30 - .../recipes/tools/iron_polearm.json | 30 - .../tools/netherite_polearm_smithing.json | 30 - .../recipes/tools/stone_polearm.json | 30 - .../recipes/tools/wooden_polearm.json | 30 - .../advancements/recipes/unicorn_amulet.json | 30 - .../advancements/recipes/weather_vane.json | 30 - .../data/unicopia/recipes/apple_pie.json | 19 - .../recipes/apple_pie_slice_to_apple_pie.json | 12 - .../data/unicopia/recipes/arrow.json | 23 - .../unicopia/recipes/bed_sheets/apple.json | 21 - .../data/unicopia/recipes/bed_sheets/bar.json | 21 - .../unicopia/recipes/bed_sheets/black.json | 18 - .../unicopia/recipes/bed_sheets/blue.json | 18 - .../unicopia/recipes/bed_sheets/brown.json | 18 - .../unicopia/recipes/bed_sheets/checker.json | 21 - .../unicopia/recipes/bed_sheets/cyan.json | 18 - .../unicopia/recipes/bed_sheets/gray.json | 18 - .../unicopia/recipes/bed_sheets/green.json | 18 - .../unicopia/recipes/bed_sheets/kelp.json | 18 - .../recipes/bed_sheets/light_blue.json | 18 - .../recipes/bed_sheets/light_gray.json | 18 - .../unicopia/recipes/bed_sheets/lime.json | 18 - .../unicopia/recipes/bed_sheets/magenta.json | 18 - .../unicopia/recipes/bed_sheets/orange.json | 18 - .../unicopia/recipes/bed_sheets/pink.json | 18 - .../unicopia/recipes/bed_sheets/purple.json | 18 - .../unicopia/recipes/bed_sheets/rainbow.json | 36 -- .../recipes/bed_sheets/rainbow_bpw.json | 24 - .../recipes/bed_sheets/rainbow_bpy.json | 24 - .../recipes/bed_sheets/rainbow_pgb.json | 27 - .../recipes/bed_sheets/rainbow_pwr.json | 24 - .../data/unicopia/recipes/bed_sheets/red.json | 18 - .../unicopia/recipes/bed_sheets/yellow.json | 18 - .../data/unicopia/recipes/burned_juice.json | 9 - .../recipes/burned_juice_to_coal.json | 9 - .../data/unicopia/recipes/burned_toast.json | 9 - .../data/unicopia/recipes/candied_apple.json | 12 - .../unicopia/recipes/chiselled_chitin.json | 13 - .../recipes/chiselled_chitin_hull.json | 16 - .../recipes/chiselled_chitin_slab.json | 12 - .../recipes/chiselled_chitin_stairs.json | 14 - .../data/unicopia/recipes/chitin.json | 14 - .../data/unicopia/recipes/chitin_spikes.json | 13 - .../data/unicopia/recipes/cider.json | 23 - .../data/unicopia/recipes/cloth_bed.json | 20 - .../data/unicopia/recipes/cloud_bed.json | 16 - .../data/unicopia/recipes/cloud_block.json | 13 - .../unicopia/recipes/cloud_brick_slab.json | 12 - .../unicopia/recipes/cloud_brick_stairs.json | 14 - .../data/unicopia/recipes/cloud_chest.json | 14 - .../data/unicopia/recipes/cloud_door.json | 14 - .../data/unicopia/recipes/cloud_lump.json | 7 - .../data/unicopia/recipes/cloud_pillar.json | 14 - .../unicopia/recipes/cloud_plank_slab.json | 12 - .../unicopia/recipes/cloud_plank_stairs.json | 14 - .../data/unicopia/recipes/cloud_planks.json | 13 - .../data/unicopia/recipes/cloud_slab.json | 12 - .../data/unicopia/recipes/cloud_stairs.json | 14 - .../unicopia/recipes/cooked_zap_apple.json | 9 - .../unicopia/recipes/copper_horse_shoe.json | 16 - .../unicopia/recipes/crispy_hay_fries.json | 9 - .../data/unicopia/recipes/crystal_door.json | 16 - .../data/unicopia/recipes/crystal_heart.json | 16 - .../data/unicopia/recipes/crystal_shard.json | 10 - .../recipes/daffodil_daisy_sandwich.json | 19 - .../recipes/dark_oak_stable_door.json | 19 - .../data/unicopia/recipes/dense_cloud.json | 14 - .../unicopia/recipes/dense_cloud_slab.json | 12 - .../unicopia/recipes/dense_cloud_stairs.json | 14 - .../unicopia/recipes/diamond_polearm.json | 19 - .../data/unicopia/recipes/easy_cider.json | 10 - .../data/unicopia/recipes/empty_jar.json | 20 - .../data/unicopia/recipes/filled_jar.json | 3 - .../unicopia/recipes/filled_jar_emptied.json | 3 - .../unicopia/recipes/friendship_bracelet.json | 19 - .../data/unicopia/recipes/gemstone.json | 15 - .../data/unicopia/recipes/giant_balloon.json | 21 - .../data/unicopia/recipes/glowing_bangle.json | 3 - .../data/unicopia/recipes/gold_nugget.json | 9 - .../data/unicopia/recipes/golden_feather.json | 19 - .../unicopia/recipes/golden_horse_shoe.json | 16 - .../data/unicopia/recipes/golden_polearm.json | 19 - .../data/unicopia/recipes/golden_wing.json | 16 - .../unicopia/recipes/gravel_to_pebbles.json | 7 - .../recipes/green_apple_to_seeds.json | 7 - .../data/unicopia/recipes/hay_burger.json | 19 - .../data/unicopia/recipes/hay_fries.json | 14 - .../resources/data/unicopia/recipes/hive.json | 17 - .../unicopia/recipes/horse_shoe_fries.json | 17 - .../unicopia/recipes/iron_horse_shoe.json | 16 - .../data/unicopia/recipes/iron_polearm.json | 19 - .../data/unicopia/recipes/jam_toast.json | 20 - .../data/unicopia/recipes/juice.json | 13 - .../data/unicopia/recipes/magic_staff.json | 19 - .../meadowbrook_staff_dissassembly.json | 10 - .../unicopia/recipes/meadowbrooks_staff.json | 16 - .../data/unicopia/recipes/muffin.json | 14 - .../resources/data/unicopia/recipes/mug.json | 17 - .../recipes/netherite_horse_shoe.json | 16 - .../recipes/netherite_polearm_smithing.json | 15 - .../data/unicopia/recipes/oatmeal.json | 11 - .../data/unicopia/recipes/pearl_necklace.json | 15 - .../unicopia/recipes/pebbles_to_gravel.json | 14 - .../data/unicopia/recipes/pegasus_amulet.json | 13 - .../unicopia/recipes/pineapple_crown.json | 7 - .../unicopia/recipes/repair_sunglasses.json | 10 - .../data/unicopia/recipes/rock_candy.json | 15 - .../data/unicopia/recipes/rock_stew.json | 10 - .../recipes/rocks_to_cobblestone.json | 13 - .../data/unicopia/recipes/shaping_bench.json | 13 - .../data/unicopia/recipes/shelly.json | 14 - .../unicopia/recipes/sour_apple_to_seeds.json | 7 - .../data/unicopia/recipes/spellbook.json | 8 - .../data/unicopia/recipes/stable_door.json | 19 - .../stone_cutting/chiselled_chitin_hull.json | 6 - .../stone_cutting/chiselled_chitin_slab.json | 6 - .../chiselled_chitin_stairs.json | 6 - .../data/unicopia/recipes/stone_polearm.json | 19 - .../unicopia/recipes/stripped_palm_wood.json | 18 - .../data/unicopia/recipes/sunglasses.json | 14 - .../recipes/sweet_apple_to_seeds.json | 7 - .../data/unicopia/recipes/toast.json | 9 - .../data/unicopia/recipes/unstable_cloud.json | 18 - .../recipes/waxed_stripped_zap_log.json | 8 - .../recipes/waxed_stripped_zap_wood.json | 8 - .../data/unicopia/recipes/waxed_zap_log.json | 8 - .../data/unicopia/recipes/weather_vane.json | 16 - .../data/unicopia/recipes/wooden_polearm.json | 19 - .../data/unicopia/recipes/worms_to_dirt.json | 19 - .../data/unicopia/recipes/writable_book.json | 17 - .../unicopia/recipes/zap_apple_jam_jar.json | 19 - 188 files changed, 681 insertions(+), 3498 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/CraftingMaterialHelper.java create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/BedSheetPatternRecipeBuilder.java delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_hull.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_slab.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_stairs.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/chitin_spikes.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_brick_slab.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_brick_stairs.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_pillar.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_plank_slab.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_plank_stairs.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_planks.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_slab.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_stairs.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud_slab.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud_stairs.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/cloud_lump.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/crystal_heart.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/empty_jar.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/apple_pie.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/apple_pie_from_slices.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/burned_juice.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/burned_toast.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/candied_apple.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/cider.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/hay_fries.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/horse_shoe_fries.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/jam_toast.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/juice.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/muffin.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/oatmeal.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/rock_candy.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/rock_stew.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/toast.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/food/zap_apple_jam_jar.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/friendship_bracelet.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/gemstone.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/golden_feather.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/golden_wing.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/meadowbrooks_staff.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/mug.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/pegasus_amulet.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/pineapple_crown.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/shelly.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/spellbook.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/tools/diamond_polearm.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/tools/golden_polearm.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/tools/iron_polearm.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/tools/netherite_polearm_smithing.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/tools/stone_polearm.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/tools/wooden_polearm.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/unicorn_amulet.json delete mode 100644 src/main/resources/data/unicopia/advancements/recipes/weather_vane.json delete mode 100644 src/main/resources/data/unicopia/recipes/apple_pie.json delete mode 100644 src/main/resources/data/unicopia/recipes/apple_pie_slice_to_apple_pie.json delete mode 100644 src/main/resources/data/unicopia/recipes/arrow.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/apple.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/bar.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/black.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/blue.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/brown.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/checker.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/cyan.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/gray.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/green.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/kelp.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/light_blue.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/light_gray.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/lime.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/magenta.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/orange.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/pink.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/purple.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/rainbow.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_bpw.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_bpy.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_pgb.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_pwr.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/red.json delete mode 100644 src/main/resources/data/unicopia/recipes/bed_sheets/yellow.json delete mode 100644 src/main/resources/data/unicopia/recipes/burned_juice.json delete mode 100644 src/main/resources/data/unicopia/recipes/burned_juice_to_coal.json delete mode 100644 src/main/resources/data/unicopia/recipes/burned_toast.json delete mode 100644 src/main/resources/data/unicopia/recipes/candied_apple.json delete mode 100644 src/main/resources/data/unicopia/recipes/chiselled_chitin.json delete mode 100644 src/main/resources/data/unicopia/recipes/chiselled_chitin_hull.json delete mode 100644 src/main/resources/data/unicopia/recipes/chiselled_chitin_slab.json delete mode 100644 src/main/resources/data/unicopia/recipes/chiselled_chitin_stairs.json delete mode 100644 src/main/resources/data/unicopia/recipes/chitin.json delete mode 100644 src/main/resources/data/unicopia/recipes/chitin_spikes.json delete mode 100644 src/main/resources/data/unicopia/recipes/cider.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloth_bed.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_bed.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_block.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_brick_slab.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_brick_stairs.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_chest.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_door.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_lump.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_pillar.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_plank_slab.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_plank_stairs.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_planks.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_slab.json delete mode 100644 src/main/resources/data/unicopia/recipes/cloud_stairs.json delete mode 100644 src/main/resources/data/unicopia/recipes/cooked_zap_apple.json delete mode 100644 src/main/resources/data/unicopia/recipes/copper_horse_shoe.json delete mode 100644 src/main/resources/data/unicopia/recipes/crispy_hay_fries.json delete mode 100644 src/main/resources/data/unicopia/recipes/crystal_door.json delete mode 100644 src/main/resources/data/unicopia/recipes/crystal_heart.json delete mode 100644 src/main/resources/data/unicopia/recipes/crystal_shard.json delete mode 100644 src/main/resources/data/unicopia/recipes/daffodil_daisy_sandwich.json delete mode 100644 src/main/resources/data/unicopia/recipes/dark_oak_stable_door.json delete mode 100644 src/main/resources/data/unicopia/recipes/dense_cloud.json delete mode 100644 src/main/resources/data/unicopia/recipes/dense_cloud_slab.json delete mode 100644 src/main/resources/data/unicopia/recipes/dense_cloud_stairs.json delete mode 100644 src/main/resources/data/unicopia/recipes/diamond_polearm.json delete mode 100644 src/main/resources/data/unicopia/recipes/easy_cider.json delete mode 100644 src/main/resources/data/unicopia/recipes/empty_jar.json delete mode 100644 src/main/resources/data/unicopia/recipes/filled_jar.json delete mode 100644 src/main/resources/data/unicopia/recipes/filled_jar_emptied.json delete mode 100644 src/main/resources/data/unicopia/recipes/friendship_bracelet.json delete mode 100644 src/main/resources/data/unicopia/recipes/gemstone.json delete mode 100644 src/main/resources/data/unicopia/recipes/giant_balloon.json delete mode 100644 src/main/resources/data/unicopia/recipes/glowing_bangle.json delete mode 100644 src/main/resources/data/unicopia/recipes/gold_nugget.json delete mode 100644 src/main/resources/data/unicopia/recipes/golden_feather.json delete mode 100644 src/main/resources/data/unicopia/recipes/golden_horse_shoe.json delete mode 100644 src/main/resources/data/unicopia/recipes/golden_polearm.json delete mode 100644 src/main/resources/data/unicopia/recipes/golden_wing.json delete mode 100644 src/main/resources/data/unicopia/recipes/gravel_to_pebbles.json delete mode 100644 src/main/resources/data/unicopia/recipes/green_apple_to_seeds.json delete mode 100644 src/main/resources/data/unicopia/recipes/hay_burger.json delete mode 100644 src/main/resources/data/unicopia/recipes/hay_fries.json delete mode 100644 src/main/resources/data/unicopia/recipes/hive.json delete mode 100644 src/main/resources/data/unicopia/recipes/horse_shoe_fries.json delete mode 100644 src/main/resources/data/unicopia/recipes/iron_horse_shoe.json delete mode 100644 src/main/resources/data/unicopia/recipes/iron_polearm.json delete mode 100644 src/main/resources/data/unicopia/recipes/jam_toast.json delete mode 100644 src/main/resources/data/unicopia/recipes/juice.json delete mode 100644 src/main/resources/data/unicopia/recipes/magic_staff.json delete mode 100644 src/main/resources/data/unicopia/recipes/meadowbrook_staff_dissassembly.json delete mode 100644 src/main/resources/data/unicopia/recipes/meadowbrooks_staff.json delete mode 100644 src/main/resources/data/unicopia/recipes/muffin.json delete mode 100644 src/main/resources/data/unicopia/recipes/mug.json delete mode 100644 src/main/resources/data/unicopia/recipes/netherite_horse_shoe.json delete mode 100644 src/main/resources/data/unicopia/recipes/netherite_polearm_smithing.json delete mode 100644 src/main/resources/data/unicopia/recipes/oatmeal.json delete mode 100644 src/main/resources/data/unicopia/recipes/pearl_necklace.json delete mode 100644 src/main/resources/data/unicopia/recipes/pebbles_to_gravel.json delete mode 100644 src/main/resources/data/unicopia/recipes/pegasus_amulet.json delete mode 100644 src/main/resources/data/unicopia/recipes/pineapple_crown.json delete mode 100644 src/main/resources/data/unicopia/recipes/repair_sunglasses.json delete mode 100644 src/main/resources/data/unicopia/recipes/rock_candy.json delete mode 100644 src/main/resources/data/unicopia/recipes/rock_stew.json delete mode 100644 src/main/resources/data/unicopia/recipes/rocks_to_cobblestone.json delete mode 100644 src/main/resources/data/unicopia/recipes/shaping_bench.json delete mode 100644 src/main/resources/data/unicopia/recipes/shelly.json delete mode 100644 src/main/resources/data/unicopia/recipes/sour_apple_to_seeds.json delete mode 100644 src/main/resources/data/unicopia/recipes/spellbook.json delete mode 100644 src/main/resources/data/unicopia/recipes/stable_door.json delete mode 100644 src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_hull.json delete mode 100644 src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_slab.json delete mode 100644 src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_stairs.json delete mode 100644 src/main/resources/data/unicopia/recipes/stone_polearm.json delete mode 100644 src/main/resources/data/unicopia/recipes/stripped_palm_wood.json delete mode 100644 src/main/resources/data/unicopia/recipes/sunglasses.json delete mode 100644 src/main/resources/data/unicopia/recipes/sweet_apple_to_seeds.json delete mode 100644 src/main/resources/data/unicopia/recipes/toast.json delete mode 100644 src/main/resources/data/unicopia/recipes/unstable_cloud.json delete mode 100644 src/main/resources/data/unicopia/recipes/waxed_stripped_zap_log.json delete mode 100644 src/main/resources/data/unicopia/recipes/waxed_stripped_zap_wood.json delete mode 100644 src/main/resources/data/unicopia/recipes/waxed_zap_log.json delete mode 100644 src/main/resources/data/unicopia/recipes/weather_vane.json delete mode 100644 src/main/resources/data/unicopia/recipes/wooden_polearm.json delete mode 100644 src/main/resources/data/unicopia/recipes/worms_to_dirt.json delete mode 100644 src/main/resources/data/unicopia/recipes/writable_book.json delete mode 100644 src/main/resources/data/unicopia/recipes/zap_apple_jam_jar.json diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index f15c228e..ecbe9cf4 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -36,6 +36,7 @@ public interface UTags { TagKey BASKETS = item("baskets"); TagKey BADGES = item("badges"); + TagKey WOOL_BED_SHEETS = item("wool_bed_sheets"); TagKey BED_SHEETS = item("bed_sheets"); TagKey CLOUD_JARS = item("cloud_jars"); diff --git a/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java b/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java index 259aca1d..c132e05e 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java @@ -127,6 +127,7 @@ public class FancyBedBlock extends BedBlock { public enum SheetPattern implements StringIdentifiable { NONE(DyeColor.WHITE), + WHITE(DyeColor.WHITE), LIGHT_GRAY(DyeColor.LIGHT_GRAY), GRAY(DyeColor.GRAY), BLACK(DyeColor.BLACK), diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/entity/CloudBedBlockEntityRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/entity/CloudBedBlockEntityRenderer.java index 9d10611a..cd1b2428 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/entity/CloudBedBlockEntityRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/entity/CloudBedBlockEntityRenderer.java @@ -100,7 +100,7 @@ public class CloudBedBlockEntityRenderer implements BlockEntityRenderer> MATERIALS = Map.of( + "wood", ItemTags.PLANKS, + "stone", ItemTags.STONE_TOOL_MATERIALS, + "iron", ConventionalItemTags.IRON_INGOTS, + "gold", ConventionalItemTags.GOLD_INGOTS, + "copper", ConventionalItemTags.COPPER_INGOTS, + "netherite", ConventionalItemTags.NETHERITE_INGOTS + ); + + static Either> getMaterial(Item output, String toStrip, String suffex) { + Identifier id = Registries.ITEM.getId(output).withPath(p -> p.replace(toStrip, "") + suffex); + TagKey tag = MATERIALS.getOrDefault(id.getPath().replace("en_", "_").split("_")[0], null); + if (tag != null) { + return Either.right(tag); + } + return Either.left( + Registries.ITEM.getOrEmpty(id) + .or(() -> Registries.ITEM.getOrEmpty(new Identifier(Identifier.DEFAULT_NAMESPACE, id.getPath()))) + .or(() -> Registries.ITEM.getOrEmpty(new Identifier(Identifier.DEFAULT_NAMESPACE, id.getPath().replace(suffex, "")))) + .orElseThrow(() -> new NoSuchElementException("No item with id " + id)) + ); + } + + static Item getItem(Identifier id) { + return Registries.ITEM.getOrEmpty(id).orElseThrow(() -> new NoSuchElementException("No item with id " + id)); + } + + static ShapedRecipeJsonBuilder input(ShapedRecipeJsonBuilder builder, char key, Either> material) { + material.ifLeft(i -> builder.input(key, i)); + material.ifRight(i -> builder.input(key, i)); + return builder; + } + + static InventoryChangedCriterion.Conditions conditionsFromEither(Either> material) { + return material.map(RecipeProvider::conditionsFromItem, RecipeProvider::conditionsFromTag); + } + + static String hasEither(Either> material) { + return material.map(VanillaRecipeProvider::hasItem, CraftingMaterialHelper::hasTag); + } + + static String hasTag(TagKey tag) { + return "has_" + tag.id(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/UBlockFamilies.java b/src/main/java/com/minelittlepony/unicopia/datagen/UBlockFamilies.java index 624d3a9c..7d80df0f 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/UBlockFamilies.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/UBlockFamilies.java @@ -19,4 +19,24 @@ public interface UBlockFamilies { .slab(UBlocks.WAXED_ZAP_SLAB).stairs(UBlocks.WAXED_ZAP_STAIRS).fence(UBlocks.WAXED_ZAP_FENCE).fenceGate(UBlocks.WAXED_ZAP_FENCE_GATE) .group("wooden").unlockCriterionName("has_planks") .build(); + BlockFamily CHISELED_CHITIN = new BlockFamily.Builder(UBlocks.CHISELLED_CHITIN) + .slab(UBlocks.CHISELLED_CHITIN_SLAB).stairs(UBlocks.CHISELLED_CHITIN_STAIRS) + .group("chitin").unlockCriterionName("has_chiselled_chitin") + .build(); + BlockFamily CLOUD = new BlockFamily.Builder(UBlocks.CLOUD) + .slab(UBlocks.CLOUD_SLAB).stairs(UBlocks.CLOUD_STAIRS) + .group("cloud").unlockCriterionName("has_cloud_lump") + .build(); + BlockFamily CLOUD_PLANKS = new BlockFamily.Builder(UBlocks.CLOUD_PLANKS) + .slab(UBlocks.CLOUD_PLANK_SLAB).stairs(UBlocks.CLOUD_PLANK_STAIRS) + .group("cloud").unlockCriterionName("has_cloud") + .build(); + BlockFamily CLOUD_BRICKS = new BlockFamily.Builder(UBlocks.CLOUD_BRICKS) + .slab(UBlocks.CLOUD_BRICK_SLAB).stairs(UBlocks.CLOUD_BRICK_STAIRS) + .group("cloud").unlockCriterionName("has_cloud_bricks") + .build(); + BlockFamily DENSE_CLOUD = new BlockFamily.Builder(UBlocks.DENSE_CLOUD) + .slab(UBlocks.DENSE_CLOUD_SLAB).stairs(UBlocks.DENSE_CLOUD_STAIRS) + .group("cloud").unlockCriterionName("has_dense_cloud") + .build(); } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/BedSheetPatternRecipeBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/BedSheetPatternRecipeBuilder.java new file mode 100644 index 00000000..2eb01643 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/BedSheetPatternRecipeBuilder.java @@ -0,0 +1,83 @@ +package com.minelittlepony.unicopia.datagen.providers; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.UTags; +import com.minelittlepony.unicopia.item.UItems; + +import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; +import net.minecraft.item.ItemConvertible; +import net.minecraft.recipe.book.RecipeCategory; + +public class BedSheetPatternRecipeBuilder { + record PatternTemplate(List symbols, List uniqueSymbols, String[] pattern) { + static final PatternTemplate ONE_COLOR = new PatternTemplate(new String[] { "###", "# #", " ##" }); + static final PatternTemplate TWO_COLOR = new PatternTemplate(new String[] { "#%#", "% %", " %#" }); + static final PatternTemplate THREE_COLOR = new PatternTemplate(new String[] { "cvc", "h h", " vc" }); + static final PatternTemplate FOUR_COLOR = new PatternTemplate(new String[] { "wgb", "p g", " pw" }); + static final PatternTemplate SEVEN_COLOR = new PatternTemplate(new String[] { "roy", "l b", " pg" }); + + PatternTemplate(String[] pattern) { + this(List.of( + pattern[1].charAt(0), + pattern[0].charAt(0), + pattern[0].charAt(1), + pattern[0].charAt(2), + pattern[1].charAt(2), + pattern[2].charAt(2), + pattern[2].charAt(1) + ), pattern); + } + + PatternTemplate(List symbols, String[] pattern) { + this(symbols, symbols.stream().distinct().toList(), pattern); + } + + void offerWithoutConversion(Consumer exporter, ItemConvertible output, ItemConvertible...wool) { + offerRecipe(this, null, exporter, output, wool); + } + + void offerTo(Consumer exporter, ItemConvertible output, ItemConvertible...wool) { + Map symbolMap = new HashMap<>(); + offerRecipe(this, symbolMap, exporter, output, wool); + offerBedSheetConversionRecipe(exporter, output, symbols.stream().map(symbolMap::get)); + } + } + + private static void offerRecipe(PatternTemplate template, @Nullable Map symbolMap, Consumer exporter, ItemConvertible output, ItemConvertible...wool) { + ShapedRecipeJsonBuilder builder = ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output); + for (int i = 0; i < template.uniqueSymbols().size(); i++) { + builder.input(template.uniqueSymbols().get(i), wool[i]); + if (symbolMap != null) { + symbolMap.put(template.uniqueSymbols().get(i), wool[i]); + } + } + for (int i = 0; i < template.pattern().length; i++) { + builder.pattern(template.pattern()[i]); + } + Arrays.asList(wool).stream().distinct().forEach(input -> { + builder.criterion(RecipeProvider.hasItem(input), RecipeProvider.conditionsFromItem(input)); + }); + builder.group("bed_sheet").offerTo(exporter); + } + + private static void offerBedSheetConversionRecipe(Consumer exporter, ItemConvertible output, Stream wools) { + var builder = ShapelessRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output) + .input(UTags.WOOL_BED_SHEETS).criterion("has_bed_sheet", RecipeProvider.conditionsFromTag(UTags.WOOL_BED_SHEETS)); + wools.forEach(builder::input); + builder + .group("bed_sheet") + .offerTo(exporter, RecipeProvider.convertBetween(output, UItems.WHITE_BED_SHEETS)); + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java index 9cd28f3a..2b86e3d2 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java @@ -108,7 +108,7 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator { // chitin blocks registerTopsoil(UBlocks.SURFACE_CHITIN, UBlocks.CHITIN); registerHollow(UBlocks.CHITIN); - registerCubeAllModelTexturePool(UBlocks.CHISELLED_CHITIN).stairs(UBlocks.CHISELLED_CHITIN_STAIRS).slab(UBlocks.CHISELLED_CHITIN_SLAB); + registerCubeAllModelTexturePool(UBlocks.CHISELLED_CHITIN).family(UBlockFamilies.CHISELED_CHITIN); registerHiveBlock(UBlocks.HIVE); registerRotated(UBlocks.CHITIN_SPIKES, BlockModels.SPIKES); registerHull(UBlocks.CHISELLED_CHITIN_HULL, UBlocks.CHITIN, UBlocks.CHISELLED_CHITIN); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UItemTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UItemTagProvider.java index 9121d3b8..058f636d 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UItemTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UItemTagProvider.java @@ -76,7 +76,8 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { .map(race -> race.getId().withPath(p -> p + "_badge")) .flatMap(id -> Registries.ITEM.getOrEmpty(id).stream()) .toArray(Item[]::new)); - getOrCreateTagBuilder(UTags.BED_SHEETS).add(BedsheetsItem.ITEMS.values().stream().toArray(Item[]::new)); + getOrCreateTagBuilder(UTags.WOOL_BED_SHEETS).add(BedsheetsItem.ITEMS.values().stream().filter(sheet -> sheet != UItems.KELP_BED_SHEETS).toArray(Item[]::new)); + getOrCreateTagBuilder(UTags.BED_SHEETS).forceAddTag(UTags.WOOL_BED_SHEETS).add(UItems.KELP_BED_SHEETS); getOrCreateTagBuilder(UTags.APPLE_SEEDS).add(UItems.GREEN_APPLE_SEEDS, UItems.SWEET_APPLE_SEEDS, UItems.SOUR_APPLE_SEEDS); getOrCreateTagBuilder(UTags.MAGIC_FEATHERS).add(UItems.PEGASUS_FEATHER, UItems.GRYPHON_FEATHER); getOrCreateTagBuilder(UTags.FRESH_APPLES).add(Items.APPLE, UItems.GREEN_APPLE, UItems.SWEET_APPLE, UItems.SOUR_APPLE); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/URecipeProvider.java index ae861761..274be45f 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/URecipeProvider.java @@ -1,72 +1,548 @@ package com.minelittlepony.unicopia.datagen.providers; import java.util.Arrays; -import java.util.NoSuchElementException; +import java.util.List; import java.util.function.Consumer; +import org.jetbrains.annotations.Nullable; +import com.minelittlepony.unicopia.UConventionalTags; import com.minelittlepony.unicopia.UTags; +import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.block.UBlocks; +import com.minelittlepony.unicopia.datagen.CraftingMaterialHelper; import com.minelittlepony.unicopia.datagen.ItemFamilies; import com.minelittlepony.unicopia.datagen.UBlockFamilies; +import com.minelittlepony.unicopia.datagen.providers.BedSheetPatternRecipeBuilder.PatternTemplate; import com.minelittlepony.unicopia.item.UItems; +import com.minelittlepony.unicopia.item.URecipes; +import com.mojang.datafixers.util.Either; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; +import net.fabricmc.fabric.api.tag.convention.v1.ConventionalItemTags; +import net.minecraft.advancement.criterion.InventoryChangedCriterion; import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.data.server.recipe.ComplexRecipeJsonBuilder; import net.minecraft.data.server.recipe.RecipeJsonProvider; -import net.minecraft.data.server.recipe.RecipeProvider; import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; -import net.minecraft.data.server.recipe.VanillaRecipeProvider; import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; import net.minecraft.item.Items; +import net.minecraft.predicate.NumberRange; +import net.minecraft.predicate.entity.LootContextPredicate; +import net.minecraft.predicate.item.ItemPredicate; +import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; +import net.minecraft.registry.tag.ItemTags; +import net.minecraft.registry.tag.TagKey; public class URecipeProvider extends FabricRecipeProvider { + private static final List WOOLS = List.of(Items.BLACK_WOOL, Items.BLUE_WOOL, Items.BROWN_WOOL, Items.CYAN_WOOL, Items.GRAY_WOOL, Items.GREEN_WOOL, Items.LIGHT_BLUE_WOOL, Items.LIGHT_GRAY_WOOL, Items.LIME_WOOL, Items.MAGENTA_WOOL, Items.ORANGE_WOOL, Items.PINK_WOOL, Items.PURPLE_WOOL, Items.RED_WOOL, Items.YELLOW_WOOL, Items.WHITE_WOOL); public URecipeProvider(FabricDataOutput output) { super(output); } @Override public void generate(Consumer exporter) { - Arrays.stream(ItemFamilies.BASKETS).forEach(basket -> { - offerBasketRecipe(exporter, basket, getMaterial(basket, "_basket", "_planks")); - }); + generateVanillaRecipeExtensions(exporter); + offerJarRecipes(exporter); + offerWoodBlocksRecipes(exporter); + offerChitinBlocksRecipes(exporter); + offerCloudRecipes(exporter); + offerFoodRecipes(exporter); + offerGemstoneAndMagicRecipes(exporter); + offerSeaponyRecipes(exporter); + offerEarthPonyRecipes(exporter); + // beds + createCustomBedRecipe(UItems.CLOUD_BED, Either.left(UBlocks.DENSE_CLOUD), Either.left(UBlocks.CLOUD_PLANKS)).offerTo(exporter); + createCustomBedRecipe(UItems.CLOTH_BED, Either.right(ItemTags.WOOL), Either.right(ItemTags.LOGS)).offerTo(exporter); + offerBedSheetRecipes(exporter); + + // sunglasses + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.SUNGLASSES) + .input('#', ConventionalItemTags.GLASS_BLOCKS).criterion("has_glass_block", conditionsFromTag(ConventionalItemTags.GLASS_BLOCKS)) + .pattern("##") + .offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.SUNGLASSES) + .input(ConventionalItemTags.GLASS_BLOCKS) + .input(UItems.SUNGLASSES).criterion("has_broken_sunglasses", conditionsFromItem(UItems.BROKEN_SUNGLASSES)) + .offerTo(exporter, convertBetween(UItems.SUNGLASSES, UItems.BROKEN_SUNGLASSES)); + } + + private void generateVanillaRecipeExtensions(Consumer exporter) { + ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, Items.WRITABLE_BOOK).input(Items.BOOK).input(Items.INK_SAC).input(UTags.MAGIC_FEATHERS).criterion("has_book", conditionsFromItem(Items.BOOK)).offerTo(exporter); + ShapedRecipeJsonBuilder.create(RecipeCategory.COMBAT, Items.ARROW, 4).input('#', UConventionalTags.STICKS).input('X', Items.FLINT).input('Y', UTags.MAGIC_FEATHERS).pattern("X").pattern("#").pattern("Y").criterion("has_feather", conditionsFromTag(UTags.MAGIC_FEATHERS)).criterion("has_flint", conditionsFromItem(Items.FLINT)).offerTo(exporter); + } + + private void offerJarRecipes(Consumer exporter) { + ComplexRecipeJsonBuilder.create(URecipes.JAR_EXTRACT_SERIALIZER).offerTo(exporter, "empty_jar_from_filled_jar"); + ComplexRecipeJsonBuilder.create(URecipes.JAR_INSERT_SERIALIZER).offerTo(exporter, "filled_jar"); + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.EMPTY_JAR, 7) + .input('#', ItemTags.PLANKS) + .input('*', ConventionalItemTags.GLASS_BLOCKS).criterion("has_glass", conditionsFromTag(ConventionalItemTags.GLASS_BLOCKS)) + .pattern("*#*") + .pattern("* *") + .pattern("***") + .offerTo(exporter); + } + + private void offerCloudRecipes(Consumer exporter) { + offerShapelessRecipe(exporter, UItems.CLOUD_LUMP, UTags.CLOUD_JARS, "cloud", 4); + generateFamily(exporter, UBlockFamilies.CLOUD); + offer2x3Recipe(exporter, UBlocks.CLOUD_PILLAR, UBlocks.CLOUD, "pillar"); + offer2x2CompactingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD, UItems.CLOUD_LUMP); + offerPolishedStoneRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_PLANKS, UBlocks.CLOUD); + generateFamily(exporter, UBlockFamilies.CLOUD_PLANKS); + offerChestRecipe(exporter, UBlocks.CLOUD_CHEST, UBlocks.CLOUD_PLANKS); + + offer2x2CompactingRecipe(exporter, RecipeCategory.DECORATIONS, UBlocks.SHAPING_BENCH, UBlocks.DENSE_CLOUD); + generateFamily(exporter, UBlockFamilies.CLOUD_BRICKS); + + offerCompactingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.DENSE_CLOUD, UBlocks.CLOUD, 4); + generateFamily(exporter, UBlockFamilies.DENSE_CLOUD); + offer2x3Recipe(exporter, UBlocks.CLOUD_DOOR, UBlocks.DENSE_CLOUD, "door"); + + // XXX: Make the unstable cloud recipe shapeless and change output to 8 (to align with making jam toast) + ShapelessRecipeJsonBuilder.create(RecipeCategory.REDSTONE, UBlocks.UNSTABLE_CLOUD, 8) + .input(UBlocks.CLOUD, 8) + .input(Ingredient.ofItems(UItems.LIGHTNING_JAR, UItems.ZAP_APPLE_JAM_JAR)) + .criterion("has_lightning_jar", conditionsFromItem(UItems.LIGHTNING_JAR)) + .criterion("has_zap_jar", conditionsFromItem(UItems.ZAP_APPLE_JAM_JAR)) + .offerTo(exporter); + } + + private void offerWoodBlocksRecipes(Consumer exporter) { + // palm wood + generateFamily(exporter, UBlockFamilies.PALM); + offerPlanksRecipe(exporter, UBlocks.PALM_PLANKS, UTags.Items.PALM_LOGS, 4); + offerBarkBlockRecipe(exporter, UBlocks.PALM_WOOD, UBlocks.PALM_LOG); + offerBarkBlockRecipe(exporter, UBlocks.STRIPPED_PALM_WOOD, UBlocks.STRIPPED_PALM_LOG); offerBoatRecipe(exporter, UItems.PALM_BOAT, UBlocks.PALM_PLANKS); offerChestBoatRecipe(exporter, UItems.PALM_CHEST_BOAT, UItems.PALM_BOAT); offerHangingSignRecipe(exporter, UBlocks.PALM_HANGING_SIGN, UBlocks.PALM_PLANKS); - offerPlanksRecipe(exporter, UBlocks.PALM_PLANKS, UTags.Items.PALM_LOGS, 4); - offerPlanksRecipe(exporter, UBlocks.ZAP_PLANKS, UTags.Items.ZAP_LOGS, 4); - offerPlanksRecipe(exporter, UBlocks.WAXED_ZAP_PLANKS, UTags.Items.WAXED_ZAP_LOGS, 4); - offerBarkBlockRecipe(exporter, UBlocks.PALM_WOOD, UBlocks.PALM_LOG); - offerBarkBlockRecipe(exporter, UBlocks.ZAP_WOOD, UBlocks.ZAP_LOG); - offerBarkBlockRecipe(exporter, UBlocks.WAXED_ZAP_WOOD, UBlocks.WAXED_ZAP_LOG); - generateFamily(exporter, UBlockFamilies.PALM); + // zap wood generateFamily(exporter, UBlockFamilies.ZAP); + offerPlanksRecipe(exporter, UBlocks.ZAP_PLANKS, UTags.Items.ZAP_LOGS, 4); + offerBarkBlockRecipe(exporter, UBlocks.ZAP_WOOD, UBlocks.ZAP_LOG); + // XXX: fixed not being able to craft stripped zap wood and waxed stripped zap wood + offerBarkBlockRecipe(exporter, UBlocks.STRIPPED_ZAP_WOOD, UBlocks.STRIPPED_ZAP_LOG); + + // waxed zap wood + offerPlanksRecipe(exporter, UBlocks.WAXED_ZAP_PLANKS, UTags.Items.WAXED_ZAP_LOGS, 4); + offerBarkBlockRecipe(exporter, UBlocks.WAXED_ZAP_WOOD, UBlocks.WAXED_ZAP_LOG); generateFamily(exporter, UBlockFamilies.WAXED_ZAP); + offerBarkBlockRecipe(exporter, UBlocks.WAXED_STRIPPED_ZAP_WOOD, UBlocks.WAXED_STRIPPED_ZAP_LOG); + offerWaxingRecipes(exporter); + + // other doors + offer2x3Recipe(exporter, UBlocks.CRYSTAL_DOOR, UItems.CRYSTAL_SHARD, "door"); + offerStableDoorRecipe(exporter, UBlocks.STABLE_DOOR, Either.right(ItemTags.PLANKS), UItems.ROCK_CANDY); + offerStableDoorRecipe(exporter, UBlocks.DARK_OAK_DOOR, Either.right(ItemTags.PLANKS), UItems.ROCK); } - private static Item getMaterial(Item output, String toStrip, String suffex) { - Identifier id = Registries.ITEM.getId(output).withPath(p -> p.replace(toStrip, "") + suffex); - return Registries.ITEM.getOrEmpty(id) - .or(() -> Registries.ITEM.getOrEmpty(new Identifier(Identifier.DEFAULT_NAMESPACE, id.getPath()))) - .orElseThrow(() -> new NoSuchElementException("No item with id " + id)); + private void offerChitinBlocksRecipes(Consumer exporter) { + // XXX: Changed chitin recipe to be reversible + offerReversibleCompactingRecipes(exporter, RecipeCategory.BUILDING_BLOCKS, UItems.CARAPACE, RecipeCategory.BUILDING_BLOCKS, UBlocks.CHITIN); + generateFamily(exporter, UBlockFamilies.CHISELED_CHITIN); + offerHiveRecipe(exporter, UBlocks.HIVE, UBlocks.CHITIN, UBlocks.MYSTERIOUS_EGG); + offerHullRecipe(exporter, UBlocks.CHISELLED_CHITIN_HULL, UBlocks.CHISELLED_CHITIN, UBlocks.CHITIN); + // XXX: Changed spikes recipe to give 8 instead of 1 + offerSpikesRecipe(exporter, UBlocks.CHITIN_SPIKES, UBlocks.CHITIN); + + // TODO: polished chitin + offerPolishedStoneRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CHISELLED_CHITIN, UBlocks.CHITIN); + + offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CHISELLED_CHITIN_HULL, UBlocks.CHISELLED_CHITIN); + offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CHISELLED_CHITIN_SLAB, UBlocks.CHISELLED_CHITIN, 2); + offerStonecuttingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CHISELLED_CHITIN_STAIRS, UBlocks.CHISELLED_CHITIN); } - public static void offerBasketRecipe(Consumer exporter, ItemConvertible output, ItemConvertible input) { - ShapedRecipeJsonBuilder.create(RecipeCategory.TRANSPORTATION, output) - .input(Character.valueOf('#'), input) + private void offerGemstoneAndMagicRecipes(Consumer exporter) { + // XXX: Change diamond to shard recipe to give 6 instead of 3 + offerShapelessRecipe(exporter, UItems.CRYSTAL_SHARD, Items.DIAMOND, "crystal_shard", 6); + // XXX: Added recipe to get shards from amethyst shards + offerShapelessRecipe(exporter, UItems.CRYSTAL_SHARD, Items.AMETHYST_SHARD, "crystal_shard", 3); + offer2x2CompactingRecipe(exporter, RecipeCategory.MISC, UItems.GEMSTONE, UItems.CRYSTAL_SHARD); + ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.SPELLBOOK) + .input(Items.BOOK).criterion("has_book", conditionsFromItem(Items.BOOK)) + .input(UItems.GEMSTONE).criterion("has_gemstone", conditionsFromItem(UItems.GEMSTONE)) + .offerTo(exporter); + + // magic staff + ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.MAGIC_STAFF) + .input('*', UItems.GEMSTONE).criterion("has_gemstone", conditionsFromItem(UItems.GEMSTONE)) + .input('#', UConventionalTags.STICKS).criterion("has_stick", conditionsFromTag(UConventionalTags.STICKS)) + .pattern(" *") + .pattern(" # ") + .pattern("# ") + .offerTo(exporter); + + // crystal heart + ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, UItems.CRYSTAL_HEART) + .input('#', UItems.CRYSTAL_SHARD).criterion("has_crystal_shard", conditionsFromItem(UItems.CRYSTAL_SHARD)) + .pattern("# #") + .pattern("###") + .pattern(" # ") + .offerTo(exporter); + + // pegasus amulet + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.GOLDEN_FEATHER) + .input('*', Items.GOLD_NUGGET).criterion("has_nugget", conditionsFromItem(Items.GOLD_NUGGET)) + .input('#', UTags.MAGIC_FEATHERS).criterion("has_feather", conditionsFromTag(UTags.MAGIC_FEATHERS)) + .pattern("***") + .pattern("*#*") + .pattern("***") + .offerTo(exporter); + offerCompactingRecipe(exporter, RecipeCategory.COMBAT, UItems.GOLDEN_WING, UItems.GOLDEN_FEATHER); + ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.PEGASUS_AMULET) + .input('*', UItems.GOLDEN_WING).criterion("has_wing", conditionsFromItem(UItems.GOLDEN_WING)) + .input('#', UItems.GEMSTONE).criterion("has_gemstone", conditionsFromItem(UItems.GEMSTONE)) + .pattern("*#*") + .offerTo(exporter); + + // unicorn amulet + /*ShapelessRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.UNICORN_AMULET) + .input(UItems.PEGASUS_AMULET) + .input(UItems.CRYSTAL_HEART) + .input(UItems.GROGARS_BELL) + .input(Items.TOTEM_OF_UNDYING) + .offerTo(exporter);*/ + + // friendship bracelet + ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.FRIENDSHIP_BRACELET) + .input('*', Items.STRING) + .input('#', Items.LEATHER).criterion(hasItem(Items.LEATHER), conditionsFromTag(UTags.MAGIC_FEATHERS)) + .pattern("*#*") + .pattern("# #") + .pattern("*#*") + .offerTo(exporter); + ComplexRecipeJsonBuilder.create(URecipes.GLOWING_SERIALIZER).offerTo(exporter, "friendship_bracelet_glowing"); + + // meadowbrook's staff + ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.MEADOWBROOKS_STAFF) + .input('*', UItems.GEMSTONE).criterion(hasItem(UItems.GEMSTONE), conditionsFromItem(UItems.GEMSTONE)) + .input('/', UConventionalTags.STICKS).criterion(hasItem(Items.STICK), conditionsFromTag(UConventionalTags.STICKS)) + .pattern(" *") + .pattern(" / ") + .pattern("/ ") + .offerTo(exporter); + offerShapelessRecipe(exporter, Items.STICK, UItems.MEADOWBROOKS_STAFF, "stick", 2); + } + + private void offerFoodRecipes(Consumer exporter) { + offerShapelessRecipe(exporter, UItems.PINEAPPLE_CROWN, UItems.PINEAPPLE, "seeds", 1); + offerShapelessRecipe(exporter, UItems.SWEET_APPLE_SEEDS, UItems.SWEET_APPLE, "seeds", 3); + offerShapelessRecipe(exporter, UItems.SOUR_APPLE_SEEDS, UItems.SOUR_APPLE, "seeds", 3); + offerShapelessRecipe(exporter, UItems.GREEN_APPLE_SEEDS, UItems.GREEN_APPLE, "seeds", 3); + // XXX: Made golden oak seeds obtainable by crafting + offerShapelessRecipe(exporter, UItems.GOLDEN_OAK_SEEDS, Items.GOLDEN_APPLE, "seeds", 1); + offerPieRecipe(exporter, UItems.APPLE_PIE, UItems.APPLE_PIE_SLICE, Items.WHEAT, UTags.FRESH_APPLES); + + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.ROCK_STEW) + .input(UItems.ROCK, 3).criterion(hasItem(UItems.ROCK), conditionsFromItem(UItems.ROCK)) + .input(Items.BOWL) + .offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.ROCK_CANDY, 3) + .input(Items.SUGAR, 6).criterion(hasItem(Items.SUGAR), conditionsFromItem(Items.SUGAR)) + .input(UItems.PEBBLES, 3) + .offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.JUICE) + .input(Ingredient.fromTag(UTags.FRESH_APPLES), 6).criterion(hasItem(Items.APPLE), conditionsFromTag(UTags.FRESH_APPLES)) + .input(Items.GLASS_BOTTLE) + .group("juice") + .offerTo(exporter); + appendIngredients(ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.MUFFIN), Items.SUGAR, Items.EGG, Items.POTATO, UItems.JUICE, UItems.WHEAT_WORMS).offerTo(exporter); + // XXX: Removed the complex cider recipe + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.MUG) + .input('*', Items.IRON_NUGGET).criterion(hasItem(Items.IRON_NUGGET), conditionsFromItem(Items.IRON_NUGGET)) + .input('#', UConventionalTags.STICKS).criterion(hasItem(Items.STICK), conditionsFromTag(UConventionalTags.STICKS)) + .pattern("# #") + .pattern("* *") + .pattern(" # ") + .offerTo(exporter); + // XXX: Changed the simple cider recipe to require apples + appendIngredients(ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.CIDER), UItems.BURNED_JUICE, UItems.MUG) + .input(Ingredient.fromTag(UTags.FRESH_APPLES)).criterion(hasItem(Items.APPLE), conditionsFromTag(UTags.FRESH_APPLES)) + .offerTo(exporter); + + ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.HAY_FRIES) + .input('#', UItems.OATS).criterion(hasItem(UItems.OATS), conditionsFromItem(UItems.OATS)) + .pattern("###") + .offerTo(exporter); + ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.HAY_BURGER) + .input('~', Items.BREAD).criterion(hasItem(Items.BREAD), conditionsFromItem(Items.BREAD)) + .input('#', UItems.OATS).criterion(hasItem(UItems.OATS), conditionsFromItem(UItems.OATS)) + .pattern(" # ") + .pattern("~~~") + .pattern(" # ") + .offerTo(exporter); + + ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.DAFFODIL_DAISY_SANDWICH) + .input('#', Items.BREAD).criterion(hasItem(Items.BREAD), conditionsFromItem(Items.BREAD)) + .input('~', ItemTags.SMALL_FLOWERS).criterion("has_flower", conditionsFromTag(ItemTags.SMALL_FLOWERS)) + .pattern(" # ") + .pattern("~~~") + .pattern(" # ") + .offerTo(exporter); + + ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.HORSE_SHOE_FRIES, 15) + .input('#', Items.BAKED_POTATO).criterion(hasItem(Items.BAKED_POTATO), conditionsFromItem(Items.BAKED_POTATO)) + .pattern("# #") + .pattern("# #") + .pattern(" # ") + .offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.OATMEAL) + .input(UItems.OATS, 3).criterion(hasItem(UItems.OATS), conditionsFromItem(UItems.OATS)) + .input(ConventionalItemTags.MILK_BUCKETS) + .input(Items.BOWL) + .offerTo(exporter); + + offerSmelting(exporter, List.of(UItems.JUICE), RecipeCategory.FOOD, UItems.BURNED_JUICE, 0, 100, "juice"); + offerSmelting(exporter, List.of(Items.BREAD), RecipeCategory.FOOD, UItems.TOAST, 0.2F, 430, "bread"); + offerSmelting(exporter, List.of(UItems.TOAST), RecipeCategory.FOOD, UItems.BURNED_TOAST, 0.2F, 30, "bread"); + offerSmelting(exporter, List.of(UItems.BURNED_JUICE, UItems.BURNED_TOAST), RecipeCategory.FOOD, Items.CHARCOAL, 1, 20, "coal"); + offerSmelting(exporter, List.of(UItems.HAY_FRIES), RecipeCategory.FOOD, UItems.CRISPY_HAY_FRIES, 1F, 25, "hay_fries"); + // XXX: Increased experience from cooking zap apples + offerSmelting(exporter, List.of(UItems.ZAP_APPLE), RecipeCategory.FOOD, UItems.COOKED_ZAP_APPLE, 1.2F, 430, "zap_apple"); + + // XXX: Make zap apple jam jar recipe shapeless + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.ZAP_APPLE_JAM_JAR) + .input(UItems.COOKED_ZAP_APPLE, 6).criterion(hasItem(UItems.COOKED_ZAP_APPLE), conditionsFromItem(UItems.COOKED_ZAP_APPLE)) + .input(UItems.EMPTY_JAR) + .offerTo(exporter); + // XXX: Make jam toast recipe shapeless + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.JAM_TOAST, 8) + .input(UItems.ZAP_APPLE_JAM_JAR).criterion(hasItem(UItems.ZAP_APPLE_JAM_JAR), conditionsFromItem(UItems.ZAP_APPLE_JAM_JAR)) + .input(UItems.TOAST, 8) + .offerTo(exporter); + + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.CANDIED_APPLE) + .input(UConventionalTags.STICKS) + .input(UTags.FRESH_APPLES).criterion(hasItem(UItems.ZAP_APPLE_JAM_JAR), conditionsFromItem(UItems.ZAP_APPLE_JAM_JAR)) + .input(Items.SUGAR, 4) + .offerTo(exporter); + } + + private void offerSeaponyRecipes(Consumer exporter) { + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.SHELLY) + .input('C', UItems.CLAM_SHELL).criterion("has_clam_shell", conditionsFromItem(UItems.CLAM_SHELL)) + .input('o', UItems.ROCK_CANDY) + .pattern("o o") + .pattern(" C ") + .offerTo(exporter); + ShapedRecipeJsonBuilder.create(RecipeCategory.COMBAT, UItems.PEARL_NECKLACE) + .input('#', UTags.SHELLS).criterion("has_shell", conditionsFromTag(UTags.SHELLS)) + .input('~', Items.STRING) + .pattern("# #") + .pattern("# #") + .pattern("~#~") + .offerTo(exporter); + } + + private void offerEarthPonyRecipes(Consumer exporter) { + Arrays.stream(ItemFamilies.BASKETS).forEach(basket -> offerBasketRecipe(exporter, basket, CraftingMaterialHelper.getMaterial(basket, "_basket", "_planks"))); + Arrays.stream(ItemFamilies.HORSE_SHOES).forEach(horseshoe -> offerHorseshoeRecipe(exporter, horseshoe, CraftingMaterialHelper.getMaterial(horseshoe, "_horse_shoe", "_ingot"))); + Arrays.stream(ItemFamilies.POLEARMS).forEach(polearm -> { + if (polearm == UItems.NETHERITE_POLEARM) { + offerNetheriteUpgradeRecipe(exporter, UItems.DIAMOND_POLEARM, RecipeCategory.TOOLS, UItems.NETHERITE_POLEARM); + } else { + offerPolearmRecipe(exporter, polearm, CraftingMaterialHelper.getMaterial(polearm, "_polearm", "_ingot")); + } + }); + // weather vane + offerWeatherVaneRecipe(exporter, UBlocks.WEATHER_VANE, Items.IRON_NUGGET); + + // Giant balloons + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.GIANT_BALLOON) + .input('-', ItemTags.WOOL_CARPETS).criterion("has_carpet", conditionsFromTag(ItemTags.WOOL_CARPETS)) + .input('#', ItemTags.WOOL).criterion("has_wool", conditionsFromTag(ItemTags.WOOL)) + .pattern("---") + .pattern("# #") + .pattern("---") + .offerTo(exporter); + + // utility + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, Items.DIRT) + .input('*', UItems.WHEAT_WORMS).criterion("has_wheat_worms", conditionsFromItem(UItems.WHEAT_WORMS)) + .input('#', ItemTags.SAND).criterion("has_sand", conditionsFromTag(ItemTags.SAND)) + .pattern("*#") + .pattern("#*") + .offerTo(exporter, convertBetween(Items.DIRT, UItems.WHEAT_WORMS)); + + offer2x2CompactingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, Items.COBBLESTONE, UItems.ROCK); + + // XXX: Made gravel <-> pebbles conversion reversable + offerReversibleCompactingRecipesWithReverseRecipeGroup(exporter, RecipeCategory.MISC, UItems.PEBBLES, RecipeCategory.BUILDING_BLOCKS, Blocks.GRAVEL, convertBetween(UItems.PEBBLES, Blocks.GRAVEL), "pebbles"); + // XXX: Added sus gravel -> pebbles recipe + offerShapelessRecipe(exporter, UItems.PEBBLES, Blocks.SUSPICIOUS_GRAVEL, "pebbles", 9); + offerSmelting(exporter, List.of(UItems.GOLDEN_OAK_SEEDS, UItems.GOLDEN_FEATHER), RecipeCategory.MISC, Items.GOLD_NUGGET, 3F, 10, "gold_nugget"); + } + + private static ShapelessRecipeJsonBuilder appendIngredients(ShapelessRecipeJsonBuilder builder, ItemConvertible...ingredients) { + for (ItemConvertible ingredient : ingredients) { + builder.input(ingredient).criterion(hasItem(ingredient), conditionsFromItem(ingredient)); + } + return builder; + } + + public static void offerShapelessRecipe(Consumer exporter, ItemConvertible output, TagKey input, @Nullable String group, int outputCount) { + ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, output, outputCount) + .input(input).criterion(CraftingMaterialHelper.hasTag(input), conditionsFromTag(input)) + .group(group) + .offerTo(exporter, getItemPath(output) + "_from_" + input.id().getPath()); + } + + public static void offerPieRecipe(Consumer exporter, ItemConvertible pie, ItemConvertible slice, ItemConvertible crust, TagKey filling) { + ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, pie) + .input('*', crust).criterion("has_crust", conditionsFromItem(crust)) + .input('#', filling).criterion("has_filling", conditionsFromTag(filling)) + .pattern("***") + .pattern("###") + .pattern("***") + .offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, pie) + .input(slice, 4) + .criterion(hasItem(slice), conditionsFromItem(slice)) + .offerTo(exporter, getItemPath(pie) + "_from_" + getItemPath(slice)); + } + + public static void offerBasketRecipe(Consumer exporter, ItemConvertible output, Either> input) { + CraftingMaterialHelper.input(ShapedRecipeJsonBuilder.create(RecipeCategory.TRANSPORTATION, output), '#', input) + .criterion(CraftingMaterialHelper.hasEither(input), CraftingMaterialHelper.conditionsFromEither(input)) .pattern("# #") .pattern("# #") .pattern("###") .group("basket") - .criterion(VanillaRecipeProvider.hasItem(input), VanillaRecipeProvider.conditionsFromItem(input)) + .offerTo(exporter); + } + + public static void offerHorseshoeRecipe(Consumer exporter, ItemConvertible output, Either> input) { + CraftingMaterialHelper + .input(ShapedRecipeJsonBuilder.create(RecipeCategory.COMBAT, output), '#', input) + .criterion(CraftingMaterialHelper.hasEither(input), CraftingMaterialHelper.conditionsFromEither(input)) + .pattern("# #") + .pattern("# #") + .pattern(" # ") + .group("horseshoe") + .offerTo(exporter); + } + + public static void offerHiveRecipe(Consumer exporter, ItemConvertible output, ItemConvertible chitin, ItemConvertible egg) { + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, output) + .input('#', chitin) + .input('o', egg).criterion(hasItem(egg), conditionsFromItem(egg)) + .pattern(" # ") + .pattern("#o#") + .pattern(" # ") + .group("chitin") + .offerTo(exporter); + } + + public static void offerPolearmRecipe(Consumer exporter, ItemConvertible output, Either> input) { + CraftingMaterialHelper + .input(ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, output), 'o', input).criterion(CraftingMaterialHelper.hasEither(input), CraftingMaterialHelper.conditionsFromEither(input)) + .input('#', UConventionalTags.STICKS) + .pattern(" o") + .pattern(" # ") + .pattern("# ") + .group("polearm") + .offerTo(exporter); + } + + public static void offerHullRecipe(Consumer exporter, ItemConvertible output, ItemConvertible outside, ItemConvertible inside) { + ShapedRecipeJsonBuilder.create(RecipeCategory.BUILDING_BLOCKS, output, 4) + .input('#', outside).criterion(hasItem(outside), conditionsFromItem(outside)) + .input('o', inside).criterion(hasItem(inside), conditionsFromItem(inside)) + .pattern("##") + .pattern("oo") + .group("hull") + .offerTo(exporter); + } + + public static void offerSpikesRecipe(Consumer exporter, ItemConvertible output, ItemConvertible input) { + ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output, 8) + .input('#', input).criterion(hasItem(input), conditionsFromItem(input)) + .pattern(" # ") + .pattern("###") + .group("spikes") + .offerTo(exporter); + } + + public static void offerChestRecipe(Consumer exporter, ItemConvertible output, ItemConvertible input) { + ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output) + .input('#', input) + .pattern("###") + .pattern("# #") + .pattern("###") + .criterion("has_lots_of_items", new InventoryChangedCriterion.Conditions(LootContextPredicate.EMPTY, NumberRange.IntRange.atLeast(10), NumberRange.IntRange.ANY, NumberRange.IntRange.ANY, new ItemPredicate[0])) + .offerTo(exporter); + } + + public static void offer2x3Recipe(Consumer exporter, ItemConvertible output, ItemConvertible input, String group) { + createDoorRecipe(output, Ingredient.ofItems(input)) + .criterion(hasItem(input), conditionsFromItem(input)) + .group(group) + .offerTo(exporter); + } + + public static void offerStableDoorRecipe(Consumer exporter, ItemConvertible output, Either> body, ItemConvertible trim) { + CraftingMaterialHelper + .input(ShapedRecipeJsonBuilder.create(RecipeCategory.REDSTONE, output, 3), '#', body).criterion(CraftingMaterialHelper.hasEither(body), CraftingMaterialHelper.conditionsFromEither(body)) + .input('*', trim).criterion(hasItem(trim), conditionsFromItem(trim)) + .pattern("*#*") + .pattern("*#*") + .pattern("*#*") + .group("stable_door") + .offerTo(exporter); + } + + public static void offerWeatherVaneRecipe(Consumer exporter, ItemConvertible output, ItemConvertible input) { + ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output) + .input('*', input).criterion(hasItem(input), conditionsFromItem(input)) + .pattern(" **") + .pattern("** ") + .pattern(" * ") + .offerTo(exporter); + } + + public static ShapedRecipeJsonBuilder createCustomBedRecipe(ItemConvertible output, Either> input, Either> planks) { + var builder = ShapedRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output); + CraftingMaterialHelper.input(builder, '#', input).criterion(CraftingMaterialHelper.hasEither(input), CraftingMaterialHelper.conditionsFromEither(input)); + return CraftingMaterialHelper.input(builder, 'X', planks) + .pattern("###") + .pattern("XXX") + .group("bed"); + } + + private void offerBedSheetRecipes(Consumer exporter) { + PatternTemplate.ONE_COLOR.offerWithoutConversion(exporter, UItems.KELP_BED_SHEETS, Items.KELP); + // XXX: Added white bed sheets, and added a recipe to dye white bed sheets any color + // XXX: Added recipes to change any bedsheet into any solid color using the right wool + WOOLS.forEach(wool -> PatternTemplate.ONE_COLOR.offerTo(exporter, CraftingMaterialHelper.getItem(Unicopia.id(Registries.ITEM.getId(wool).getPath().replace("_wool", "_bed_sheets"))), wool)); + + PatternTemplate.TWO_COLOR.offerTo(exporter, UItems.APPLE_BED_SHEETS, Items.GREEN_WOOL, Items.LIME_WOOL); + PatternTemplate.TWO_COLOR.offerTo(exporter, UItems.BARRED_BED_SHEETS, Items.LIGHT_BLUE_WOOL, Items.WHITE_WOOL); + PatternTemplate.TWO_COLOR.offerTo(exporter, UItems.CHECKERED_BED_SHEETS, Items.GREEN_WOOL, Items.BROWN_WOOL); + PatternTemplate.THREE_COLOR.offerTo(exporter, UItems.RAINBOW_PWR_BED_SHEETS, Items.WHITE_WOOL, Items.PINK_WOOL, Items.RED_WOOL); + PatternTemplate.THREE_COLOR.offerTo(exporter, UItems.RAINBOW_BPY_BED_SHEETS, Items.PINK_WOOL, Items.YELLOW_WOOL, Items.LIGHT_BLUE_WOOL); + PatternTemplate.THREE_COLOR.offerTo(exporter, UItems.RAINBOW_BPW_BED_SHEETS, Items.PINK_WOOL, Items.LIGHT_BLUE_WOOL, Items.WHITE_WOOL); + PatternTemplate.FOUR_COLOR.offerTo(exporter, UItems.RAINBOW_PBG_BED_SHEETS, Items.PURPLE_WOOL, Items.WHITE_WOOL, Items.LIGHT_GRAY_WOOL, Items.BLACK_WOOL); + PatternTemplate.SEVEN_COLOR.offerTo(exporter, UItems.RAINBOW_BED_SHEETS, UItems.RAINBOW_BED_SHEETS, Items.LIGHT_BLUE_WOOL, Items.RED_WOOL, Items.ORANGE_WOOL, Items.YELLOW_WOOL, Items.BLUE_WOOL, Items.GREEN_WOOL, Items.PURPLE_WOOL); + } + + public static void offerCompactingRecipe(Consumer exporter, RecipeCategory category, ItemConvertible output, ItemConvertible input, int resultCount) { + offerCompactingRecipe(exporter, category, output, input, hasItem(input), resultCount); + } + + public static void offerCompactingRecipe(Consumer exporter, RecipeCategory category, ItemConvertible output, ItemConvertible input, String criterionName, int resultCount) { + ShapelessRecipeJsonBuilder.create(category, output, resultCount) + .input(input, 9).criterion(criterionName, conditionsFromItem(input)) .offerTo(exporter); } @@ -76,14 +552,17 @@ public class URecipeProvider extends FabricRecipeProvider { offerWaxingRecipe(exporter, output, input); }); offerWaxingRecipe(exporter, UBlocks.WAXED_ZAP_PLANKS, UBlocks.ZAP_PLANKS); + offerWaxingRecipe(exporter, UBlocks.WAXED_ZAP_LOG, UBlocks.ZAP_LOG); offerWaxingRecipe(exporter, UBlocks.WAXED_ZAP_WOOD, UBlocks.ZAP_WOOD); + offerWaxingRecipe(exporter, UBlocks.WAXED_STRIPPED_ZAP_LOG, UBlocks.STRIPPED_ZAP_LOG); + offerWaxingRecipe(exporter, UBlocks.WAXED_STRIPPED_ZAP_WOOD, UBlocks.STRIPPED_ZAP_WOOD); } public static void offerWaxingRecipe(Consumer exporter, ItemConvertible output, ItemConvertible input) { ShapelessRecipeJsonBuilder.create(RecipeCategory.BUILDING_BLOCKS, output) - .input(input) - .input(Items.HONEYCOMB).group(RecipeProvider.getItemPath(output)) - .criterion(RecipeProvider.hasItem(input), RecipeProvider.conditionsFromItem(input)) - .offerTo(exporter, RecipeProvider.convertBetween(output, Items.HONEYCOMB)); + .input(Items.HONEYCOMB) + .input(input).criterion(hasItem(input), conditionsFromItem(input)) + .group(getItemPath(output)) + .offerTo(exporter, convertBetween(output, Items.HONEYCOMB)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 8d30b634..3bffbf64 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -166,6 +166,7 @@ public interface UItems { Item GIANT_BALLOON = register("giant_balloon", new HotAirBalloonItem(new Item.Settings().maxCount(1)), ItemGroups.TOOLS); Item SPECTRAL_CLOCK = register("spectral_clock", new Item(new Item.Settings()), ItemGroups.TOOLS); + Item WHITE_BED_SHEETS = register(CloudBedBlock.SheetPattern.WHITE); Item LIGHT_GRAY_BED_SHEETS = register(CloudBedBlock.SheetPattern.LIGHT_GRAY); Item GRAY_BED_SHEETS = register(CloudBedBlock.SheetPattern.GRAY); Item BLACK_BED_SHEETS = register(CloudBedBlock.SheetPattern.BLACK); diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin.json deleted file mode 100644 index fba2676d..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:chiselled_chitin" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:chitin" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:chiselled_chitin" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_hull.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_hull.json deleted file mode 100644 index ed8d7a6e..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_hull.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:chiselled_chitin_hull" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:chiselled_chitin" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:chiselled_chitin_hull" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_slab.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_slab.json deleted file mode 100644 index f1e2b4e7..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_slab.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:chiselled_chitin_slab" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:chiselled_chitin" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:chiselled_chitin_slab" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_stairs.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_stairs.json deleted file mode 100644 index 9a08e521..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/chiselled_chitin_stairs.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:chiselled_chitin_stairs" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:chiselled_chitin" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:chiselled_chitin_stairs" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/chitin_spikes.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/chitin_spikes.json deleted file mode 100644 index 6379d4a9..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/chitin_spikes.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:chitin_spikes" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:chitin" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:chitin_spikes" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_brick_slab.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_brick_slab.json deleted file mode 100644 index 75101d52..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_brick_slab.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:cloud_brick_slab" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:cloud_bricks" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:cloud_brick_slab" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_brick_stairs.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_brick_stairs.json deleted file mode 100644 index d7ca8f88..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_brick_stairs.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:cloud_brick_stairs" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:cloud_bricks" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:cloud_brick_stairs" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_pillar.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_pillar.json deleted file mode 100644 index b5248c89..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_pillar.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:cloud_pillar" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:cloud" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:cloud_pillar" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_plank_slab.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_plank_slab.json deleted file mode 100644 index 19e93f24..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_plank_slab.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:cloud_plank_slab" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:cloud_planks" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:cloud_plank_slab" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_plank_stairs.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_plank_stairs.json deleted file mode 100644 index 0d7a9c07..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_plank_stairs.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:cloud_plank_stairs" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:cloud_planks" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:cloud_plank_stairs" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_planks.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_planks.json deleted file mode 100644 index 20658432..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_planks.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:cloud_planks" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:cloud" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:cloud_planks" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_slab.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_slab.json deleted file mode 100644 index 762518c1..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_slab.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:cloud_slab" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:cloud" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:cloud_slab" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_stairs.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_stairs.json deleted file mode 100644 index d484ad65..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/cloud_stairs.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:cloud_stairs" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:cloud" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:cloud_stairs" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud.json deleted file mode 100644 index 51f03735..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:dense_cloud" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:cloud" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:dense_cloud" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud_slab.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud_slab.json deleted file mode 100644 index 1ca251e5..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud_slab.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:dense_cloud_slab" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:dense_cloud" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:dense_cloud_slab" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud_stairs.json b/src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud_stairs.json deleted file mode 100644 index aba8906a..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/blocks/dense_cloud_stairs.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:dense_cloud_stairs" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:dense_cloud" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:dense_cloud_stairs" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/cloud_lump.json b/src/main/resources/data/unicopia/advancements/recipes/cloud_lump.json deleted file mode 100644 index 39ec6b06..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/cloud_lump.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:cloud_lump" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "tag": "unicopia:cloud_jars" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:cloud_lump" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/crystal_heart.json b/src/main/resources/data/unicopia/advancements/recipes/crystal_heart.json deleted file mode 100644 index 2ed03717..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/crystal_heart.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:crystal_heart" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:crystal_shard" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:crystal_heart" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/empty_jar.json b/src/main/resources/data/unicopia/advancements/recipes/empty_jar.json deleted file mode 100644 index 4911ca96..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/empty_jar.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:empty_jar" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:glass" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:empty_jar" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/apple_pie.json b/src/main/resources/data/unicopia/advancements/recipes/food/apple_pie.json deleted file mode 100644 index 7d6bf9d5..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/apple_pie.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:apple_pie" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "tag": "unicopia:fresh_apples" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:apple_pie" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/apple_pie_from_slices.json b/src/main/resources/data/unicopia/advancements/recipes/food/apple_pie_from_slices.json deleted file mode 100644 index 9d4e91ea..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/apple_pie_from_slices.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:apple_pie_slice_to_apple_pie" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "tag": "unicopia:apple_pie_slice" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:apple_pie_slice_to_apple_pie" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/burned_juice.json b/src/main/resources/data/unicopia/advancements/recipes/food/burned_juice.json deleted file mode 100644 index 49b46b08..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/burned_juice.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:burned_juice" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:juice" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:burned_juice" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/burned_toast.json b/src/main/resources/data/unicopia/advancements/recipes/food/burned_toast.json deleted file mode 100644 index 312159fe..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/burned_toast.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:burned_toast" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:toast" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:burned_toast" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/candied_apple.json b/src/main/resources/data/unicopia/advancements/recipes/food/candied_apple.json deleted file mode 100644 index c135476b..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/candied_apple.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:candied_apple" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:stick" ] }, - { "items": [ "minecraft:sugar" ] }, - { "tag": "unicopia:fresh_apples" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:candied_apple" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/cider.json b/src/main/resources/data/unicopia/advancements/recipes/food/cider.json deleted file mode 100644 index f11ac1be..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/cider.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:cider", - "unicopia:easy_cider" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:burned_juice" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:cider" - } - }, - "has_the_easy_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:easy_cider" - } - } - }, - "requirements": [ - [ "has_ingredients", "has_the_recipe", "has_the_easy_recipe" ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/hay_fries.json b/src/main/resources/data/unicopia/advancements/recipes/food/hay_fries.json deleted file mode 100644 index d22ae87a..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/hay_fries.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:hay_fries" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "unicopia:oats" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:hay_fries" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/horse_shoe_fries.json b/src/main/resources/data/unicopia/advancements/recipes/food/horse_shoe_fries.json deleted file mode 100644 index bdbfd011..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/horse_shoe_fries.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:horse_shoe_fries" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:baked_potato" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:horse_shoe_fries" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/jam_toast.json b/src/main/resources/data/unicopia/advancements/recipes/food/jam_toast.json deleted file mode 100644 index bec51648..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/jam_toast.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:jam_toast" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:toast" ] }, - { "items": [ "unicopia:zap_apple_jam_jar" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:jam_toast" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/juice.json b/src/main/resources/data/unicopia/advancements/recipes/food/juice.json deleted file mode 100644 index 9076bddc..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/juice.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:juice" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "tag": "unicopia:fresh_apples" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:juice" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/muffin.json b/src/main/resources/data/unicopia/advancements/recipes/food/muffin.json deleted file mode 100644 index 12fc8008..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/muffin.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:muffin" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { - "items": [ - "minecraft:sugar", - "minecraft:egg", - "minecraft:potato", - "unicopia:juice", - "unicopia:wheat_worms" - ] - } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:muffin" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/oatmeal.json b/src/main/resources/data/unicopia/advancements/recipes/food/oatmeal.json deleted file mode 100644 index 1bcf0711..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/oatmeal.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:oatmeal" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "tag": "unicopia:oats" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:oatmeal" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/rock_candy.json b/src/main/resources/data/unicopia/advancements/recipes/food/rock_candy.json deleted file mode 100644 index 6a633e0f..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/rock_candy.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:rock_candy" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:pebbles" ] }, - { "items": [ "minecraft:sugar" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:rock_candy" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/rock_stew.json b/src/main/resources/data/unicopia/advancements/recipes/food/rock_stew.json deleted file mode 100644 index 69621f28..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/rock_stew.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:rock_stew" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "tag": "unicopia:rock" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:rock_stew" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/toast.json b/src/main/resources/data/unicopia/advancements/recipes/food/toast.json deleted file mode 100644 index 7548a5fc..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/toast.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:toast" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:bread" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:toast" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/food/zap_apple_jam_jar.json b/src/main/resources/data/unicopia/advancements/recipes/food/zap_apple_jam_jar.json deleted file mode 100644 index 7d3d9474..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/food/zap_apple_jam_jar.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:zap_apple_jam_jar" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:empty_jar" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:zap_apple_jam_jar" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/friendship_bracelet.json b/src/main/resources/data/unicopia/advancements/recipes/friendship_bracelet.json deleted file mode 100644 index 278fdaad..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/friendship_bracelet.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:friendship_bracelet" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:leather", "minecraft:string" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:friendship_bracelet" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/gemstone.json b/src/main/resources/data/unicopia/advancements/recipes/gemstone.json deleted file mode 100644 index b6fcf7b1..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/gemstone.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:gemstone" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:crystal_shard" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:gemstone" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/golden_feather.json b/src/main/resources/data/unicopia/advancements/recipes/golden_feather.json deleted file mode 100644 index 2878ae38..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/golden_feather.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:golden_feather", - "unicopia:pegasus_amulet" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "tag": "unicopia:magic_feathers" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:golden_feather" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/golden_wing.json b/src/main/resources/data/unicopia/advancements/recipes/golden_wing.json deleted file mode 100644 index f35f7e46..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/golden_wing.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:golden_wing" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:golden_feather" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:golden_wing" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/meadowbrooks_staff.json b/src/main/resources/data/unicopia/advancements/recipes/meadowbrooks_staff.json deleted file mode 100644 index 26462f67..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/meadowbrooks_staff.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:meadowbrooks_staff" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "minecraft:stick" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:meadowbrooks_staff" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/mug.json b/src/main/resources/data/unicopia/advancements/recipes/mug.json deleted file mode 100644 index 0620cedf..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/mug.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:mug" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:stick" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:mug" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/pegasus_amulet.json b/src/main/resources/data/unicopia/advancements/recipes/pegasus_amulet.json deleted file mode 100644 index 8129b43e..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/pegasus_amulet.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:pegasus_amulet" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:golden_wing" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:pegasus_amulet" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/pineapple_crown.json b/src/main/resources/data/unicopia/advancements/recipes/pineapple_crown.json deleted file mode 100644 index 13904af1..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/pineapple_crown.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:pineapple_crown" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:pineapple" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:pineapple_crown" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/shelly.json b/src/main/resources/data/unicopia/advancements/recipes/shelly.json deleted file mode 100644 index 08119d10..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/shelly.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:shelly" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:clam_shell", "unicopia:rock_candy" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:shelly" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/spellbook.json b/src/main/resources/data/unicopia/advancements/recipes/spellbook.json deleted file mode 100644 index 7d4a3307..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/spellbook.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:spellbook" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:gemstone", "unicopia:botched_gem" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:spellbook" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/tools/diamond_polearm.json b/src/main/resources/data/unicopia/advancements/recipes/tools/diamond_polearm.json deleted file mode 100644 index 52794d3d..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/tools/diamond_polearm.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:diamond_polearm" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:diamond" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:diamond_polearm" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/tools/golden_polearm.json b/src/main/resources/data/unicopia/advancements/recipes/tools/golden_polearm.json deleted file mode 100644 index ab03c0bd..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/tools/golden_polearm.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:golden_polearm" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:gold_ingot" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:golden_polearm" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/tools/iron_polearm.json b/src/main/resources/data/unicopia/advancements/recipes/tools/iron_polearm.json deleted file mode 100644 index 4db161bd..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/tools/iron_polearm.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:iron_polearm" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:iron_ingot" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:iron_polearm" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/tools/netherite_polearm_smithing.json b/src/main/resources/data/unicopia/advancements/recipes/tools/netherite_polearm_smithing.json deleted file mode 100644 index 07d09b50..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/tools/netherite_polearm_smithing.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:netherite_polearm_smithing" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:netherite_ingot" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:netherite_polearm_smithing" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/tools/stone_polearm.json b/src/main/resources/data/unicopia/advancements/recipes/tools/stone_polearm.json deleted file mode 100644 index bd846770..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/tools/stone_polearm.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:stone_polearm" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "tag": "minecraft:stone_tool_materials" } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:stone_polearm" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/tools/wooden_polearm.json b/src/main/resources/data/unicopia/advancements/recipes/tools/wooden_polearm.json deleted file mode 100644 index fd9a8fd9..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/tools/wooden_polearm.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:wooden_polearm" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:stick" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:wooden_polearm" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/unicorn_amulet.json b/src/main/resources/data/unicopia/advancements/recipes/unicorn_amulet.json deleted file mode 100644 index a0de0620..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/unicorn_amulet.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:unicorn_amulet" - ] - }, - "criteria": { - "has_ingredients": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:broken_alicorn_amulet" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:broken_alicorn_amulet" - } - } - }, - "requirements": [ - [ - "has_ingredients", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/recipes/weather_vane.json b/src/main/resources/data/unicopia/advancements/recipes/weather_vane.json deleted file mode 100644 index 3b6f199a..00000000 --- a/src/main/resources/data/unicopia/advancements/recipes/weather_vane.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "minecraft:recipes/root", - "rewards": { - "recipes": [ - "unicopia:weather_vane" - ] - }, - "criteria": { - "has_iron": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:iron_nugget", "minecraft:iron_ingot" ] } - ] - } - }, - "has_the_recipe": { - "trigger": "minecraft:recipe_unlocked", - "conditions": { - "recipe": "unicopia:weather_vane" - } - } - }, - "requirements": [ - [ - "has_iron", - "has_the_recipe" - ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/apple_pie.json b/src/main/resources/data/unicopia/recipes/apple_pie.json deleted file mode 100644 index 85f86ec6..00000000 --- a/src/main/resources/data/unicopia/recipes/apple_pie.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "***", - "###", - "***" - ], - "key": { - "#": { - "tag": "unicopia:fresh_apples" - }, - "*": { - "item": "minecraft:wheat" - } - }, - "result": { - "item": "unicopia:apple_pie" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/apple_pie_slice_to_apple_pie.json b/src/main/resources/data/unicopia/recipes/apple_pie_slice_to_apple_pie.json deleted file mode 100644 index e3a5c84b..00000000 --- a/src/main/resources/data/unicopia/recipes/apple_pie_slice_to_apple_pie.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:apple_pie_slice" }, - { "item": "unicopia:apple_pie_slice" }, - { "item": "unicopia:apple_pie_slice" }, - { "item": "unicopia:apple_pie_slice" } - ], - "result": { - "item": "unicopia:apple_pie" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/arrow.json b/src/main/resources/data/unicopia/recipes/arrow.json deleted file mode 100644 index d5339b04..00000000 --- a/src/main/resources/data/unicopia/recipes/arrow.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "X", - "#", - "Y" - ], - "key": { - "#": { - "item": "minecraft:stick" - }, - "X": { - "item": "minecraft:flint" - }, - "Y": { - "tag": "unicopia:magic_feathers" - } - }, - "result": { - "item": "minecraft:arrow", - "count": 4 - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/apple.json b/src/main/resources/data/unicopia/recipes/bed_sheets/apple.json deleted file mode 100644 index 59c07b8a..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/apple.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "#%#", - "% %", - " %#" - ], - "key": { - "#": { - "item": "minecraft:green_wool" - }, - "%": { - "item": "minecraft:lime_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:apple_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/bar.json b/src/main/resources/data/unicopia/recipes/bed_sheets/bar.json deleted file mode 100644 index c851297e..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/bar.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "#%#", - "% %", - " %#" - ], - "key": { - "#": { - "item": "minecraft:light_blue_wool" - }, - "%": { - "item": "minecraft:white_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:barred_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/black.json b/src/main/resources/data/unicopia/recipes/bed_sheets/black.json deleted file mode 100644 index 9bc645a0..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/black.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:black_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:black_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/blue.json b/src/main/resources/data/unicopia/recipes/bed_sheets/blue.json deleted file mode 100644 index a327c38e..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/blue.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:blue_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:blue_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/brown.json b/src/main/resources/data/unicopia/recipes/bed_sheets/brown.json deleted file mode 100644 index 873eee0a..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/brown.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:brown_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:brown_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/checker.json b/src/main/resources/data/unicopia/recipes/bed_sheets/checker.json deleted file mode 100644 index eb41d549..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/checker.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "#%#", - "% %", - " %#" - ], - "key": { - "#": { - "item": "minecraft:green_wool" - }, - "%": { - "item": "minecraft:brown_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:checkered_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/cyan.json b/src/main/resources/data/unicopia/recipes/bed_sheets/cyan.json deleted file mode 100644 index 55d27f39..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/cyan.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:cyan_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:cyan_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/gray.json b/src/main/resources/data/unicopia/recipes/bed_sheets/gray.json deleted file mode 100644 index c22908d1..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/gray.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:gray_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:gray_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/green.json b/src/main/resources/data/unicopia/recipes/bed_sheets/green.json deleted file mode 100644 index 44cefb48..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/green.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:green_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:green_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/kelp.json b/src/main/resources/data/unicopia/recipes/bed_sheets/kelp.json deleted file mode 100644 index 31590054..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/kelp.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:kelp" - } - }, - "result": { - "count": 1, - "item": "unicopia:kelp_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/light_blue.json b/src/main/resources/data/unicopia/recipes/bed_sheets/light_blue.json deleted file mode 100644 index 7da12483..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/light_blue.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:light_blue_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:light_blue_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/light_gray.json b/src/main/resources/data/unicopia/recipes/bed_sheets/light_gray.json deleted file mode 100644 index 2762e0a7..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/light_gray.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:light_gray_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:light_gray_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/lime.json b/src/main/resources/data/unicopia/recipes/bed_sheets/lime.json deleted file mode 100644 index 88734f2c..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/lime.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:lime_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:lime_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/magenta.json b/src/main/resources/data/unicopia/recipes/bed_sheets/magenta.json deleted file mode 100644 index eb70f444..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/magenta.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:magenta_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:magenta_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/orange.json b/src/main/resources/data/unicopia/recipes/bed_sheets/orange.json deleted file mode 100644 index 3fa98370..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/orange.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:orange_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:orange_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/pink.json b/src/main/resources/data/unicopia/recipes/bed_sheets/pink.json deleted file mode 100644 index 2d93ece3..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/pink.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:pink_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:pink_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/purple.json b/src/main/resources/data/unicopia/recipes/bed_sheets/purple.json deleted file mode 100644 index ab41e3ad..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/purple.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:purple_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:purple_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow.json b/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow.json deleted file mode 100644 index 16b2493b..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "ROY", - "L B", - " PG" - ], - "key": { - "Y": { - "item": "minecraft:yellow_wool" - }, - "O": { - "item": "minecraft:orange_wool" - }, - "R": { - "item": "minecraft:red_wool" - }, - "G": { - "item": "minecraft:green_wool" - }, - "B": { - "item": "minecraft:blue_wool" - }, - "P": { - "item": "minecraft:purple_wool" - }, - "L": { - "item": "minecraft:light_blue_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:rainbow_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_bpw.json b/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_bpw.json deleted file mode 100644 index 431b5bad..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_bpw.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "PWP", - "B B", - " WP" - ], - "key": { - "B": { - "item": "minecraft:light_blue_wool" - }, - "P": { - "item": "minecraft:pink_wool" - }, - "W": { - "item": "minecraft:white_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:rainbow_bpw_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_bpy.json b/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_bpy.json deleted file mode 100644 index f67eb380..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_bpy.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "PBP", - "Y Y", - " BP" - ], - "key": { - "P": { - "item": "minecraft:pink_wool" - }, - "B": { - "item": "minecraft:light_blue_wool" - }, - "Y": { - "item": "minecraft:yellow_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:rainbow_bpy_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_pgb.json b/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_pgb.json deleted file mode 100644 index 3e61b550..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_pgb.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "WGB", - "P G", - " PW" - ], - "key": { - "P": { - "item": "minecraft:purple_wool" - }, - "W": { - "item": "minecraft:white_wool" - }, - "G": { - "item": "minecraft:light_gray_wool" - }, - "B": { - "item": "minecraft:black_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:rainbow_pbg_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_pwr.json b/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_pwr.json deleted file mode 100644 index ba2c76df..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/rainbow_pwr.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "WRW", - "P P", - " RW" - ], - "key": { - "P": { - "item": "minecraft:pink_wool" - }, - "W": { - "item": "minecraft:white_wool" - }, - "R": { - "item": "minecraft:red_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:rainbow_pwr_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/red.json b/src/main/resources/data/unicopia/recipes/bed_sheets/red.json deleted file mode 100644 index ef489f95..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/red.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:red_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:red_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/bed_sheets/yellow.json b/src/main/resources/data/unicopia/recipes/bed_sheets/yellow.json deleted file mode 100644 index 84bdbe03..00000000 --- a/src/main/resources/data/unicopia/recipes/bed_sheets/yellow.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed_sheets", - "pattern": [ - "###", - "# #", - " ##" - ], - "key": { - "#": { - "item": "minecraft:yellow_wool" - } - }, - "result": { - "count": 1, - "item": "unicopia:yellow_bed_sheets" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/burned_juice.json b/src/main/resources/data/unicopia/recipes/burned_juice.json deleted file mode 100644 index 22ddf879..00000000 --- a/src/main/resources/data/unicopia/recipes/burned_juice.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "smelting", - "ingredient": { - "item": "unicopia:juice" - }, - "result": "unicopia:burned_juice", - "experience": 0, - "cookingtime": 100 -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/burned_juice_to_coal.json b/src/main/resources/data/unicopia/recipes/burned_juice_to_coal.json deleted file mode 100644 index 52f8062a..00000000 --- a/src/main/resources/data/unicopia/recipes/burned_juice_to_coal.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "smelting", - "ingredient": { - "item": "unicopia:burned_juice" - }, - "result": "minecraft:coal", - "experience": 1, - "cookingtime": 20 -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/burned_toast.json b/src/main/resources/data/unicopia/recipes/burned_toast.json deleted file mode 100644 index 341cb93e..00000000 --- a/src/main/resources/data/unicopia/recipes/burned_toast.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "smelting", - "ingredient": { - "item": "unicopia:toast" - }, - "result": "unicopia:burned_toast", - "experience": 0.2, - "cookingtime": 30 -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/candied_apple.json b/src/main/resources/data/unicopia/recipes/candied_apple.json deleted file mode 100644 index 0745ca43..00000000 --- a/src/main/resources/data/unicopia/recipes/candied_apple.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "minecraft:stick" }, - { "tag": "unicopia:fresh_apples" }, - { "item": "minecraft:sugar" }, - { "item": "minecraft:sugar" }, - { "item": "minecraft:sugar" }, - { "item": "minecraft:sugar" } - ], - "result": { "item": "unicopia:candied_apple" } -} diff --git a/src/main/resources/data/unicopia/recipes/chiselled_chitin.json b/src/main/resources/data/unicopia/recipes/chiselled_chitin.json deleted file mode 100644 index 66888165..00000000 --- a/src/main/resources/data/unicopia/recipes/chiselled_chitin.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "##", - "##" - ], - "key": { - "#": [ - { "item": "unicopia:chitin" } - ] - }, - "result": { "item": "unicopia:chiselled_chitin", "count": 4 } -} diff --git a/src/main/resources/data/unicopia/recipes/chiselled_chitin_hull.json b/src/main/resources/data/unicopia/recipes/chiselled_chitin_hull.json deleted file mode 100644 index 30b4a65e..00000000 --- a/src/main/resources/data/unicopia/recipes/chiselled_chitin_hull.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "##", - "%%" - ], - "key": { - "#": [ - { "item": "unicopia:chiselled_chitin" } - ], - "%": [ - { "item": "unicopia:chitin" } - ] - }, - "result": { "item": "unicopia:chiselled_chitin_hull", "count": 4 } -} diff --git a/src/main/resources/data/unicopia/recipes/chiselled_chitin_slab.json b/src/main/resources/data/unicopia/recipes/chiselled_chitin_slab.json deleted file mode 100644 index b5a25d9d..00000000 --- a/src/main/resources/data/unicopia/recipes/chiselled_chitin_slab.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###" - ], - "key": { - "#": [ - { "item": "unicopia:chiselled_chitin" } - ] - }, - "result": { "item": "unicopia:chiselled_chitin_slab", "count": 6 } -} diff --git a/src/main/resources/data/unicopia/recipes/chiselled_chitin_stairs.json b/src/main/resources/data/unicopia/recipes/chiselled_chitin_stairs.json deleted file mode 100644 index e74fdbd8..00000000 --- a/src/main/resources/data/unicopia/recipes/chiselled_chitin_stairs.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "# ", - "## ", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:chiselled_chitin" } - ] - }, - "result": { "item": "unicopia:chiselled_chitin_stairs", "count": 4 } -} diff --git a/src/main/resources/data/unicopia/recipes/chitin.json b/src/main/resources/data/unicopia/recipes/chitin.json deleted file mode 100644 index c3509060..00000000 --- a/src/main/resources/data/unicopia/recipes/chitin.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###", - "###", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:carapace" } - ] - }, - "result": { "item": "unicopia:chitin", "count": 1 } -} diff --git a/src/main/resources/data/unicopia/recipes/chitin_spikes.json b/src/main/resources/data/unicopia/recipes/chitin_spikes.json deleted file mode 100644 index f7f20647..00000000 --- a/src/main/resources/data/unicopia/recipes/chitin_spikes.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " # ", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:chitin" } - ] - }, - "result": { "item": "unicopia:chitin_spikes", "count": 1 } -} diff --git a/src/main/resources/data/unicopia/recipes/cider.json b/src/main/resources/data/unicopia/recipes/cider.json deleted file mode 100644 index 2fbe7a94..00000000 --- a/src/main/resources/data/unicopia/recipes/cider.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "SBS", - "NAN", - " S " - ], - "key": { - "S": [ - { "item": "minecraft:stick" } - ], - "B": [ - { "item": "unicopia:burned_juice" } - ], - "N": [ - { "item": "minecraft:iron_nugget" } - ], - "A": [ - { "tag": "unicopia:fresh_apples" } - ] - }, - "result": { "item": "unicopia:cider" } -} diff --git a/src/main/resources/data/unicopia/recipes/cloth_bed.json b/src/main/resources/data/unicopia/recipes/cloth_bed.json deleted file mode 100644 index 54ba7a7f..00000000 --- a/src/main/resources/data/unicopia/recipes/cloth_bed.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "bed", - "pattern": [ - "^^^", - "###" - ], - "key": { - "^": { - "tag": "minecraft:wool" - }, - "#": { - "tag": "minecraft:logs" - } - }, - "result": { - "count": 1, - "item": "unicopia:cloth_bed" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/cloud_bed.json b/src/main/resources/data/unicopia/recipes/cloud_bed.json deleted file mode 100644 index b1de9a60..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_bed.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "$$$", - "###" - ], - "key": { - "$": [ - { "item": "unicopia:dense_cloud" } - ], - "#": [ - { "item": "unicopia:cloud_planks" } - ] - }, - "result": { "item": "unicopia:cloud_bed", "count": 1 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_block.json b/src/main/resources/data/unicopia/recipes/cloud_block.json deleted file mode 100644 index 949938df..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_block.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "##", - "##" - ], - "key": { - "#": [ - { "item": "unicopia:cloud_lump" } - ] - }, - "result": { "item": "unicopia:cloud", "count": 1 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_brick_slab.json b/src/main/resources/data/unicopia/recipes/cloud_brick_slab.json deleted file mode 100644 index 9b4480e8..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_brick_slab.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###" - ], - "key": { - "#": [ - { "item": "unicopia:cloud_bricks" } - ] - }, - "result": { "item": "unicopia:cloud_brick_slab", "count": 6 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_brick_stairs.json b/src/main/resources/data/unicopia/recipes/cloud_brick_stairs.json deleted file mode 100644 index 01d2cea2..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_brick_stairs.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "# ", - "## ", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:cloud_bricks" } - ] - }, - "result": { "item": "unicopia:cloud_brick_stairs", "count": 4 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_chest.json b/src/main/resources/data/unicopia/recipes/cloud_chest.json deleted file mode 100644 index 5373f56c..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_chest.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###", - "# #", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:cloud_planks" } - ] - }, - "result": { "item": "unicopia:cloud_chest", "count": 1 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_door.json b/src/main/resources/data/unicopia/recipes/cloud_door.json deleted file mode 100644 index 240bf34b..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_door.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "##", - "##", - "##" - ], - "key": { - "#": [ - { "item": "unicopia:dense_cloud" } - ] - }, - "result": { "item": "unicopia:cloud_door", "count": 3 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_lump.json b/src/main/resources/data/unicopia/recipes/cloud_lump.json deleted file mode 100644 index 6890547d..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_lump.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "tag": "unicopia:cloud_jars" } - ], - "result": { "item": "unicopia:cloud_lump", "count": 4 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_pillar.json b/src/main/resources/data/unicopia/recipes/cloud_pillar.json deleted file mode 100644 index 202fc0d8..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_pillar.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "##", - "##", - "##" - ], - "key": { - "#": [ - { "item": "unicopia:cloud" } - ] - }, - "result": { "item": "unicopia:cloud_pillar", "count": 3 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_plank_slab.json b/src/main/resources/data/unicopia/recipes/cloud_plank_slab.json deleted file mode 100644 index 4eca09e0..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_plank_slab.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###" - ], - "key": { - "#": [ - { "item": "unicopia:cloud_planks" } - ] - }, - "result": { "item": "unicopia:cloud_plank_slab", "count": 6 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_plank_stairs.json b/src/main/resources/data/unicopia/recipes/cloud_plank_stairs.json deleted file mode 100644 index 82295d31..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_plank_stairs.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "# ", - "## ", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:cloud_planks" } - ] - }, - "result": { "item": "unicopia:cloud_plank_stairs", "count": 4 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_planks.json b/src/main/resources/data/unicopia/recipes/cloud_planks.json deleted file mode 100644 index 1e02127f..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_planks.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "##", - "##" - ], - "key": { - "#": [ - { "item": "unicopia:cloud" } - ] - }, - "result": { "item": "unicopia:cloud_planks", "count": 4 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_slab.json b/src/main/resources/data/unicopia/recipes/cloud_slab.json deleted file mode 100644 index 0612dbf3..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_slab.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###" - ], - "key": { - "#": [ - { "item": "unicopia:cloud" } - ] - }, - "result": { "item": "unicopia:cloud_slab", "count": 6 } -} diff --git a/src/main/resources/data/unicopia/recipes/cloud_stairs.json b/src/main/resources/data/unicopia/recipes/cloud_stairs.json deleted file mode 100644 index d1e30a9f..00000000 --- a/src/main/resources/data/unicopia/recipes/cloud_stairs.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "# ", - "## ", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:cloud" } - ] - }, - "result": { "item": "unicopia:cloud_stairs", "count": 4 } -} diff --git a/src/main/resources/data/unicopia/recipes/cooked_zap_apple.json b/src/main/resources/data/unicopia/recipes/cooked_zap_apple.json deleted file mode 100644 index 4a37347e..00000000 --- a/src/main/resources/data/unicopia/recipes/cooked_zap_apple.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "smelting", - "ingredient": { - "item": "unicopia:zap_apple" - }, - "result": "unicopia:cooked_zap_apple", - "experience": 0.2, - "cookingtime": 430 -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/copper_horse_shoe.json b/src/main/resources/data/unicopia/recipes/copper_horse_shoe.json deleted file mode 100644 index 275c7652..00000000 --- a/src/main/resources/data/unicopia/recipes/copper_horse_shoe.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "* *", - "* *", - " * " - ], - "key": { - "*": { - "item": "minecraft:copper_ingot" - } - }, - "result": { - "item": "unicopia:copper_horse_shoe" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/crispy_hay_fries.json b/src/main/resources/data/unicopia/recipes/crispy_hay_fries.json deleted file mode 100644 index 69f54f7a..00000000 --- a/src/main/resources/data/unicopia/recipes/crispy_hay_fries.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "smelting", - "ingredient": { - "item": "unicopia:hay_fries" - }, - "result": "unicopia:crispy_hay_fries", - "experience": 1, - "cookingtime": 25 -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/crystal_door.json b/src/main/resources/data/unicopia/recipes/crystal_door.json deleted file mode 100644 index 0d952926..00000000 --- a/src/main/resources/data/unicopia/recipes/crystal_door.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "**", - "**", - "**" - ], - "key": { - "*": { - "item": "unicopia:crystal_shard" - } - }, - "result": { - "item": "unicopia:crystal_door" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/crystal_heart.json b/src/main/resources/data/unicopia/recipes/crystal_heart.json deleted file mode 100644 index 9f100a13..00000000 --- a/src/main/resources/data/unicopia/recipes/crystal_heart.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "* *", - "***", - " * " - ], - "key": { - "*": { - "item": "unicopia:crystal_shard" - } - }, - "result": { - "item": "unicopia:crystal_heart" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/crystal_shard.json b/src/main/resources/data/unicopia/recipes/crystal_shard.json deleted file mode 100644 index b01d5883..00000000 --- a/src/main/resources/data/unicopia/recipes/crystal_shard.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "minecraft:diamond" } - ], - "result": { - "item": "unicopia:crystal_shard", - "count": 3 - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/daffodil_daisy_sandwich.json b/src/main/resources/data/unicopia/recipes/daffodil_daisy_sandwich.json deleted file mode 100644 index ea2cf1e1..00000000 --- a/src/main/resources/data/unicopia/recipes/daffodil_daisy_sandwich.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " # ", - "~~~", - " # " - ], - "key": { - "#": { - "item": "minecraft:bread" - }, - "~": { - "tag": "minecraft:small_flowers" - } - }, - "result": { - "item": "unicopia:daffodil_daisy_sandwich" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/dark_oak_stable_door.json b/src/main/resources/data/unicopia/recipes/dark_oak_stable_door.json deleted file mode 100644 index 21aef6a2..00000000 --- a/src/main/resources/data/unicopia/recipes/dark_oak_stable_door.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "*#*", - "*#*", - "*#*" - ], - "key": { - "*": { - "item": "unicopia:rock" - }, - "#": { - "tag": "minecraft:planks" - } - }, - "result": { - "item": "unicopia:dark_oak_stable_door" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/dense_cloud.json b/src/main/resources/data/unicopia/recipes/dense_cloud.json deleted file mode 100644 index d1e57d5a..00000000 --- a/src/main/resources/data/unicopia/recipes/dense_cloud.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###", - "###", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:cloud" } - ] - }, - "result": { "item": "unicopia:dense_cloud", "count": 4 } -} diff --git a/src/main/resources/data/unicopia/recipes/dense_cloud_slab.json b/src/main/resources/data/unicopia/recipes/dense_cloud_slab.json deleted file mode 100644 index 54a6f9ba..00000000 --- a/src/main/resources/data/unicopia/recipes/dense_cloud_slab.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###" - ], - "key": { - "#": [ - { "item": "unicopia:dense_cloud" } - ] - }, - "result": { "item": "unicopia:dense_cloud_slab", "count": 6 } -} diff --git a/src/main/resources/data/unicopia/recipes/dense_cloud_stairs.json b/src/main/resources/data/unicopia/recipes/dense_cloud_stairs.json deleted file mode 100644 index 1e4392ef..00000000 --- a/src/main/resources/data/unicopia/recipes/dense_cloud_stairs.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "# ", - "## ", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:dense_cloud" } - ] - }, - "result": { "item": "unicopia:dense_cloud_stairs", "count": 4 } -} diff --git a/src/main/resources/data/unicopia/recipes/diamond_polearm.json b/src/main/resources/data/unicopia/recipes/diamond_polearm.json deleted file mode 100644 index 5818e4cb..00000000 --- a/src/main/resources/data/unicopia/recipes/diamond_polearm.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " X", - " # ", - "# " - ], - "key": { - "#": { - "item": "minecraft:stick" - }, - "X": { - "item": "minecraft:diamond" - } - }, - "result": { - "item": "unicopia:diamond_polearm" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/easy_cider.json b/src/main/resources/data/unicopia/recipes/easy_cider.json deleted file mode 100644 index 9b88ce07..00000000 --- a/src/main/resources/data/unicopia/recipes/easy_cider.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:burned_juice" }, - { "item": "unicopia:mug" } - ], - "result": { - "item": "unicopia:cider" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/empty_jar.json b/src/main/resources/data/unicopia/recipes/empty_jar.json deleted file mode 100644 index e4915306..00000000 --- a/src/main/resources/data/unicopia/recipes/empty_jar.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "*#*", - "* *", - "***" - ], - "key": { - "#": { - "tag": "minecraft:planks" - }, - "*": { - "item": "minecraft:glass" - } - }, - "result": { - "item": "unicopia:empty_jar", - "count": 7 - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/filled_jar.json b/src/main/resources/data/unicopia/recipes/filled_jar.json deleted file mode 100644 index c18321e9..00000000 --- a/src/main/resources/data/unicopia/recipes/filled_jar.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "unicopia:jar_insert" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/filled_jar_emptied.json b/src/main/resources/data/unicopia/recipes/filled_jar_emptied.json deleted file mode 100644 index 7c78b525..00000000 --- a/src/main/resources/data/unicopia/recipes/filled_jar_emptied.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "unicopia:jar_extract" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/friendship_bracelet.json b/src/main/resources/data/unicopia/recipes/friendship_bracelet.json deleted file mode 100644 index 20a716d0..00000000 --- a/src/main/resources/data/unicopia/recipes/friendship_bracelet.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "*#*", - "# #", - "*#*" - ], - "key": { - "*": { - "item": "minecraft:string" - }, - "#": { - "item": "minecraft:leather" - } - }, - "result": { - "item": "unicopia:friendship_bracelet" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/gemstone.json b/src/main/resources/data/unicopia/recipes/gemstone.json deleted file mode 100644 index 927c960c..00000000 --- a/src/main/resources/data/unicopia/recipes/gemstone.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "**", - "**" - ], - "key": { - "*": { - "item": "unicopia:crystal_shard" - } - }, - "result": { - "item": "unicopia:gemstone" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/giant_balloon.json b/src/main/resources/data/unicopia/recipes/giant_balloon.json deleted file mode 100644 index 25e370e9..00000000 --- a/src/main/resources/data/unicopia/recipes/giant_balloon.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "group": "basket", - "key": { - "#": { - "item": "minecraft:white_wool" - }, - "-": { - "item": "minecraft:white_carpet" - } - }, - "pattern": [ - "---", - "# #", - "---" - ], - "result": { - "count": 1, - "item": "unicopia:giant_balloon" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/glowing_bangle.json b/src/main/resources/data/unicopia/recipes/glowing_bangle.json deleted file mode 100644 index 3e5bd045..00000000 --- a/src/main/resources/data/unicopia/recipes/glowing_bangle.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "unicopia:crafting_glowing" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/gold_nugget.json b/src/main/resources/data/unicopia/recipes/gold_nugget.json deleted file mode 100644 index 5b393a11..00000000 --- a/src/main/resources/data/unicopia/recipes/gold_nugget.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "smelting", - "ingredient": { - "item": "unicopia:golden_oak_seeds" - }, - "result": "minecraft:gold_nugget", - "experience": 0.2, - "cookingtime": 10 -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/golden_feather.json b/src/main/resources/data/unicopia/recipes/golden_feather.json deleted file mode 100644 index 3977a01c..00000000 --- a/src/main/resources/data/unicopia/recipes/golden_feather.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "***", - "*#*", - "***" - ], - "key": { - "#": [ - { "tag": "unicopia:magic_feathers" } - ], - "*": { - "item": "minecraft:gold_nugget" - } - }, - "result": { - "item": "unicopia:golden_feather" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/golden_horse_shoe.json b/src/main/resources/data/unicopia/recipes/golden_horse_shoe.json deleted file mode 100644 index 81ccb8a1..00000000 --- a/src/main/resources/data/unicopia/recipes/golden_horse_shoe.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "* *", - "* *", - " * " - ], - "key": { - "*": { - "item": "minecraft:gold_ingot" - } - }, - "result": { - "item": "unicopia:golden_horse_shoe" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/golden_polearm.json b/src/main/resources/data/unicopia/recipes/golden_polearm.json deleted file mode 100644 index 6c5297a3..00000000 --- a/src/main/resources/data/unicopia/recipes/golden_polearm.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " X", - " # ", - "# " - ], - "key": { - "#": { - "item": "minecraft:stick" - }, - "X": { - "item": "minecraft:gold_ingot" - } - }, - "result": { - "item": "unicopia:golden_polearm" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/golden_wing.json b/src/main/resources/data/unicopia/recipes/golden_wing.json deleted file mode 100644 index e150c42f..00000000 --- a/src/main/resources/data/unicopia/recipes/golden_wing.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "***", - "***", - "***" - ], - "key": { - "*": { - "item": "unicopia:golden_feather" - } - }, - "result": { - "item": "unicopia:golden_wing" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/gravel_to_pebbles.json b/src/main/resources/data/unicopia/recipes/gravel_to_pebbles.json deleted file mode 100644 index 0f33de27..00000000 --- a/src/main/resources/data/unicopia/recipes/gravel_to_pebbles.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "minecraft:gravel" } - ], - "result": { "item": "unicopia:pebbles", "count": 9 } -} diff --git a/src/main/resources/data/unicopia/recipes/green_apple_to_seeds.json b/src/main/resources/data/unicopia/recipes/green_apple_to_seeds.json deleted file mode 100644 index 7794b7ea..00000000 --- a/src/main/resources/data/unicopia/recipes/green_apple_to_seeds.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:green_apple" } - ], - "result": { "item": "unicopia:green_apple_seeds", "count": 3 } -} diff --git a/src/main/resources/data/unicopia/recipes/hay_burger.json b/src/main/resources/data/unicopia/recipes/hay_burger.json deleted file mode 100644 index e6d4e43a..00000000 --- a/src/main/resources/data/unicopia/recipes/hay_burger.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " # ", - "~~~", - " # " - ], - "key": { - "#": { - "item": "minecraft:bread" - }, - "~": { - "item": "unicopia:oats" - } - }, - "result": { - "item": "unicopia:hay_burger" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/hay_fries.json b/src/main/resources/data/unicopia/recipes/hay_fries.json deleted file mode 100644 index 23a921d6..00000000 --- a/src/main/resources/data/unicopia/recipes/hay_fries.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###" - ], - "key": { - "#": { - "item": "unicopia:oats" - } - }, - "result": { - "item": "unicopia:hay_fries" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/hive.json b/src/main/resources/data/unicopia/recipes/hive.json deleted file mode 100644 index 28e4e633..00000000 --- a/src/main/resources/data/unicopia/recipes/hive.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " # ", - "#o#", - " # " - ], - "key": { - "#": [ - { "item": "unicopia:chitin" } - ], - "o": [ - { "item": "unicopia:mysterious_egg" } - ] - }, - "result": { "item": "unicopia:hive", "count": 1 } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/horse_shoe_fries.json b/src/main/resources/data/unicopia/recipes/horse_shoe_fries.json deleted file mode 100644 index fd256912..00000000 --- a/src/main/resources/data/unicopia/recipes/horse_shoe_fries.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "* *", - "* *", - " * " - ], - "key": { - "*": { - "item": "minecraft:baked_potato" - } - }, - "result": { - "item": "unicopia:horse_shoe_fries", - "count": 15 - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/iron_horse_shoe.json b/src/main/resources/data/unicopia/recipes/iron_horse_shoe.json deleted file mode 100644 index 4adc2b0b..00000000 --- a/src/main/resources/data/unicopia/recipes/iron_horse_shoe.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "* *", - "* *", - " * " - ], - "key": { - "*": { - "item": "minecraft:iron_ingot" - } - }, - "result": { - "item": "unicopia:iron_horse_shoe" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/iron_polearm.json b/src/main/resources/data/unicopia/recipes/iron_polearm.json deleted file mode 100644 index ceceac21..00000000 --- a/src/main/resources/data/unicopia/recipes/iron_polearm.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " X", - " # ", - "# " - ], - "key": { - "#": { - "item": "minecraft:stick" - }, - "X": { - "item": "minecraft:iron_ingot" - } - }, - "result": { - "item": "unicopia:iron_polearm" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/jam_toast.json b/src/main/resources/data/unicopia/recipes/jam_toast.json deleted file mode 100644 index 7e5bbd06..00000000 --- a/src/main/resources/data/unicopia/recipes/jam_toast.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "___", - "_X_", - "___" - ], - "key": { - "_": { - "item": "unicopia:toast" - }, - "X": { - "item": "unicopia:zap_apple_jam_jar" - } - }, - "result": { - "item": "unicopia:jam_toast", - "count": 8 - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/juice.json b/src/main/resources/data/unicopia/recipes/juice.json deleted file mode 100644 index a68d49df..00000000 --- a/src/main/resources/data/unicopia/recipes/juice.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "minecraft:glass_bottle" }, - { "tag": "unicopia:fresh_apples" }, - { "tag": "unicopia:fresh_apples" }, - { "tag": "unicopia:fresh_apples" }, - { "tag": "unicopia:fresh_apples" }, - { "tag": "unicopia:fresh_apples" }, - { "tag": "unicopia:fresh_apples" } - ], - "result": { "item": "unicopia:juice" } -} diff --git a/src/main/resources/data/unicopia/recipes/magic_staff.json b/src/main/resources/data/unicopia/recipes/magic_staff.json deleted file mode 100644 index 9ce441a0..00000000 --- a/src/main/resources/data/unicopia/recipes/magic_staff.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "unicopia:crafting_magical", - "pattern": [ - " o", - " # ", - "# " - ], - "key": { - "#": { - "item": "minecraft:stick" - }, - "o": { - "item": "unicopia:gemstone" - } - }, - "result": { - "item": "unicopia:magic_staff" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/meadowbrook_staff_dissassembly.json b/src/main/resources/data/unicopia/recipes/meadowbrook_staff_dissassembly.json deleted file mode 100644 index 75fd4264..00000000 --- a/src/main/resources/data/unicopia/recipes/meadowbrook_staff_dissassembly.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:meadowbrooks_staff" } - ], - "result": { - "item": "minecraft:stick", - "count": 2 - } -} diff --git a/src/main/resources/data/unicopia/recipes/meadowbrooks_staff.json b/src/main/resources/data/unicopia/recipes/meadowbrooks_staff.json deleted file mode 100644 index 5382d9ce..00000000 --- a/src/main/resources/data/unicopia/recipes/meadowbrooks_staff.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " #", - " # ", - "# " - ], - "key": { - "#": { - "item": "minecraft:stick" - } - }, - "result": { - "item": "unicopia:meadowbrooks_staff" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/muffin.json b/src/main/resources/data/unicopia/recipes/muffin.json deleted file mode 100644 index f78266a5..00000000 --- a/src/main/resources/data/unicopia/recipes/muffin.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "minecraft:sugar" }, - { "item": "minecraft:egg" }, - { "item": "minecraft:potato" }, - { "item": "unicopia:juice" }, - { "item": "unicopia:wheat_worms" } - ], - "result": { - "item": "unicopia:muffin", - "count": 12 - } -} diff --git a/src/main/resources/data/unicopia/recipes/mug.json b/src/main/resources/data/unicopia/recipes/mug.json deleted file mode 100644 index 55404f71..00000000 --- a/src/main/resources/data/unicopia/recipes/mug.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "# #", - "* *", - " # " - ], - "key": { - "#": [ - { "item": "minecraft:stick" } - ], - "*": [ - { "item": "minecraft:iron_nugget" } - ] - }, - "result": { "item": "unicopia:mug" } -} diff --git a/src/main/resources/data/unicopia/recipes/netherite_horse_shoe.json b/src/main/resources/data/unicopia/recipes/netherite_horse_shoe.json deleted file mode 100644 index 12ab6bed..00000000 --- a/src/main/resources/data/unicopia/recipes/netherite_horse_shoe.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "* *", - "* *", - " * " - ], - "key": { - "*": { - "item": "minecraft:netherite_ingot" - } - }, - "result": { - "item": "unicopia:netherite_horse_shoe" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/netherite_polearm_smithing.json b/src/main/resources/data/unicopia/recipes/netherite_polearm_smithing.json deleted file mode 100644 index 39fc0414..00000000 --- a/src/main/resources/data/unicopia/recipes/netherite_polearm_smithing.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "minecraft:smithing_transform", - "addition": { - "item": "minecraft:netherite_ingot" - }, - "base": { - "item": "unicopia:diamond_polearm" - }, - "result": { - "item": "unicopia:netherite_polearm" - }, - "template": { - "item": "minecraft:netherite_upgrade_smithing_template" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/oatmeal.json b/src/main/resources/data/unicopia/recipes/oatmeal.json deleted file mode 100644 index 14a6d641..00000000 --- a/src/main/resources/data/unicopia/recipes/oatmeal.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:oats" }, - { "item": "unicopia:oats" }, - { "item": "unicopia:oats" }, - { "item": "minecraft:milk_bucket" }, - { "item": "minecraft:bowl" } - ], - "result": { "item": "unicopia:oatmeal" } -} diff --git a/src/main/resources/data/unicopia/recipes/pearl_necklace.json b/src/main/resources/data/unicopia/recipes/pearl_necklace.json deleted file mode 100644 index 4b9a4db6..00000000 --- a/src/main/resources/data/unicopia/recipes/pearl_necklace.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "# #", - "# #", - "~#~" - ], - "key": { - "#": { "tag": "unicopia:food_types/shells" }, - "~": { "item": "minecraft:string" } - }, - "result": { - "item": "unicopia:pearl_necklace" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/pebbles_to_gravel.json b/src/main/resources/data/unicopia/recipes/pebbles_to_gravel.json deleted file mode 100644 index fa55f673..00000000 --- a/src/main/resources/data/unicopia/recipes/pebbles_to_gravel.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###", - "###", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:pebbles" } - ] - }, - "result": { "item": "minecraft:gravel" } -} diff --git a/src/main/resources/data/unicopia/recipes/pegasus_amulet.json b/src/main/resources/data/unicopia/recipes/pegasus_amulet.json deleted file mode 100644 index 71d48454..00000000 --- a/src/main/resources/data/unicopia/recipes/pegasus_amulet.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "*#*" - ], - "key": { - "#": { "item": "unicopia:gemstone" }, - "*": { "item": "unicopia:golden_wing" } - }, - "result": { - "item": "unicopia:pegasus_amulet" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/pineapple_crown.json b/src/main/resources/data/unicopia/recipes/pineapple_crown.json deleted file mode 100644 index 1d79690b..00000000 --- a/src/main/resources/data/unicopia/recipes/pineapple_crown.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:pineapple" } - ], - "result": { "item": "unicopia:pineapple_crown" } -} diff --git a/src/main/resources/data/unicopia/recipes/repair_sunglasses.json b/src/main/resources/data/unicopia/recipes/repair_sunglasses.json deleted file mode 100644 index d6c4a284..00000000 --- a/src/main/resources/data/unicopia/recipes/repair_sunglasses.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "minecraft:glass" }, - { "item": "unicopia:broken_sunglasses" } - ], - "result": { - "item": "unicopia:sunglasses" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/rock_candy.json b/src/main/resources/data/unicopia/recipes/rock_candy.json deleted file mode 100644 index 043e1a51..00000000 --- a/src/main/resources/data/unicopia/recipes/rock_candy.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:pebbles" }, - { "item": "unicopia:pebbles" }, - { "item": "unicopia:pebbles" }, - { "item": "minecraft:sugar" }, - { "item": "minecraft:sugar" }, - { "item": "minecraft:sugar" }, - { "item": "minecraft:sugar" }, - { "item": "minecraft:sugar" }, - { "item": "minecraft:sugar" } - ], - "result": { "item": "unicopia:rock_candy", "count": 3 } -} diff --git a/src/main/resources/data/unicopia/recipes/rock_stew.json b/src/main/resources/data/unicopia/recipes/rock_stew.json deleted file mode 100644 index 907b249b..00000000 --- a/src/main/resources/data/unicopia/recipes/rock_stew.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:rock" }, - { "item": "unicopia:rock" }, - { "item": "unicopia:rock" }, - { "item": "minecraft:bowl" } - ], - "result": { "item": "unicopia:rock_stew" } -} diff --git a/src/main/resources/data/unicopia/recipes/rocks_to_cobblestone.json b/src/main/resources/data/unicopia/recipes/rocks_to_cobblestone.json deleted file mode 100644 index d6aa926b..00000000 --- a/src/main/resources/data/unicopia/recipes/rocks_to_cobblestone.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "##", - "##" - ], - "key": { - "#": [ - { "item": "unicopia:rock" } - ] - }, - "result": { "item": "minecraft:cobblestone" } -} diff --git a/src/main/resources/data/unicopia/recipes/shaping_bench.json b/src/main/resources/data/unicopia/recipes/shaping_bench.json deleted file mode 100644 index 98263612..00000000 --- a/src/main/resources/data/unicopia/recipes/shaping_bench.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "##", - "##" - ], - "key": { - "#": [ - { "item": "unicopia:dense_cloud" } - ] - }, - "result": { "item": "unicopia:shaping_bench", "count": 1 } -} diff --git a/src/main/resources/data/unicopia/recipes/shelly.json b/src/main/resources/data/unicopia/recipes/shelly.json deleted file mode 100644 index 54c4a93d..00000000 --- a/src/main/resources/data/unicopia/recipes/shelly.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "o o", - " C " - ], - "key": { - "C": { "item": "unicopia:clam_shell" }, - "o": { "item": "unicopia:rock_candy" } - }, - "result": { - "item": "unicopia:shelly" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/sour_apple_to_seeds.json b/src/main/resources/data/unicopia/recipes/sour_apple_to_seeds.json deleted file mode 100644 index 7884a668..00000000 --- a/src/main/resources/data/unicopia/recipes/sour_apple_to_seeds.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:sour_apple" } - ], - "result": { "item": "unicopia:sour_apple_seeds", "count": 2 } -} diff --git a/src/main/resources/data/unicopia/recipes/spellbook.json b/src/main/resources/data/unicopia/recipes/spellbook.json deleted file mode 100644 index 35b9a050..00000000 --- a/src/main/resources/data/unicopia/recipes/spellbook.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:gemstone" }, - { "item": "minecraft:book" } - ], - "result": { "item": "unicopia:spellbook" } -} diff --git a/src/main/resources/data/unicopia/recipes/stable_door.json b/src/main/resources/data/unicopia/recipes/stable_door.json deleted file mode 100644 index c1acd242..00000000 --- a/src/main/resources/data/unicopia/recipes/stable_door.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "*#*", - "*#*", - "*#*" - ], - "key": { - "*": { - "item": "unicopia:rock_candy" - }, - "#": { - "tag": "minecraft:planks" - } - }, - "result": { - "item": "unicopia:stable_door" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_hull.json b/src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_hull.json deleted file mode 100644 index 296f1c4d..00000000 --- a/src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_hull.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "ingredient": { "item": "unicopia:chiselled_chitin" }, - "result": "unicopia:chiselled_chitin_hull", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_slab.json b/src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_slab.json deleted file mode 100644 index a9392025..00000000 --- a/src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_slab.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "ingredient": { "item": "unicopia:chiselled_chitin" }, - "result": "unicopia:chiselled_chitin_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_stairs.json b/src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_stairs.json deleted file mode 100644 index 77707741..00000000 --- a/src/main/resources/data/unicopia/recipes/stone_cutting/chiselled_chitin_stairs.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "minecraft:stonecutting", - "ingredient": { "item": "unicopia:chiselled_chitin" }, - "result": "unicopia:chiselled_chitin_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/stone_polearm.json b/src/main/resources/data/unicopia/recipes/stone_polearm.json deleted file mode 100644 index 49dcd70a..00000000 --- a/src/main/resources/data/unicopia/recipes/stone_polearm.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " X", - " # ", - "# " - ], - "key": { - "#": { - "item": "minecraft:stick" - }, - "X": { - "tag": "minecraft:stone_tool_materials" - } - }, - "result": { - "item": "unicopia:stone_polearm" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/stripped_palm_wood.json b/src/main/resources/data/unicopia/recipes/stripped_palm_wood.json deleted file mode 100644 index 1b4f818e..00000000 --- a/src/main/resources/data/unicopia/recipes/stripped_palm_wood.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "category": "building", - "group": "bark", - "pattern": [ - "##", - "##" - ], - "key": { - "#": { - "item": "unicopia:stripped_palm_log" - } - }, - "result": { - "count": 3, - "item": "unicopia:stripped_palm_wood" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/sunglasses.json b/src/main/resources/data/unicopia/recipes/sunglasses.json deleted file mode 100644 index 63961ec1..00000000 --- a/src/main/resources/data/unicopia/recipes/sunglasses.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "**" - ], - "key": { - "*": { - "item": "minecraft:glass" - } - }, - "result": { - "item": "unicopia:sunglasses" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/sweet_apple_to_seeds.json b/src/main/resources/data/unicopia/recipes/sweet_apple_to_seeds.json deleted file mode 100644 index efdbcc70..00000000 --- a/src/main/resources/data/unicopia/recipes/sweet_apple_to_seeds.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:sweet_apple" } - ], - "result": { "item": "unicopia:sweet_apple_seeds", "count": 3 } -} diff --git a/src/main/resources/data/unicopia/recipes/toast.json b/src/main/resources/data/unicopia/recipes/toast.json deleted file mode 100644 index 7edc3a02..00000000 --- a/src/main/resources/data/unicopia/recipes/toast.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "smelting", - "ingredient": { - "item": "minecraft:bread" - }, - "result": "unicopia:toast", - "experience": 0.2, - "cookingtime": 430 -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/unstable_cloud.json b/src/main/resources/data/unicopia/recipes/unstable_cloud.json deleted file mode 100644 index 6ccbf5d4..00000000 --- a/src/main/resources/data/unicopia/recipes/unstable_cloud.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "###", - "#O#", - "###" - ], - "key": { - "#": [ - { "item": "unicopia:cloud" } - ], - "O": [ - { "item": "unicopia:lightning_jar" }, - { "item": "unicopia:zap_apple_jam_jar" } - ] - }, - "result": { "item": "unicopia:unstable_cloud", "count": 8 } -} diff --git a/src/main/resources/data/unicopia/recipes/waxed_stripped_zap_log.json b/src/main/resources/data/unicopia/recipes/waxed_stripped_zap_log.json deleted file mode 100644 index 49358b05..00000000 --- a/src/main/resources/data/unicopia/recipes/waxed_stripped_zap_log.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:stripped_zap_log" }, - { "item": "minecraft:honeycomb" } - ], - "result": { "item": "unicopia:waxed_stripped_zap_log" } -} diff --git a/src/main/resources/data/unicopia/recipes/waxed_stripped_zap_wood.json b/src/main/resources/data/unicopia/recipes/waxed_stripped_zap_wood.json deleted file mode 100644 index a025fe57..00000000 --- a/src/main/resources/data/unicopia/recipes/waxed_stripped_zap_wood.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:stripped_zap_wood" }, - { "item": "minecraft:honeycomb" } - ], - "result": { "item": "unicopia:waxed_stripped_zap_wood" } -} diff --git a/src/main/resources/data/unicopia/recipes/waxed_zap_log.json b/src/main/resources/data/unicopia/recipes/waxed_zap_log.json deleted file mode 100644 index 7196b38f..00000000 --- a/src/main/resources/data/unicopia/recipes/waxed_zap_log.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { "item": "unicopia:zap_log" }, - { "item": "minecraft:honeycomb" } - ], - "result": { "item": "unicopia:waxed_zap_log" } -} diff --git a/src/main/resources/data/unicopia/recipes/weather_vane.json b/src/main/resources/data/unicopia/recipes/weather_vane.json deleted file mode 100644 index 4818dbcc..00000000 --- a/src/main/resources/data/unicopia/recipes/weather_vane.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " **", - "** ", - " * " - ], - "key": { - "*": { - "item": "minecraft:iron_nugget" - } - }, - "result": { - "item": "unicopia:weather_vane" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/wooden_polearm.json b/src/main/resources/data/unicopia/recipes/wooden_polearm.json deleted file mode 100644 index 3b659c76..00000000 --- a/src/main/resources/data/unicopia/recipes/wooden_polearm.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - " X", - " # ", - "# " - ], - "key": { - "#": { - "item": "minecraft:stick" - }, - "X": { - "tag": "minecraft:planks" - } - }, - "result": { - "item": "unicopia:wooden_polearm" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/worms_to_dirt.json b/src/main/resources/data/unicopia/recipes/worms_to_dirt.json deleted file mode 100644 index 172b1e4f..00000000 --- a/src/main/resources/data/unicopia/recipes/worms_to_dirt.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "WX", - "XW" - ], - "key": { - "W": { - "item": "unicopia:wheat_worms" - }, - "X": { - "item": "minecraft:sand" - } - }, - "result": { - "item": "minecraft:dirt", - "count": 2 - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/writable_book.json b/src/main/resources/data/unicopia/recipes/writable_book.json deleted file mode 100644 index 49af1f20..00000000 --- a/src/main/resources/data/unicopia/recipes/writable_book.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { - "item": "minecraft:book" - }, - { - "item": "minecraft:ink_sac" - }, - { - "tag": "unicopia:magic_feathers" - } - ], - "result": { - "item": "minecraft:writable_book" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/zap_apple_jam_jar.json b/src/main/resources/data/unicopia/recipes/zap_apple_jam_jar.json deleted file mode 100644 index abc7831d..00000000 --- a/src/main/resources/data/unicopia/recipes/zap_apple_jam_jar.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "type": "minecraft:crafting_shaped", - "pattern": [ - "***", - "***", - " U " - ], - "key": { - "*": { - "item": "unicopia:cooked_zap_apple" - }, - "U": { - "item": "unicopia:empty_jar" - } - }, - "result": { - "item": "unicopia:zap_apple_jam_jar" - } -} \ No newline at end of file From 07c81706529aba1f739846f1f427e1f8ec86a8fa Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 22 Mar 2024 17:55:21 +0000 Subject: [PATCH 02/73] Move all remaining recipes to datagen. Summary of changes: - Changed cutting recipe for etched clouds to require normal clouds - Added cutting recipe for cloud planks - Made the unstable cloud recipe shapeless - Unstable cloud recipe now outputs 8 blocks - Added recipes for stripped zap wood and waxed stripped zap wood - Made chitin<->carapace recipe reversible - Made gravel <-> pebbles recipe reversable - The sus gravel -> pebbles recipe is among us now - Changed chitin spikes recipe to give 8 instead of 1 - Changed diamond to shard recipe to give 6 instead of 3 - Added recipe to get 3 shards from amethyst shards - Made golden oak seeds obtainable by crafting a golden apple - Removed the complex cider recipe - The simple cider recipe now requires requires apple to craft - Increased experience gained from cooking zap apples - Made the zap apple jam jar recipe shapeless - Made the jam toast recipe shapeless - Added trick recipes for golden apple, mango, pineapple, and horseshoe fries - Added white bed sheets, and added a recipe to dye white bed sheets any color and pattern - Added recipes to change any bedsheet into any color or pattern using the right wool --- .../magic/spell/trait/SpellTraits.java | 7 + .../ability/magic/spell/trait/Trait.java | 7 + .../magic/spell/trait/TraitDiscovery.java | 13 +- .../advancement/TraitDiscoveredCriterion.java | 63 ++++++ .../unicopia/advancement/UCriteria.java | 1 + .../unicopia/datagen/Datagen.java | 2 +- .../BedSheetPatternRecipeBuilder.java | 2 +- ...ComplexSpellcraftingRecipeJsonBuilder.java | 55 ++++++ .../recipe}/CraftingMaterialHelper.java | 27 ++- .../recipe/GrowingRecipeJsonBuilder.java | 131 +++++++++++++ .../SpellcraftingRecipeJsonBuilder.java | 163 ++++++++++++++++ .../TrickCraftingRecipeJsonBuilder.java | 129 +++++++++++++ .../{ => recipe}/URecipeProvider.java | 179 +++++++++++++++--- .../data/unicopia/recipes/alicorn_amulet.json | 14 -- .../recipes/carving/carved_cloud_cutting.json | 6 - .../carving/cloud_brick_slab_cutting.json | 6 - .../carving/cloud_brick_stairs_cutting.json | 6 - .../recipes/carving/cloud_bricks_cutting.json | 6 - .../recipes/carving/cloud_pillar_cutting.json | 6 - .../carving/cloud_plank_slab_cutting.json | 6 - .../carving/cloud_plank_stairs_cutting.json | 6 - .../recipes/carving/cloud_planks_cutting.json | 6 - .../recipes/carving/cloud_slab_cutting.json | 6 - .../recipes/carving/cloud_stairs_cutting.json | 6 - .../carving/dense_cloud_slab_cutting.json | 6 - .../carving/dense_cloud_stairs_cutting.json | 6 - .../recipes/carving/etched_cloud_cutting.json | 6 - .../carving/etched_cloud_slab_cutting.json | 6 - .../carving/etched_cloud_stairs_cutting.json | 6 - .../recipes/dragon_breath_scroll.json | 15 -- .../unicopia/recipes/growing/curing_joke.json | 12 -- .../unicopia/recipes/growing/gold_root.json | 12 -- .../recipes/growing/golden_oak_sapling.json | 12 -- .../recipes/growing/plunder_vine.json | 12 -- .../unicopia/recipes/growing/zapling.json | 12 -- .../spell_duplicating_botched_gemstone.json | 4 - .../recipes/spells/arcane_protection.json | 14 -- .../data/unicopia/recipes/spells/bubble.json | 14 -- .../unicopia/recipes/spells/catapult.json | 14 -- .../recipes/spells/chilling_breath.json | 15 -- .../unicopia/recipes/spells/dark_vortex.json | 14 -- .../unicopia/recipes/spells/dispel_evil.json | 16 -- .../unicopia/recipes/spells/displacement.json | 12 -- .../unicopia/recipes/spells/feather_fall.json | 15 -- .../unicopia/recipes/spells/fire_bolt.json | 14 -- .../data/unicopia/recipes/spells/flame.json | 14 -- .../data/unicopia/recipes/spells/frost.json | 12 -- .../unicopia/recipes/spells/hydrophobic.json | 15 -- .../unicopia/recipes/spells/infernal.json | 14 -- .../data/unicopia/recipes/spells/light.json | 14 -- .../data/unicopia/recipes/spells/mimic.json | 14 -- .../unicopia/recipes/spells/mind_swap.json | 14 -- .../unicopia/recipes/spells/necromancy.json | 15 -- .../data/unicopia/recipes/spells/portal.json | 15 -- .../data/unicopia/recipes/spells/reveal.json | 14 -- .../data/unicopia/recipes/spells/scorch.json | 12 -- .../data/unicopia/recipes/spells/shield.json | 12 -- .../unicopia/recipes/spells/siphoning.json | 14 -- .../recipes/spells/transformation.json | 12 -- .../data/unicopia/recipes/spells/vortex.json | 14 -- .../trait_combining_botched_gemstone.json | 4 - .../recipes/trait_combining_gemstone.json | 4 - .../unicopia/recipes/trick_green_apple.json | 8 - .../unicopia/recipes/trick_red_apple.json | 8 - .../unicopia/recipes/trick_sour_apple.json | 8 - .../unicopia/recipes/trick_sweet_apple.json | 8 - .../unicopia/recipes/trick_zap_apple.json | 8 - .../data/unicopia/recipes/unicorn_amulet.json | 16 -- 68 files changed, 745 insertions(+), 614 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/advancement/TraitDiscoveredCriterion.java rename src/main/java/com/minelittlepony/unicopia/datagen/providers/{ => recipe}/BedSheetPatternRecipeBuilder.java (98%) create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/ComplexSpellcraftingRecipeJsonBuilder.java rename src/main/java/com/minelittlepony/unicopia/datagen/{ => providers/recipe}/CraftingMaterialHelper.java (70%) create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java rename src/main/java/com/minelittlepony/unicopia/datagen/providers/{ => recipe}/URecipeProvider.java (72%) delete mode 100644 src/main/resources/data/unicopia/recipes/alicorn_amulet.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/carved_cloud_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/cloud_brick_slab_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/cloud_brick_stairs_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/cloud_bricks_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/cloud_pillar_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/cloud_plank_slab_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/cloud_plank_stairs_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/cloud_planks_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/cloud_slab_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/cloud_stairs_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/dense_cloud_slab_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/dense_cloud_stairs_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/etched_cloud_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/etched_cloud_slab_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/carving/etched_cloud_stairs_cutting.json delete mode 100644 src/main/resources/data/unicopia/recipes/dragon_breath_scroll.json delete mode 100644 src/main/resources/data/unicopia/recipes/growing/curing_joke.json delete mode 100644 src/main/resources/data/unicopia/recipes/growing/gold_root.json delete mode 100644 src/main/resources/data/unicopia/recipes/growing/golden_oak_sapling.json delete mode 100644 src/main/resources/data/unicopia/recipes/growing/plunder_vine.json delete mode 100644 src/main/resources/data/unicopia/recipes/growing/zapling.json delete mode 100644 src/main/resources/data/unicopia/recipes/spell_duplicating_botched_gemstone.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/arcane_protection.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/bubble.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/catapult.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/chilling_breath.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/dark_vortex.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/dispel_evil.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/displacement.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/feather_fall.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/fire_bolt.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/flame.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/frost.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/hydrophobic.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/infernal.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/light.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/mimic.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/mind_swap.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/necromancy.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/portal.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/reveal.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/scorch.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/shield.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/siphoning.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/transformation.json delete mode 100644 src/main/resources/data/unicopia/recipes/spells/vortex.json delete mode 100644 src/main/resources/data/unicopia/recipes/trait_combining_botched_gemstone.json delete mode 100644 src/main/resources/data/unicopia/recipes/trait_combining_gemstone.json delete mode 100644 src/main/resources/data/unicopia/recipes/trick_green_apple.json delete mode 100644 src/main/resources/data/unicopia/recipes/trick_red_apple.json delete mode 100644 src/main/resources/data/unicopia/recipes/trick_sour_apple.json delete mode 100644 src/main/resources/data/unicopia/recipes/trick_sweet_apple.json delete mode 100644 src/main/resources/data/unicopia/recipes/trick_zap_apple.json delete mode 100644 src/main/resources/data/unicopia/recipes/unicorn_amulet.json diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java index d6ca4d8c..5c9b9ca8 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java @@ -17,6 +17,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.client.gui.ItemTraitsTooltipRenderer; @@ -256,6 +257,12 @@ public final class SpellTraits implements Iterable> { return fromEntries(streamFromJson(traits)); } + public static JsonElement toJson(SpellTraits traits) { + JsonObject json = new JsonObject(); + traits.forEach(entry -> json.addProperty(entry.getKey().getId().toString(), entry.getValue())); + return json; + } + public static Optional fromPacketOrEmpty(PacketByteBuf buf) { return buf.readOptional(SpellTraits::fromPacket).filter(SpellTraits::isPresent); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java index 8a1e0a05..341525b4 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java @@ -61,6 +61,13 @@ public enum Trait implements CommandArgumentEnum { private static final Map REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(Trait::name, Function.identity())); private static final Map IDS = Arrays.stream(values()).collect(Collectors.toMap(Trait::getId, Function.identity())); + + public static final com.mojang.serialization.Codec CODEC = StringIdentifiable.createCodec(Trait::values, n -> Unicopia.id(n.toLowerCase(Locale.ROOT)).toString()); + public static final com.mojang.serialization.Codec> SET_CODEC = CODEC.listOf().xmap( + l -> l.stream().distinct().collect(Collectors.toSet()), + s -> s.stream().toList() + ); + private final Identifier id; private final Identifier sprite; private final TraitGroup group; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java index 929f54e1..29ce78d5 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.ability.magic.spell.trait; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -10,6 +11,7 @@ import java.util.stream.Stream; import org.jetbrains.annotations.Nullable; +import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.MsgMarkTraitRead; @@ -76,8 +78,11 @@ public class TraitDiscovery implements NbtSerialisable, Copyable }); unreadTraits.addAll(newTraits); pony.setDirty(); - if (!newTraits.isEmpty() && !pony.asWorld().isClient) { - Channel.UNLOCK_TRAITS.sendToPlayer(new MsgUnlockTraits(newTraits), (ServerPlayerEntity)pony.asEntity()); + if (!newTraits.isEmpty()) { + if (!pony.asWorld().isClient) { + Channel.UNLOCK_TRAITS.sendToPlayer(new MsgUnlockTraits(newTraits), (ServerPlayerEntity)pony.asEntity()); + } + UCriteria.TRAIT_DISCOVERED.trigger(pony.asEntity()); } } @@ -103,6 +108,10 @@ public class TraitDiscovery implements NbtSerialisable, Copyable return traits.contains(trait); } + public boolean isKnown(Collection traits) { + return traits.containsAll(traits); + } + @Environment(EnvType.CLIENT) public void appendTooltip(ItemStack stack, @Nullable World world, List tooltip) { SpellTraits.getEmbeddedTraits(stack) diff --git a/src/main/java/com/minelittlepony/unicopia/advancement/TraitDiscoveredCriterion.java b/src/main/java/com/minelittlepony/unicopia/advancement/TraitDiscoveredCriterion.java new file mode 100644 index 00000000..2a98ed9b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/advancement/TraitDiscoveredCriterion.java @@ -0,0 +1,63 @@ +package com.minelittlepony.unicopia.advancement; + +import java.util.Set; + +import com.google.gson.JsonObject; +import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.mojang.serialization.JsonOps; + +import net.minecraft.advancement.criterion.AbstractCriterion; +import net.minecraft.advancement.criterion.AbstractCriterionConditions; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer; +import net.minecraft.predicate.entity.AdvancementEntityPredicateSerializer; +import net.minecraft.predicate.entity.LootContextPredicate; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.Identifier; +import net.minecraft.util.JsonHelper; + +public class TraitDiscoveredCriterion extends AbstractCriterion { + private static final Identifier ID = Unicopia.id("trait_discovered"); + + @Override + public Identifier getId() { + return ID; + } + + @Override + protected Conditions conditionsFromJson(JsonObject json, LootContextPredicate playerPredicate, AdvancementEntityPredicateDeserializer deserializer) { + return new Conditions(playerPredicate, Trait.SET_CODEC.decode(JsonOps.INSTANCE, JsonHelper.getArray(json, "traits")).result().get().getFirst()); + } + + public static Conditions create(Set traits) { + return new Conditions(LootContextPredicate.EMPTY, traits); + } + + public void trigger(PlayerEntity player) { + if (player instanceof ServerPlayerEntity) { + trigger((ServerPlayerEntity)player, c -> c.test((ServerPlayerEntity)player)); + } + } + + public static class Conditions extends AbstractCriterionConditions { + private final Set traits; + + public Conditions(LootContextPredicate playerPredicate, Set traits) { + super(ID, playerPredicate); + this.traits = traits; + } + + public boolean test(ServerPlayerEntity player) { + return Pony.of(player).getDiscoveries().isKnown(traits); + } + + @Override + public JsonObject toJson(AdvancementEntityPredicateSerializer serializer) { + JsonObject json = super.toJson(serializer); + json.add("traits", Trait.SET_CODEC.encodeStart(JsonOps.INSTANCE, traits).result().get()); + return json; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java b/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java index a652354d..db4d1224 100644 --- a/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java +++ b/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java @@ -6,6 +6,7 @@ public interface UCriteria { CustomEventCriterion CUSTOM_EVENT = Criteria.register(new CustomEventCriterion()); RaceChangeCriterion PLAYER_CHANGE_RACE = Criteria.register(new RaceChangeCriterion()); SendViaDragonBreathScrollCriterion SEND_DRAGON_BREATH = Criteria.register(new SendViaDragonBreathScrollCriterion()); + TraitDiscoveredCriterion TRAIT_DISCOVERED = Criteria.register(new TraitDiscoveredCriterion()); CustomEventCriterion.Trigger LOOK_INTO_SUN = CUSTOM_EVENT.createTrigger("look_into_sun"); CustomEventCriterion.Trigger WEAR_SHADES = CUSTOM_EVENT.createTrigger("wear_shades"); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java index 24f1f53b..527af08a 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java @@ -7,10 +7,10 @@ import com.minelittlepony.unicopia.datagen.providers.SeasonsGrowthRatesProvider; import com.minelittlepony.unicopia.datagen.providers.UBlockTagProvider; import com.minelittlepony.unicopia.datagen.providers.UItemTagProvider; import com.minelittlepony.unicopia.datagen.providers.UModelProvider; -import com.minelittlepony.unicopia.datagen.providers.URecipeProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UBlockAdditionsLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UBlockLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UChestAdditionsLootTableProvider; +import com.minelittlepony.unicopia.datagen.providers.recipe.URecipeProvider; import com.minelittlepony.unicopia.server.world.UWorldGen; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/BedSheetPatternRecipeBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/BedSheetPatternRecipeBuilder.java similarity index 98% rename from src/main/java/com/minelittlepony/unicopia/datagen/providers/BedSheetPatternRecipeBuilder.java rename to src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/BedSheetPatternRecipeBuilder.java index 2eb01643..0cd69ce6 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/BedSheetPatternRecipeBuilder.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/BedSheetPatternRecipeBuilder.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.datagen.providers; +package com.minelittlepony.unicopia.datagen.providers.recipe; import java.util.Arrays; import java.util.HashMap; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/ComplexSpellcraftingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/ComplexSpellcraftingRecipeJsonBuilder.java new file mode 100644 index 00000000..1f5a9d5c --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/ComplexSpellcraftingRecipeJsonBuilder.java @@ -0,0 +1,55 @@ +package com.minelittlepony.unicopia.datagen.providers.recipe; + +import java.util.function.Consumer; + +import com.google.gson.JsonObject; +import com.minelittlepony.unicopia.Unicopia; +import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.item.ItemConvertible; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.util.Identifier; + +public class ComplexSpellcraftingRecipeJsonBuilder { + private final RecipeSerializer serializer; + + private final ItemConvertible material; + + public ComplexSpellcraftingRecipeJsonBuilder(RecipeSerializer serializer, ItemConvertible material) { + this.serializer = serializer; + this.material = material; + } + + public static ComplexSpellcraftingRecipeJsonBuilder create(RecipeSerializer serializer, ItemConvertible material) { + return new ComplexSpellcraftingRecipeJsonBuilder(serializer, material); + } + + public void offerTo(Consumer exporter, final String recipeId) { + exporter.accept(new RecipeJsonProvider() { + @Override + public void serialize(JsonObject json) { + json.add("material", Ingredient.ofItems(material).toJson()); + } + + @Override + public Identifier getRecipeId() { + return Unicopia.id(recipeId); + } + + @Override + public RecipeSerializer getSerializer() { + return serializer; + } + + @Override + public JsonObject toAdvancementJson() { + return null; + } + + @Override + public Identifier getAdvancementId() { + return new Identifier(""); + } + }); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/CraftingMaterialHelper.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/CraftingMaterialHelper.java similarity index 70% rename from src/main/java/com/minelittlepony/unicopia/datagen/CraftingMaterialHelper.java rename to src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/CraftingMaterialHelper.java index 76614d70..25118dd3 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/CraftingMaterialHelper.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/CraftingMaterialHelper.java @@ -1,17 +1,24 @@ -package com.minelittlepony.unicopia.datagen; +package com.minelittlepony.unicopia.datagen.providers.recipe; import java.util.Map; import java.util.NoSuchElementException; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.item.URecipes; import com.mojang.datafixers.util.Either; import net.fabricmc.fabric.api.tag.convention.v1.ConventionalItemTags; import net.minecraft.advancement.criterion.InventoryChangedCriterion; import net.minecraft.data.server.recipe.RecipeProvider; import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.data.server.recipe.SingleItemRecipeJsonBuilder; import net.minecraft.data.server.recipe.VanillaRecipeProvider; import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.predicate.item.ItemPredicate; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.registry.Registries; import net.minecraft.registry.tag.ItemTags; import net.minecraft.registry.tag.TagKey; @@ -62,4 +69,22 @@ public interface CraftingMaterialHelper { static String hasTag(TagKey tag) { return "has_" + tag.id(); } + + static InventoryChangedCriterion.Conditions conditionsFromSpell(ItemConvertible gem, SpellType spell) { + NbtCompound nbt = new NbtCompound(); + nbt.putString("spell", spell.getId().toString()); + return RecipeProvider.conditionsFromItemPredicates(ItemPredicate.Builder.create() + .items(gem) + .nbt(nbt) + .build() + ); + } + + static String hasSpell(SpellType spell) { + return "has_" + spell.getId() + "_gemstone"; + } + + static SingleItemRecipeJsonBuilder createCloudShaping(Ingredient input, RecipeCategory category, ItemConvertible output, int count) { + return new SingleItemRecipeJsonBuilder(category, URecipes.CLOUD_SHAPING_SERIALIZER, input, output, count); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java new file mode 100644 index 00000000..1daab591 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java @@ -0,0 +1,131 @@ +package com.minelittlepony.unicopia.datagen.providers.recipe; + +import java.util.Objects; +import java.util.function.Consumer; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.include.com.google.common.base.Preconditions; + +import com.google.gson.JsonObject; +import com.minelittlepony.unicopia.item.URecipes; +import com.mojang.serialization.JsonOps; + +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementRewards; +import net.minecraft.advancement.CriterionMerger; +import net.minecraft.advancement.criterion.CriterionConditions; +import net.minecraft.advancement.criterion.RecipeUnlockedCriterion; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder; +import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.registry.Registries; +import net.minecraft.util.Identifier; + +public class GrowingRecipeJsonBuilder { + private final Advancement.Builder advancementBuilder = Advancement.Builder.createUntelemetered(); + @Nullable + private String group; + private final RecipeCategory category; + private final BlockState output; + private Block target; + private BlockState fuel; + + public static GrowingRecipeJsonBuilder create(RecipeCategory category, BlockState output) { + return new GrowingRecipeJsonBuilder(category, output); + } + + protected GrowingRecipeJsonBuilder(RecipeCategory category, BlockState output) { + this.category = category; + this.output = output; + } + + public GrowingRecipeJsonBuilder target(Block target) { + this.target = target; + return this; + } + + public GrowingRecipeJsonBuilder fuel(BlockState fuel) { + this.fuel = fuel; + return this; + } + + public GrowingRecipeJsonBuilder criterion(String name, CriterionConditions condition) { + advancementBuilder.criterion(name, condition); + return this; + } + + public GrowingRecipeJsonBuilder group(String group) { + this.group = group; + return this; + } + + public void offerTo(Consumer exporter, Identifier id) { + Preconditions.checkState(!advancementBuilder.getCriteria().isEmpty(), "No way of obtaining recipe " + id); + advancementBuilder + .parent(CraftingRecipeJsonBuilder.ROOT) + .criterion("has_the_recipe", RecipeUnlockedCriterion.create(id)) + .rewards(AdvancementRewards.Builder.recipe(id)) + .criteriaMerger(CriterionMerger.OR); + exporter.accept(new JsonProvider(id, id.withPrefixedPath("recipes/" + category.getName() + "/"), group, target, fuel)); + } + + public void offerTo(Consumer exporter) { + offerTo(exporter, Registries.BLOCK.getId(output.getBlock())); + } + + public void offerTo(Consumer exporter, String recipePath) { + Identifier recipeId = new Identifier(recipePath); + Identifier id = Registries.BLOCK.getId(output.getBlock()); + if (recipeId.equals(id)) { + throw new IllegalStateException("Recipe " + recipePath + " should remove its 'save' argument as it is equal to default one"); + } + offerTo(exporter, recipeId); + } + + private class JsonProvider implements RecipeJsonProvider { + private final Identifier recipeId; + private final Identifier advancementId; + private final String group; + private final Block target; + private final BlockState fuel; + + JsonProvider(Identifier recipeId, Identifier advancementId, String group, Block target, BlockState fuel) { + this.recipeId = recipeId; + this.advancementId = advancementId; + this.group = group; + this.target = Objects.requireNonNull(target, "Target"); + this.fuel = Objects.requireNonNull(fuel, "Fuel"); + } + + @Override + public void serialize(JsonObject json) { + json.addProperty("group", group); + json.addProperty("target", Registries.BLOCK.getId(target).toString()); + json.add("consume", BlockState.CODEC.encodeStart(JsonOps.INSTANCE, fuel).result().get()); + json.add("output", BlockState.CODEC.encodeStart(JsonOps.INSTANCE, output).result().get()); + } + + @Override + public Identifier getRecipeId() { + return recipeId; + } + + @Override + public RecipeSerializer getSerializer() { + return URecipes.TRANSFORM_CROP_SERIALIZER; + } + + @Override + public JsonObject toAdvancementJson() { + return advancementBuilder.toJson(); + } + + @Override + public Identifier getAdvancementId() { + return advancementId; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java new file mode 100644 index 00000000..ca8d7b58 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java @@ -0,0 +1,163 @@ +package com.minelittlepony.unicopia.datagen.providers.recipe; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.include.com.google.common.base.Preconditions; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; +import com.minelittlepony.unicopia.advancement.TraitDiscoveredCriterion; +import com.minelittlepony.unicopia.item.UItems; +import com.minelittlepony.unicopia.item.URecipes; +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementRewards; +import net.minecraft.advancement.CriterionMerger; +import net.minecraft.advancement.criterion.CriterionConditions; +import net.minecraft.advancement.criterion.RecipeUnlockedCriterion; +import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder; +import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.item.ItemConvertible; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.util.Identifier; + +public class SpellcraftingRecipeJsonBuilder { + private final Advancement.Builder advancementBuilder = Advancement.Builder.createUntelemetered(); + @Nullable + private String group; + private final RecipeCategory category; + + private EnchantedIngredient base = new EnchantedIngredient(UItems.GEMSTONE, SpellType.EMPTY_KEY); + private final EnchantedIngredient output; + private final List ingredients = new ArrayList<>(); + private SpellTraits traits = SpellTraits.EMPTY; + + public static SpellcraftingRecipeJsonBuilder create(RecipeCategory category, ItemConvertible gem, SpellType spell) { + return new SpellcraftingRecipeJsonBuilder(category, new EnchantedIngredient(gem, spell)); + } + + protected SpellcraftingRecipeJsonBuilder(RecipeCategory category, EnchantedIngredient output) { + this.category = category; + this.output = output; + } + + public SpellcraftingRecipeJsonBuilder base(ItemConvertible gem, SpellType spell) { + base = new EnchantedIngredient(gem, spell); + return this; + } + + public SpellcraftingRecipeJsonBuilder input(ItemConvertible gem, SpellType spell) { + ingredients.add(new EnchantedIngredient(gem, spell)); + return this; + } + + public SpellcraftingRecipeJsonBuilder traits(SpellTraits.Builder traits) { + this.traits = traits.build(); + return this; + } + + public SpellcraftingRecipeJsonBuilder criterion(String name, CriterionConditions condition) { + advancementBuilder.criterion(name, condition); + return this; + } + + public SpellcraftingRecipeJsonBuilder group(String group) { + this.group = group; + return this; + } + + public void offerTo(Consumer exporter, Identifier id) { + if (!traits.isEmpty()) { + advancementBuilder.criterion("has_traits", TraitDiscoveredCriterion.create(traits.stream().map(Map.Entry::getKey).collect(Collectors.toUnmodifiableSet()))); + } + Preconditions.checkState(!advancementBuilder.getCriteria().isEmpty(), "No way of obtaining recipe " + id); + advancementBuilder + .parent(CraftingRecipeJsonBuilder.ROOT) + .criterion("has_the_recipe", RecipeUnlockedCriterion.create(id)) + .rewards(AdvancementRewards.Builder.recipe(id)) + .criteriaMerger(CriterionMerger.OR); + exporter.accept(new JsonProvider(id, id.withPrefixedPath("recipes/" + category.getName() + "/"), group, ingredients, traits)); + } + + public void offerTo(Consumer exporter) { + offerTo(exporter, output.spell().getId()); + } + + public void offerTo(Consumer exporter, String recipePath) { + Identifier recipeId = new Identifier(recipePath); + if (recipeId.equals(output.spell().getId())) { + throw new IllegalStateException("Recipe " + recipePath + " should remove its 'save' argument as it is equal to default one"); + } + offerTo(exporter, recipeId); + } + + record EnchantedIngredient (ItemConvertible gem, SpellType spell) { + JsonObject toJson(JsonObject json) { + json.addProperty("item", CraftingRecipeJsonBuilder.getItemId(gem).toString()); + if (!spell.isEmpty()) { + json.addProperty("spell", spell.getId().toString()); + } + return json; + } + } + + private class JsonProvider implements RecipeJsonProvider { + private final Identifier recipeId; + private final Identifier advancementId; + private final String group; + private final List ingredients; + private final SpellTraits traits; + + JsonProvider(Identifier recipeId, Identifier advancementId, String group, List ingredients, SpellTraits traits) { + this.recipeId = recipeId; + this.advancementId = advancementId; + this.group = group; + this.ingredients = new ArrayList<>(ingredients); + this.traits = traits; + } + + @Override + public void serialize(JsonObject json) { + json.addProperty("group", group); + json.add("material", base.toJson(new JsonObject())); + json.add("result", output.toJson(new JsonObject())); + JsonArray ingredientsJson = new JsonArray(); + ingredients.forEach(ingredient -> { + ingredientsJson.add(ingredient.toJson(new JsonObject())); + }); + json.add("ingredients", ingredientsJson); + JsonObject traitsJson = new JsonObject(); + traits.forEach(entry -> { + traitsJson.addProperty(entry.getKey().getId().toString(), entry.getValue()); + }); + json.add("traits", traitsJson); + } + + @Override + public Identifier getRecipeId() { + return recipeId; + } + + @Override + public RecipeSerializer getSerializer() { + return URecipes.TRAIT_REQUIREMENT; + } + + @Override + public JsonObject toAdvancementJson() { + return advancementBuilder.toJson(); + } + + @Override + public Identifier getAdvancementId() { + return advancementId; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java new file mode 100644 index 00000000..bb8df54e --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java @@ -0,0 +1,129 @@ +package com.minelittlepony.unicopia.datagen.providers.recipe; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.include.com.google.common.base.Preconditions; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementRewards; +import net.minecraft.advancement.CriterionMerger; +import net.minecraft.advancement.criterion.CriterionConditions; +import net.minecraft.advancement.criterion.RecipeUnlockedCriterion; +import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder; +import net.minecraft.data.server.recipe.RecipeJsonBuilder; +import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.item.Item; +import net.minecraft.item.ItemConvertible; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.recipe.book.CraftingRecipeCategory; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.registry.Registries; +import net.minecraft.util.Identifier; + +public class TrickCraftingRecipeJsonBuilder extends RecipeJsonBuilder implements CraftingRecipeJsonBuilder { + private final Advancement.Builder advancementBuilder = Advancement.Builder.createUntelemetered(); + @Nullable + private String group; + private final RecipeCategory category; + private final Item output; + + private final List inputs = new ArrayList<>(); + + public TrickCraftingRecipeJsonBuilder(RecipeCategory category, ItemConvertible output) { + this.category = category; + this.output = output.asItem(); + } + + public static TrickCraftingRecipeJsonBuilder create(RecipeCategory category, ItemConvertible output) { + return new TrickCraftingRecipeJsonBuilder(category, output); + } + + @Override + public Item getOutputItem() { + return output; + } + + public TrickCraftingRecipeJsonBuilder input(ItemConvertible input) { + inputs.add(Ingredient.ofItems(input)); + return this; + } + + @Override + public TrickCraftingRecipeJsonBuilder criterion(String name, CriterionConditions condition) { + advancementBuilder.criterion(name, condition); + return this; + } + + @Override + public TrickCraftingRecipeJsonBuilder group(String group) { + this.group = group; + return this; + } + + @Override + public void offerTo(Consumer exporter, Identifier id) { + Preconditions.checkState(!advancementBuilder.getCriteria().isEmpty(), "No way of obtaining recipe " + id); + advancementBuilder + .parent(CraftingRecipeJsonBuilder.ROOT) + .criterion("has_the_recipe", RecipeUnlockedCriterion.create(id)) + .rewards(AdvancementRewards.Builder.recipe(id)) + .criteriaMerger(CriterionMerger.OR); + exporter.accept(new JsonProvider(id, id.withPrefixedPath("recipes/" + category.getName() + "/"), group == null ? "" : group, inputs)); + } + + private class JsonProvider extends RecipeJsonBuilder.CraftingRecipeJsonProvider { + private final Identifier recipeId; + private final String group; + private final List inputs; + private final Identifier advancementId; + + protected JsonProvider(Identifier recipeId, Identifier advancementId, String group, List inputs) { + super(CraftingRecipeCategory.MISC); + this.recipeId = recipeId; + this.advancementId = advancementId; + this.group = group; + this.inputs = new ArrayList<>(inputs); + } + + @Override + public void serialize(JsonObject json) { + super.serialize(json); + if (!group.isEmpty()) { + json.addProperty("group", group); + } + JsonArray jsonArray = new JsonArray(); + for (Ingredient ingredient : inputs) { + jsonArray.add(ingredient.toJson()); + } + json.add("ingredients", jsonArray); + json.addProperty("appearance", Registries.ITEM.getId(output).toString()); + } + + @Override + public RecipeSerializer getSerializer() { + return RecipeSerializer.SHAPELESS; + } + + @Override + public Identifier getRecipeId() { + return this.recipeId; + } + + @Override + @Nullable + public JsonObject toAdvancementJson() { + return advancementBuilder.toJson(); + } + + @Override + @Nullable + public Identifier getAdvancementId() { + return advancementId; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java similarity index 72% rename from src/main/java/com/minelittlepony/unicopia/datagen/providers/URecipeProvider.java rename to src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index 274be45f..942131c8 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.datagen.providers; +package com.minelittlepony.unicopia.datagen.providers.recipe; import java.util.Arrays; import java.util.List; @@ -8,13 +8,16 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.UConventionalTags; import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; +import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.block.UBlocks; -import com.minelittlepony.unicopia.datagen.CraftingMaterialHelper; import com.minelittlepony.unicopia.datagen.ItemFamilies; import com.minelittlepony.unicopia.datagen.UBlockFamilies; -import com.minelittlepony.unicopia.datagen.providers.BedSheetPatternRecipeBuilder.PatternTemplate; +import com.minelittlepony.unicopia.datagen.providers.recipe.BedSheetPatternRecipeBuilder.PatternTemplate; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.server.world.UTreeGen; import com.mojang.datafixers.util.Either; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; @@ -25,6 +28,7 @@ import net.minecraft.block.Block; import net.minecraft.block.Blocks; import net.minecraft.data.server.recipe.ComplexRecipeJsonBuilder; import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.data.server.recipe.RecipeProvider; import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; import net.minecraft.item.Item; @@ -54,6 +58,7 @@ public class URecipeProvider extends FabricRecipeProvider { offerCloudRecipes(exporter); offerFoodRecipes(exporter); offerGemstoneAndMagicRecipes(exporter); + offerMagicSpellRecipes(exporter); offerSeaponyRecipes(exporter); offerEarthPonyRecipes(exporter); @@ -102,11 +107,33 @@ public class URecipeProvider extends FabricRecipeProvider { offer2x2CompactingRecipe(exporter, RecipeCategory.DECORATIONS, UBlocks.SHAPING_BENCH, UBlocks.DENSE_CLOUD); generateFamily(exporter, UBlockFamilies.CLOUD_BRICKS); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CARVED_CLOUD, UBlocks.CLOUD); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.ETCHED_CLOUD, UBlocks.CLOUD); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_BRICKS, UBlocks.CLOUD); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_PLANKS, UBlocks.CLOUD); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_PILLAR, UBlocks.CLOUD); + + // TODO: Cut Cloud, Smooth Cloud, Polished Cloud, Raked Cloud + + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_SLAB, UBlocks.CLOUD, 2); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_STAIRS, UBlocks.CLOUD); + + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_BRICK_SLAB, UBlocks.CLOUD_BRICKS, 2); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_BRICK_STAIRS, UBlocks.CLOUD_BRICKS); + + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_PLANK_SLAB, UBlocks.CLOUD_PLANKS, 2); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_PLANK_STAIRS, UBlocks.CLOUD_PLANKS); + + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.DENSE_CLOUD_SLAB, UBlocks.DENSE_CLOUD, 2); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.DENSE_CLOUD_STAIRS, UBlocks.DENSE_CLOUD); + + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.ETCHED_CLOUD_SLAB, UBlocks.ETCHED_CLOUD, 2); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.ETCHED_CLOUD_STAIRS, UBlocks.ETCHED_CLOUD); + offerCompactingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.DENSE_CLOUD, UBlocks.CLOUD, 4); generateFamily(exporter, UBlockFamilies.DENSE_CLOUD); offer2x3Recipe(exporter, UBlocks.CLOUD_DOOR, UBlocks.DENSE_CLOUD, "door"); - // XXX: Make the unstable cloud recipe shapeless and change output to 8 (to align with making jam toast) ShapelessRecipeJsonBuilder.create(RecipeCategory.REDSTONE, UBlocks.UNSTABLE_CLOUD, 8) .input(UBlocks.CLOUD, 8) .input(Ingredient.ofItems(UItems.LIGHTNING_JAR, UItems.ZAP_APPLE_JAM_JAR)) @@ -129,7 +156,6 @@ public class URecipeProvider extends FabricRecipeProvider { generateFamily(exporter, UBlockFamilies.ZAP); offerPlanksRecipe(exporter, UBlocks.ZAP_PLANKS, UTags.Items.ZAP_LOGS, 4); offerBarkBlockRecipe(exporter, UBlocks.ZAP_WOOD, UBlocks.ZAP_LOG); - // XXX: fixed not being able to craft stripped zap wood and waxed stripped zap wood offerBarkBlockRecipe(exporter, UBlocks.STRIPPED_ZAP_WOOD, UBlocks.STRIPPED_ZAP_LOG); // waxed zap wood @@ -147,12 +173,10 @@ public class URecipeProvider extends FabricRecipeProvider { } private void offerChitinBlocksRecipes(Consumer exporter) { - // XXX: Changed chitin recipe to be reversible offerReversibleCompactingRecipes(exporter, RecipeCategory.BUILDING_BLOCKS, UItems.CARAPACE, RecipeCategory.BUILDING_BLOCKS, UBlocks.CHITIN); generateFamily(exporter, UBlockFamilies.CHISELED_CHITIN); offerHiveRecipe(exporter, UBlocks.HIVE, UBlocks.CHITIN, UBlocks.MYSTERIOUS_EGG); offerHullRecipe(exporter, UBlocks.CHISELLED_CHITIN_HULL, UBlocks.CHISELLED_CHITIN, UBlocks.CHITIN); - // XXX: Changed spikes recipe to give 8 instead of 1 offerSpikesRecipe(exporter, UBlocks.CHITIN_SPIKES, UBlocks.CHITIN); // TODO: polished chitin @@ -164,9 +188,7 @@ public class URecipeProvider extends FabricRecipeProvider { } private void offerGemstoneAndMagicRecipes(Consumer exporter) { - // XXX: Change diamond to shard recipe to give 6 instead of 3 offerShapelessRecipe(exporter, UItems.CRYSTAL_SHARD, Items.DIAMOND, "crystal_shard", 6); - // XXX: Added recipe to get shards from amethyst shards offerShapelessRecipe(exporter, UItems.CRYSTAL_SHARD, Items.AMETHYST_SHARD, "crystal_shard", 3); offer2x2CompactingRecipe(exporter, RecipeCategory.MISC, UItems.GEMSTONE, UItems.CRYSTAL_SHARD); ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.SPELLBOOK) @@ -206,14 +228,6 @@ public class URecipeProvider extends FabricRecipeProvider { .pattern("*#*") .offerTo(exporter); - // unicorn amulet - /*ShapelessRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.UNICORN_AMULET) - .input(UItems.PEGASUS_AMULET) - .input(UItems.CRYSTAL_HEART) - .input(UItems.GROGARS_BELL) - .input(Items.TOTEM_OF_UNDYING) - .offerTo(exporter);*/ - // friendship bracelet ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.FRIENDSHIP_BRACELET) .input('*', Items.STRING) @@ -235,12 +249,65 @@ public class URecipeProvider extends FabricRecipeProvider { offerShapelessRecipe(exporter, Items.STICK, UItems.MEADOWBROOKS_STAFF, "stick", 2); } + private void offerMagicSpellRecipes(Consumer exporter) { + offerSpell(exporter, UItems.GEMSTONE, SpellType.DISPLACEMENT, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 10).with(Trait.CHAOS, 10)); + offerSpell(exporter, UItems.GEMSTONE, SpellType.FROST, new SpellTraits.Builder().with(Trait.ICE, 10)); + offerSpell(exporter, UItems.GEMSTONE, SpellType.SCORCH, new SpellTraits.Builder().with(Trait.FIRE, 10)); + offerSpell(exporter, UItems.GEMSTONE, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.STRENGTH, 10).with(Trait.FOCUS, 6).with(Trait.POWER, 10)); + offerSpell(exporter, UItems.GEMSTONE, SpellType.TRANSFORMATION, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 10).with(Trait.LIFE, 10).with(Trait.CHAOS, 4)); + + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.ARCANE_PROTECTION, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.STRENGTH, 10).with(Trait.KNOWLEDGE, 18).with(Trait.DARKNESS, 1)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.BUBBLE, SpellType.CATAPULT, new SpellTraits.Builder().with(Trait.WATER, 9).with(Trait.AIR, 9)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.CATAPULT, SpellType.FLAME, new SpellTraits.Builder().with(Trait.FOCUS, 9).with(Trait.AIR, 9)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.CHILLING_BREATH, SpellType.FROST, new SpellTraits.Builder().with(Trait.ICE, 5).with(Trait.KNOWLEDGE, 10)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.DARK_VORTEX, SpellType.VORTEX, new SpellTraits.Builder().with(Trait.STRENGTH, 10).with(Trait.KNOWLEDGE, 8).with(Trait.DARKNESS, 9).with(Trait.CHAOS, 8)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.FEATHER_FALL, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 20).with(Trait.LIFE, 10).with(Trait.CHAOS, 4).with(Trait.GENEROSITY, 10)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.FIRE_BOLT, SpellType.FLAME, new SpellTraits.Builder().with(Trait.FOCUS, 9).with(Trait.FIRE, 30)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.FLAME, SpellType.SCORCH, new SpellTraits.Builder().with(Trait.FIRE, 15)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.INFERNAL, SpellType.FLAME, new SpellTraits.Builder().with(Trait.FIRE, 50).with(Trait.DARKNESS, 10)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.LIGHT, SpellType.FIRE_BOLT, new SpellTraits.Builder().with(Trait.ICE, 30).with(Trait.LIFE, 30).with(Trait.FOCUS, 10)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.MIMIC, SpellType.TRANSFORMATION, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 19).with(Trait.LIFE, 10).with(Trait.CHAOS, 4)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.MIND_SWAP, SpellType.MIMIC, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 19).with(Trait.LIFE, 10).with(Trait.CHAOS, 40)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.NECROMANCY, SpellType.SIPHONING, new SpellTraits.Builder().with(Trait.STRENGTH, 10).with(Trait.KNOWLEDGE, 8).with(Trait.DARKNESS, 19).with(Trait.CHAOS, 8).with(Trait.BLOOD, 10).with(Trait.POISON, 9)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.REVEALING, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 18).with(Trait.LIFE, 1).with(Trait.ORDER, 4)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.SIPHONING, SpellType.INFERNAL, new SpellTraits.Builder().with(Trait.BLOOD, 8).with(Trait.POISON, 10)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.VORTEX, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.STRENGTH, 10).with(Trait.KNOWLEDGE, 8).with(Trait.AIR, 9)); + + offerSpellFromTwoSpells(exporter, UItems.GEMSTONE, SpellType.DISPEL_EVIL, SpellType.ARCANE_PROTECTION, SpellType.DISPLACEMENT, new SpellTraits.Builder().with(Trait.KINDNESS, 1).with(Trait.POWER, 1)); + offerSpellFromTwoSpells(exporter, UItems.GEMSTONE, SpellType.HYDROPHOBIC, SpellType.FROST, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.FOCUS, 6)); + offerSpellFromTwoSpells(exporter, UItems.GEMSTONE, SpellType.PORTAL, SpellType.DISPLACEMENT, SpellType.DARK_VORTEX, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 18).with(Trait.CHAOS, 20)); + + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.ALICORN_AMULET, SpellType.EMPTY_KEY) + .base(UItems.GEMSTONE, SpellType.DARK_VORTEX) + .traits(new SpellTraits.Builder().with(Trait.DARKNESS, 30).with(Trait.POWER, 30).with(Trait.BLOOD, 30)) + .offerTo(exporter, "alicorn_amulet"); + + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.UNICORN_AMULET, SpellType.EMPTY_KEY) + .base(UItems.BROKEN_ALICORN_AMULET, SpellType.EMPTY_KEY) + .input(UItems.PEGASUS_AMULET, SpellType.EMPTY_KEY) + .input(UItems.CRYSTAL_HEART, SpellType.EMPTY_KEY) + .input(UItems.GROGARS_BELL, SpellType.EMPTY_KEY) + .input(Items.TOTEM_OF_UNDYING, SpellType.EMPTY_KEY) + .traits(new SpellTraits.Builder()) + .criterion(hasItem(UItems.BROKEN_ALICORN_AMULET), conditionsFromItem(UItems.BROKEN_ALICORN_AMULET)) + .offerTo(exporter, "unicorn_amulet"); + + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.DRAGON_BREATH_SCROLL, SpellType.EMPTY_KEY) + .base(Items.PAPER, SpellType.EMPTY_KEY) + .input(Items.PAPER, SpellType.EMPTY_KEY) + .traits(new SpellTraits.Builder().with(Trait.FIRE, 1)) + .offerTo(exporter, "dragon_breath_scroll"); + + ComplexSpellcraftingRecipeJsonBuilder.create(URecipes.SPELL_DUPLICATING, UItems.BOTCHED_GEM).offerTo(exporter, "spell_duplicating"); + ComplexSpellcraftingRecipeJsonBuilder.create(URecipes.TRAIT_COMBINING, UItems.BOTCHED_GEM).offerTo(exporter, "trait_combining_botched_gem"); + ComplexSpellcraftingRecipeJsonBuilder.create(URecipes.TRAIT_COMBINING, UItems.GEMSTONE).offerTo(exporter, "trait_combining_gemstone"); + } + private void offerFoodRecipes(Consumer exporter) { offerShapelessRecipe(exporter, UItems.PINEAPPLE_CROWN, UItems.PINEAPPLE, "seeds", 1); offerShapelessRecipe(exporter, UItems.SWEET_APPLE_SEEDS, UItems.SWEET_APPLE, "seeds", 3); offerShapelessRecipe(exporter, UItems.SOUR_APPLE_SEEDS, UItems.SOUR_APPLE, "seeds", 3); offerShapelessRecipe(exporter, UItems.GREEN_APPLE_SEEDS, UItems.GREEN_APPLE, "seeds", 3); - // XXX: Made golden oak seeds obtainable by crafting offerShapelessRecipe(exporter, UItems.GOLDEN_OAK_SEEDS, Items.GOLDEN_APPLE, "seeds", 1); offerPieRecipe(exporter, UItems.APPLE_PIE, UItems.APPLE_PIE_SLICE, Items.WHEAT, UTags.FRESH_APPLES); @@ -258,7 +325,6 @@ public class URecipeProvider extends FabricRecipeProvider { .group("juice") .offerTo(exporter); appendIngredients(ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.MUFFIN), Items.SUGAR, Items.EGG, Items.POTATO, UItems.JUICE, UItems.WHEAT_WORMS).offerTo(exporter); - // XXX: Removed the complex cider recipe ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.MUG) .input('*', Items.IRON_NUGGET).criterion(hasItem(Items.IRON_NUGGET), conditionsFromItem(Items.IRON_NUGGET)) .input('#', UConventionalTags.STICKS).criterion(hasItem(Items.STICK), conditionsFromTag(UConventionalTags.STICKS)) @@ -266,7 +332,6 @@ public class URecipeProvider extends FabricRecipeProvider { .pattern("* *") .pattern(" # ") .offerTo(exporter); - // XXX: Changed the simple cider recipe to require apples appendIngredients(ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.CIDER), UItems.BURNED_JUICE, UItems.MUG) .input(Ingredient.fromTag(UTags.FRESH_APPLES)).criterion(hasItem(Items.APPLE), conditionsFromTag(UTags.FRESH_APPLES)) .offerTo(exporter); @@ -308,25 +373,42 @@ public class URecipeProvider extends FabricRecipeProvider { offerSmelting(exporter, List.of(UItems.TOAST), RecipeCategory.FOOD, UItems.BURNED_TOAST, 0.2F, 30, "bread"); offerSmelting(exporter, List.of(UItems.BURNED_JUICE, UItems.BURNED_TOAST), RecipeCategory.FOOD, Items.CHARCOAL, 1, 20, "coal"); offerSmelting(exporter, List.of(UItems.HAY_FRIES), RecipeCategory.FOOD, UItems.CRISPY_HAY_FRIES, 1F, 25, "hay_fries"); - // XXX: Increased experience from cooking zap apples offerSmelting(exporter, List.of(UItems.ZAP_APPLE), RecipeCategory.FOOD, UItems.COOKED_ZAP_APPLE, 1.2F, 430, "zap_apple"); - // XXX: Make zap apple jam jar recipe shapeless ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.ZAP_APPLE_JAM_JAR) .input(UItems.COOKED_ZAP_APPLE, 6).criterion(hasItem(UItems.COOKED_ZAP_APPLE), conditionsFromItem(UItems.COOKED_ZAP_APPLE)) .input(UItems.EMPTY_JAR) .offerTo(exporter); - // XXX: Make jam toast recipe shapeless ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.JAM_TOAST, 8) .input(UItems.ZAP_APPLE_JAM_JAR).criterion(hasItem(UItems.ZAP_APPLE_JAM_JAR), conditionsFromItem(UItems.ZAP_APPLE_JAM_JAR)) .input(UItems.TOAST, 8) .offerTo(exporter); - ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.CANDIED_APPLE) .input(UConventionalTags.STICKS) .input(UTags.FRESH_APPLES).criterion(hasItem(UItems.ZAP_APPLE_JAM_JAR), conditionsFromItem(UItems.ZAP_APPLE_JAM_JAR)) .input(Items.SUGAR, 4) .offerTo(exporter); + + // trick apples + offerTrickRecipe(exporter, UItems.GREEN_APPLE, Items.GREEN_DYE); + offerTrickRecipe(exporter, Items.APPLE, Items.RED_DYE); + offerTrickRecipe(exporter, UItems.SOUR_APPLE, Items.YELLOW_DYE); + offerTrickRecipe(exporter, UItems.SWEET_APPLE, Items.ORANGE_DYE); + offerTrickRecipe(exporter, UItems.ROTTEN_APPLE, Items.ROTTEN_FLESH); + offerTrickRecipe(exporter, UItems.COOKED_ZAP_APPLE, Items.SPIDER_EYE); + offerTrickRecipe(exporter, Items.GOLDEN_APPLE, Items.GOLD_NUGGET); + offerTrickRecipe(exporter, Items.ENCHANTED_GOLDEN_APPLE, Items.GOLD_INGOT); + offerTrickRecipe(exporter, UItems.MANGO, Items.LIME_DYE); + offerTrickRecipe(exporter, UItems.PINEAPPLE, UItems.PINEAPPLE_CROWN); + offerTrickRecipe(exporter, UItems.HORSE_SHOE_FRIES, UItems.IRON_HORSE_SHOE); + offerTrickRecipe(exporter, UItems.MUFFIN, UItems.ROCK); + } + + public static void offerTrickRecipe(Consumer exporter, ItemConvertible output, ItemConvertible input) { + TrickCraftingRecipeJsonBuilder.create(RecipeCategory.FOOD, output) + .input(UItems.ZAP_APPLE).criterion(hasItem(UItems.ZAP_APPLE), conditionsFromItem(UItems.ZAP_APPLE)) + .input(input) + .offerTo(exporter, convertBetween(output, input) + "_trick"); } private void offerSeaponyRecipes(Consumer exporter) { @@ -376,12 +458,15 @@ public class URecipeProvider extends FabricRecipeProvider { .offerTo(exporter, convertBetween(Items.DIRT, UItems.WHEAT_WORMS)); offer2x2CompactingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, Items.COBBLESTONE, UItems.ROCK); - - // XXX: Made gravel <-> pebbles conversion reversable offerReversibleCompactingRecipesWithReverseRecipeGroup(exporter, RecipeCategory.MISC, UItems.PEBBLES, RecipeCategory.BUILDING_BLOCKS, Blocks.GRAVEL, convertBetween(UItems.PEBBLES, Blocks.GRAVEL), "pebbles"); - // XXX: Added sus gravel -> pebbles recipe offerShapelessRecipe(exporter, UItems.PEBBLES, Blocks.SUSPICIOUS_GRAVEL, "pebbles", 9); offerSmelting(exporter, List.of(UItems.GOLDEN_OAK_SEEDS, UItems.GOLDEN_FEATHER), RecipeCategory.MISC, Items.GOLD_NUGGET, 3F, 10, "gold_nugget"); + + offerGrowing(exporter, UBlocks.CURING_JOKE, Blocks.LAPIS_BLOCK, Blocks.CORNFLOWER); + offerGrowing(exporter, UBlocks.GOLD_ROOT, Blocks.RAW_GOLD_BLOCK, Blocks.CARROTS); + offerGrowing(exporter, UTreeGen.GOLDEN_APPLE_TREE.sapling().get(), Blocks.RAW_GOLD_BLOCK, Blocks.OAK_SAPLING); + offerGrowing(exporter, UBlocks.PLUNDER_VINE_BUD, Blocks.NETHERRACK, Blocks.WITHER_ROSE); + offerGrowing(exporter, UTreeGen.ZAP_APPLE_TREE.sapling().get(), UBlocks.CHITIN, Blocks.DARK_OAK_SAPLING); } private static ShapelessRecipeJsonBuilder appendIngredients(ShapelessRecipeJsonBuilder builder, ItemConvertible...ingredients) { @@ -522,8 +607,6 @@ public class URecipeProvider extends FabricRecipeProvider { private void offerBedSheetRecipes(Consumer exporter) { PatternTemplate.ONE_COLOR.offerWithoutConversion(exporter, UItems.KELP_BED_SHEETS, Items.KELP); - // XXX: Added white bed sheets, and added a recipe to dye white bed sheets any color - // XXX: Added recipes to change any bedsheet into any solid color using the right wool WOOLS.forEach(wool -> PatternTemplate.ONE_COLOR.offerTo(exporter, CraftingMaterialHelper.getItem(Unicopia.id(Registries.ITEM.getId(wool).getPath().replace("_wool", "_bed_sheets"))), wool)); PatternTemplate.TWO_COLOR.offerTo(exporter, UItems.APPLE_BED_SHEETS, Items.GREEN_WOOL, Items.LIME_WOOL); @@ -565,4 +648,42 @@ public class URecipeProvider extends FabricRecipeProvider { .group(getItemPath(output)) .offerTo(exporter, convertBetween(output, Items.HONEYCOMB)); } + + public static void offerCloudShapingRecipe(Consumer exporter, RecipeCategory category, ItemConvertible output, ItemConvertible input) { + offerCloudShapingRecipe(exporter, category, output, input, 1); + } + + public static void offerCloudShapingRecipe(Consumer exporter, RecipeCategory category, ItemConvertible output, ItemConvertible input, int count) { + CraftingMaterialHelper.createCloudShaping(Ingredient.ofItems(input), category, output, count) + .criterion(RecipeProvider.hasItem(input), RecipeProvider.conditionsFromItem(input)) + .offerTo(exporter, RecipeProvider.convertBetween(output, input) + "_cloud_shaping"); + } + + public static void offerGrowing(Consumer exporter, Block output, Block fuel, Block target) { + GrowingRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output.getDefaultState()) + .fuel(fuel.getDefaultState()) + .target(target).criterion(hasItem(target), conditionsFromItem(target)) + .offerTo(exporter); + } + + public void offerSpell(Consumer exporter, ItemConvertible gemstone, SpellType output, SpellTraits.Builder traits) { + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, gemstone, output) + .traits(traits) + .offerTo(exporter); + } + + public void offerSpellFromSpell(Consumer exporter, ItemConvertible gemstone, SpellType output, SpellType input, SpellTraits.Builder traits) { + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, gemstone, output) + .input(gemstone, input) + .traits(traits) + .offerTo(exporter); + } + + public void offerSpellFromTwoSpells(Consumer exporter, ItemConvertible gemstone, SpellType output, SpellType input1, SpellType input2, SpellTraits.Builder traits) { + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, gemstone, output) + .input(gemstone, input1) + .input(gemstone, input2) + .traits(traits) + .offerTo(exporter); + } } diff --git a/src/main/resources/data/unicopia/recipes/alicorn_amulet.json b/src/main/resources/data/unicopia/recipes/alicorn_amulet.json deleted file mode 100644 index 14db2133..00000000 --- a/src/main/resources/data/unicopia/recipes/alicorn_amulet.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { - "item": "unicopia:gemstone", - "spell": "unicopia:dark_vortex" - }, - "traits": { - "darkness": 30, "power": 30, "blood": 30 - }, - "ingredients": [], - "result": { - "item": "unicopia:alicorn_amulet" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/carving/carved_cloud_cutting.json b/src/main/resources/data/unicopia/recipes/carving/carved_cloud_cutting.json deleted file mode 100644 index 4a933c98..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/carved_cloud_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:carved_cloud", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_brick_slab_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_brick_slab_cutting.json deleted file mode 100644 index 80f2e283..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_brick_slab_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud_bricks" }, - "result": "unicopia:cloud_brick_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_brick_stairs_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_brick_stairs_cutting.json deleted file mode 100644 index 536622ad..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_brick_stairs_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud_bricks" }, - "result": "unicopia:cloud_brick_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_bricks_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_bricks_cutting.json deleted file mode 100644 index fde1cb89..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_bricks_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:cloud_bricks", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_pillar_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_pillar_cutting.json deleted file mode 100644 index 1d60c72d..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_pillar_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:cloud_pillar", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_plank_slab_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_plank_slab_cutting.json deleted file mode 100644 index 0ab285b9..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_plank_slab_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud_planks" }, - "result": "unicopia:cloud_plank_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_plank_stairs_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_plank_stairs_cutting.json deleted file mode 100644 index 77eed444..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_plank_stairs_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud_planks" }, - "result": "unicopia:cloud_plank_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_planks_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_planks_cutting.json deleted file mode 100644 index 97e40db7..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_planks_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:cloud_planks", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_slab_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_slab_cutting.json deleted file mode 100644 index 03a75d8e..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_slab_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:cloud_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_stairs_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_stairs_cutting.json deleted file mode 100644 index a43df56c..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_stairs_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:cloud_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/dense_cloud_slab_cutting.json b/src/main/resources/data/unicopia/recipes/carving/dense_cloud_slab_cutting.json deleted file mode 100644 index 45688bd5..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/dense_cloud_slab_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:dense_cloud" }, - "result": "unicopia:dense_cloud_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/dense_cloud_stairs_cutting.json b/src/main/resources/data/unicopia/recipes/carving/dense_cloud_stairs_cutting.json deleted file mode 100644 index 13b6e197..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/dense_cloud_stairs_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:dense_cloud" }, - "result": "unicopia:dense_cloud_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_cutting.json b/src/main/resources/data/unicopia/recipes/carving/etched_cloud_cutting.json deleted file mode 100644 index 9f8b76ff..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:dense_cloud" }, - "result": "unicopia:etched_cloud", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_slab_cutting.json b/src/main/resources/data/unicopia/recipes/carving/etched_cloud_slab_cutting.json deleted file mode 100644 index 951b6f70..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_slab_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:etched_cloud" }, - "result": "unicopia:etched_cloud_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_stairs_cutting.json b/src/main/resources/data/unicopia/recipes/carving/etched_cloud_stairs_cutting.json deleted file mode 100644 index 85ddf8e0..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_stairs_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:etched_cloud" }, - "result": "unicopia:etched_cloud_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/dragon_breath_scroll.json b/src/main/resources/data/unicopia/recipes/dragon_breath_scroll.json deleted file mode 100644 index 468565ca..00000000 --- a/src/main/resources/data/unicopia/recipes/dragon_breath_scroll.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { - "item": "minecraft:paper" - }, - "traits": { - "fire": 1 - }, - "ingredients": [ - { "item": "minecraft:paper" } - ], - "result": { - "item": "unicopia:dragon_breath_scroll" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/growing/curing_joke.json b/src/main/resources/data/unicopia/recipes/growing/curing_joke.json deleted file mode 100644 index 61625b41..00000000 --- a/src/main/resources/data/unicopia/recipes/growing/curing_joke.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:transform_crop", - "target": "minecraft:cornflower", - "consume": { - "Name": "minecraft:lapis_block", - "Properties": {} - }, - "output": { - "Name": "unicopia:curing_joke", - "Properties": {} - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/growing/gold_root.json b/src/main/resources/data/unicopia/recipes/growing/gold_root.json deleted file mode 100644 index a6d2d09b..00000000 --- a/src/main/resources/data/unicopia/recipes/growing/gold_root.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:transform_crop", - "target": "minecraft:carrots", - "consume": { - "Name": "minecraft:raw_gold_block", - "Properties": {} - }, - "output": { - "Name": "unicopia:gold_root", - "Properties": {} - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/growing/golden_oak_sapling.json b/src/main/resources/data/unicopia/recipes/growing/golden_oak_sapling.json deleted file mode 100644 index b129e3ae..00000000 --- a/src/main/resources/data/unicopia/recipes/growing/golden_oak_sapling.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:transform_crop", - "target": "minecraft:oak_sapling", - "consume": { - "Name": "minecraft:raw_gold_block", - "Properties": {} - }, - "output": { - "Name": "unicopia:golden_oak_sapling", - "Properties": {} - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/growing/plunder_vine.json b/src/main/resources/data/unicopia/recipes/growing/plunder_vine.json deleted file mode 100644 index df6a6eac..00000000 --- a/src/main/resources/data/unicopia/recipes/growing/plunder_vine.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:transform_crop", - "target": "minecraft:wither_rose", - "consume": { - "Name": "minecraft:netherrack", - "Properties": {} - }, - "output": { - "Name": "unicopia:plunder_vine_bud", - "Properties": {} - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/growing/zapling.json b/src/main/resources/data/unicopia/recipes/growing/zapling.json deleted file mode 100644 index 971c2099..00000000 --- a/src/main/resources/data/unicopia/recipes/growing/zapling.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:transform_crop", - "target": "minecraft:dark_oak_sapling", - "consume": { - "Name": "unicopia:chitin", - "Properties": {} - }, - "output": { - "Name": "unicopia:zapling", - "Properties": {} - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spell_duplicating_botched_gemstone.json b/src/main/resources/data/unicopia/recipes/spell_duplicating_botched_gemstone.json deleted file mode 100644 index 7994e225..00000000 --- a/src/main/resources/data/unicopia/recipes/spell_duplicating_botched_gemstone.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "unicopia:spellbook/duplicating", - "material": { "item": "unicopia:botched_gem" } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/arcane_protection.json b/src/main/resources/data/unicopia/recipes/spells/arcane_protection.json deleted file mode 100644 index 0e394aef..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/arcane_protection.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "strength": 10, "knowledge": 18, "darkness": 1 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:shield" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:arcane_protection" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/bubble.json b/src/main/resources/data/unicopia/recipes/spells/bubble.json deleted file mode 100644 index 49127861..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/bubble.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "water": 9, "air": 9 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:catapult" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:bubble" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/catapult.json b/src/main/resources/data/unicopia/recipes/spells/catapult.json deleted file mode 100644 index d479f3ad..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/catapult.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "focus": 9, "air": 9 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:flame" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:catapult" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/chilling_breath.json b/src/main/resources/data/unicopia/recipes/spells/chilling_breath.json deleted file mode 100644 index aabe879c..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/chilling_breath.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "ice": 5, - "knowledge": 10 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:frost" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:chilling_breath" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/dark_vortex.json b/src/main/resources/data/unicopia/recipes/spells/dark_vortex.json deleted file mode 100644 index 09c5d5d1..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/dark_vortex.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "strength": 10, "knowledge": 8, "darkness": 9, "chaos": 8 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:vortex" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:dark_vortex" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/dispel_evil.json b/src/main/resources/data/unicopia/recipes/spells/dispel_evil.json deleted file mode 100644 index e0993076..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/dispel_evil.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "kindness": 1, - "power": 1 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:arcane_protection" }, - { "item": "unicopia:gemstone", "spell": "unicopia:displacement" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:dispel_evil" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/displacement.json b/src/main/resources/data/unicopia/recipes/spells/displacement.json deleted file mode 100644 index 2cd2aa77..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/displacement.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 18, "chaos": 20 - }, - "ingredients": [], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:displacement" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/feather_fall.json b/src/main/resources/data/unicopia/recipes/spells/feather_fall.json deleted file mode 100644 index 0d3b161a..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/feather_fall.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 20, "life": 10, "chaos": 4, - "generosity": 10 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:shield" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:feather_fall" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/fire_bolt.json b/src/main/resources/data/unicopia/recipes/spells/fire_bolt.json deleted file mode 100644 index b9c4e45e..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/fire_bolt.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "focus": 9, "fire": 30 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:flame" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:fire_bolt" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/flame.json b/src/main/resources/data/unicopia/recipes/spells/flame.json deleted file mode 100644 index dca992e7..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/flame.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "fire": 15 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:scorch" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:flame" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/frost.json b/src/main/resources/data/unicopia/recipes/spells/frost.json deleted file mode 100644 index 4009534a..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/frost.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "ice": 15 - }, - "ingredients": [], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:frost" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/hydrophobic.json b/src/main/resources/data/unicopia/recipes/spells/hydrophobic.json deleted file mode 100644 index 681b1595..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/hydrophobic.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "focus": 6 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:frost" }, - { "item": "unicopia:gemstone", "spell": "unicopia:shield" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:hydrophobic" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/infernal.json b/src/main/resources/data/unicopia/recipes/spells/infernal.json deleted file mode 100644 index 9f2c8995..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/infernal.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "fire": 50, "darkness": 10 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:flame" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:infernal" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/light.json b/src/main/resources/data/unicopia/recipes/spells/light.json deleted file mode 100644 index daee45cb..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/light.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "ice": 30, "life": 30, "focus": 10 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:fire_bolt" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:light" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/mimic.json b/src/main/resources/data/unicopia/recipes/spells/mimic.json deleted file mode 100644 index 546c0908..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/mimic.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 19, "life": 10, "chaos": 4 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:transformation" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:mimic" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/mind_swap.json b/src/main/resources/data/unicopia/recipes/spells/mind_swap.json deleted file mode 100644 index c98d477b..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/mind_swap.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 19, "life": 10, "chaos": 40 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:mimic" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:mind_swap" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/necromancy.json b/src/main/resources/data/unicopia/recipes/spells/necromancy.json deleted file mode 100644 index bd106820..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/necromancy.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "strength": 10, "knowledge": 8, "darkness": 19, "chaos": 8, - "blood": 10, "poison": 9 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:siphoning" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:necromancy" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/portal.json b/src/main/resources/data/unicopia/recipes/spells/portal.json deleted file mode 100644 index 6e6f60f8..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/portal.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 18, "chaos": 20 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:displacement" }, - { "item": "unicopia:gemstone", "spell": "unicopia:dark_vortex" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:portal" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/reveal.json b/src/main/resources/data/unicopia/recipes/spells/reveal.json deleted file mode 100644 index 6b9f8c9c..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/reveal.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 18, "life": 1, "order": 4 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:shield" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:reveal" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/scorch.json b/src/main/resources/data/unicopia/recipes/spells/scorch.json deleted file mode 100644 index 499bce01..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/scorch.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "fire": 10 - }, - "ingredients": [], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:scorch" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/shield.json b/src/main/resources/data/unicopia/recipes/spells/shield.json deleted file mode 100644 index 2b12b91f..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/shield.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "strength": 10, "focus": 6, "power": 10 - }, - "ingredients": [], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:shield" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/siphoning.json b/src/main/resources/data/unicopia/recipes/spells/siphoning.json deleted file mode 100644 index 7c01454d..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/siphoning.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "blood": 8, "poison": 10 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:infernal" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:siphoning" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/transformation.json b/src/main/resources/data/unicopia/recipes/spells/transformation.json deleted file mode 100644 index 588cdcec..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/transformation.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 18, "life": 10, "chaos": 4 - }, - "ingredients": [], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:transformation" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/vortex.json b/src/main/resources/data/unicopia/recipes/spells/vortex.json deleted file mode 100644 index 46e9a351..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/vortex.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "strength": 10, "knowledge": 8, "air": 9 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:shield" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:vortex" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trait_combining_botched_gemstone.json b/src/main/resources/data/unicopia/recipes/trait_combining_botched_gemstone.json deleted file mode 100644 index 9950b4dc..00000000 --- a/src/main/resources/data/unicopia/recipes/trait_combining_botched_gemstone.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "unicopia:spellbook/combining", - "material": { "item": "unicopia:botched_gem" } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trait_combining_gemstone.json b/src/main/resources/data/unicopia/recipes/trait_combining_gemstone.json deleted file mode 100644 index 13ab2a9f..00000000 --- a/src/main/resources/data/unicopia/recipes/trait_combining_gemstone.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "unicopia:spellbook/combining", - "material": { "item": "unicopia:gemstone" } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trick_green_apple.json b/src/main/resources/data/unicopia/recipes/trick_green_apple.json deleted file mode 100644 index b914d534..00000000 --- a/src/main/resources/data/unicopia/recipes/trick_green_apple.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "unicopia:crafting_zap_apple", - "ingredients": [ - { "item": "unicopia:zap_apple" }, - { "item": "minecraft:green_dye" } - ], - "appearance": "unicopia:green_apple" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trick_red_apple.json b/src/main/resources/data/unicopia/recipes/trick_red_apple.json deleted file mode 100644 index cd5095ea..00000000 --- a/src/main/resources/data/unicopia/recipes/trick_red_apple.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "unicopia:crafting_zap_apple", - "ingredients": [ - { "item": "unicopia:zap_apple" }, - { "item": "minecraft:red_dye" } - ], - "appearance": "minecraft:apple" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trick_sour_apple.json b/src/main/resources/data/unicopia/recipes/trick_sour_apple.json deleted file mode 100644 index f5be4b69..00000000 --- a/src/main/resources/data/unicopia/recipes/trick_sour_apple.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "unicopia:crafting_zap_apple", - "ingredients": [ - { "item": "unicopia:zap_apple" }, - { "item": "minecraft:yellow_dye" } - ], - "appearance": "unicopia:sour_apple" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trick_sweet_apple.json b/src/main/resources/data/unicopia/recipes/trick_sweet_apple.json deleted file mode 100644 index 48794044..00000000 --- a/src/main/resources/data/unicopia/recipes/trick_sweet_apple.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "unicopia:crafting_zap_apple", - "ingredients": [ - { "item": "unicopia:zap_apple" }, - { "item": "minecraft:orange_dye" } - ], - "appearance": "unicopia:sweet_apple" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trick_zap_apple.json b/src/main/resources/data/unicopia/recipes/trick_zap_apple.json deleted file mode 100644 index 38555616..00000000 --- a/src/main/resources/data/unicopia/recipes/trick_zap_apple.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "unicopia:crafting_zap_apple", - "ingredients": [ - { "item": "unicopia:zap_apple" }, - { "item": "minecraft:rotten_flesh" } - ], - "appearance": "unicopia:cooked_zap_apple" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/unicorn_amulet.json b/src/main/resources/data/unicopia/recipes/unicorn_amulet.json deleted file mode 100644 index b5a4f434..00000000 --- a/src/main/resources/data/unicopia/recipes/unicorn_amulet.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { - "item": "unicopia:broken_alicorn_amulet" - }, - "traits": {}, - "ingredients": [ - { "item": "unicopia:pegasus_amulet" }, - { "item": "unicopia:crystal_heart" }, - { "item": "unicopia:grogars_bell" }, - { "item": "minecraft:totem_of_undying" } - ], - "result": { - "item": "unicopia:unicorn_amulet" - } -} \ No newline at end of file From e3afab9858c26a101569b72065aa074dbecfffde Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 22 Mar 2024 18:35:17 +0000 Subject: [PATCH 03/73] Fix cloud pillar dropping too many blocks --- .../datagen/providers/loot/UBlockLootTableProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java index 34db9593..9b3b4364 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java @@ -106,7 +106,8 @@ public class UBlockLootTableProvider extends FabricBlockLootTableProvider { addDrop(UBlocks.ETCHED_CLOUD, drops(UBlocks.ETCHED_CLOUD, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(9))); addDrop(UBlocks.ETCHED_CLOUD_STAIRS, drops(UBlocks.ETCHED_CLOUD_STAIRS, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(13))); - addDrop(UBlocks.CLOUD_PILLAR, drops(UBlocks.CLOUD_PILLAR, UBlocks.CLOUD, ConstantLootNumberProvider.create(6))); + // recipe produces: 6 blocks -> 3 pillars means: 6/3 = 2 + addDrop(UBlocks.CLOUD_PILLAR, drops(UBlocks.CLOUD_PILLAR, UBlocks.CLOUD, ConstantLootNumberProvider.create(2))); addDrop(UBlocks.FROSTED_OBSIDIAN, Blocks.OBSIDIAN); } From 64fb0ecc074c40e8917dfabfbafe9bea5e744c4c Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 22 Mar 2024 18:37:22 +0000 Subject: [PATCH 04/73] Fixed trick recipe generation --- .../providers/recipe/TrickCraftingRecipeJsonBuilder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java index bb8df54e..22868e0c 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java @@ -8,6 +8,8 @@ import org.spongepowered.include.com.google.common.base.Preconditions; import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import com.minelittlepony.unicopia.item.URecipes; + import net.minecraft.advancement.Advancement; import net.minecraft.advancement.AdvancementRewards; import net.minecraft.advancement.CriterionMerger; @@ -106,7 +108,7 @@ public class TrickCraftingRecipeJsonBuilder extends RecipeJsonBuilder implements @Override public RecipeSerializer getSerializer() { - return RecipeSerializer.SHAPELESS; + return URecipes.ZAP_APPLE_SERIALIZER; } @Override From bc90a96e44b095b962670dd2933424d8e6c65d08 Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 22 Mar 2024 18:52:30 +0000 Subject: [PATCH 05/73] Fixed trait serialization --- .../unicopia/ability/magic/spell/trait/Trait.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java index 341525b4..20b6e151 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java @@ -62,7 +62,7 @@ public enum Trait implements CommandArgumentEnum { private static final Map REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(Trait::name, Function.identity())); private static final Map IDS = Arrays.stream(values()).collect(Collectors.toMap(Trait::getId, Function.identity())); - public static final com.mojang.serialization.Codec CODEC = StringIdentifiable.createCodec(Trait::values, n -> Unicopia.id(n.toLowerCase(Locale.ROOT)).toString()); + public static final com.mojang.serialization.Codec CODEC = StringIdentifiable.createCodec(Trait::values, n -> n.toLowerCase(Locale.ROOT)); public static final com.mojang.serialization.Codec> SET_CODEC = CODEC.listOf().xmap( l -> l.stream().distinct().collect(Collectors.toSet()), s -> s.stream().toList() @@ -109,7 +109,7 @@ public enum Trait implements CommandArgumentEnum { @Override public String asString() { - return name(); + return getId().getPath(); } public TraitGroup getGroup() { From 7c484869562b7a13fc1a68e2c2b4329edb9d236a Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 22 Mar 2024 18:52:42 +0000 Subject: [PATCH 06/73] Added texture and name for white bed sheets --- .../resources/assets/unicopia/lang/en_us.json | 1 + .../unicopia/textures/item/white_bed_sheets.png | Bin 0 -> 9249 bytes 2 files changed, 1 insertion(+) create mode 100644 src/main/resources/assets/unicopia/textures/item/white_bed_sheets.png diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 9213335e..3db1ce68 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -197,6 +197,7 @@ "item.unicopia.music_disc_funk.desc": "funk, just funk", "item.unicopia.cloud_lump": "Cloud Lump", + "item.unicopia.white_bed_sheets": "White Bed Sheets", "item.unicopia.light_gray_bed_sheets": "Light Gray Bed Sheets", "item.unicopia.gray_bed_sheets": "Gray Bed Sheets", "item.unicopia.black_bed_sheets": "Black Bed Sheets", diff --git a/src/main/resources/assets/unicopia/textures/item/white_bed_sheets.png b/src/main/resources/assets/unicopia/textures/item/white_bed_sheets.png new file mode 100644 index 0000000000000000000000000000000000000000..daec608f95a851f9cdafb5baa20fd433f7e779d7 GIT binary patch literal 9249 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 byeo$^Ya%Z|! Date: Fri, 22 Mar 2024 19:09:50 +0000 Subject: [PATCH 07/73] Fixed fancy beds deleting their sheets when broken --- .../unicopia/block/FancyBedBlock.java | 14 ++++++++++++++ .../minelittlepony/unicopia/item/FancyBedItem.java | 1 - 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java b/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java index c132e05e..99b843eb 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java @@ -57,6 +57,20 @@ public class FancyBedBlock extends BedBlock { return SHAPES.get(state.get(PART).ordinal()).apply(BedBlock.getOppositePartDirection(state)); } + @Deprecated + @Override + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { + if (state.hasBlockEntity() && !state.isOf(newState.getBlock()) && state.get(PART) == BedPart.HEAD) { + world.getBlockEntity(pos, UBlockEntities.FANCY_BED).ifPresent(tile -> { + SheetPattern pattern = tile.getPattern(); + if (pattern != SheetPattern.NONE) { + dropStack(world, pos, BedsheetsItem.forPattern(pattern).getDefaultStack()); + } + }); + } + super.onStateReplaced(state, world, pos, newState, moved); + } + @Override public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { return new Tile(pos, state); diff --git a/src/main/java/com/minelittlepony/unicopia/item/FancyBedItem.java b/src/main/java/com/minelittlepony/unicopia/item/FancyBedItem.java index cc63ea79..c9f2f404 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/FancyBedItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/FancyBedItem.java @@ -6,7 +6,6 @@ import org.jetbrains.annotations.Nullable; import com.google.common.base.Suppliers; import com.minelittlepony.unicopia.block.FancyBedBlock; - import net.minecraft.block.Block; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.entity.BlockEntity; From f67ab25a54b63c75b843f04cc9cce72fa1853bfd Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 22 Mar 2024 20:34:27 +0000 Subject: [PATCH 08/73] Fix MC-269785 for our own beds --- .../unicopia/block/FancyBedBlock.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java b/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java index 99b843eb..bc26712f 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java @@ -17,8 +17,11 @@ import net.minecraft.block.entity.BedBlockEntity; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.enums.BedPart; +import net.minecraft.entity.mob.PiglinBrain; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.tag.BlockTags; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.DyeColor; import net.minecraft.util.StringIdentifiable; @@ -28,6 +31,8 @@ import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; +import net.minecraft.world.event.GameEvent; public class FancyBedBlock extends BedBlock { private static final List> SHAPES = List.of( @@ -71,6 +76,30 @@ public class FancyBedBlock extends BedBlock { super.onStateReplaced(state, world, pos, newState, moved); } + @Override + public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) { + // MC-269785 + BedPart part = state.get(PART); + BlockPos otherHalfPos = pos.offset(getDirectionTowardsOtherPart(part, state.get(FACING))); + BlockState otherHalfState = world.getBlockState(otherHalfPos); + if (/*!world.isClient &&*/ player.isCreative() && part == BedPart.FOOT && otherHalfState.isOf(this) && otherHalfState.get(PART) == BedPart.HEAD) { + if (!world.isClient) { + world.setBlockState(otherHalfPos, otherHalfState.getFluidState().getBlockState(), Block.NOTIFY_ALL | Block.SKIP_DROPS); + } + spawnBreakParticles(world, player, otherHalfPos, otherHalfState); + if (state.isIn(BlockTags.GUARDED_BY_PIGLINS)) { + PiglinBrain.onGuardedBlockInteracted(player, false); + } + world.emitGameEvent(GameEvent.BLOCK_DESTROY, pos, GameEvent.Emitter.of(player, state)); + } else { + spawnBreakParticles(world, player, pos, state); + if (state.isIn(BlockTags.GUARDED_BY_PIGLINS)) { + PiglinBrain.onGuardedBlockInteracted(player, false); + } + world.emitGameEvent(GameEvent.BLOCK_DESTROY, pos, GameEvent.Emitter.of(player, state)); + } + } + @Override public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { return new Tile(pos, state); From d0d17a3eed2c6485dcdf25fc12d8acbe1d957708 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 23 Mar 2024 23:16:44 +0000 Subject: [PATCH 09/73] Move all remaining advancements to datagen and some new ones --- .../com/minelittlepony/unicopia/UTags.java | 2 + .../advancement/CustomEventCriterion.java | 16 ++ .../unicopia/advancement/RacePredicate.java | 6 +- .../SendViaDragonBreathScrollCriterion.java | 5 +- .../unicopia/datagen/Datagen.java | 2 + .../providers/AdvancementDisplayBuilder.java | 137 ++++++++++ .../providers/UAdvancementsProvider.java | 250 ++++++++++++++++++ .../resources/assets/unicopia/lang/en_us.json | 32 ++- .../advancements/unicopia/apple_route.json | 31 --- .../advancements/unicopia/baked_bads.json | 31 --- .../unicopia/bat/cool_potato.json | 29 -- .../unicopia/bat/extra_spooky.json | 29 -- .../unicopia/bat/night_route.json | 29 -- .../unicopia/bat/praise_the_sun.json | 29 -- .../unicopia/bat/screech_self.json | 29 -- .../unicopia/bat/screech_twenty_mobs.json | 30 --- .../unicopia/bat/sweet_sweet_revenge.json | 37 --- .../advancements/unicopia/brew_cider.json | 31 --- .../advancements/unicopia/burn_juice.json | 31 --- .../advancements/unicopia/burn_toast.json | 31 --- .../unicopia/earth/blasphemy.json | 37 --- .../unicopia/earth/born_on_a_rock_farm.json | 31 --- .../unicopia/earth/dead_ringer.json | 36 --- .../unicopia/earth/earth_route.json | 37 --- .../unicopia/earth/eat_pinecone.json | 31 --- .../unicopia/earth/imported_oats.json | 40 --- .../unicopia/earth/sticks_and_stones.json | 36 --- .../unicopia/earth/thats_unusual.json | 31 --- .../unicopia/earth/travelling_in_style.json | 29 -- .../unicopia/eat_trick_apple.json | 29 -- .../unicopia/enchanting/experimental.json | 36 --- .../hearts_stronger_than_horses.json | 36 --- .../unicopia/enchanting/soulmate.json | 32 --- .../unicopia/enchanting/xp_miner.json | 32 --- .../unicopia/feed_trick_apple.json | 29 -- .../advancements/unicopia/gotcha.json | 35 --- .../unicopia/advancements/unicopia/jar.json | 31 --- .../unicopia/advancements/unicopia/juice.json | 31 --- .../advancements/unicopia/lightning_bug.json | 115 -------- .../unicopia/advancements/unicopia/lucky.json | 31 --- .../unicopia/mid_flight_interruption.json | 29 -- .../unicopia/pegasus/deter_phantom.json | 32 --- .../unicopia/pegasus/molting_season_1.json | 29 -- .../unicopia/pegasus/molting_season_2.json | 30 --- .../unicopia/pegasus/molting_season_3.json | 30 --- .../unicopia/pegasus/rainbow_crash.json | 29 -- .../unicopia/pegasus/second_wind.json | 29 -- .../unicopia/pegasus/sky_route.json | 32 --- .../unicopia/advancements/unicopia/root.json | 31 --- .../unicopia/sweet_apple_acres.json | 97 ------- .../unicopia/advancements/unicopia/toast.json | 31 --- .../advancements/unicopia/trick_apple.json | 31 --- .../unicopia/unicorn/a_falling_wizard.json | 29 -- .../unicopia/unicorn/ascension.json | 31 --- .../advancements/unicopia/unicorn/books.json | 31 --- .../unicopia/unicorn/crystaline.json | 31 --- .../unicopia/unicorn/doctor_sombrero.json | 30 --- .../unicorn/hello_darkness_my_old_friend.json | 29 -- .../unicopia/unicorn/magical_route.json | 35 --- .../unicopia/unicorn/power_up_heart.json | 29 -- .../unicopia/unicorn/save_the_day.json | 29 -- .../unicopia/unicorn/split_the_sea.json | 29 -- .../unicopia/unicorn/tempted.json | 31 --- .../unicopia/tags/items/magic_spell_base.json | 7 - 64 files changed, 444 insertions(+), 1889 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/apple_route.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/baked_bads.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/bat/cool_potato.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/bat/extra_spooky.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/bat/night_route.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/bat/praise_the_sun.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/bat/screech_self.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/bat/screech_twenty_mobs.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/bat/sweet_sweet_revenge.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/brew_cider.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/burn_juice.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/burn_toast.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/earth/blasphemy.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/earth/born_on_a_rock_farm.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/earth/dead_ringer.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/earth/earth_route.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/earth/eat_pinecone.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/earth/imported_oats.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/earth/sticks_and_stones.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/earth/thats_unusual.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/earth/travelling_in_style.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/eat_trick_apple.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/enchanting/experimental.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/enchanting/hearts_stronger_than_horses.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/enchanting/soulmate.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/enchanting/xp_miner.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/feed_trick_apple.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/gotcha.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/jar.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/juice.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/lightning_bug.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/lucky.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/mid_flight_interruption.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/pegasus/deter_phantom.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_1.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_2.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_3.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/pegasus/rainbow_crash.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/pegasus/second_wind.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/pegasus/sky_route.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/root.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/sweet_apple_acres.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/toast.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/trick_apple.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/a_falling_wizard.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/ascension.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/books.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/crystaline.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/doctor_sombrero.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/hello_darkness_my_old_friend.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/magical_route.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/power_up_heart.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/save_the_day.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/split_the_sea.json delete mode 100644 src/main/resources/data/unicopia/advancements/unicopia/unicorn/tempted.json delete mode 100644 src/main/resources/data/unicopia/tags/items/magic_spell_base.json diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index ecbe9cf4..34a9f654 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -57,6 +57,8 @@ public interface UTags { TagKey BREAKS_SUNGLASSES = damage("breaks_sunglasses"); TagKey SPELLBOOK_IMMUNE_TO = damage("spellbook_immune_to"); + TagKey FROM_ROCKS = damage("from_rocks"); + TagKey FROM_HORSESHOES = damage("from_horseshoes"); TagKey HAS_NO_ATMOSPHERE = dimension("has_no_atmosphere"); diff --git a/src/main/java/com/minelittlepony/unicopia/advancement/CustomEventCriterion.java b/src/main/java/com/minelittlepony/unicopia/advancement/CustomEventCriterion.java index ca2d64e6..4105b13b 100644 --- a/src/main/java/com/minelittlepony/unicopia/advancement/CustomEventCriterion.java +++ b/src/main/java/com/minelittlepony/unicopia/advancement/CustomEventCriterion.java @@ -50,6 +50,22 @@ public class CustomEventCriterion extends AbstractCriterion include, Set exclude) implements Pre return of(getRaces(root, "include"), getRaces(root, "exclude")); } - private static RacePredicate of(Set include, Set exclude) { + public static RacePredicate of(Set include, Set exclude) { if (include.isEmpty() && exclude.isEmpty()) { return EMPTY; } @@ -56,6 +56,10 @@ public record RacePredicate(Set include, Set exclude) implements Pre return (include.isEmpty() || include.contains(race)) && !(!exclude.isEmpty() && exclude.contains(race)); } + public boolean isEmpty() { + return include.isEmpty() && exclude.isEmpty(); + } + public JsonObject toJson() { JsonObject json = new JsonObject(); if (!include.isEmpty()) { diff --git a/src/main/java/com/minelittlepony/unicopia/advancement/SendViaDragonBreathScrollCriterion.java b/src/main/java/com/minelittlepony/unicopia/advancement/SendViaDragonBreathScrollCriterion.java index 8dce0b3a..a7fe2681 100644 --- a/src/main/java/com/minelittlepony/unicopia/advancement/SendViaDragonBreathScrollCriterion.java +++ b/src/main/java/com/minelittlepony/unicopia/advancement/SendViaDragonBreathScrollCriterion.java @@ -97,7 +97,10 @@ public class SendViaDragonBreathScrollCriterion extends AbstractCriterion json.addProperty("recipient_name", recipient)); if (recipientPresent != TriState.DEFAULT) { json.addProperty("recipient_present", recipientPresent.getBoxed()); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java index 527af08a..972699d1 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.minelittlepony.unicopia.datagen.providers.SeasonsGrowthRatesProvider; +import com.minelittlepony.unicopia.datagen.providers.UAdvancementsProvider; import com.minelittlepony.unicopia.datagen.providers.UBlockTagProvider; import com.minelittlepony.unicopia.datagen.providers.UItemTagProvider; import com.minelittlepony.unicopia.datagen.providers.UModelProvider; @@ -38,6 +39,7 @@ public class Datagen implements DataGeneratorEntrypoint { pack.addProvider(UBlockAdditionsLootTableProvider::new); pack.addProvider(UChestAdditionsLootTableProvider::new); pack.addProvider(SeasonsGrowthRatesProvider::new); + pack.addProvider(UAdvancementsProvider::new); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java new file mode 100644 index 00000000..3043a8bb --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java @@ -0,0 +1,137 @@ +package com.minelittlepony.unicopia.datagen.providers; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.Unicopia; + +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementCriterion; +import net.minecraft.advancement.AdvancementDisplay; +import net.minecraft.advancement.AdvancementFrame; +import net.minecraft.advancement.AdvancementRewards; +import net.minecraft.advancement.CriterionMerger; +import net.minecraft.advancement.criterion.CriterionConditions; +import net.minecraft.item.ItemConvertible; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; + +public class AdvancementDisplayBuilder { + private static final Identifier BACKGROUND = new Identifier("textures/gui/advancements/backgrounds/stone.png"); + + public static AdvancementDisplayBuilder create(ItemConvertible icon) { + return new AdvancementDisplayBuilder(icon, Advancement.Builder.create(), false, false, false); + } + + private Identifier background = BACKGROUND; + + private boolean toast; + private boolean hidden; + private boolean announce; + private final ItemConvertible icon; + private AdvancementFrame frame = AdvancementFrame.TASK; + @Nullable + private String group; + + private final Advancement.Builder advancementBuilder; + + AdvancementDisplayBuilder(ItemConvertible icon, Advancement.Builder advancementBuilder, boolean toast, boolean announce, boolean hidden) { + this.icon = icon; + this.advancementBuilder = advancementBuilder; + this.toast = toast; + this.announce = announce; + this.hidden = hidden; + } + + public AdvancementDisplayBuilder frame(AdvancementFrame frame) { + this.frame = frame; + return this; + } + + public AdvancementDisplayBuilder background(Identifier background) { + this.background = background; + return this; + } + + public AdvancementDisplayBuilder showToast() { + this.toast = true; + return this; + } + + public AdvancementDisplayBuilder hidden() { + this.hidden = true; + return this; + } + + public AdvancementDisplayBuilder visible() { + this.hidden = false; + return this; + } + + public AdvancementDisplayBuilder announce() { + this.announce = true; + return this; + } + + public AdvancementDisplayBuilder group(String group) { + this.group = group; + return this; + } + + public AdvancementDisplayBuilder rewards(AdvancementRewards.Builder builder) { + advancementBuilder.rewards(builder.build()); + return this; + } + + public AdvancementDisplayBuilder criterion(String name, CriterionConditions conditions) { + advancementBuilder.criterion(name, new AdvancementCriterion(conditions)); + return this; + } + + public AdvancementDisplayBuilder criteriaMerger(CriterionMerger merger) { + advancementBuilder.criteriaMerger(merger); + return this; + } + + public AdvancementDisplayBuilder parent(Identifier parent) { + advancementBuilder.parent(parent); + return this; + } + + public AdvancementDisplayBuilder apply(Consumer consumer) { + consumer.accept(this); + return this; + } + + public Parent build(Consumer exporter, String name) { + Identifier id = Unicopia.id(group == null ? name : group + "/" + name); + String key = Util.createTranslationKey("advancements", Unicopia.id(name)); + Advancement advancement = advancementBuilder.display(new AdvancementDisplay(icon.asItem().getDefaultStack(), + Text.translatable(key + ".title"), + Text.translatable(key + ".description"), background, frame, toast, announce, hidden)) + .build(id); + exporter.accept(advancement); + return new Parent(advancement, group); + } + + public record Parent(Advancement parent, @Nullable String group) { + public AdvancementDisplayBuilder child(ItemConvertible icon) { + return new AdvancementDisplayBuilder(icon, Advancement.Builder.create().parent(parent), + parent.getDisplay().shouldShowToast(), + parent.getDisplay().shouldAnnounceToChat(), + parent.getDisplay().isHidden() + ).frame(parent.getDisplay().getFrame()).background(parent.getDisplay().getBackground()).group(group); + } + + public void children(Consumer children) { + children.accept(this); + } + + public void children(Consumer exporter, BiConsumer, Parent> children) { + children.accept(exporter, this); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java new file mode 100644 index 00000000..b815f246 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java @@ -0,0 +1,250 @@ +package com.minelittlepony.unicopia.datagen.providers; + +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; + +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.UTags; +import com.minelittlepony.unicopia.advancement.CustomEventCriterion; +import com.minelittlepony.unicopia.advancement.RaceChangeCriterion; +import com.minelittlepony.unicopia.advancement.RacePredicate; +import com.minelittlepony.unicopia.advancement.SendViaDragonBreathScrollCriterion; +import com.minelittlepony.unicopia.item.UItems; +import com.minelittlepony.unicopia.item.enchantment.UEnchantments; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricAdvancementProvider; +import net.fabricmc.fabric.api.util.TriState; +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementFrame; +import net.minecraft.advancement.AdvancementRewards; +import net.minecraft.advancement.CriterionMerger; +import net.minecraft.advancement.criterion.ConsumeItemCriterion; +import net.minecraft.advancement.criterion.CriterionConditions; +import net.minecraft.advancement.criterion.EnchantedItemCriterion; +import net.minecraft.advancement.criterion.InventoryChangedCriterion; +import net.minecraft.advancement.criterion.OnKilledCriterion; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.damage.DamageType; +import net.minecraft.item.Item; +import net.minecraft.item.ItemConvertible; +import net.minecraft.item.Items; +import net.minecraft.predicate.NumberRange; +import net.minecraft.predicate.TagPredicate; +import net.minecraft.predicate.entity.DamageSourcePredicate; +import net.minecraft.predicate.entity.EntityPredicate; +import net.minecraft.predicate.entity.LootContextPredicate; +import net.minecraft.predicate.item.EnchantmentPredicate; +import net.minecraft.predicate.item.ItemPredicate; +import net.minecraft.registry.Registries; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; + +public class UAdvancementsProvider extends FabricAdvancementProvider { + public UAdvancementsProvider(FabricDataOutput output) { + super(output); + } + + @Override + public void generateAdvancement(Consumer consumer) { + AdvancementDisplayBuilder.create(UItems.ALICORN_BADGE).criterion("crafting_table", hasItems(Items.CRAFTING_TABLE)).build(consumer, "root").children(root -> { + createTribeRootAdvancement(consumer, root, Race.EARTH).children(consumer, this::generateEarthTribeAdvancementsTree); + createTribeRootAdvancement(consumer, root, Race.BAT).children(consumer, this::generateBatTribeAdvancementsTree); + createTribeRootAdvancement(consumer, root, Race.PEGASUS).children(consumer, this::generatePegasusTribeAdvancementsTree); + createTribeRootAdvancement(consumer, root, Race.UNICORN).children(consumer, this::generateUnicornTribeAdvancementsTree); + + root.child(UItems.DRAGON_BREATH_SCROLL).criterion("has_scroll", hasItems(UItems.DRAGON_BREATH_SCROLL)).build(consumer, "take_a_note").children(p -> { + p.child(UItems.DRAGON_BREATH_SCROLL).criterion("send_scroll", dragonScroll(false, Items.WRITTEN_BOOK)).build(consumer, "dear_princess"); + p.child(UItems.IMPORTED_OATS).hidden().frame(AdvancementFrame.CHALLENGE) + .criterion("send_oats", dragonScroll(false, UItems.OATS, UItems.IMPORTED_OATS)) + .criterion("receieve_oats", dragonScroll(true, UItems.OATS, UItems.IMPORTED_OATS)) + .criteriaMerger(CriterionMerger.OR) + .build(consumer, "imported_oats"); + p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(), Set.of(Race.BAT))).build(consumer, "blasphemy"); + p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(Race.BAT), Set.of())).build(consumer, "sweet_sweet_revenge"); + }); + root.child(UItems.OATS).criterion("has_oats", hasItems(UItems.OATS)).build(consumer, "what_the_hay"); + root.child(UItems.IRON_HORSE_SHOE).criterion("killed_entity_with_horseshoe", killWithItems(UTags.FROM_HORSESHOES)).build(consumer, "dead_ringer"); + root.child(UItems.PINECONE).frame(AdvancementFrame.CHALLENGE).criterion("eat_pinecone", ConsumeItemCriterion.Conditions.item(UItems.PINECONE)).build(consumer, "eat_pinecone"); + root.child(UItems.GIANT_BALLOON).criterion("ride_balloon", CustomEventCriterion.create("ride_balloon")).build(consumer, "travelling_in_style"); + root.child(UItems.MUFFIN).hidden().criterion("has_muffin", hasItems(UItems.MUFFIN)).build(consumer, "baked_bads"); + root.child(UItems.HORSE_SHOE_FRIES).criterion("has_horse_shoe_fries", hasItems(UItems.HORSE_SHOE_FRIES)).build(consumer, "lucky"); + root.child(UItems.TOAST).criterion("has_toast", hasItems(UItems.TOAST)).build(consumer, "toast") + .child(UItems.BURNED_TOAST).hidden().criterion("has_burned_toast", hasItems(UItems.BURNED_TOAST)).build(consumer, "burn_toast"); + root.child(UItems.GREEN_APPLE).criterion("has_apple", hasItems(UTags.FRESH_APPLES)).build(consumer, "apple_route").children(p -> { + p.child(UItems.SWEET_APPLE) + .criterion("has_all_apples", hasItems(Items.APPLE, UItems.GREEN_APPLE, UItems.SWEET_APPLE, UItems.SOUR_APPLE, UItems.ROTTEN_APPLE, UItems.ZAP_APPLE, UItems.COOKED_ZAP_APPLE, Items.GOLDEN_APPLE)) + .build(consumer, "sweet_apple_acres"); + p.child(UItems.ZAP_BULB).criterion("has_zap_apple", hasItems(UItems.ZAP_APPLE)).build(consumer, "trick_apple").children(pp -> { + pp.child(UItems.ZAP_APPLE).hidden().criterion("eat_trick_apple", CustomEventCriterion.createFlying("eat_trick_apple")).build(consumer, "eat_trick_apple"); + pp.child(UItems.ZAP_APPLE).hidden().criterion("feed_trick_apple", CustomEventCriterion.createFlying("feed_trick_apple")).build(consumer, "feed_trick_apple"); + }); + p.child(UItems.JUICE).criterion("has_juice", hasItems(UItems.JUICE)).build(consumer, "juice") + .child(UItems.BURNED_JUICE).hidden().criterion("has_burned_juice", hasItems(UItems.BURNED_JUICE)).build(consumer, "burn_juice") + .child(UItems.CIDER).visible().criterion("has_cider", hasItems(UItems.CIDER)).rewards(AdvancementRewards.Builder.experience(12)).build(consumer, "brew_cider"); + }); + }); + + generateEnchantmentsAdvancementsTree(consumer); + } + + private AdvancementDisplayBuilder.Parent createTribeRootAdvancement(Consumer consumer, AdvancementDisplayBuilder.Parent root, Race race) { + AdvancementDisplayBuilder builder = root.child(Registries.ITEM.get(race.getId().withSuffixedPath("_badge"))).showToast().announce().group(race.getId().getPath()) + .criterion("be_" + race.getId().getPath(), new RaceChangeCriterion.Conditions(LootContextPredicate.EMPTY, race)); + + if (race == Race.UNICORN) { + builder + .criterion("be_alicorn", new RaceChangeCriterion.Conditions(LootContextPredicate.EMPTY, Race.ALICORN)) + .criteriaMerger(CriterionMerger.OR); + } + + return builder.build(consumer, race.getId().getPath() + "_route"); + } + + private void generateEarthTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { + parent.child(UItems.ROCK).criterion("has_rock", hasItems(UItems.ROCK)).build(consumer, "born_on_a_rock_farm").children(p -> { + p.child(UItems.PEBBLES).criterion("killed_entity_with_rock", killWithItems(UTags.FROM_ROCKS)).build(consumer, "sticks_and_stones"); + p.child(UItems.WEIRD_ROCK).hidden().criterion("has_rock", hasItems(UItems.WEIRD_ROCK)).build(consumer, "thats_unusual"); + }); + } + + private void generatePegasusTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { + parent.child(Items.PHANTOM_MEMBRANE).hidden().frame(AdvancementFrame.CHALLENGE).criterion("deter_phantom", CustomEventCriterion.createFlying("kill_phantom_while_flying")).rewards(AdvancementRewards.Builder.experience(100)).build(consumer, "deter_phantom"); + parent.child(Items.GLASS_PANE).criterion("break_window", CustomEventCriterion.createFlying("break_window")).rewards(AdvancementRewards.Builder.experience(10)).build(consumer, "rainbow_crash"); + parent.child(UItems.PEGASUS_BADGE).criterion("fly_through_the_pain", CustomEventCriterion.createFlying("second_wind")).rewards(AdvancementRewards.Builder.experience(10)).build(consumer, "second_wind"); + parent.child(UItems.EMPTY_JAR).criterion("has_empty_jar", hasItems(UItems.EMPTY_JAR)).build(consumer, "jar") + .child(UItems.RAIN_CLOUD_JAR).criterion("has_cloud_jar", hasItems(UTags.CLOUD_JARS)).rewards(AdvancementRewards.Builder.experience(55)).build(consumer, "gotcha"); + parent.child(UItems.LIGHTNING_JAR).frame(AdvancementFrame.CHALLENGE).criterion("lightning_strike", CustomEventCriterion.createFlying("lightning_strike")).rewards(AdvancementRewards.Builder.experience(30)).build(consumer, "mid_flight_interruption").children(p -> { + p.child(UItems.LIGHTNING_JAR).hidden().frame(AdvancementFrame.CHALLENGE).apply(d -> applyLightningBugCriterions(d, RacePredicate.of(Set.of(Race.CHANGELING), Set.of()), 10, 90)).build(consumer, "lightning_bug"); + p.child(UItems.LIGHTNING_JAR).hidden().frame(AdvancementFrame.CHALLENGE).apply(d -> applyLightningBugCriterions(d, RacePredicate.of(Set.of(), Set.of(Race.CHANGELING)), 10, 90)).build(consumer, "wonder_bolt"); + }); + parent.child(UItems.PEGASUS_FEATHER).hidden().frame(AdvancementFrame.CHALLENGE).criterion("shed_feather", CustomEventCriterion.createFlying("shed_feather")).rewards(AdvancementRewards.Builder.experience(1)).build(consumer, "molting_season_1") + .child(UItems.PEGASUS_FEATHER).apply(d -> applyShedFeatherCriterions(d, 2, 2)).build(consumer, "molting_season_2") + .child(UItems.PEGASUS_FEATHER).apply(d -> applyShedFeatherCriterions(d, 4, 8)).build(consumer, "molting_season_3") + .child(UItems.PEGASUS_FEATHER).apply(d -> applyShedFeatherCriterions(d, 8, 20)).build(consumer, "molting_season_4") + .child(UItems.PEGASUS_FEATHER).apply(d -> applyShedFeatherCriterions(d, 16, 40)).build(consumer, "molting_season_5") + .child(UItems.PEGASUS_FEATHER).apply(d -> applyShedFeatherCriterions(d, 32, 80)).build(consumer, "molting_season_6") + .child(UItems.PEGASUS_FEATHER).apply(d -> applyShedFeatherCriterions(d, 64, 200)).build(consumer, "molting_season_7") + .child(UItems.PEGASUS_FEATHER).apply(d -> applyShedFeatherCriterions(d, 128, 500)).build(consumer, "molting_season_8") + .child(UItems.PEGASUS_FEATHER).apply(d -> applyShedFeatherCriterions(d, 256, 1000)).build(consumer, "molting_season_9") + .child(UItems.PEGASUS_FEATHER).apply(d -> applyShedFeatherCriterions(d, 512, 2280)).build(consumer, "molting_season_10") + .child(UItems.GOLDEN_FEATHER).apply(d -> applyShedFeatherCriterions(d, 1024, 4560)).build(consumer, "molting_season_11") + .child(UItems.GOLDEN_FEATHER).apply(d -> applyShedFeatherCriterions(d, 2048, 10000)).frame(AdvancementFrame.GOAL).build(consumer, "dedicated_flier"); + } + + private AdvancementDisplayBuilder applyShedFeatherCriterions(AdvancementDisplayBuilder builder, int repeats, int experience) { + for (int i = 1; i <= repeats; i++) { + builder.criterion("shed_feather_" + i, CustomEventCriterion.createFlying("shed_feather", i)); + } + return builder.criteriaMerger(CriterionMerger.AND).rewards(AdvancementRewards.Builder.experience(experience)); + } + + private AdvancementDisplayBuilder applyLightningBugCriterions(AdvancementDisplayBuilder builder, RacePredicate race, int repeats, int experience) { + for (int i = 1; i <= repeats; i++) { + builder.criterion("lightning_struck_player_" + i, new CustomEventCriterion.Conditions(LootContextPredicate.EMPTY, "lightning_struck_player", race, true, i)); + } + return builder.criteriaMerger(CriterionMerger.AND).rewards(AdvancementRewards.Builder.experience(experience)); + } + + private void generateUnicornTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { + parent.child(UItems.SPELLBOOK).criterion("has_spellbook", hasItems(UItems.SPELLBOOK)).build(consumer, "books").children(p -> { + p.child(UItems.CRYSTAL_SHARD).criterion("has_shard", hasItems(UItems.CRYSTAL_SHARD)).build(consumer, "crystaline").children(pp -> { + pp.child(UItems.CRYSTAL_HEART).criterion("power_up_heart", CustomEventCriterion.create("power_up_heart")).rewards(AdvancementRewards.Builder.experience(105)).build(consumer, "power_up_heart"); + }); + p.child(UItems.ALICORN_AMULET).criterion("has_alicorn_amulet", hasItems(UItems.ALICORN_AMULET)).build(consumer, "tempting") + .child(Items.CRYING_OBSIDIAN).criterion("light_altar", CustomEventCriterion.create("light_altar")).build(consumer, "hello_darkness_my_old_friend") + .child(UItems.BROKEN_ALICORN_AMULET).frame(AdvancementFrame.GOAL).criterion("defeat_sombra", CustomEventCriterion.create("defeat_sombra")).rewards(AdvancementRewards.Builder.experience(2000)).build(consumer, "save_the_day") + .children(pp -> { + pp.child(UItems.UNICORN_AMULET).frame(AdvancementFrame.GOAL).criterion("obtain_the_thing", hasItems(UItems.UNICORN_AMULET)).rewards(AdvancementRewards.Builder.experience(1100)).build(consumer, "ascension"); + pp.child(UItems.BROKEN_ALICORN_AMULET).hidden().frame(AdvancementFrame.CHALLENGE).criterion("defeat_sombra_again", CustomEventCriterion.create("defeat_sombra", 2)).rewards(AdvancementRewards.Builder.experience(2000)).build(consumer, "doctor_sombrero"); + }); + p.child(Items.WATER_BUCKET).criterion("split_sea", CustomEventCriterion.create("split_sea")).rewards(AdvancementRewards.Builder.experience(105)).build(consumer, "split_the_sea"); + }); + + parent.child(UItems.PEGASUS_AMULET).hidden().frame(AdvancementFrame.CHALLENGE).criterion("teleport_above_world", CustomEventCriterion.create("teleport_above_world")).rewards(AdvancementRewards.Builder.experience(100)).build(consumer, "a_falling_wizard"); + + } + + private void generateBatTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { + parent.child(Items.LIGHT).criterion("look_into_sun", CustomEventCriterion.create("look_into_sun")).build(consumer, "praise_the_sun").children(p -> { + p.child(UItems.SUNGLASSES).criterion("wear_shades", CustomEventCriterion.create("wear_shades")).build(consumer, "cool_potato"); + p.child(Items.BLACK_CANDLE).frame(AdvancementFrame.CHALLENGE).criterion("screech_twenty_mobs", CustomEventCriterion.createFlying("screech_twenty_mobs")).build(consumer, "screech_twenty_mobs").children(pp -> { + pp.child(Items.BRICK).frame(AdvancementFrame.CHALLENGE).criterion("super_scare_entity", CustomEventCriterion.createFlying("super_scare_entity")).build(consumer, "extra_spooky"); + }); + p.child(Items.BLACK_CANDLE).frame(AdvancementFrame.CHALLENGE).criterion("screech_self", CustomEventCriterion.createFlying("screech_self")).build(consumer, "screech_self"); + }); + } + + private void generateEnchantmentsAdvancementsTree(Consumer consumer) { + AdvancementDisplayBuilder.create(Items.NETHERITE_SCRAP) + .criterion("enchant_with_consumption", enchant(UEnchantments.CONSUMPTION)) + .rewards(AdvancementRewards.Builder.experience(120)) + .parent(new Identifier("story/enchant_item")) + .group("enchanting") + .build(consumer, "experimental") + .child(Items.NETHERITE_PICKAXE) + .criterion("use_consumption", CustomEventCriterion.create("use_consumption")) + .rewards(AdvancementRewards.Builder.experience(1200)) + .group("enchanting") + .hidden() + .build(consumer, "xp_miner"); + AdvancementDisplayBuilder.create(Items.GOLDEN_APPLE) + .criterion("enchant_with_heart_bound", enchant(UEnchantments.HEART_BOUND)) + .rewards(AdvancementRewards.Builder.experience(120)) + .group("enchanting") + .build(consumer, "hearts_stronger_than_horses") + .child(Items.GOLDEN_PICKAXE) + .criterion("use_soulmate", CustomEventCriterion.create("use_soulmate")) + .rewards(AdvancementRewards.Builder.experience(1200)) + .group("enchanting") + .hidden() + .build(consumer, "soulmate"); + } + + public static CriterionConditions enchant(Enchantment enchantment) { + return new EnchantedItemCriterion.Conditions(LootContextPredicate.EMPTY, ItemPredicate.Builder.create() + .enchantment(new EnchantmentPredicate(enchantment, NumberRange.IntRange.ANY)) + .build(), NumberRange.IntRange.ANY); + } + + public static CriterionConditions dragonScroll(boolean receiving, ItemConvertible...items) { + return dragonScroll(receiving, ItemPredicate.Builder.create().items(items).build()); + } + + public static CriterionConditions dragonScroll(boolean receiving, ItemPredicate items) { + return new SendViaDragonBreathScrollCriterion.Conditions( + LootContextPredicate.EMPTY, + ItemPredicate.ANY, + receiving, + Optional.empty(), + TriState.DEFAULT, + Optional.empty(), + RacePredicate.EMPTY + ); + } + + static CriterionConditions hasItems(ItemConvertible...items) { + return InventoryChangedCriterion.Conditions.items(items); + } + + static CriterionConditions hasItems(TagKey items) { + return InventoryChangedCriterion.Conditions.items(ItemPredicate.Builder.create().tag(items).build()); + } + + static CriterionConditions killWithItems(TagKey tag) { + return OnKilledCriterion.Conditions.createPlayerKilledEntity(EntityPredicate.ANY, + DamageSourcePredicate.Builder.create().tag(TagPredicate.expected(tag)).build() + ); + } + + static CriterionConditions dingCelestia(Set includeTribes, Set excludeTribes) { + return new SendViaDragonBreathScrollCriterion.Conditions( + LootContextPredicate.EMPTY, + ItemPredicate.Builder.create().tag(UTags.IS_DELIVERED_AGGRESSIVELY).build(), false, + Optional.of("princess celestia"), + TriState.FALSE, + Optional.of("dings_on_celestias_head"), + RacePredicate.of(includeTribes, excludeTribes)); + } +} diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 3db1ce68..ccba8c05 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -1594,12 +1594,18 @@ "advancements.unicopia.praise_the_sun.description": "Experience Celestia's unbridled glory", "advancements.unicopia.cool_potato.title": "Cool Potato", "advancements.unicopia.cool_potato.description": "Protect your eyes from the sun", + "advancements.unicopia.take_a_note.title": "Take a Note, Spike", + "advancements.unicopia.take_a_note.description": "Obtain a dragon breath scroll", + "advancements.unicopia.dear_princess.title": "Dear princess...", + "advancements.unicopia.dear_princess.description": "Send a letter with a dragon's breath scroll", "advancements.unicopia.baked_bads.title": "Baked Bads", "advancements.unicopia.baked_bads.description": "Bake a delicious muffin", "advancements.unicopia.mid_flight_interruption.title": "Mid-Flight Interruption", "advancements.unicopia.mid_flight_interruption.description": "Get struck by lightning whilst flying in a storm", "advancements.unicopia.lightning_bug.title": "Lightning Bug", - "advancements.unicopia.lightning_bug.description": "Attract 10 lightning strikes", + "advancements.unicopia.lightning_bug.description": "Attract 10 lightning strikes as a changeling", + "advancements.unicopia.wonder_bolt.title": "Wonder Bolt", + "advancements.unicopia.wonder_bolt.description": "Attract 10 lightning strikes", "advancements.unicopia.jar.title": "Oh wow. What's this?", "advancements.unicopia.jar.description": "Find an empty jar", "advancements.unicopia.gotcha.title": "Got'cha!", @@ -1672,11 +1678,29 @@ "advancements.unicopia.sky_route.title": "Path of the Pegasus", "advancements.unicopia.sky_route.description": "Join the Clousdale Pegasi", "advancements.unicopia.molting_season_1.title": "Molting Season", - "advancements.unicopia.molting_season_1.description": "Drop a feather whilst flying", + "advancements.unicopia.molting_season_1.description": "Drop your first feather whilst flying", "advancements.unicopia.molting_season_2.title": "Molting Season 2", - "advancements.unicopia.molting_season_2.description": "Drop 5 feathers whilst flying", + "advancements.unicopia.molting_season_2.description": "Drop your second feather whilst flying", "advancements.unicopia.molting_season_3.title": "Molting Season 3", - "advancements.unicopia.molting_season_3.description": "Drop 15 feathers whilst flying", + "advancements.unicopia.molting_season_3.description": "Drop your fourth feather whilst flying", + "advancements.unicopia.molting_season_4.title": "Molting Season 4", + "advancements.unicopia.molting_season_4.description": "Drop your eighth feather whilst flying", + "advancements.unicopia.molting_season_5.title": "Molting Season 5", + "advancements.unicopia.molting_season_5.description": "Drop your sixteenth feather whilst flying", + "advancements.unicopia.molting_season_6.title": "Molting Season 6", + "advancements.unicopia.molting_season_6.description": "Drop your thirty-second feather whilst flying", + "advancements.unicopia.molting_season_7.title": "Molting Season 7", + "advancements.unicopia.molting_season_7.description": "Drop your sixty-fourth feather whilst flying", + "advancements.unicopia.molting_season_8.title": "Molting Season 8", + "advancements.unicopia.molting_season_8.description": "Drop your hundred-and-twenty-eighth feather whilst flying", + "advancements.unicopia.molting_season_9.title": "Molting Season 9", + "advancements.unicopia.molting_season_9.description": "Drop your two-hundred-and-fifty-sixth feather whilst flying", + "advancements.unicopia.molting_season_10.title": "Molting Season 10", + "advancements.unicopia.molting_season_10.description": "Drop your five-hundred-and-twelth feather whilst flying", + "advancements.unicopia.molting_season_11.title": "Molting Season 11", + "advancements.unicopia.molting_season_11.description": "Drop your one-thousand-and-twenty-fourth feather whilst flying", + "advancements.unicopia.dedicated_flier.title": "It's okay, you can stop now", + "advancements.unicopia.dedicated_flier.description": "Drop your two-thousand-and-fourty-eighth feather whilst flying", "advancements.unicopia.rainbow_crash.title": "Dammit, Rainbow", "advancements.unicopia.rainbow_crash.description": "Wage war on the evil glass window nation", "advancements.unicopia.second_wind.title": "Second Wind", diff --git a/src/main/resources/data/unicopia/advancements/unicopia/apple_route.json b/src/main/resources/data/unicopia/advancements/unicopia/apple_route.json deleted file mode 100644 index 1191a00d..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/apple_route.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/earth/earth_route", - "display": { - "icon": { - "item": "unicopia:green_apple" - }, - "title": { - "translate": "advancements.unicopia.apple_route.title" - }, - "description": { - "translate": "advancements.unicopia.apple_route.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": false, - "hidden": true - }, - "criteria": { - "has_apple": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "tag": "unicopia:apples" } - ] - } - } - }, - "requirements": [ - [ "has_apple" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/baked_bads.json b/src/main/resources/data/unicopia/advancements/unicopia/baked_bads.json deleted file mode 100644 index a71df331..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/baked_bads.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/earth/earth_route", - "display": { - "icon": { - "item": "unicopia:muffin" - }, - "title": { - "translate": "advancements.unicopia.baked_bads.title" - }, - "description": { - "translate": "advancements.unicopia.baked_bads.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "throw_muffin": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:muffin" ] } - ] - } - } - }, - "requirements": [ - [ "throw_muffin" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/bat/cool_potato.json b/src/main/resources/data/unicopia/advancements/unicopia/bat/cool_potato.json deleted file mode 100644 index b320384b..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/bat/cool_potato.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/bat/praise_the_sun", - "display": { - "icon": { - "item": "unicopia:sunglasses" - }, - "title": { - "translate": "advancements.unicopia.cool_potato.title" - }, - "description": { - "translate": "advancements.unicopia.cool_potato.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "wear_shades": { - "trigger": "unicopia:custom", - "conditions": { - "event": "wear_shades" - } - } - }, - "requirements": [ - [ "wear_shades" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/bat/extra_spooky.json b/src/main/resources/data/unicopia/advancements/unicopia/bat/extra_spooky.json deleted file mode 100644 index 322c20d0..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/bat/extra_spooky.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/bat/screech_twenty_mobs", - "display": { - "icon": { - "item": "minecraft:brick" - }, - "title": { - "translate": "advancements.unicopia.extra_spooky.title" - }, - "description": { - "translate": "advancements.unicopia.extra_spooky.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "spook_extra_hard": { - "trigger": "unicopia:custom", - "conditions": { - "event": "super_scare_entity" - } - } - }, - "requirements": [ - [ "spook_extra_hard" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/bat/night_route.json b/src/main/resources/data/unicopia/advancements/unicopia/bat/night_route.json deleted file mode 100644 index 572b1896..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/bat/night_route.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/root", - "display": { - "icon": { - "item": "unicopia:bat_badge" - }, - "title": { - "translate": "advancements.unicopia.night_route.title" - }, - "description": { - "translate": "advancements.unicopia.night_route.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "be_bat": { - "trigger": "unicopia:player_change_race", - "conditions": { - "race": "bat" - } - } - }, - "requirements": [ - [ "be_bat" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/bat/praise_the_sun.json b/src/main/resources/data/unicopia/advancements/unicopia/bat/praise_the_sun.json deleted file mode 100644 index 6d0298ee..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/bat/praise_the_sun.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/bat/night_route", - "display": { - "icon": { - "item": "minecraft:light" - }, - "title": { - "translate": "advancements.unicopia.praise_the_sun.title" - }, - "description": { - "translate": "advancements.unicopia.praise_the_sun.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "look_into_sun": { - "trigger": "unicopia:custom", - "conditions": { - "event": "look_into_sun" - } - } - }, - "requirements": [ - [ "look_into_sun" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/bat/screech_self.json b/src/main/resources/data/unicopia/advancements/unicopia/bat/screech_self.json deleted file mode 100644 index a2d24129..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/bat/screech_self.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/bat/night_route", - "display": { - "icon": { - "item": "minecraft:black_candle" - }, - "title": { - "translate": "advancements.unicopia.screech_self.title" - }, - "description": { - "translate": "advancements.unicopia.screech_self.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "screech_self": { - "trigger": "unicopia:custom", - "conditions": { - "event": "screech_self" - } - } - }, - "requirements": [ - [ "screech_self" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/bat/screech_twenty_mobs.json b/src/main/resources/data/unicopia/advancements/unicopia/bat/screech_twenty_mobs.json deleted file mode 100644 index 3d50551c..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/bat/screech_twenty_mobs.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "unicopia:unicopia/bat/night_route", - "display": { - "icon": { - "item": "minecraft:black_candle" - }, - "title": { - "translate": "advancements.unicopia.screech_twenty_mobs.title" - }, - "description": { - "translate": "advancements.unicopia.screech_twenty_mobs.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "screech_twenty_mobs": { - "trigger": "unicopia:custom", - "conditions": { - "event": "screech_twenty_mobs", - "flying": true - } - } - }, - "requirements": [ - [ "screech_twenty_mobs" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/bat/sweet_sweet_revenge.json b/src/main/resources/data/unicopia/advancements/unicopia/bat/sweet_sweet_revenge.json deleted file mode 100644 index 66bbcd5f..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/bat/sweet_sweet_revenge.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "parent": "unicopia:unicopia/bat/praise_the_sun", - "display": { - "icon": { - "item": "minecraft:anvil" - }, - "title": { - "translate": "advancements.unicopia.sweet_sweet_revenge.title" - }, - "description": { - "translate": "advancements.unicopia.sweet_sweet_revenge.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "ding_sun": { - "trigger": "unicopia:send_dragon_breath", - "conditions": { - "item": { - "tag": "unicopia:is_delivered_aggressively" - }, - "recipient_name": "princess celestia", - "recipient_present": false, - "counter": "dings_on_celestias_head", - "race": { - "include": [ "unicopia:bat" ] - } - } - } - }, - "requirements": [ - [ "ding_sun" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/brew_cider.json b/src/main/resources/data/unicopia/advancements/unicopia/brew_cider.json deleted file mode 100644 index 2d81dfcf..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/brew_cider.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/burn_juice", - "display": { - "icon": { - "item": "unicopia:cider" - }, - "title": { - "translate": "advancements.unicopia.brew_cider.title" - }, - "description": { - "translate": "advancements.unicopia.brew_cider.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "has_cider": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:cider" ] } - ] - } - } - }, - "requirements": [ - [ "has_cider" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/burn_juice.json b/src/main/resources/data/unicopia/advancements/unicopia/burn_juice.json deleted file mode 100644 index 43ddb181..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/burn_juice.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/juice", - "display": { - "icon": { - "item": "unicopia:burned_juice" - }, - "title": { - "translate": "advancements.unicopia.burn_juice.title" - }, - "description": { - "translate": "advancements.unicopia.burn_juice.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "has_burned_juice": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:burned_juice" ] } - ] - } - } - }, - "requirements": [ - [ "has_burned_juice" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/burn_toast.json b/src/main/resources/data/unicopia/advancements/unicopia/burn_toast.json deleted file mode 100644 index 1a667430..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/burn_toast.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/toast", - "display": { - "icon": { - "item": "unicopia:burned_toast" - }, - "title": { - "translate": "advancements.unicopia.burn_toast.title" - }, - "description": { - "translate": "advancements.unicopia.burn_toast.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "has_burned_toast": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:burned_toast" ] } - ] - } - } - }, - "requirements": [ - [ "has_burned_toast" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/earth/blasphemy.json b/src/main/resources/data/unicopia/advancements/unicopia/earth/blasphemy.json deleted file mode 100644 index f3285cbd..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/earth/blasphemy.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "parent": "unicopia:unicopia/earth/earth_route", - "display": { - "icon": { - "item": "minecraft:anvil" - }, - "title": { - "translate": "advancements.unicopia.blasphemy.title" - }, - "description": { - "translate": "advancements.unicopia.blasphemy.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "ding_sun": { - "trigger": "unicopia:send_dragon_breath", - "conditions": { - "item": { - "tag": "unicopia:is_delivered_aggressively" - }, - "recipient_name": "princess celestia", - "recipient_present": false, - "counter": "dings_on_celestias_head", - "race": { - "exclude": [ "unicopia:bat" ] - } - } - } - }, - "requirements": [ - [ "ding_sun" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/earth/born_on_a_rock_farm.json b/src/main/resources/data/unicopia/advancements/unicopia/earth/born_on_a_rock_farm.json deleted file mode 100644 index 792cd712..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/earth/born_on_a_rock_farm.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/earth/earth_route", - "display": { - "icon": { - "item": "unicopia:rock" - }, - "title": { - "translate": "advancements.unicopia.born_on_a_rock_farm.title" - }, - "description": { - "translate": "advancements.unicopia.born_on_a_rock_farm.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "has_rock": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:rock" ] } - ] - } - } - }, - "requirements": [ - [ "has_rock" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/earth/dead_ringer.json b/src/main/resources/data/unicopia/advancements/unicopia/earth/dead_ringer.json deleted file mode 100644 index dc70d6e7..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/earth/dead_ringer.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "parent": "unicopia:unicopia/earth/born_on_a_rock_farm", - "display": { - "icon": { - "item": "unicopia:iron_horse_shoe" - }, - "title": { - "translate": "advancements.unicopia.dead_ringer.title" - }, - "description": { - "translate": "advancements.unicopia.dead_ringer.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "killed_entity_with_horseshoe": { - "trigger": "minecraft:player_killed_entity", - "conditions": { - "killing_blow": { - "tags": [ - { - "id": "unicopia:from_horseshoes", - "expected": true - } - ] - } - } - } - }, - "requirements": [ - [ "killed_entity_with_horseshoe" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/earth/earth_route.json b/src/main/resources/data/unicopia/advancements/unicopia/earth/earth_route.json deleted file mode 100644 index c9adaf77..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/earth/earth_route.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "parent": "unicopia:unicopia/root", - "display": { - "icon": { - "item": "unicopia:earth_badge" - }, - "title": { - "translate": "advancements.unicopia.earth_route.title" - }, - "description": { - "translate": "advancements.unicopia.earth_route.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "be_pony": { - "trigger": "unicopia:player_change_race", - "conditions": { - "race": "earth" - } - }, - "has_rock": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:rock" ] } - ] - } - } - }, - "requirements": [ - [ "be_pony", "has_rock" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/earth/eat_pinecone.json b/src/main/resources/data/unicopia/advancements/unicopia/earth/eat_pinecone.json deleted file mode 100644 index 43c1e8ee..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/earth/eat_pinecone.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/earth/earth_route", - "display": { - "icon": { - "item": "unicopia:pinecone" - }, - "title": { - "translate": "advancements.unicopia.eat_pinecone.title" - }, - "description": { - "translate": "advancements.unicopia.eat_pinecone.description" - }, - "frame": "goal", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "eat_pinecone": { - "trigger": "minecraft:consume_item", - "conditions": { - "item": { - "items": [ "unicopia:pinecone" ] - } - } - } - }, - "requirements": [ - [ "eat_pinecone" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/earth/imported_oats.json b/src/main/resources/data/unicopia/advancements/unicopia/earth/imported_oats.json deleted file mode 100644 index 8c58133d..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/earth/imported_oats.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "parent": "unicopia:unicopia/earth/earth_route", - "display": { - "icon": { - "item": "unicopia:imported_oats" - }, - "title": { - "translate": "advancements.unicopia.imported_oats.title" - }, - "description": { - "translate": "advancements.unicopia.imported_oats.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "send_oats": { - "trigger": "unicopia:send_dragon_breath", - "conditions": { - "item": { - "items": [ "unicopia:oats", "unicopia:imported_oats" ] - } - } - }, - "receive_oats": { - "trigger": "unicopia:send_dragon_breath", - "conditions": { - "item": { - "items": [ "unicopia:oats", "unicopia:imported_oats" ] - }, - "is_receiving_end": true - } - } - }, - "requirements": [ - [ "send_oats", "receive_oats" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/earth/sticks_and_stones.json b/src/main/resources/data/unicopia/advancements/unicopia/earth/sticks_and_stones.json deleted file mode 100644 index 083c3c04..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/earth/sticks_and_stones.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "parent": "unicopia:unicopia/earth/born_on_a_rock_farm", - "display": { - "icon": { - "item": "unicopia:rock" - }, - "title": { - "translate": "advancements.unicopia.sticks_and_stones.title" - }, - "description": { - "translate": "advancements.unicopia.sticks_and_stones.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "killed_entity_with_rock": { - "trigger": "minecraft:player_killed_entity", - "conditions": { - "killing_blow": { - "tags": [ - { - "id": "unicopia:from_rocks", - "expected": true - } - ] - } - } - } - }, - "requirements": [ - [ "killed_entity_with_rock" ] - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/advancements/unicopia/earth/thats_unusual.json b/src/main/resources/data/unicopia/advancements/unicopia/earth/thats_unusual.json deleted file mode 100644 index 4ec3184e..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/earth/thats_unusual.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/earth/born_on_a_rock_farm", - "display": { - "icon": { - "item": "unicopia:weird_rock" - }, - "title": { - "translate": "advancements.unicopia.thats_unusual.title" - }, - "description": { - "translate": "advancements.unicopia.thats_unusual.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "has_rock": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:weird_rock" ] } - ] - } - } - }, - "requirements": [ - [ "has_rock" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/earth/travelling_in_style.json b/src/main/resources/data/unicopia/advancements/unicopia/earth/travelling_in_style.json deleted file mode 100644 index 5da55b06..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/earth/travelling_in_style.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/earth/earth_route", - "display": { - "icon": { - "item": "unicopia:imported_oats" - }, - "title": { - "translate": "advancements.unicopia.travelling_in_style.title" - }, - "description": { - "translate": "advancements.unicopia.travelling_in_style.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "ride_balloon": { - "trigger": "unicopia:custom", - "conditions": { - "event": "ride_balloon" - } - } - }, - "requirements": [ - [ "ride_balloon" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/eat_trick_apple.json b/src/main/resources/data/unicopia/advancements/unicopia/eat_trick_apple.json deleted file mode 100644 index 98a60749..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/eat_trick_apple.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/trick_apple", - "display": { - "icon": { - "item": "unicopia:zap_apple" - }, - "title": { - "translate": "advancements.unicopia.eat_trick_apple.title" - }, - "description": { - "translate": "advancements.unicopia.eat_trick_apple.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "eat_trick_apple": { - "trigger": "unicopia:custom", - "conditions": { - "event": "eat_trick_apple" - } - } - }, - "requirements": [ - [ "eat_trick_apple" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/enchanting/experimental.json b/src/main/resources/data/unicopia/advancements/unicopia/enchanting/experimental.json deleted file mode 100644 index 5f6b8dcd..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/enchanting/experimental.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "parent": "minecraft:story/enchant_item", - "display": { - "icon": { - "item": "minecraft:netherite_pickaxe" - }, - "title": { - "translate": "advancements.unicopia.experimental.title" - }, - "description": { - "translate": "advancements.unicopia.experimental.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "rewards": { - "experience": 120 - }, - "criteria": { - "enchant_with_consumption": { - "trigger": "minecraft:enchanted_item", - "conditions": { - "item": { - "enchantments": [ - { "enchantment": "unicopia:consumption" } - ] - } - } - } - }, - "requirements": [ - [ "enchant_with_consumption" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/enchanting/hearts_stronger_than_horses.json b/src/main/resources/data/unicopia/advancements/unicopia/enchanting/hearts_stronger_than_horses.json deleted file mode 100644 index ceaf66b9..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/enchanting/hearts_stronger_than_horses.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "parent": "minecraft:story/enchant_item", - "display": { - "icon": { - "item": "minecraft:golden_pickaxe" - }, - "title": { - "translate": "advancements.unicopia.hearts_stronger_than_horses.title" - }, - "description": { - "translate": "advancements.unicopia.hearts_stronger_than_horses.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "rewards": { - "experience": 120 - }, - "criteria": { - "enchant_with_heart_bound": { - "trigger": "minecraft:enchanted_item", - "conditions": { - "item": { - "enchantments": [ - { "enchantment": "unicopia:heart_bound" } - ] - } - } - } - }, - "requirements": [ - [ "enchant_with_heart_bound" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/enchanting/soulmate.json b/src/main/resources/data/unicopia/advancements/unicopia/enchanting/soulmate.json deleted file mode 100644 index 18ef64c7..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/enchanting/soulmate.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "parent": "unicopia:unicopia/enchanting/hearts_stronger_than_horses", - "display": { - "icon": { - "item": "minecraft:golden_apple" - }, - "title": { - "translate": "advancements.unicopia.soulmate.title" - }, - "description": { - "translate": "advancements.unicopia.soulmate.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "rewards": { - "experience": 1200 - }, - "criteria": { - "use_soulmate": { - "trigger": "unicopia:custom", - "conditions": { - "event": "use_soulmate" - } - } - }, - "requirements": [ - [ "use_soulmate" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/enchanting/xp_miner.json b/src/main/resources/data/unicopia/advancements/unicopia/enchanting/xp_miner.json deleted file mode 100644 index ceec072b..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/enchanting/xp_miner.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "parent": "unicopia:unicopia/enchanting/experimental", - "display": { - "icon": { - "item": "minecraft:netherite_pickaxe" - }, - "title": { - "translate": "advancements.unicopia.xp_miner.title" - }, - "description": { - "translate": "advancements.unicopia.xp_miner.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "rewards": { - "experience": 1200 - }, - "criteria": { - "mine_xp": { - "trigger": "unicopia:custom", - "conditions": { - "event": "use_consumption" - } - } - }, - "requirements": [ - [ "mine_xp" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/feed_trick_apple.json b/src/main/resources/data/unicopia/advancements/unicopia/feed_trick_apple.json deleted file mode 100644 index 20d98e4e..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/feed_trick_apple.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/trick_apple", - "display": { - "icon": { - "item": "unicopia:zap_apple" - }, - "title": { - "translate": "advancements.unicopia.feed_trick_apple.title" - }, - "description": { - "translate": "advancements.unicopia.feed_trick_apple.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "eat_trick_apple": { - "trigger": "unicopia:custom", - "conditions": { - "event": "feed_trick_apple" - } - } - }, - "requirements": [ - [ "eat_trick_apple" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/gotcha.json b/src/main/resources/data/unicopia/advancements/unicopia/gotcha.json deleted file mode 100644 index 3c5b6708..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/gotcha.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "unicopia:unicopia/jar", - "display": { - "icon": { - "item": "unicopia:rain_cloud_jar" - }, - "title": { - "translate": "advancements.unicopia.gotcha.title" - }, - "description": { - "translate": "advancements.unicopia.gotcha.description" - }, - "frame": "goal", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "rewards": { - "experience": 55 - }, - "criteria": { - "has_the_jar": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:rain_cloud_jar" ] }, - { "items": [ "unicopia:storm_cloud_jar" ] } - ] - } - } - }, - "requirements": [ - [ "has_the_jar" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/jar.json b/src/main/resources/data/unicopia/advancements/unicopia/jar.json deleted file mode 100644 index 9e7d9158..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/jar.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/pegasus/sky_route", - "display": { - "icon": { - "item": "unicopia:empty_jar" - }, - "title": { - "translate": "advancements.unicopia.jar.title" - }, - "description": { - "translate": "advancements.unicopia.jar.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "has_the_jar": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:empty_jar" ] } - ] - } - } - }, - "requirements": [ - [ "has_the_jar" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/juice.json b/src/main/resources/data/unicopia/advancements/unicopia/juice.json deleted file mode 100644 index ff380f21..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/juice.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/apple_route", - "display": { - "icon": { - "item": "unicopia:juice" - }, - "title": { - "translate": "advancements.unicopia.juice.title" - }, - "description": { - "translate": "advancements.unicopia.juice.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "has_juice": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:juice" ] } - ] - } - } - }, - "requirements": [ - [ "has_juice" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/lightning_bug.json b/src/main/resources/data/unicopia/advancements/unicopia/lightning_bug.json deleted file mode 100644 index f440b3fc..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/lightning_bug.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "parent": "unicopia:unicopia/mid_flight_interruption", - "display": { - "icon": { - "item": "unicopia:lightning_jar" - }, - "title": { - "translate": "advancements.unicopia.lightning_bug.title" - }, - "description": { - "translate": "advancements.unicopia.lightning_bug.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "rewards": { - "experience": 90 - }, - "criteria": { - "lightning_struck_player_1": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player", - "race": ["bat"], - "repeats": 1 - } - }, - "lightning_struck_player_2": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player", - "race": ["bat"], - "repeats": 2 - } - }, - "lightning_struck_player_3": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player", - "race": ["bat"], - "repeats": 3 - } - }, - "lightning_struck_player_4": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player", - "race": ["bat"], - "repeats": 4 - } - }, - "lightning_struck_player_5": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player", - "race": ["bat"], - "repeats": 5 - } - }, - "lightning_struck_player_6": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player", - "race": ["bat"], - "repeats": 6 - } - }, - "lightning_struck_player_7": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player", - "race": ["bat"], - "repeats": 7 - } - }, - "lightning_struck_player_8": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player", - "race": ["bat"], - "repeats": 8 - } - }, - "lightning_struck_player_9": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player", - "race": ["bat"], - "repeats": 9 - } - }, - "lightning_struck_player_10": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player", - "race": ["bat"], - "repeats": 10 - } - } - }, - "requirements": [ - [ "lightning_struck_player_1" ], - [ "lightning_struck_player_2" ], - [ "lightning_struck_player_3" ], - [ "lightning_struck_player_4" ], - [ "lightning_struck_player_5" ], - [ "lightning_struck_player_6" ], - [ "lightning_struck_player_7" ], - [ "lightning_struck_player_8" ], - [ "lightning_struck_player_9" ], - [ "lightning_struck_player_10" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/lucky.json b/src/main/resources/data/unicopia/advancements/unicopia/lucky.json deleted file mode 100644 index ba89a4ba..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/lucky.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/apple_route", - "display": { - "icon": { - "item": "unicopia:horse_shoe_fries" - }, - "title": { - "translate": "advancements.unicopia.lucky.title" - }, - "description": { - "translate": "advancements.unicopia.lucky.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "has_horse_shoe_fries": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:horse_shoe_fries" ] } - ] - } - } - }, - "requirements": [ - [ "has_horse_shoe_fries" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/mid_flight_interruption.json b/src/main/resources/data/unicopia/advancements/unicopia/mid_flight_interruption.json deleted file mode 100644 index 11eadf3a..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/mid_flight_interruption.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/pegasus/sky_route", - "display": { - "icon": { - "item": "unicopia:pegasus_feather" - }, - "title": { - "translate": "advancements.unicopia.mid_flight_interruption.title" - }, - "description": { - "translate": "advancements.unicopia.mid_flight_interruption.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "lightning_strike": { - "trigger": "unicopia:custom", - "conditions": { - "event": "lightning_struck_player" - } - } - }, - "requirements": [ - [ "lightning_strike" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/deter_phantom.json b/src/main/resources/data/unicopia/advancements/unicopia/pegasus/deter_phantom.json deleted file mode 100644 index a506144c..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/deter_phantom.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "parent": "unicopia:unicopia/pegasus/sky_route", - "display": { - "icon": { - "item": "minecraft:phantom_membrane" - }, - "title": { - "translate": "advancements.unicopia.deter_phantom.title" - }, - "description": { - "translate": "advancements.unicopia.deter_phantom.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "the_thing": { - "trigger": "unicopia:custom", - "conditions": { - "event": "kill_phantom_while_flying" - } - } - }, - "requirements": [ - [ "the_thing" ] - ], - "rewards": { - "experience": 100 - } -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_1.json b/src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_1.json deleted file mode 100644 index f6003423..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_1.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/pegasus/sky_route", - "display": { - "icon": { - "item": "unicopia:pegasus_feather" - }, - "title": { - "translate": "advancements.unicopia.molting_season_1.title" - }, - "description": { - "translate": "advancements.unicopia.molting_season_1.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "shed_feather": { - "trigger": "unicopia:custom", - "conditions": { - "event": "shed_feather" - } - } - }, - "requirements": [ - [ "shed_feather" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_2.json b/src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_2.json deleted file mode 100644 index 107577eb..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_2.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "unicopia:unicopia/pegasus/molting_season_1", - "display": { - "icon": { - "item": "unicopia:pegasus_feather" - }, - "title": { - "translate": "advancements.unicopia.molting_season_2.title" - }, - "description": { - "translate": "advancements.unicopia.molting_season_2.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "shed_feather_5": { - "trigger": "unicopia:custom", - "conditions": { - "event": "shed_feather", - "repeats": 5 - } - } - }, - "requirements": [ - [ "shed_feather_5" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_3.json b/src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_3.json deleted file mode 100644 index 723c1e05..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/molting_season_3.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "unicopia:unicopia/pegasus/molting_season_2", - "display": { - "icon": { - "item": "unicopia:pegasus_feather" - }, - "title": { - "translate": "advancements.unicopia.molting_season_3.title" - }, - "description": { - "translate": "advancements.unicopia.molting_season_3.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "shed_feather_15": { - "trigger": "unicopia:custom", - "conditions": { - "event": "shed_feather", - "repeats": 15 - } - } - }, - "requirements": [ - [ "shed_feather_15" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/rainbow_crash.json b/src/main/resources/data/unicopia/advancements/unicopia/pegasus/rainbow_crash.json deleted file mode 100644 index 2d46bd33..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/rainbow_crash.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/pegasus/sky_route", - "display": { - "icon": { - "item": "minecraft:glass_pane" - }, - "title": { - "translate": "advancements.unicopia.rainbow_crash.title" - }, - "description": { - "translate": "advancements.unicopia.rainbow_crash.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "break_window": { - "trigger": "unicopia:custom", - "conditions": { - "event": "break_window" - } - } - }, - "requirements": [ - [ "break_window" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/second_wind.json b/src/main/resources/data/unicopia/advancements/unicopia/pegasus/second_wind.json deleted file mode 100644 index 86417cee..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/second_wind.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/pegasus/sky_route", - "display": { - "icon": { - "item": "unicopia:pegasus_badge" - }, - "title": { - "translate": "advancements.unicopia.second_wind.title" - }, - "description": { - "translate": "advancements.unicopia.second_wind.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "fly_through_the_pain": { - "trigger": "unicopia:custom", - "conditions": { - "event": "second_wind" - } - } - }, - "requirements": [ - [ "fly_through_the_pain" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/sky_route.json b/src/main/resources/data/unicopia/advancements/unicopia/pegasus/sky_route.json deleted file mode 100644 index d015e522..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/pegasus/sky_route.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "parent": "unicopia:unicopia/root", - "display": { - "icon": { - "item": "unicopia:pegasus_badge" - }, - "title": { - "translate": "advancements.unicopia.sky_route.title" - }, - "description": { - "translate": "advancements.unicopia.sky_route.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "be_birb": { - "trigger": "unicopia:player_change_race", - "conditions": { - "race": "pegasus" - } - } - }, - "requirements": [ - [ "be_birb" ] - ], - "rewards": { - "experience": 100 - } -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/root.json b/src/main/resources/data/unicopia/advancements/unicopia/root.json deleted file mode 100644 index f554b338..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/root.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "display": { - "icon": { - "item": "unicopia:alicorn_badge" - }, - "title": { - "translate": "advancements.unicopia.root.title" - }, - "description": { - "translate": "advancements.unicopia.root.description" - }, - "frame": "task", - "show_toast": false, - "announce_to_chat": false, - "hidden": false, - "background": "minecraft:textures/gui/advancements/backgrounds/stone.png" - }, - "criteria": { - "crafting_table": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "item": "minecraft:crafting_table" } - ] - } - } - }, - "requirements": [ - [ "crafting_table" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/sweet_apple_acres.json b/src/main/resources/data/unicopia/advancements/unicopia/sweet_apple_acres.json deleted file mode 100644 index 6be80c2c..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/sweet_apple_acres.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "parent": "unicopia:unicopia/apple_route", - "display": { - "icon": { - "item": "unicopia:sweet_apple" - }, - "title": { - "translate": "advancements.unicopia.sweet_apple_acres.title" - }, - "description": { - "translate": "advancements.unicopia.sweet_apple_acres.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "rewards": { - "experience": 120 - }, - "criteria": { - "red_apple": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:apple" ] } - ] - } - }, - "green_apple": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:green_apple" ] } - ] - } - }, - "sweet_apple": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:sweet_apple" ] } - ] - } - }, - "sour_apple": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:sour_apple" ] } - ] - } - }, - "rotten_apple": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:rotten_apple" ] } - ] - } - }, - "zap_apple": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:zap_apple" ] } - ] - } - }, - "cooked_zap_apple": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:cooked_zap_apple" ] } - ] - } - }, - "golden_apple": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "minecraft:golden_apple" ] } - ] - } - } - }, - "requirements": [ - [ "red_apple" ], - [ "green_apple" ], - [ "sweet_apple" ], - [ "sour_apple" ], - [ "rotten_apple" ], - [ "zap_apple" ], - [ "cooked_zap_apple" ], - [ "golden_apple" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/toast.json b/src/main/resources/data/unicopia/advancements/unicopia/toast.json deleted file mode 100644 index 35500103..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/toast.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/apple_route", - "display": { - "icon": { - "item": "unicopia:toast" - }, - "title": { - "translate": "advancements.unicopia.toast.title" - }, - "description": { - "translate": "advancements.unicopia.toast.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "has_toast": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:toast" ] } - ] - } - } - }, - "requirements": [ - [ "has_toast" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/trick_apple.json b/src/main/resources/data/unicopia/advancements/unicopia/trick_apple.json deleted file mode 100644 index 3cb00e0b..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/trick_apple.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/apple_route", - "display": { - "icon": { - "item": "minecraft:enchanted_golden_apple" - }, - "title": { - "translate": "advancements.unicopia.trick_apple.title" - }, - "description": { - "translate": "advancements.unicopia.trick_apple.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": false, - "hidden": false - }, - "criteria": { - "has_apple": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:zap_apple" ] } - ] - } - } - }, - "requirements": [ - [ "has_apple" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/a_falling_wizard.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/a_falling_wizard.json deleted file mode 100644 index bb6eada4..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/a_falling_wizard.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/unicorn/magical_route", - "display": { - "icon": { - "item": "unicopia:pegasus_amulet" - }, - "title": { - "translate": "advancements.unicopia.a_falling_wizard.title" - }, - "description": { - "translate": "advancements.unicopia.a_falling_wizard.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "teleport_above_world": { - "trigger": "unicopia:custom", - "conditions": { - "event": "teleport_above_world" - } - } - }, - "requirements": [ - [ "teleport_above_world" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/ascension.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/ascension.json deleted file mode 100644 index 243f2e51..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/ascension.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/unicorn/save_the_day", - "display": { - "icon": { - "item": "unicopia:unicorn_amulet" - }, - "title": { - "translate": "advancements.unicopia.ascension.title" - }, - "description": { - "translate": "advancements.unicopia.ascension.description" - }, - "frame": "goal", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "obtain_the_thing": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:unicorn_amulet" ] } - ] - } - } - }, - "requirements": [ - [ "obtain_the_thing" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/books.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/books.json deleted file mode 100644 index 9265ea81..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/books.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/unicorn/magical_route", - "display": { - "icon": { - "item": "unicopia:spellbook" - }, - "title": { - "translate": "advancements.unicopia.books.title" - }, - "description": { - "translate": "advancements.unicopia.books.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "has_book": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:spellbook" ] } - ] - } - } - }, - "requirements": [ - [ "has_book" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/crystaline.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/crystaline.json deleted file mode 100644 index 083b3c0d..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/crystaline.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/unicorn/books", - "display": { - "icon": { - "item": "unicopia:crystal_shard" - }, - "title": { - "translate": "advancements.unicopia.crystaline.title" - }, - "description": { - "translate": "advancements.unicopia.crystaline.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "has_shard": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:crystal_shard" ] } - ] - } - } - }, - "requirements": [ - [ "has_shard" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/doctor_sombrero.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/doctor_sombrero.json deleted file mode 100644 index 27f88d72..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/doctor_sombrero.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "parent": "unicopia:unicopia/unicorn/save_the_day", - "display": { - "icon": { - "item": "unicopia:broken_alicorn_amulet" - }, - "title": { - "translate": "advancements.unicopia.doctor_sombrero.title" - }, - "description": { - "translate": "advancements.unicopia.doctor_sombrero.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "defeat_sombra": { - "trigger": "unicopia:custom", - "conditions": { - "event": "defeat_sombra", - "repeats": 2 - } - } - }, - "requirements": [ - [ "defeat_sombra" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/hello_darkness_my_old_friend.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/hello_darkness_my_old_friend.json deleted file mode 100644 index 3a6b55d3..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/hello_darkness_my_old_friend.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/unicorn/tempted", - "display": { - "icon": { - "item": "unicopia:alicorn_amulet" - }, - "title": { - "translate": "advancements.unicopia.hello_darkness_my_old_friend.title" - }, - "description": { - "translate": "advancements.unicopia.hello_darkness_my_old_friend.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "light_altar": { - "trigger": "unicopia:custom", - "conditions": { - "event": "light_altar" - } - } - }, - "requirements": [ - [ "light_altar" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/magical_route.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/magical_route.json deleted file mode 100644 index cfa84eaf..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/magical_route.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "parent": "unicopia:unicopia/root", - "display": { - "icon": { - "item": "unicopia:unicorn_badge" - }, - "title": { - "translate": "advancements.unicopia.magical_route.title" - }, - "description": { - "translate": "advancements.unicopia.magical_route.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "be_horned": { - "trigger": "unicopia:player_change_race", - "conditions": { - "race": "unicorn" - } - }, - "be_alihorned": { - "trigger": "unicopia:player_change_race", - "conditions": { - "race": "alicorn" - } - } - }, - "requirements": [ - [ "be_horned", "be_alihorned" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/power_up_heart.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/power_up_heart.json deleted file mode 100644 index 6356e60e..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/power_up_heart.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/unicorn/crystaline", - "display": { - "icon": { - "item": "unicopia:crystal_heart" - }, - "title": { - "translate": "advancements.unicopia.power_up_heart.title" - }, - "description": { - "translate": "advancements.unicopia.power_up_heart.description" - }, - "frame": "task", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "power_up_heart": { - "trigger": "unicopia:custom", - "conditions": { - "event": "power_up_heart" - } - } - }, - "requirements": [ - [ "power_up_heart" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/save_the_day.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/save_the_day.json deleted file mode 100644 index eb47d02e..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/save_the_day.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/unicorn/hello_darkness_my_old_friend", - "display": { - "icon": { - "item": "unicopia:broken_alicorn_amulet" - }, - "title": { - "translate": "advancements.unicopia.save_the_day.title" - }, - "description": { - "translate": "advancements.unicopia.save_the_day.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "defeat_sombra": { - "trigger": "unicopia:custom", - "conditions": { - "event": "defeat_sombra" - } - } - }, - "requirements": [ - [ "defeat_sombra" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/split_the_sea.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/split_the_sea.json deleted file mode 100644 index b2a69db4..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/split_the_sea.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "parent": "unicopia:unicopia/unicorn/books", - "display": { - "icon": { - "item": "minecraft:water_bucket" - }, - "title": { - "translate": "advancements.unicopia.split_the_sea.title" - }, - "description": { - "translate": "advancements.unicopia.split_the_sea.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": true - }, - "criteria": { - "split_sea": { - "trigger": "unicopia:custom", - "conditions": { - "event": "split_sea" - } - } - }, - "requirements": [ - [ "split_sea" ] - ] -} diff --git a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/tempted.json b/src/main/resources/data/unicopia/advancements/unicopia/unicorn/tempted.json deleted file mode 100644 index fdb951f1..00000000 --- a/src/main/resources/data/unicopia/advancements/unicopia/unicorn/tempted.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "parent": "unicopia:unicopia/unicorn/books", - "display": { - "icon": { - "item": "unicopia:alicorn_amulet" - }, - "title": { - "translate": "advancements.unicopia.tempted.title" - }, - "description": { - "translate": "advancements.unicopia.tempted.description" - }, - "frame": "challenge", - "show_toast": true, - "announce_to_chat": true, - "hidden": false - }, - "criteria": { - "has_amulet": { - "trigger": "minecraft:inventory_changed", - "conditions": { - "items": [ - { "items": [ "unicopia:alicorn_amulet" ] } - ] - } - } - }, - "requirements": [ - [ "has_amulet" ] - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/magic_spell_base.json b/src/main/resources/data/unicopia/tags/items/magic_spell_base.json deleted file mode 100644 index d3e5b431..00000000 --- a/src/main/resources/data/unicopia/tags/items/magic_spell_base.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:gemstone", - "unicopia:magic_staff" - ] -} From a4fb5e7ae7155bef99dcc01072a084a3869b584c Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 23 Mar 2024 23:17:47 +0000 Subject: [PATCH 10/73] Fix jar and bottle stack sizes to reflect the vanilla counterparts, and make filled jars fireproof same as the rest --- .../minelittlepony/unicopia/item/UItems.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 3bffbf64..b75f9a6f 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -49,12 +49,12 @@ public interface UItems { FriendshipBraceletItem FRIENDSHIP_BRACELET = register("friendship_bracelet", new FriendshipBraceletItem(new FabricItemSettings().rarity(Rarity.UNCOMMON)), ItemGroups.TOOLS); Item PLUNDER_VINE = register("plunder_vine", new BlockItem(UBlocks.PLUNDER_VINE_BUD, new Item.Settings())); - Item EMPTY_JAR = register("empty_jar", new JarItem(new Item.Settings().maxCount(16).fireproof(), false, false, false), ItemGroups.FUNCTIONAL); - FilledJarItem FILLED_JAR = register("filled_jar", new FilledJarItem(new Item.Settings().maxCount(1).recipeRemainder(EMPTY_JAR))); - Item RAIN_CLOUD_JAR = register("rain_cloud_jar", new JarItem(new Item.Settings().maxCount(1).fireproof().recipeRemainder(EMPTY_JAR), true, false, false), ItemGroups.FUNCTIONAL); - Item STORM_CLOUD_JAR = register("storm_cloud_jar", new JarItem(new Item.Settings().maxCount(1).fireproof().recipeRemainder(EMPTY_JAR), true, true, false), ItemGroups.FUNCTIONAL); - Item LIGHTNING_JAR = register("lightning_jar", new JarItem(new Item.Settings().maxCount(1).fireproof().recipeRemainder(EMPTY_JAR), false, false, true), ItemGroups.FUNCTIONAL); - Item ZAP_APPLE_JAM_JAR = register("zap_apple_jam_jar", new JarItem(new Item.Settings().maxCount(1).fireproof().recipeRemainder(EMPTY_JAR), false, false, true), ItemGroups.FUNCTIONAL); + Item EMPTY_JAR = register("empty_jar", new JarItem(new Item.Settings().fireproof(), false, false, false), ItemGroups.FUNCTIONAL); + FilledJarItem FILLED_JAR = register("filled_jar", new FilledJarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR))); + Item RAIN_CLOUD_JAR = register("rain_cloud_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), true, false, false), ItemGroups.FUNCTIONAL); + Item STORM_CLOUD_JAR = register("storm_cloud_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), true, true, false), ItemGroups.FUNCTIONAL); + Item LIGHTNING_JAR = register("lightning_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), false, false, true), ItemGroups.FUNCTIONAL); + Item ZAP_APPLE_JAM_JAR = register("zap_apple_jam_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), false, false, true), ItemGroups.FUNCTIONAL); Item TOAST = register("toast", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.TOAST)), ItemGroups.FOOD_AND_DRINK); Item BURNED_TOAST = register("burned_toast", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.BURNED_TOAST)), ItemGroups.FOOD_AND_DRINK); @@ -110,10 +110,10 @@ public interface UItems { Item SOUR_APPLE_SEEDS = register("sour_apple_seeds", new AliasedBlockItem(UBlocks.SOUR_APPLE_SPROUT, new Item.Settings()), ItemGroups.NATURAL); Item GOLDEN_OAK_SEEDS = register("golden_oak_seeds", new AliasedBlockItem(UBlocks.GOLDEN_OAK_SPROUT, new Item.Settings()), ItemGroups.NATURAL); - Item MUG = register("mug", new Item(new Settings().maxCount(16)), ItemGroups.TOOLS); - Item CIDER = register("cider", new DrinkableItem(new Item.Settings().food(UFoodComponents.CIDER).maxCount(1).recipeRemainder(MUG)), ItemGroups.FOOD_AND_DRINK); - Item JUICE = register("juice", new DrinkableItem(new Item.Settings().recipeRemainder(Items.GLASS_BOTTLE).maxCount(1).food(UFoodComponents.JUICE)), ItemGroups.FOOD_AND_DRINK); - Item BURNED_JUICE = register("burned_juice", new DrinkableItem(new Item.Settings().recipeRemainder(Items.GLASS_BOTTLE).maxCount(1).food(UFoodComponents.BURNED_JUICE)), ItemGroups.FOOD_AND_DRINK); + Item MUG = register("mug", new Item(new Settings()), ItemGroups.TOOLS); + Item CIDER = register("cider", new DrinkableItem(new Item.Settings().food(UFoodComponents.CIDER).maxCount(16).recipeRemainder(MUG)), ItemGroups.FOOD_AND_DRINK); + Item JUICE = register("juice", new DrinkableItem(new Item.Settings().recipeRemainder(Items.GLASS_BOTTLE).maxCount(16).food(UFoodComponents.JUICE)), ItemGroups.FOOD_AND_DRINK); + Item BURNED_JUICE = register("burned_juice", new DrinkableItem(new Item.Settings().recipeRemainder(Items.GLASS_BOTTLE).maxCount(16).food(UFoodComponents.BURNED_JUICE)), ItemGroups.FOOD_AND_DRINK); Item APPLE_PIE = register("apple_pie", new BlockItem(UBlocks.APPLE_PIE, new Item.Settings().maxCount(1)), ItemGroups.FOOD_AND_DRINK); Item APPLE_PIE_HOOF = register("apple_pie_hoof", new AliasedBlockItem(UBlocks.APPLE_PIE, new Item.Settings().maxCount(1)), ItemGroups.FOOD_AND_DRINK); Item APPLE_PIE_SLICE = register("apple_pie_slice", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.PIE)), ItemGroups.FOOD_AND_DRINK); From aa1973181fae2b33073f97b54f51951ada568d6f Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 23 Mar 2024 23:40:00 +0000 Subject: [PATCH 11/73] #317 +Allow bats and hippos to walk on clouds without having to give them other pegasus abilities Separate cloud interaction and ability to collect weather jars/use rainboom ability into two flags --- .../unicopia/EquineContext.java | 2 +- .../unicopia/EquinePredicates.java | 3 +-- .../com/minelittlepony/unicopia/Race.java | 20 +++++++++++++++++++ .../ability/PegasusCaptureStormAbility.java | 2 +- .../ability/PegasusRainboomAbility.java | 2 +- .../unicopia/entity/ItemImpl.java | 2 +- .../unicopia/item/FriendshipBraceletItem.java | 7 +++++-- 7 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/EquineContext.java b/src/main/java/com/minelittlepony/unicopia/EquineContext.java index bea77626..2bd9bf0b 100644 --- a/src/main/java/com/minelittlepony/unicopia/EquineContext.java +++ b/src/main/java/com/minelittlepony/unicopia/EquineContext.java @@ -22,7 +22,7 @@ public interface EquineContext { } default boolean collidesWithClouds() { - return getCompositeRace().any(Race::canInteractWithClouds); + return getCompositeRace().canInteractWithClouds(); } static EquineContext of(ShapeContext context) { diff --git a/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java b/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java index 6286b123..2e67d2c2 100644 --- a/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java +++ b/src/main/java/com/minelittlepony/unicopia/EquinePredicates.java @@ -20,7 +20,7 @@ public interface EquinePredicates { Predicate BAT = physicalRaceMatches(Race.BAT::equals); Predicate CHANGELING = physicalRaceMatches(Race.CHANGELING::equals); - Predicate RACE_INTERACT_WITH_CLOUDS = raceMatches(Race::canInteractWithClouds); + Predicate RACE_CAN_INFLUENCE_WEATHER = raceMatches(Race::canInfluenceWeather); Predicate RAGING = IS_PLAYER.and(SpellType.RAGE::isOn); Predicate PLAYER_EARTH = IS_PLAYER.and(ofRace(Race.EARTH)); @@ -28,7 +28,6 @@ public interface EquinePredicates { Predicate PLAYER_UNICORN = IS_PLAYER.and(raceMatches(Race::canCast)); Predicate PLAYER_CHANGELING = IS_PLAYER.and(ofRace(Race.CHANGELING)); Predicate PLAYER_KIRIN = IS_PLAYER.and(ofRace(Race.KIRIN)); - Predicate PLAYER_PEGASUS = IS_PLAYER.and(e -> ((PlayerEntity)e).getAbilities().creativeMode || RACE_INTERACT_WITH_CLOUDS.test(e)); Predicate PLAYER_SEAPONY = IS_PLAYER.and(raceMatches(Race::isFish)); Predicate PLAYER_CAN_USE_EARTH = IS_PLAYER.and(raceMatches(Race::canUseEarth)); diff --git a/src/main/java/com/minelittlepony/unicopia/Race.java b/src/main/java/com/minelittlepony/unicopia/Race.java index a6d73d72..a6ae1c58 100644 --- a/src/main/java/com/minelittlepony/unicopia/Race.java +++ b/src/main/java/com/minelittlepony/unicopia/Race.java @@ -108,9 +108,17 @@ public record Race (Supplier compositeSupplier, Availability availabi } public boolean canInteractWithClouds() { + return canFly() && this != CHANGELING; + } + + public boolean canInfluenceWeather() { return canFly() && this != CHANGELING && this != BAT && this != HIPPOGRIFF; } + public boolean hasPersistentWeatherMagic() { + return canInfluenceWeather(); + } + public Identifier getId() { return REGISTRY.getId(this); } @@ -225,6 +233,18 @@ public record Race (Supplier compositeSupplier, Availability availabi return any(Race::canCast); } + public boolean canInteractWithClouds() { + return any(Race::canInteractWithClouds); + } + + public boolean canInfluenceWeather() { + return any(Race::canInfluenceWeather); + } + + public boolean hasPersistentWeatherMagic() { + return any(Race::hasPersistentWeatherMagic); + } + public FlightType flightType() { if (pseudo() == null) { return physical().flightType(); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/PegasusCaptureStormAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/PegasusCaptureStormAbility.java index 3bbdd31f..b02579df 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/PegasusCaptureStormAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/PegasusCaptureStormAbility.java @@ -35,7 +35,7 @@ public class PegasusCaptureStormAbility implements Ability { @Override public boolean canUse(Race race) { - return race.canInteractWithClouds(); + return race.canInfluenceWeather(); } @Nullable diff --git a/src/main/java/com/minelittlepony/unicopia/ability/PegasusRainboomAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/PegasusRainboomAbility.java index bbe7256e..606cd65f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/PegasusRainboomAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/PegasusRainboomAbility.java @@ -28,7 +28,7 @@ public class PegasusRainboomAbility implements Ability { @Override public boolean canUse(Race race) { - return race.canInteractWithClouds(); + return race.canInfluenceWeather(); } @Nullable diff --git a/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java b/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java index 3d594ea7..59d84ddb 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java @@ -160,7 +160,7 @@ public class ItemImpl implements Equine { @Override public boolean collidesWithClouds() { - return entity.getStack().isIn(UTags.FLOATS_ON_CLOUDS) || getSpecies().canInteractWithClouds(); + return entity.getStack().isIn(UTags.FLOATS_ON_CLOUDS) || getSpecies().hasPersistentWeatherMagic(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java b/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java index 8a9c2416..40e10dc4 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/FriendshipBraceletItem.java @@ -39,8 +39,11 @@ public class FriendshipBraceletItem extends WearableItem implements DyeableItem, public TypedActionResult use(World world, PlayerEntity player, Hand hand) { ItemStack stack = player.getStackInHand(hand); - if (!isSigned(stack) && (EquinePredicates.PLAYER_UNICORN.test(player) || EquinePredicates.PLAYER_PEGASUS.test(player) - || AmuletSelectors.PEARL_NECKLACE.test(player))) { + if (!isSigned(stack) && ( + EquinePredicates.PLAYER_UNICORN.test(player) + || EquinePredicates.RACE_CAN_INFLUENCE_WEATHER.test(player) + || AmuletSelectors.PEARL_NECKLACE.test(player) + )) { player.setCurrentHand(hand); ItemStack result = stack.copy(); From b3be98f664eda6b96eafbdb112266175bf5ff11e Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 23 Mar 2024 23:40:15 +0000 Subject: [PATCH 12/73] #317 Buff changeling food options slightly --- .../data/unicopia/diets/races/changeling.json | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main/resources/data/unicopia/diets/races/changeling.json b/src/main/resources/data/unicopia/diets/races/changeling.json index d728f503..a60fb6bd 100644 --- a/src/main/resources/data/unicopia/diets/races/changeling.json +++ b/src/main/resources/data/unicopia/diets/races/changeling.json @@ -1,16 +1,16 @@ { "default_multiplier": 0.15, - "foraging_multiplier": 0, + "foraging_multiplier": 0.1, "multipliers": [ { "tags": [ "unicopia:food_types/cooked_insect" ], - "hunger": 0.3, - "saturation": 0.3 + "hunger": 2.0, + "saturation": 1.3 }, { "tags": [ "unicopia:food_types/cooked_meat" ], - "hunger": 0.1, - "saturation": 0.1 + "hunger": 1.9, + "saturation": 1.2 }, { "tags": [ "unicopia:food_types/raw_insect" ], @@ -19,8 +19,8 @@ }, { "tags": [ "unicopia:food_types/raw_meat" ], - "hunger": 0.25, - "saturation": 0.25 + "hunger": 1.25, + "saturation": 1.25 }, { "tags": [ "unicopia:food_types/rotten_meat" ], @@ -36,8 +36,8 @@ }, { "tags": [ "unicopia:food_types/love" ], - "hunger": 1, - "saturation": 1 + "hunger": 5, + "saturation": 3 } ], "default_effects": { @@ -104,7 +104,12 @@ "unicopia:food_types/rotten_meat" ], "ailment": { - "effects": [ ] + "effects": [ + { + "name": "Love Consumption", + "type": "unicopia:cure_love_sickness" + } + ] } }, { @@ -120,12 +125,12 @@ "effects": [ { "effect": "unicopia:food_poisoning", - "seconds": 100, + "seconds": 10, "amplifier": 2 }, { "effect": "minecraft:weakness", - "seconds": 200, + "seconds": 2, "amplifier": 1 }, { From a266253d53cf1d8c923ceb89e368f44224e9bd9d Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 24 Mar 2024 00:49:28 +0000 Subject: [PATCH 13/73] Fix build --- .../unicopia/advancement/CustomEventCriterion.java | 6 ++++-- .../datagen/providers/AdvancementDisplayBuilder.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/advancement/CustomEventCriterion.java b/src/main/java/com/minelittlepony/unicopia/advancement/CustomEventCriterion.java index 4105b13b..98a3a930 100644 --- a/src/main/java/com/minelittlepony/unicopia/advancement/CustomEventCriterion.java +++ b/src/main/java/com/minelittlepony/unicopia/advancement/CustomEventCriterion.java @@ -94,11 +94,13 @@ public class CustomEventCriterion extends AbstractCriterion 0) { + if (repeatCount > 1) { json.addProperty("repeats", repeatCount); } return json; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java index 3043a8bb..40f5d832 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java @@ -97,7 +97,7 @@ public class AdvancementDisplayBuilder { } public AdvancementDisplayBuilder parent(Identifier parent) { - advancementBuilder.parent(parent); + advancementBuilder.parent(Advancement.Builder.createUntelemetered().build(parent)); return this; } From c59b9366f6337ef19a2d5741ba6684e35fed0702 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 24 Mar 2024 22:08:11 +0000 Subject: [PATCH 14/73] Fix some advancement names and heirarchy --- .../datagen/providers/UAdvancementsProvider.java | 10 ++++++---- .../resources/assets/unicopia/lang/en_us.json | 16 ++++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java index b815f246..52c85a0c 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java @@ -64,7 +64,8 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(), Set.of(Race.BAT))).build(consumer, "blasphemy"); p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(Race.BAT), Set.of())).build(consumer, "sweet_sweet_revenge"); }); - root.child(UItems.OATS).criterion("has_oats", hasItems(UItems.OATS)).build(consumer, "what_the_hay"); + root.child(UItems.OATS).criterion("has_oats", hasItems(UItems.OATS)).build(consumer, "oats_so_easy"); + root.child(Items.HAY_BLOCK).criterion("eat_hay", ConsumeItemCriterion.Conditions.item(Items.HAY_BLOCK)).build(consumer, "what_the_hay"); root.child(UItems.IRON_HORSE_SHOE).criterion("killed_entity_with_horseshoe", killWithItems(UTags.FROM_HORSESHOES)).build(consumer, "dead_ringer"); root.child(UItems.PINECONE).frame(AdvancementFrame.CHALLENGE).criterion("eat_pinecone", ConsumeItemCriterion.Conditions.item(UItems.PINECONE)).build(consumer, "eat_pinecone"); root.child(UItems.GIANT_BALLOON).criterion("ride_balloon", CustomEventCriterion.create("ride_balloon")).build(consumer, "travelling_in_style"); @@ -152,7 +153,7 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { p.child(UItems.CRYSTAL_SHARD).criterion("has_shard", hasItems(UItems.CRYSTAL_SHARD)).build(consumer, "crystaline").children(pp -> { pp.child(UItems.CRYSTAL_HEART).criterion("power_up_heart", CustomEventCriterion.create("power_up_heart")).rewards(AdvancementRewards.Builder.experience(105)).build(consumer, "power_up_heart"); }); - p.child(UItems.ALICORN_AMULET).criterion("has_alicorn_amulet", hasItems(UItems.ALICORN_AMULET)).build(consumer, "tempting") + p.child(UItems.ALICORN_AMULET).criterion("has_alicorn_amulet", hasItems(UItems.ALICORN_AMULET)).build(consumer, "tempted") .child(Items.CRYING_OBSIDIAN).criterion("light_altar", CustomEventCriterion.create("light_altar")).build(consumer, "hello_darkness_my_old_friend") .child(UItems.BROKEN_ALICORN_AMULET).frame(AdvancementFrame.GOAL).criterion("defeat_sombra", CustomEventCriterion.create("defeat_sombra")).rewards(AdvancementRewards.Builder.experience(2000)).build(consumer, "save_the_day") .children(pp -> { @@ -177,7 +178,7 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { } private void generateEnchantmentsAdvancementsTree(Consumer consumer) { - AdvancementDisplayBuilder.create(Items.NETHERITE_SCRAP) + AdvancementDisplayBuilder.create(Items.NETHERITE_SCRAP).showToast().announce() .criterion("enchant_with_consumption", enchant(UEnchantments.CONSUMPTION)) .rewards(AdvancementRewards.Builder.experience(120)) .parent(new Identifier("story/enchant_item")) @@ -189,9 +190,10 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { .group("enchanting") .hidden() .build(consumer, "xp_miner"); - AdvancementDisplayBuilder.create(Items.GOLDEN_APPLE) + AdvancementDisplayBuilder.create(Items.GOLDEN_APPLE).showToast().announce() .criterion("enchant_with_heart_bound", enchant(UEnchantments.HEART_BOUND)) .rewards(AdvancementRewards.Builder.experience(120)) + .parent(new Identifier("story/enchant_item")) .group("enchanting") .build(consumer, "hearts_stronger_than_horses") .child(Items.GOLDEN_PICKAXE) diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index ccba8c05..7599643d 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -1618,6 +1618,10 @@ "advancements.unicopia.eat_trick_apple.description": "Bite into a zap apple", "advancements.unicopia.eat_pinecone.title": "Desperation", "advancements.unicopia.eat_pinecone.description": "Eat a pinecone", + "advancements.unicopia.what_the_hay.title": "What The Hay", + "advancements.unicopia.what_the_hay.description": "Eat an entire block of hay", + "advancements.unicopia.oats_so_easy.title": "Oats So Easy", + "advancements.unicopia.oats_so_easy.description": "Farm some oats", "advancements.unicopia.imported_oats.title": "Delicious As They Are Expensive", "advancements.unicopia.imported_oats.description": "Send or receive fancy imported oats", @@ -1650,8 +1654,8 @@ "advancements.unicopia.travelling_in_style.title": "Travelling in Style", "advancements.unicopia.travelling_in_style.description": "Ride a hot air balloon", - "advancements.unicopia.night_route.title": "Children of The Night", - "advancements.unicopia.night_route.description": "Walk the path of the night", + "advancements.unicopia.bat_route.title": "Children of The Night", + "advancements.unicopia.bat_route.description": "Walk the path of the night", "advancements.unicopia.screech_twenty_mobs.title": "Terror From The Skies", "advancements.unicopia.screech_twenty_mobs.description": "Rain down terror on at least 20 mobs at once", "advancements.unicopia.screech_self.title": "Jeepers!", @@ -1675,8 +1679,8 @@ "advancements.unicopia.thats_unusual.title": "That's Unusual", "advancements.unicopia.thats_unusual.description": "But what does it do?", - "advancements.unicopia.sky_route.title": "Path of the Pegasus", - "advancements.unicopia.sky_route.description": "Join the Clousdale Pegasi", + "advancements.unicopia.pegasus_route.title": "Path of the Pegasus", + "advancements.unicopia.pegasus_route.description": "Join the Clousdale Pegasi", "advancements.unicopia.molting_season_1.title": "Molting Season", "advancements.unicopia.molting_season_1.description": "Drop your first feather whilst flying", "advancements.unicopia.molting_season_2.title": "Molting Season 2", @@ -1708,8 +1712,8 @@ "advancements.unicopia.deter_phantom.title": "What Flies Around", "advancements.unicopia.deter_phantom.description": "Get up there and give those phantoms a taste of their own medicine", - "advancements.unicopia.magical_route.title": "Horn of the Unicorn", - "advancements.unicopia.magical_route.description": "Delve into the world of glitter and rainbows", + "advancements.unicopia.unicorn_route.title": "Horn of the Unicorn", + "advancements.unicopia.unicorn_route.description": "Delve into the world of glitter and rainbows", "advancements.unicopia.books.title": "Books!", "advancements.unicopia.books.description": "This is MY spellbook and I'm going to READ it!", From ac5aedb4889c6968706f1f7eb22a5f16fa30cc78 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 24 Mar 2024 23:06:26 +0000 Subject: [PATCH 15/73] Fix some advancements and add some new ones --- .../unicopia/advancement/UCriteria.java | 1 + .../providers/UAdvancementsProvider.java | 55 ++++++++++--------- .../unicopia/entity/mob/AirBalloonEntity.java | 6 ++ .../resources/assets/unicopia/lang/en_us.json | 14 +++++ 4 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java b/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java index db4d1224..339c0aac 100644 --- a/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java +++ b/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java @@ -28,6 +28,7 @@ public interface UCriteria { CustomEventCriterion.Trigger POWER_UP_HEART = CUSTOM_EVENT.createTrigger("power_up_heart"); CustomEventCriterion.Trigger SPLIT_SEA = CUSTOM_EVENT.createTrigger("split_sea"); CustomEventCriterion.Trigger RIDE_BALLOON = CUSTOM_EVENT.createTrigger("ride_balloon"); + CustomEventCriterion.Trigger CONSTRUCT_BALLOON = CUSTOM_EVENT.createTrigger("construct_balloon"); CustomEventCriterion.Trigger TELEPORT_ABOVE_WORLD = CUSTOM_EVENT.createTrigger("teleport_above_world"); static void bootstrap() { } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java index 52c85a0c..fc831f33 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java @@ -54,32 +54,37 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { createTribeRootAdvancement(consumer, root, Race.PEGASUS).children(consumer, this::generatePegasusTribeAdvancementsTree); createTribeRootAdvancement(consumer, root, Race.UNICORN).children(consumer, this::generateUnicornTribeAdvancementsTree); - root.child(UItems.DRAGON_BREATH_SCROLL).criterion("has_scroll", hasItems(UItems.DRAGON_BREATH_SCROLL)).build(consumer, "take_a_note").children(p -> { - p.child(UItems.DRAGON_BREATH_SCROLL).criterion("send_scroll", dragonScroll(false, Items.WRITTEN_BOOK)).build(consumer, "dear_princess"); + root.child(UItems.DRAGON_BREATH_SCROLL).showToast().announce().criterion("has_scroll", hasItems(UItems.DRAGON_BREATH_SCROLL)).build(consumer, "take_a_note").children(p -> { + p.child(UItems.DRAGON_BREATH_SCROLL).criterion("send_book", dragonScroll(false, Items.WRITTEN_BOOK)).build(consumer, "dear_princess") + .child(UItems.DRAGON_BREATH_SCROLL).criterion("send_scroll", dragonScroll(false, UItems.DRAGON_BREATH_SCROLL)).build(consumer, "i_await_your_reply"); p.child(UItems.IMPORTED_OATS).hidden().frame(AdvancementFrame.CHALLENGE) .criterion("send_oats", dragonScroll(false, UItems.OATS, UItems.IMPORTED_OATS)) - .criterion("receieve_oats", dragonScroll(true, UItems.OATS, UItems.IMPORTED_OATS)) - .criteriaMerger(CriterionMerger.OR) - .build(consumer, "imported_oats"); + .criterion("receieve_oats", dragonScroll(true, UItems.IMPORTED_OATS)) + .criteriaMerger(CriterionMerger.OR).build(consumer, "imported_oats"); p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(), Set.of(Race.BAT))).build(consumer, "blasphemy"); p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(Race.BAT), Set.of())).build(consumer, "sweet_sweet_revenge"); }); - root.child(UItems.OATS).criterion("has_oats", hasItems(UItems.OATS)).build(consumer, "oats_so_easy"); - root.child(Items.HAY_BLOCK).criterion("eat_hay", ConsumeItemCriterion.Conditions.item(Items.HAY_BLOCK)).build(consumer, "what_the_hay"); - root.child(UItems.IRON_HORSE_SHOE).criterion("killed_entity_with_horseshoe", killWithItems(UTags.FROM_HORSESHOES)).build(consumer, "dead_ringer"); - root.child(UItems.PINECONE).frame(AdvancementFrame.CHALLENGE).criterion("eat_pinecone", ConsumeItemCriterion.Conditions.item(UItems.PINECONE)).build(consumer, "eat_pinecone"); - root.child(UItems.GIANT_BALLOON).criterion("ride_balloon", CustomEventCriterion.create("ride_balloon")).build(consumer, "travelling_in_style"); - root.child(UItems.MUFFIN).hidden().criterion("has_muffin", hasItems(UItems.MUFFIN)).build(consumer, "baked_bads"); - root.child(UItems.HORSE_SHOE_FRIES).criterion("has_horse_shoe_fries", hasItems(UItems.HORSE_SHOE_FRIES)).build(consumer, "lucky"); - root.child(UItems.TOAST).criterion("has_toast", hasItems(UItems.TOAST)).build(consumer, "toast") + root.child(UItems.OATS).showToast().announce().criterion("has_oats", hasItems(UItems.OATS)).build(consumer, "oats_so_easy"); + root.child(Items.HAY_BLOCK).showToast().announce().criterion("eat_hay", ConsumeItemCriterion.Conditions.item(Items.HAY_BLOCK)).build(consumer, "what_the_hay"); + root.child(UItems.COPPER_HORSE_SHOE).showToast().announce().criterion("has_horseshoe", hasItems(UTags.HORSE_SHOES)).build(consumer, "blacksmith").children(p -> { + p.child(UItems.IRON_HORSE_SHOE).criterion("has_iron_horseshoe", hasItems(UItems.IRON_HORSE_SHOE)).build(consumer, "change_of_shoes") + .child(UItems.GOLDEN_HORSE_SHOE).criterion("has_gold_horseshoe", hasItems(UItems.GOLDEN_HORSE_SHOE)).build(consumer, "fashionably_expensive") + .child(UItems.NETHERITE_HORSE_SHOE).criterion("has_netherite_horseshoe", hasItems(UItems.NETHERITE_HORSE_SHOE)).build(consumer, "overkill"); + p.child(UItems.IRON_HORSE_SHOE).hidden().frame(AdvancementFrame.CHALLENGE).criterion("killed_entity_with_horseshoe", killWithItems(UTags.FROM_HORSESHOES)).build(consumer, "dead_ringer"); + }); + root.child(UItems.PINECONE).showToast().announce().frame(AdvancementFrame.CHALLENGE).criterion("eat_pinecone", ConsumeItemCriterion.Conditions.item(UItems.PINECONE)).build(consumer, "eat_pinecone"); + root.child(UItems.OAK_BASKET).showToast().criterion("has_basket", hasItems(UTags.BASKETS)).build(consumer, "basket_case") + .child(Items.LANTERN).showToast().criterion("construct_balloon", CustomEventCriterion.create("construct_balloon")).build(consumer, "aeronaut") + .child(UItems.GIANT_BALLOON).showToast().announce().frame(AdvancementFrame.CHALLENGE).criterion("ride_balloon", CustomEventCriterion.create("ride_balloon")).build(consumer, "travelling_in_style"); + root.child(UItems.MUFFIN).showToast().announce().hidden().criterion("has_muffin", hasItems(UItems.MUFFIN)).build(consumer, "baked_bads"); + root.child(UItems.HORSE_SHOE_FRIES).showToast().announce().criterion("has_horse_shoe_fries", hasItems(UItems.HORSE_SHOE_FRIES)).build(consumer, "lucky"); + root.child(UItems.TOAST).showToast().announce().criterion("has_toast", hasItems(UItems.TOAST)).build(consumer, "toast") .child(UItems.BURNED_TOAST).hidden().criterion("has_burned_toast", hasItems(UItems.BURNED_TOAST)).build(consumer, "burn_toast"); - root.child(UItems.GREEN_APPLE).criterion("has_apple", hasItems(UTags.FRESH_APPLES)).build(consumer, "apple_route").children(p -> { - p.child(UItems.SWEET_APPLE) - .criterion("has_all_apples", hasItems(Items.APPLE, UItems.GREEN_APPLE, UItems.SWEET_APPLE, UItems.SOUR_APPLE, UItems.ROTTEN_APPLE, UItems.ZAP_APPLE, UItems.COOKED_ZAP_APPLE, Items.GOLDEN_APPLE)) - .build(consumer, "sweet_apple_acres"); + root.child(UItems.GREEN_APPLE).showToast().announce().criterion("has_apple", hasItems(UTags.FRESH_APPLES)).build(consumer, "apple_route").children(p -> { + p.child(UItems.SWEET_APPLE).criterion("has_all_apples", hasItems(Items.APPLE, UItems.GREEN_APPLE, UItems.SWEET_APPLE, UItems.SOUR_APPLE, UItems.ROTTEN_APPLE, UItems.ZAP_APPLE, UItems.COOKED_ZAP_APPLE, Items.GOLDEN_APPLE)).build(consumer, "sweet_apple_acres"); p.child(UItems.ZAP_BULB).criterion("has_zap_apple", hasItems(UItems.ZAP_APPLE)).build(consumer, "trick_apple").children(pp -> { - pp.child(UItems.ZAP_APPLE).hidden().criterion("eat_trick_apple", CustomEventCriterion.createFlying("eat_trick_apple")).build(consumer, "eat_trick_apple"); - pp.child(UItems.ZAP_APPLE).hidden().criterion("feed_trick_apple", CustomEventCriterion.createFlying("feed_trick_apple")).build(consumer, "feed_trick_apple"); + pp.child(UItems.ZAP_APPLE).hidden().criterion("eat_trick_apple", CustomEventCriterion.createFlying("eat_trick_apple")).build(consumer, "eat_trick_apple"); + pp.child(UItems.ZAP_APPLE).hidden().criterion("feed_trick_apple", CustomEventCriterion.createFlying("feed_trick_apple")).build(consumer, "feed_trick_apple"); }); p.child(UItems.JUICE).criterion("has_juice", hasItems(UItems.JUICE)).build(consumer, "juice") .child(UItems.BURNED_JUICE).hidden().criterion("has_burned_juice", hasItems(UItems.BURNED_JUICE)).build(consumer, "burn_juice") @@ -151,12 +156,11 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { private void generateUnicornTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { parent.child(UItems.SPELLBOOK).criterion("has_spellbook", hasItems(UItems.SPELLBOOK)).build(consumer, "books").children(p -> { p.child(UItems.CRYSTAL_SHARD).criterion("has_shard", hasItems(UItems.CRYSTAL_SHARD)).build(consumer, "crystaline").children(pp -> { - pp.child(UItems.CRYSTAL_HEART).criterion("power_up_heart", CustomEventCriterion.create("power_up_heart")).rewards(AdvancementRewards.Builder.experience(105)).build(consumer, "power_up_heart"); + pp.child(UItems.CRYSTAL_HEART).criterion("power_up_heart", CustomEventCriterion.create("power_up_heart")).rewards(AdvancementRewards.Builder.experience(105)).build(consumer, "power_up_heart"); }); p.child(UItems.ALICORN_AMULET).criterion("has_alicorn_amulet", hasItems(UItems.ALICORN_AMULET)).build(consumer, "tempted") .child(Items.CRYING_OBSIDIAN).criterion("light_altar", CustomEventCriterion.create("light_altar")).build(consumer, "hello_darkness_my_old_friend") - .child(UItems.BROKEN_ALICORN_AMULET).frame(AdvancementFrame.GOAL).criterion("defeat_sombra", CustomEventCriterion.create("defeat_sombra")).rewards(AdvancementRewards.Builder.experience(2000)).build(consumer, "save_the_day") - .children(pp -> { + .child(UItems.BROKEN_ALICORN_AMULET).frame(AdvancementFrame.GOAL).criterion("defeat_sombra", CustomEventCriterion.create("defeat_sombra")).rewards(AdvancementRewards.Builder.experience(2000)).build(consumer, "save_the_day").children(pp -> { pp.child(UItems.UNICORN_AMULET).frame(AdvancementFrame.GOAL).criterion("obtain_the_thing", hasItems(UItems.UNICORN_AMULET)).rewards(AdvancementRewards.Builder.experience(1100)).build(consumer, "ascension"); pp.child(UItems.BROKEN_ALICORN_AMULET).hidden().frame(AdvancementFrame.CHALLENGE).criterion("defeat_sombra_again", CustomEventCriterion.create("defeat_sombra", 2)).rewards(AdvancementRewards.Builder.experience(2000)).build(consumer, "doctor_sombrero"); }); @@ -170,9 +174,8 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { private void generateBatTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { parent.child(Items.LIGHT).criterion("look_into_sun", CustomEventCriterion.create("look_into_sun")).build(consumer, "praise_the_sun").children(p -> { p.child(UItems.SUNGLASSES).criterion("wear_shades", CustomEventCriterion.create("wear_shades")).build(consumer, "cool_potato"); - p.child(Items.BLACK_CANDLE).frame(AdvancementFrame.CHALLENGE).criterion("screech_twenty_mobs", CustomEventCriterion.createFlying("screech_twenty_mobs")).build(consumer, "screech_twenty_mobs").children(pp -> { - pp.child(Items.BRICK).frame(AdvancementFrame.CHALLENGE).criterion("super_scare_entity", CustomEventCriterion.createFlying("super_scare_entity")).build(consumer, "extra_spooky"); - }); + p.child(Items.BLACK_CANDLE).frame(AdvancementFrame.CHALLENGE).criterion("screech_twenty_mobs", CustomEventCriterion.createFlying("screech_twenty_mobs")).build(consumer, "screech_twenty_mobs") + .child(Items.BRICK).frame(AdvancementFrame.CHALLENGE).criterion("super_scare_entity", CustomEventCriterion.createFlying("super_scare_entity")).build(consumer, "extra_spooky"); p.child(Items.BLACK_CANDLE).frame(AdvancementFrame.CHALLENGE).criterion("screech_self", CustomEventCriterion.createFlying("screech_self")).build(consumer, "screech_self"); }); } @@ -217,7 +220,7 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { public static CriterionConditions dragonScroll(boolean receiving, ItemPredicate items) { return new SendViaDragonBreathScrollCriterion.Conditions( LootContextPredicate.EMPTY, - ItemPredicate.ANY, + items, receiving, Optional.empty(), TriState.DEFAULT, diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java index d6f032c8..57cbc2ef 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java @@ -380,6 +380,9 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp getWorld().emitGameEvent(player, GameEvent.EQUIP, getBlockPos()); } setDesign(HotAirBalloonItem.getDesign(getWorld(), stack)); + if (hasBurner() && hasBalloon()) { + UCriteria.CONSTRUCT_BALLOON.trigger(player); + } return ActionResult.SUCCESS; } @@ -405,6 +408,9 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp if (!player.isSneaky()) { getWorld().emitGameEvent(player, GameEvent.EQUIP, getBlockPos()); } + if (hasBurner() && hasBalloon()) { + UCriteria.CONSTRUCT_BALLOON.trigger(player); + } return ActionResult.SUCCESS; } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 7599643d..f7497d0c 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -1598,6 +1598,8 @@ "advancements.unicopia.take_a_note.description": "Obtain a dragon breath scroll", "advancements.unicopia.dear_princess.title": "Dear princess...", "advancements.unicopia.dear_princess.description": "Send a letter with a dragon's breath scroll", + "advancements.unicopia.i_await_your_reply.title": "I Await Your Reply", + "advancements.unicopia.i_await_your_reply.description": "Use the dragon's breath scroll to send someone a dragon's breath scroll", "advancements.unicopia.baked_bads.title": "Baked Bads", "advancements.unicopia.baked_bads.description": "Bake a delicious muffin", "advancements.unicopia.mid_flight_interruption.title": "Mid-Flight Interruption", @@ -1651,6 +1653,10 @@ "advancements.unicopia.sweet_apple_acres.description": "Obtain one of every apple", "advancements.unicopia.brew_cider.title": "Applejack's Finest", "advancements.unicopia.brew_cider.description": "Brew some cider", + "advancements.unicopia.basket_case.title": "Basket Case", + "advancements.unicopia.basket_case.description": "Weave a basket", + "advancements.unicopia.aeronaut.title": "Aeronaut", + "advancements.unicopia.aeronaut.description": "Equip your basket with a lantern and hot air balloon", "advancements.unicopia.travelling_in_style.title": "Travelling in Style", "advancements.unicopia.travelling_in_style.description": "Ride a hot air balloon", @@ -1672,6 +1678,14 @@ "advancements.unicopia.earth_route.description": "Join the Apple Clan", "advancements.unicopia.sticks_and_stones.title": "Sticks and Stones", "advancements.unicopia.sticks_and_stones.description": "Kill a mob by throwing rocks at it", + "advancements.unicopia.blacksmith.title": "Blacksmith", + "advancements.unicopia.blacksmith.description": "Craft a horseshoe", + "advancements.unicopia.change_of_shoes.title": "A Change of Shoes", + "advancements.unicopia.change_of_shoes.description": "Craft an iron horse shoe", + "advancements.unicopia.fashionably_expensive.title": "Fashionably Expensive", + "advancements.unicopia.fashionably_expensive.description": "Upgrade to a set of golden horse shoes", + "advancements.unicopia.overkill.title": "Overkill", + "advancements.unicopia.overkill.description": "Craft a netherite horse shoe", "advancements.unicopia.dead_ringer.title": "Dead Ringer", "advancements.unicopia.dead_ringer.description": "Kill a mob with a horseshoe", "advancements.unicopia.born_on_a_rock_farm.title": "Born on a Rock Farm", From 9ef3a946f6b3c6e389f82652c60de21fe220810c Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Mar 2024 00:41:10 +0000 Subject: [PATCH 16/73] Cache computed shapes (should improve bed performance) --- .../com/minelittlepony/unicopia/block/FancyBedBlock.java | 1 - .../com/minelittlepony/unicopia/util/VoxelShapeUtil.java | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java b/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java index bc26712f..f2fa1820 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/FancyBedBlock.java @@ -31,7 +31,6 @@ import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; import net.minecraft.world.World; -import net.minecraft.world.WorldAccess; import net.minecraft.world.event.GameEvent; public class FancyBedBlock extends BedBlock { diff --git a/src/main/java/com/minelittlepony/unicopia/util/VoxelShapeUtil.java b/src/main/java/com/minelittlepony/unicopia/util/VoxelShapeUtil.java index adff046a..0a14890d 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/VoxelShapeUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/util/VoxelShapeUtil.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.util; +import net.minecraft.util.Util; import net.minecraft.util.math.Box; import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; @@ -14,7 +15,7 @@ public interface VoxelShapeUtil { Vec3d CENTER = new Vec3d(0.5, 0, 0.5); static Function rotator(VoxelShape base) { - return d -> rotate(base, d); + return Util.memoize(d -> rotate(base, d)); } static VoxelShape rotate(VoxelShape shape, Direction direction) { @@ -27,7 +28,7 @@ public interface VoxelShapeUtil { float angle = direction.asRotation() * MathHelper.RADIANS_PER_DEGREE; return VoxelShapes.union(VoxelShapes.empty(), shape.getBoundingBoxes().stream() .map(box -> { - //These first two are enough for orthogonal rotations + //These first two are enough for orthogonal rotations Vec3d a = rotate(box.minX, box.minZ, angle); Vec3d b = rotate(box.maxX, box.maxZ, angle); //These cover odd angles From a6b8e6fe93245c27af9f64711b7a94747a127943 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Mar 2024 00:41:42 +0000 Subject: [PATCH 17/73] You can now place cloud pillars horizontally --- .../block/cloud/CloudPillarBlock.java | 92 +++++++++++++------ .../providers/UBlockStateModelGenerator.java | 14 ++- 2 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java index 69b372b8..baeb2f16 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java @@ -1,79 +1,115 @@ package com.minelittlepony.unicopia.block.cloud; import java.util.Map; +import java.util.function.Function; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.EquineContext; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.PillarBlock; import net.minecraft.block.ShapeContext; import net.minecraft.item.ItemPlacementContext; import net.minecraft.state.StateManager; import net.minecraft.state.property.BooleanProperty; +import net.minecraft.state.property.EnumProperty; import net.minecraft.state.property.Properties; +import net.minecraft.util.BlockRotation; +import net.minecraft.util.Util; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Direction.AxisDirection; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; import net.minecraft.world.WorldAccess; public class CloudPillarBlock extends CloudBlock { - private static final BooleanProperty NORTH = Properties.NORTH; - private static final BooleanProperty SOUTH = Properties.SOUTH; + public static final EnumProperty AXIS = Properties.AXIS; + private static final BooleanProperty TOP = Properties.NORTH; + private static final BooleanProperty BOTTOM = Properties.SOUTH; private static final Map DIRECTION_PROPERTIES = Map.of( - Direction.UP, NORTH, - Direction.DOWN, SOUTH + Direction.UP, TOP, Direction.DOWN, BOTTOM, + Direction.SOUTH, TOP, Direction.NORTH, BOTTOM, + Direction.EAST, TOP, Direction.WEST, BOTTOM ); - - private static final VoxelShape CORE_SHAPE = Block.createCuboidShape(1, 0, 1, 15, 16, 15); - private static final VoxelShape FOOT_SHAPE = Block.createCuboidShape(0, 0, 0, 16, 5, 16); - private static final VoxelShape CAP_SHAPE = FOOT_SHAPE.offset(0, 11F / 16F, 0); - - private static final VoxelShape[] SHAPES = new VoxelShape[] { - CORE_SHAPE, - VoxelShapes.union(CORE_SHAPE, FOOT_SHAPE), - VoxelShapes.union(CORE_SHAPE, CAP_SHAPE), - VoxelShapes.union(CORE_SHAPE, FOOT_SHAPE, CAP_SHAPE) - }; - // [0,0] [0,1] - // [1,0] [1,1] + private static final Function SHAPES = Util.memoize(axis -> { + int[] offsets = { axis.choose(1, 0, 0), axis.choose(0, 1, 0), axis.choose(0, 0, 1) }; + float capOffset = 11F / 16F; + VoxelShape core = Block.createCuboidShape( + axis.choose(0, 1, 1), axis.choose(1, 0, 1), axis.choose(1, 1, 0), + 16 - axis.choose(0, 1, 1), 16 - axis.choose(1, 0, 1), 16 - axis.choose(1, 1, 0) + ); + VoxelShape foot = Block.createCuboidShape(0, 0, 0, 16 - (11 * offsets[0]), 16 - (11 * offsets[1]), 16 - (11 * offsets[2])); + VoxelShape cap = foot.offset(capOffset * offsets[0], capOffset * offsets[1], capOffset * offsets[2]); + return new VoxelShape[] { + core, + VoxelShapes.union(core, foot), + VoxelShapes.union(core, cap), + VoxelShapes.union(core, cap, foot) + }; + }); public CloudPillarBlock(Settings settings) { super(settings, false); - setDefaultState(getDefaultState().with(NORTH, true).with(SOUTH, true)); + setDefaultState(getDefaultState().with(TOP, true).with(BOTTOM, true).with(AXIS, Direction.Axis.Y)); } @Override protected void appendProperties(StateManager.Builder builder) { - builder.add(NORTH, SOUTH); + builder.add(AXIS, TOP, BOTTOM); } @Override protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context, EquineContext equineContext) { - return SHAPES[(state.get(NORTH) ? 0 : 2) + (state.get(SOUTH) ? 0 : 1)]; + var axis = state.get(AXIS); + + int[] offsets = { axis.choose(1, 0, 0), axis.choose(0, 1, 0), axis.choose(0, 0, 1) }; + float capOffset = 11F / 16F; + VoxelShape core = Block.createCuboidShape( + axis.choose(0, 1, 1), axis.choose(1, 0, 1), axis.choose(1, 1, 0), + 16 - axis.choose(0, 1, 1), 16 - axis.choose(1, 0, 1), 16 - axis.choose(1, 1, 0) + ); + VoxelShape foot = Block.createCuboidShape(0, 0, 0, 16 - (11 * offsets[0]), 16 - (11 * offsets[1]), 16 - (11 * offsets[2])); + VoxelShape cap = foot.offset(capOffset * offsets[0], capOffset * offsets[1], capOffset * offsets[2]); + var temp = new VoxelShape[] { + core, + VoxelShapes.union(core, foot), + VoxelShapes.union(core, cap), + VoxelShapes.union(core, cap, foot) + }; + return temp[(state.get(TOP) ? 0 : 2) + (state.get(BOTTOM) ? 0 : 1)]; + //return SHAPES.apply(state.get(AXIS))[(state.get(TOP) ? 0 : 2) + (state.get(BOTTOM) ? 0 : 1)]; } @Override @Nullable protected BlockState getPlacementState(ItemPlacementContext placementContext, EquineContext equineContext) { BlockPos pos = placementContext.getBlockPos(); - BlockState state = super.getPlacementState(placementContext, equineContext); - for (var property : DIRECTION_PROPERTIES.entrySet()) { - state = state.with(property.getValue(), placementContext.getWorld().getBlockState(pos.offset(property.getKey())).isOf(this)); - } - return state; + Direction.Axis axis = placementContext.getSide().getAxis(); + Direction upDirection = Direction.get(AxisDirection.POSITIVE, axis); + Direction downDirection = Direction.get(AxisDirection.NEGATIVE, axis); + BlockState above = placementContext.getWorld().getBlockState(pos.offset(upDirection)); + BlockState below = placementContext.getWorld().getBlockState(pos.offset(downDirection)); + return super.getPlacementState(placementContext, equineContext) + .with(DIRECTION_PROPERTIES.get(upDirection), above.isOf(this) && above.get(AXIS) == axis) + .with(DIRECTION_PROPERTIES.get(downDirection), below.isOf(this) && below.get(AXIS) == axis) + .with(AXIS, axis); } @Deprecated @Override public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { - if (direction.getAxis() == Direction.Axis.Y) { - return state.with(DIRECTION_PROPERTIES.get(direction), neighborState.isOf(this)); + if (direction.getAxis() == state.get(AXIS)) { + return state.with(DIRECTION_PROPERTIES.get(direction), neighborState.isOf(this) && neighborState.get(AXIS) == state.get(AXIS)); } return state; } + + @Override + public BlockState rotate(BlockState state, BlockRotation rotation) { + return PillarBlock.changeRotation(state, rotation); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java index 2b86e3d2..283e25ef 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java @@ -381,9 +381,17 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator { Identifier middle = BlockModels.TEMPLATE_PILLAR.upload(pillar, textures, modelCollector); Identifier end = BlockModels.TEMPLATE_PILLAR_END.upload(pillar, textures, modelCollector); blockStateCollector.accept(MultipartBlockStateSupplier.create(pillar) - .with(BlockStateVariant.create().put(MODEL, middle)) - .with(When.create().set(Properties.NORTH, false), BlockStateVariant.create().put(MODEL, end).put(UVLOCK, true).put(X, R180)) - .with(When.create().set(Properties.SOUTH, false), BlockStateVariant.create().put(MODEL, end)) + .with(When.create().set(Properties.AXIS, Direction.Axis.X), BlockStateVariant.create().put(MODEL, middle).put(X, R90).put(Y, R90)) + .with(When.create().set(Properties.AXIS, Direction.Axis.X).set(Properties.NORTH, false), BlockStateVariant.create().put(MODEL, end).put(X, R270).put(Y, R90)) + .with(When.create().set(Properties.AXIS, Direction.Axis.X).set(Properties.SOUTH, false), BlockStateVariant.create().put(MODEL, end).put(X, R90).put(Y, R90)) + + .with(When.create().set(Properties.AXIS, Direction.Axis.Y), BlockStateVariant.create().put(MODEL, middle)) + .with(When.create().set(Properties.AXIS, Direction.Axis.Y).set(Properties.NORTH, false), BlockStateVariant.create().put(MODEL, end).put(X, R180)) + .with(When.create().set(Properties.AXIS, Direction.Axis.Y).set(Properties.SOUTH, false), BlockStateVariant.create().put(MODEL, end)) + + .with(When.create().set(Properties.AXIS, Direction.Axis.Z), BlockStateVariant.create().put(MODEL, middle).put(X, R90)) + .with(When.create().set(Properties.AXIS, Direction.Axis.Z).set(Properties.NORTH, false), BlockStateVariant.create().put(MODEL, end).put(X, R90)) + .with(When.create().set(Properties.AXIS, Direction.Axis.Z).set(Properties.SOUTH, false), BlockStateVariant.create().put(MODEL, end).put(X, R270)) ); ItemModels.TEMPLATE_PILLAR.upload(ModelIds.getItemModelId(pillar.asItem()), textures, modelCollector); } From c91b5ac985cdc0faf1fcce5d922e2a6c69de1dd4 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Mar 2024 18:06:50 +0000 Subject: [PATCH 18/73] Smol todo --- .../unicopia/datagen/providers/UAdvancementsProvider.java | 3 ++- src/main/resources/assets/unicopia/lang/en_us.json | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java index fc831f33..994082f4 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java @@ -3,7 +3,6 @@ package com.minelittlepony.unicopia.datagen.providers; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; - import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.advancement.CustomEventCriterion; @@ -155,6 +154,8 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { private void generateUnicornTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { parent.child(UItems.SPELLBOOK).criterion("has_spellbook", hasItems(UItems.SPELLBOOK)).build(consumer, "books").children(p -> { + //ItemPredicate bookPredicate = ItemPredicate.Builder.create().tag(ItemTags.BOOKSHELF_BOOKS).build(); + //p.child(Items.BOOK).hidden().frame(AdvancementFrame.CHALLENGE).criterion("has_books", InventoryChangedCriterion.Conditions.items(IntStream.range(0, 9 * 4).mapToObj(i -> bookPredicate).toArray(ItemPredicate[]::new))).build(consumer, "books_books_books"); p.child(UItems.CRYSTAL_SHARD).criterion("has_shard", hasItems(UItems.CRYSTAL_SHARD)).build(consumer, "crystaline").children(pp -> { pp.child(UItems.CRYSTAL_HEART).criterion("power_up_heart", CustomEventCriterion.create("power_up_heart")).rewards(AdvancementRewards.Builder.experience(105)).build(consumer, "power_up_heart"); }); diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index f7497d0c..d9c8f395 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -1731,6 +1731,8 @@ "advancements.unicopia.books.title": "Books!", "advancements.unicopia.books.description": "This is MY spellbook and I'm going to READ it!", + "advancements.unicopia.books_books_books.title": "Books! Books! Books!", + "advancements.unicopia.books_books_books.description": "Have an inventory full of books", "advancements.unicopia.tempted.title": "Tempting...", "advancements.unicopia.tempted.description": "Put on the alicorn amulet", "advancements.unicopia.hello_darkness_my_old_friend.title": "Hello Darkness...", From fd03dabdd67b84a5e90be4dc981c4a9221eb2919 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Mar 2024 18:08:40 +0000 Subject: [PATCH 19/73] Added specter --- .../unicopia/client/URenderers.java | 7 +- .../client/particle/FootprintParticle.java | 74 +++++++++++ .../client/particle/RunesParticle.java | 123 ------------------ .../unicopia/entity/mob/SpecterEntity.java | 118 +++++++++++++++++ .../unicopia/entity/mob/UEntities.java | 12 +- .../particle/FootprintParticleEffect.java | 42 ++++++ .../unicopia/particle/UParticles.java | 4 +- .../resources/assets/unicopia/lang/en_us.json | 1 + .../assets/unicopia/particles/footprint.json | 5 + .../unicopia/textures/particle/footprint.png | Bin 0 -> 6935 bytes 10 files changed, 256 insertions(+), 130 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/client/particle/FootprintParticle.java delete mode 100644 src/main/java/com/minelittlepony/unicopia/client/particle/RunesParticle.java create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/mob/SpecterEntity.java create mode 100644 src/main/java/com/minelittlepony/unicopia/particle/FootprintParticleEffect.java create mode 100644 src/main/resources/assets/unicopia/particles/footprint.json create mode 100644 src/main/resources/assets/unicopia/textures/particle/footprint.png diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index 69d0ab9c..e5896bd6 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -12,6 +12,7 @@ import com.minelittlepony.unicopia.client.particle.CloudsEscapingParticle; import com.minelittlepony.unicopia.client.particle.DiskParticle; import com.minelittlepony.unicopia.client.particle.DustCloudParticle; import com.minelittlepony.unicopia.client.particle.FloatingBubbleParticle; +import com.minelittlepony.unicopia.client.particle.FootprintParticle; import com.minelittlepony.unicopia.client.particle.GroundPoundParticle; import com.minelittlepony.unicopia.client.particle.HealthDrainParticle; import com.minelittlepony.unicopia.client.particle.LightningBoltParticle; @@ -19,7 +20,6 @@ import com.minelittlepony.unicopia.client.particle.MagicParticle; import com.minelittlepony.unicopia.client.particle.RainboomParticle; import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle; import com.minelittlepony.unicopia.client.particle.RaindropsParticle; -import com.minelittlepony.unicopia.client.particle.RunesParticle; import com.minelittlepony.unicopia.client.particle.ShockwaveParticle; import com.minelittlepony.unicopia.client.particle.SphereParticle; import com.minelittlepony.unicopia.client.render.*; @@ -54,6 +54,7 @@ import net.minecraft.client.particle.SpriteProvider; import net.minecraft.client.render.*; import net.minecraft.client.render.VertexConsumerProvider.Immediate; import net.minecraft.client.render.block.entity.BlockEntityRendererFactories; +import net.minecraft.client.render.entity.EmptyEntityRenderer; import net.minecraft.client.render.entity.FlyingItemEntityRenderer; import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.model.json.ModelTransformationMode; @@ -68,7 +69,6 @@ import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.world.BlockRenderView; -@SuppressWarnings("deprecation") public interface URenderers { BlockEntity CHEST_RENDER_ENTITY = new CloudChestBlock.TileData(BlockPos.ORIGIN, UBlocks.CLOUD_CHEST.getDefaultState()); @@ -78,10 +78,10 @@ public interface URenderers { ParticleFactoryRegistry.getInstance().register(UParticles.BUBBLE, createFactory(FloatingBubbleParticle::new)); ParticleFactoryRegistry.getInstance().register(UParticles.RAIN_DROPS, createFactory(RaindropsParticle::new)); ParticleFactoryRegistry.getInstance().register(UParticles.HEALTH_DRAIN, createFactory(HealthDrainParticle::create)); + ParticleFactoryRegistry.getInstance().register(UParticles.FOOTPRINT, createFactory(FootprintParticle::new)); ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_RING, RainboomParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.RAINBOOM_TRAIL, RainbowTrailParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.SHOCKWAVE, ShockwaveParticle::new); - ParticleFactoryRegistry.getInstance().register(UParticles.MAGIC_RUNES, RunesParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.SPHERE, SphereParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.DISK, DiskParticle::new); ParticleFactoryRegistry.getInstance().register(UParticles.GROUND_POUND, GroundPoundParticle::new); @@ -111,6 +111,7 @@ public interface URenderers { EntityRendererRegistry.register(UEntities.LOOT_BUG, LootBugEntityRenderer::new); EntityRendererRegistry.register(UEntities.TENTACLE, TentacleEntityRenderer::new); EntityRendererRegistry.register(UEntities.IGNOMINIOUS_BULB, IgnominiousBulbEntityRenderer::new); + EntityRendererRegistry.register(UEntities.SPECTER, EmptyEntityRenderer::new); BlockEntityRendererFactories.register(UBlockEntities.WEATHER_VANE, WeatherVaneBlockEntityRenderer::new); BlockEntityRendererFactories.register(UBlockEntities.FANCY_BED, CloudBedBlockEntityRenderer::new); diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/FootprintParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/FootprintParticle.java new file mode 100644 index 00000000..32075c5e --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/particle/FootprintParticle.java @@ -0,0 +1,74 @@ +package com.minelittlepony.unicopia.client.particle; + +import org.joml.Vector3f; + +import com.minelittlepony.unicopia.particle.FootprintParticleEffect; + +import net.minecraft.client.particle.ParticleTextureSheet; +import net.minecraft.client.particle.SpriteBillboardParticle; +import net.minecraft.client.particle.SpriteProvider; +import net.minecraft.client.render.Camera; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +public class FootprintParticle extends SpriteBillboardParticle { + // specter + + public FootprintParticle(FootprintParticleEffect effect, SpriteProvider provider, ClientWorld world, double x, double y, double z, double dx, double dy, double dz) { + super(world, x, y, z, 0, 0, 0); + setVelocity(0, 0, 0); + setSprite(provider.getSprite(world.random)); + this.angle = effect.yaw() * MathHelper.RADIANS_PER_DEGREE; + this.maxAge = 1000; + this.gravityStrength = 1; + } + + @Override + public ParticleTextureSheet getType() { + return ParticleTextureSheet.PARTICLE_SHEET_TRANSLUCENT; + } + + @Override + public void tick() { + super.tick(); + } + + @Override + public void buildGeometry(VertexConsumer drawer, Camera camera, float tickDelta) { + Vec3d cam = camera.getPos(); + + float renderX = (float)(MathHelper.lerp(tickDelta, prevPosX, x) - cam.getX()); + float renderY = (float)(MathHelper.lerp(tickDelta, prevPosY, y) - cam.getY()); + float renderZ = (float)(MathHelper.lerp(tickDelta, prevPosZ, z) - cam.getZ()); + + Vector3f[] corners = new Vector3f[]{ + new Vector3f(-1, 0, -1), + new Vector3f(-1, 0, 1), + new Vector3f( 1, 0, 1), + new Vector3f( 1, 0, -1) + }; + for (int k = 0; k < 4; ++k) { + Vector3f corner = corners[k]; + corner.mul(0.2F); + corner.rotateAxis(angle, 0, 1, 0); + corner.add(renderX, renderY + 0.0001F, renderZ); + } + + float alpha = this.alpha * (1 - ((float)age / maxAge)); + int light = getBrightness(tickDelta); + + float minU = this.sprite.getMinU(); + float maxU = this.sprite.getMaxU(); + + float minV = this.sprite.getMinV(); + float maxV = this.sprite.getMaxV(); + + drawer.vertex(corners[0].x, corners[0].y, corners[0].z).texture(minU, minV).color(red, green, blue, alpha).light(light).next(); + drawer.vertex(corners[1].x, corners[1].y, corners[1].z).texture(maxU, minV).color(red, green, blue, alpha).light(light).next(); + drawer.vertex(corners[2].x, corners[2].y, corners[2].z).texture(maxU, maxV).color(red, green, blue, alpha).light(light).next(); + drawer.vertex(corners[3].x, corners[3].y, corners[3].z).texture(minU, maxV).color(red, green, blue, alpha).light(light).next(); + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/particle/RunesParticle.java b/src/main/java/com/minelittlepony/unicopia/client/particle/RunesParticle.java deleted file mode 100644 index 21294ca3..00000000 --- a/src/main/java/com/minelittlepony/unicopia/client/particle/RunesParticle.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.minelittlepony.unicopia.client.particle; - -import org.joml.Quaternionf; -import org.joml.Vector3f; - -import com.minelittlepony.unicopia.Unicopia; -import com.minelittlepony.unicopia.particle.OrientedBillboardParticleEffect; -import com.mojang.blaze3d.systems.RenderSystem; - -import net.minecraft.client.render.BufferBuilder; -import net.minecraft.client.render.Tessellator; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.*; - -@Deprecated -public class RunesParticle extends OrientedBillboardParticle { - - private static final Identifier[] TEXTURES = new Identifier[] { - Unicopia.id("textures/particles/runes_0.png"), - Unicopia.id("textures/particles/runes_1.png"), - Unicopia.id("textures/particles/runes_2.png"), - Unicopia.id("textures/particles/runes_3.png"), - Unicopia.id("textures/particles/runes_4.png"), - Unicopia.id("textures/particles/runes_5.png") - }; - - protected float targetSize = 3; - - protected float prevBaseSize = 0; - protected float baseSize = 0; - - private float prevRotationAngle; - private float rotationAngle; - - public RunesParticle(OrientedBillboardParticleEffect effect, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) { - super(effect, world, x, y, z, velocityX, velocityY, velocityZ); - setMaxAge(70); - - red = world.random.nextFloat(); - green = world.random.nextFloat(); - blue = world.random.nextFloat(); - } - - @Override - public float getScale(float tickDelta) { - return MathHelper.lerp(tickDelta, prevBaseSize, baseSize) * super.getScale(tickDelta); - } - - @Override - protected Identifier getTexture() { - return TEXTURES[0]; - } - - private float getAlphaScale() { - float transitionScale = age < maxAge / 2 ? 5 : 3; - return (float)Math.min(1, Math.sin(Math.PI * age / maxAge) * transitionScale); - } - - @Override - protected int getBrightness(float tint) { - return 0xF000F0; - } - - @Override - protected void renderQuads(Tessellator te, BufferBuilder buffer, float x, float y, float z, float tickDelta) { - - float alpha = this.alpha * getAlphaScale(); - - float angle = MathHelper.lerp(tickDelta, prevRotationAngle, rotationAngle); - - for (int i = 0; i < TEXTURES.length; i++) { - for (int dim = 0; dim < 3; dim++) { - RenderSystem.setShaderTexture(0, TEXTURES[i]); - RenderSystem.setShaderColor(red, green, blue, alpha / ((float)(dim * 3) + 1)); - - Vector3f[] corners = new Vector3f[]{ - new Vector3f(-1, -1, 0), - new Vector3f(-1, 1, 0), - new Vector3f( 1, 1, 0), - new Vector3f( 1, -1, 0) - }; - float scale = getScale(tickDelta); - - float ringSpeed = (i % 2 == 0 ? i : -1) * i; - - Quaternionf ringAngle = RotationAxis.POSITIVE_Z.rotationDegrees(angle * ringSpeed); - Quaternionf ringFlip = RotationAxis.POSITIVE_Y.rotationDegrees(angle * ringSpeed * dim); - Quaternionf ringRoll = RotationAxis.POSITIVE_X.rotationDegrees(angle * ringSpeed * dim); - - for(int k = 0; k < 4; ++k) { - Vector3f corner = corners[k]; - corner.rotate(ringAngle); - corner.rotate(ringFlip); - corner.rotate(ringRoll); - corner.rotate(rotation); - corner.mul(scale); - corner.add(x, y + 0.001F, z); - } - - renderQuad(te, buffer, corners, alpha, tickDelta); - } - } - - RenderSystem.setShaderColor(1, 1, 1, 1); - } - - @Override - public void tick() { - super.tick(); - - prevBaseSize = baseSize; - if (baseSize < targetSize) { - baseSize += 0.1F; - } - if (baseSize > targetSize) { - baseSize -= 0.1F; - } - - rotationAngle = (rotationAngle + 0.3F) % 360; - prevRotationAngle = rotationAngle - 0.3F; - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/SpecterEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/SpecterEntity.java new file mode 100644 index 00000000..91f9b407 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/SpecterEntity.java @@ -0,0 +1,118 @@ +package com.minelittlepony.unicopia.entity.mob; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.particle.FootprintParticleEffect; +import com.minelittlepony.unicopia.particle.ParticleUtils; + +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.goal.ActiveTargetGoal; +import net.minecraft.entity.ai.goal.LookAroundGoal; +import net.minecraft.entity.ai.goal.LookAtEntityGoal; +import net.minecraft.entity.ai.goal.MeleeAttackGoal; +import net.minecraft.entity.ai.goal.RevengeGoal; +import net.minecraft.entity.ai.goal.SwimGoal; +import net.minecraft.entity.ai.goal.WanderAroundFarGoal; +import net.minecraft.entity.attribute.DefaultAttributeContainer; +import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.mob.HostileEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.particle.BlockStateParticleEffect; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.registry.tag.BlockTags; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.GameRules; +import net.minecraft.world.World; + +public class SpecterEntity extends HostileEntity { + public static DefaultAttributeContainer.Builder createAttributes() { + return HostileEntity.createHostileAttributes() + .add(EntityAttributes.GENERIC_MAX_HEALTH, 16F) + .add(EntityAttributes.GENERIC_MOVEMENT_SPEED, 0.5F); + } + + private double stepDistance; + private double nextStepDistance; + private boolean wasLeft; + + public SpecterEntity(EntityType entityType, World world) { + super(entityType, world); + } + + @Override + protected void initGoals() { + this.goalSelector.add(1, new SwimGoal(this)); + this.goalSelector.add(4, new MeleeAttackGoal(this, 1.0, true)); + this.goalSelector.add(5, new WanderAroundFarGoal(this, 0.8)); + this.goalSelector.add(6, new LookAtEntityGoal(this, PlayerEntity.class, 8.0f)); + this.goalSelector.add(6, new LookAroundGoal(this)); + this.targetSelector.add(1, new RevengeGoal(this)); + this.targetSelector.add(2, new TargetGoal<>(this, PlayerEntity.class)); + } + + @SuppressWarnings("deprecation") + @Override + public void tick() { + Vec3d prevPosition = getPos(); + super.tick(); + if (getBrightnessAtEyes() < 0.5F || getTarget() != null) { + ParticleUtils.spawnParticles(ParticleTypes.AMBIENT_ENTITY_EFFECT, this, 6); + + if (getWorld().getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING)) { + if (getWorld().getBlockState(getBlockPos()).isIn(BlockTags.REPLACEABLE_BY_TREES)) { + getWorld().breakBlock(getBlockPos(), true); + } + } + } + + if (!hasVehicle() && isOnGround()) { + stepDistance += getPos().subtract(prevPosition).horizontalLength() * 0.6F; + if (stepDistance >= nextStepDistance) { + nextStepDistance = stepDistance + 1; + wasLeft = !wasLeft; + float offset = 0.4F; + float yaw = getHeadYaw(); + Vec3d offsetVec = new Vec3d((wasLeft ? offset : -offset), 0, 0).rotateY(yaw); + getWorld().addParticle(new FootprintParticleEffect(yaw), true, getX() + offsetVec.getX(), getY(), getZ() + offsetVec.getZ(), 0, 0, 0); + ParticleUtils.spawnParticles(new BlockStateParticleEffect(ParticleTypes.BLOCK, getSteppingBlockState()), getWorld(), getPos(), 6); + playSound(getSteppingBlockState().getSoundGroup().getStepSound(), 0.5F, 1); + } + } + } + + @Override + public float getSoundPitch() { + return super.getSoundPitch() * 0.3F; + } + + @Override + @Nullable + protected SoundEvent getHurtSound(DamageSource source) { + return null; + } + + @Override + protected void playSwimSound(float volume) { + + } + + @Override + protected void onSwimmingStart() { + + } + + static class TargetGoal extends ActiveTargetGoal { + public TargetGoal(SpecterEntity specter, Class targetEntityClass) { + super(specter, targetEntityClass, true); + } + + @SuppressWarnings("deprecation") + @Override + public boolean canStart() { + return mob.getBrightnessAtEyes() < 0.5F && super.canStart(); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java index 924ca810..407710ef 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java @@ -7,7 +7,6 @@ import com.minelittlepony.unicopia.entity.behaviour.EntityBehaviour; import com.minelittlepony.unicopia.projectile.MagicBeamEntity; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import com.minelittlepony.unicopia.projectile.PhysicsBodyProjectileEntity; - import net.fabricmc.fabric.api.biome.v1.BiomeModifications; import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext; import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; @@ -17,10 +16,13 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnGroup; +import net.minecraft.entity.SpawnRestriction.Location; import net.minecraft.entity.decoration.painting.PaintingVariant; import net.minecraft.entity.mob.FlyingEntity; +import net.minecraft.entity.mob.HostileEntity; import net.minecraft.registry.*; import net.minecraft.registry.tag.BiomeTags; +import net.minecraft.world.Heightmap.Type; public interface UEntities { EntityType BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.create(SpawnGroup.AMBIENT, ButterflyEntity::new) @@ -74,6 +76,11 @@ public interface UEntities { EntityType IGNOMINIOUS_BULB = register("ignominious_bulb", FabricEntityTypeBuilder.create(SpawnGroup.MISC, IgnominiousBulbEntity::new) .trackRangeChunks(8) .dimensions(EntityDimensions.fixed(3, 2))); + EntityType SPECTER = register("specter", FabricEntityTypeBuilder.createMob().spawnGroup(SpawnGroup.MONSTER).entityFactory(SpecterEntity::new) + .spawnRestriction(Location.ON_GROUND, Type.WORLD_SURFACE, HostileEntity::canSpawnInDark) + .fireImmune() + .spawnableFarFromPlayer() + .dimensions(EntityDimensions.fixed(1, 2))); static EntityType register(String name, FabricEntityTypeBuilder builder) { EntityType type = builder.build(); @@ -89,6 +96,7 @@ public interface UEntities { FabricDefaultAttributeRegistry.register(FRIENDLY_CREEPER, FriendlyCreeperEntity.createCreeperAttributes()); FabricDefaultAttributeRegistry.register(LOOT_BUG, LootBugEntity.createSilverfishAttributes()); FabricDefaultAttributeRegistry.register(IGNOMINIOUS_BULB, IgnominiousBulbEntity.createMobAttributes()); + FabricDefaultAttributeRegistry.register(SPECTER, SpecterEntity.createAttributes()); if (!Unicopia.getConfig().disableButterflySpawning.get()) { final Predicate butterflySpawnable = BiomeSelectors.foundInOverworld() @@ -105,6 +113,8 @@ public interface UEntities { ), SpawnGroup.AMBIENT, BUTTERFLY, 7, 5, 19); } + BiomeModifications.addSpawn(BiomeSelectors.spawnsOneOf(EntityType.ZOMBIE), SpawnGroup.MONSTER, SPECTER, 2, 1, 2); + UTradeOffers.bootstrap(); EntityBehaviour.bootstrap(); UEntityAttributes.bootstrap(); diff --git a/src/main/java/com/minelittlepony/unicopia/particle/FootprintParticleEffect.java b/src/main/java/com/minelittlepony/unicopia/particle/FootprintParticleEffect.java new file mode 100644 index 00000000..69ef2300 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/particle/FootprintParticleEffect.java @@ -0,0 +1,42 @@ +package com.minelittlepony.unicopia.particle; + +import java.util.Locale; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import net.minecraft.particle.ParticleEffect; +import net.minecraft.particle.ParticleType; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.registry.Registries; + +public record FootprintParticleEffect ( + float yaw + ) implements ParticleEffect { + @SuppressWarnings("deprecation") + public static final ParticleEffect.Factory FACTORY = ParticleFactoryHelper.of(FootprintParticleEffect::new, FootprintParticleEffect::new); + + protected FootprintParticleEffect(ParticleType type, StringReader reader) throws CommandSyntaxException { + this(ParticleFactoryHelper.readFloat(reader)); + } + + protected FootprintParticleEffect(ParticleType particleType, PacketByteBuf buf) { + this(buf.readFloat()); + } + + @Override + public ParticleType getType() { + return UParticles.FOOTPRINT; + } + + @Override + public void write(PacketByteBuf buf) { + buf.writeFloat(yaw); + } + + @Override + public String asString() { + return String.format(Locale.ROOT, "%s %.2f", Registries.PARTICLE_TYPE.getId(getType()), yaw); + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java b/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java index 9bec2e5c..da302010 100644 --- a/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java +++ b/src/main/java/com/minelittlepony/unicopia/particle/UParticles.java @@ -14,14 +14,12 @@ public interface UParticles { ParticleType UNICORN_MAGIC = register("unicorn_magic", FabricParticleTypes.complex(MagicParticleEffect.FACTORY)); DefaultParticleType CHANGELING_MAGIC = register("changeling_magic", FabricParticleTypes.simple()); DefaultParticleType BUBBLE = register("bubble", FabricParticleTypes.simple()); + ParticleType FOOTPRINT = register("footprint", FabricParticleTypes.complex(FootprintParticleEffect.FACTORY)); ParticleType DUST_CLOUD = register("dust_cloud", FabricParticleTypes.complex(BlockStateParticleEffect.PARAMETERS_FACTORY)); ParticleType RAINBOOM_RING = register("rainboom_ring", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY)); ParticleType RAINBOOM_TRAIL = register("rainboom_trail", FabricParticleTypes.complex(TargetBoundParticleEffect.FACTORY)); - @Deprecated - ParticleType MAGIC_RUNES = register("magic_runes", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY)); - DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple()); ParticleType SPHERE = register("sphere", FabricParticleTypes.complex(true, SphereParticleEffect.FACTORY)); diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index d9c8f395..01a3726f 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -355,6 +355,7 @@ "entity.unicopia.butterfly": "Butterfly", "entity.unicopia.twittermite": "Twittermite", + "entity.unicopia.specter": "Specter", "entity.unicopia.cast_spell": "Cast Spell", "entity.unicopia.cast_spell.by": "a spell cast by %s", "entity.unicopia.spellbook": "Spellbook", diff --git a/src/main/resources/assets/unicopia/particles/footprint.json b/src/main/resources/assets/unicopia/particles/footprint.json new file mode 100644 index 00000000..50c757f1 --- /dev/null +++ b/src/main/resources/assets/unicopia/particles/footprint.json @@ -0,0 +1,5 @@ +{ + "textures": [ + "unicopia:footprint" + ] +} diff --git a/src/main/resources/assets/unicopia/textures/particle/footprint.png b/src/main/resources/assets/unicopia/textures/particle/footprint.png new file mode 100644 index 0000000000000000000000000000000000000000..a0ea4822b22157f122b708ac5ca0d3ab18ba4a0b GIT binary patch literal 6935 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 literal 0 HcmV?d00001 From f0c5cdb156265f7362b3bf804cce7e9ab4387eed Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Mar 2024 18:09:16 +0000 Subject: [PATCH 20/73] Fix butterflies spawning in the middle of nowhere --- .../minelittlepony/unicopia/entity/mob/ButterflyEntity.java | 4 ++++ .../com/minelittlepony/unicopia/entity/mob/UEntities.java | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java index 088529b2..d1a43978 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java @@ -72,6 +72,10 @@ public class ButterflyEntity extends AmbientEntity { return createMobAttributes().add(EntityAttributes.GENERIC_MAX_HEALTH, 2); } + public static boolean canSpawn(EntityType type, WorldAccess world, SpawnReason spawnReason, BlockPos pos, Random random) { + return world.getBlockState(pos.down()).isIn(BlockTags.ANIMALS_SPAWNABLE_ON); + } + @Override public float getSoundPitch() { return super.getSoundPitch() * 0.95F; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java index 407710ef..9200384f 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java @@ -25,7 +25,8 @@ import net.minecraft.registry.tag.BiomeTags; import net.minecraft.world.Heightmap.Type; public interface UEntities { - EntityType BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.create(SpawnGroup.AMBIENT, ButterflyEntity::new) + EntityType BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.createMob().spawnGroup(SpawnGroup.AMBIENT).entityFactory(ButterflyEntity::new) + .spawnRestriction(Location.NO_RESTRICTIONS, Type.WORLD_SURFACE_WG, ButterflyEntity::canSpawn) .dimensions(EntityDimensions.fixed(0.25F, 0.25F))); EntityType THROWN_ITEM = register("thrown_item", FabricEntityTypeBuilder.create(SpawnGroup.MISC, MagicProjectileEntity::new) .trackRangeBlocks(100) From 2ac6970e04a2360c60b0a8eb3a14c3d65435075c Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Mar 2024 18:09:48 +0000 Subject: [PATCH 21/73] Added block of worms --- .../minelittlepony/unicopia/block/UBlocks.java | 4 ++++ .../providers/UBlockStateModelGenerator.java | 3 ++- .../datagen/providers/UBlockTagProvider.java | 1 + .../providers/loot/UBlockLootTableProvider.java | 3 ++- .../providers/recipe/URecipeProvider.java | 3 +++ .../resources/assets/unicopia/lang/en_us.json | 1 + .../unicopia/textures/block/worm_block.png | Bin 0 -> 7064 bytes .../resources/data/c/tags/items/raw_insects.json | 3 ++- 8 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/assets/unicopia/textures/block/worm_block.png diff --git a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java index 1c45b8a8..32e48568 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java +++ b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java @@ -36,6 +36,7 @@ import com.minelittlepony.unicopia.item.cloud.CloudBlockItem; import com.minelittlepony.unicopia.item.group.ItemGroupRegistry; import com.minelittlepony.unicopia.server.world.UTreeGen; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.fabricmc.fabric.api.registry.CompostingChanceRegistry; import net.fabricmc.fabric.api.registry.FlammableBlockRegistry; import net.fabricmc.fabric.api.registry.OxidizableBlocksRegistry; import net.fabricmc.fabric.api.registry.StrippableBlockRegistry; @@ -253,6 +254,7 @@ public interface UBlocks { Block SPECTRAL_FIRE = register("spectral_fire", new SpectralFireBlock(Settings.copy(Blocks.SOUL_FIRE))); + Block WORM_BLOCK = register("worm_block", new FallingBlock(Settings.create().hardness(0.1F).resistance(0).requiresTool().sounds(BlockSoundGroup.MUD)), ItemGroups.NATURAL); EdibleBlock HAY_BLOCK = register("hay_block", new EdibleBlock(new Identifier("hay_block"), new Identifier("wheat"), true)); private static T register(String name, T item) { @@ -328,6 +330,8 @@ public interface UBlocks { FlammableBlockRegistry.getDefaultInstance().add(BANANAS, 5, 20); FlammableBlockRegistry.getDefaultInstance().add(CURING_JOKE, 60, 100); + CompostingChanceRegistry.INSTANCE.add(WORM_BLOCK, 8F); + UBlockEntities.bootstrap(); EdibleBlock.bootstrap(); } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java index 283e25ef..45274e75 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java @@ -123,7 +123,7 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator { registerLog(UBlocks.STRIPPED_PALM_LOG).log(UBlocks.STRIPPED_PALM_LOG).wood(UBlocks.STRIPPED_PALM_WOOD); registerCubeAllModelTexturePool(UBlocks.PALM_PLANKS).family(UBlockFamilies.PALM); registerHangingSign(UBlocks.STRIPPED_PALM_LOG, UBlocks.PALM_HANGING_SIGN, UBlocks.PALM_WALL_HANGING_SIGN); - registerSimpleCubeAll(UBlocks.PALM_LEAVES); + registerSingleton(UBlocks.PALM_LEAVES, TexturedModel.LEAVES); // zap wood registerLog(UBlocks.ZAP_LOG) @@ -170,6 +170,7 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator { // shells registerAll(UBlockStateModelGenerator::registerShell, UBlocks.CLAM_SHELL, UBlocks.TURRET_SHELL, UBlocks.SCALLOP_SHELL); // other + registerSimpleCubeAll(UBlocks.WORM_BLOCK); registerBuiltinWithParticle(UBlocks.WEATHER_VANE, UBlocks.WEATHER_VANE.asItem()); registerWithStages(UBlocks.FROSTED_OBSIDIAN, Properties.AGE_3, BlockModels.CUBE_ALL, 0, 1, 2, 3); registerWithStagesBuiltinModels(UBlocks.ROCKS, Properties.AGE_7, 0, 1, 2, 3, 4, 5, 6, 7); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java index 2deff29f..cc6d6411 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java @@ -48,6 +48,7 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { getOrCreateTagBuilder(BlockTags.DRAGON_IMMUNE).add(UBlocks.FROSTED_OBSIDIAN, UBlocks.GOLDEN_OAK_LOG, UBlocks.GOLDEN_OAK_LEAVES); getOrCreateTagBuilder(BlockTags.FIRE).add(UBlocks.SPECTRAL_FIRE); getOrCreateTagBuilder(BlockTags.HOE_MINEABLE).add(UBlocks.HAY_BLOCK).addOptional(Unicopia.id("rice_block")).addOptional(Unicopia.id("straw_block")); + getOrCreateTagBuilder(BlockTags.SHOVEL_MINEABLE).add(UBlocks.WORM_BLOCK); addZapWoodset(); addPalmWoodset(); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java index 9b3b4364..fba77f65 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java @@ -54,7 +54,8 @@ public class UBlockLootTableProvider extends FabricBlockLootTableProvider { UBlocks.WEATHER_VANE, UBlocks.ZAP_FENCE_GATE, UBlocks.ZAP_FENCE, - UBlocks.ZAP_LOG, UBlocks.ZAP_PLANKS, UBlocks.ZAP_STAIRS, UBlocks.ZAP_WOOD + UBlocks.ZAP_LOG, UBlocks.ZAP_PLANKS, UBlocks.ZAP_STAIRS, UBlocks.ZAP_WOOD, + UBlocks.WORM_BLOCK ).forEach(this::addDrop); // slabs diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index 942131c8..8250dd9b 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -67,6 +67,9 @@ public class URecipeProvider extends FabricRecipeProvider { createCustomBedRecipe(UItems.CLOTH_BED, Either.right(ItemTags.WOOL), Either.right(ItemTags.LOGS)).offerTo(exporter); offerBedSheetRecipes(exporter); + // worms + offerReversibleCompactingRecipes(exporter, RecipeCategory.BUILDING_BLOCKS, UItems.WHEAT_WORMS, RecipeCategory.BUILDING_BLOCKS, UBlocks.WORM_BLOCK); + // sunglasses ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.SUNGLASSES) .input('#', ConventionalItemTags.GLASS_BLOCKS).criterion("has_glass_block", conditionsFromTag(ConventionalItemTags.GLASS_BLOCKS)) diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 01a3726f..a83cc748 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -280,6 +280,7 @@ "block.unicopia.golden_oak_leaves": "Golden Oak Leaves", "block.unicopia.golden_oak_log": "Golden Oak Log", "block.unicopia.mango": "Mango", + "block.unicopia.worm_block": "Block of Worms", "block.unicopia.mango_leaves": "Mango Leaves", "block.unicopia.mango_sapling": "Mango Sapling", "block.unicopia.potted_mango_sapling": "Potted Mango Sapling", diff --git a/src/main/resources/assets/unicopia/textures/block/worm_block.png b/src/main/resources/assets/unicopia/textures/block/worm_block.png new file mode 100644 index 0000000000000000000000000000000000000000..f27791b88df812c891fbf467a4d45e7d428e6c92 GIT binary patch literal 7064 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 Date: Mon, 25 Mar 2024 18:10:12 +0000 Subject: [PATCH 22/73] Allow changelings to eat blocks (should be only humans here since the food rewrite) --- src/main/java/com/minelittlepony/unicopia/Race.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/Race.java b/src/main/java/com/minelittlepony/unicopia/Race.java index a6ae1c58..dd3bf4d9 100644 --- a/src/main/java/com/minelittlepony/unicopia/Race.java +++ b/src/main/java/com/minelittlepony/unicopia/Race.java @@ -80,7 +80,7 @@ public record Race (Supplier compositeSupplier, Availability availabi } public boolean hasIronGut() { - return !isHuman() && this != CHANGELING; + return !isHuman(); } public boolean isUnset() { From 0f681b07b32d26a2fee80e1bf2a45fcc4511eea2 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Mar 2024 18:11:31 +0000 Subject: [PATCH 23/73] Rebalance and beef up the insects food group to help changelings and bat ponies --- .../unicopia/diets/food_effects/insect/raw.json | 4 ++-- .../data/unicopia/diets/races/changeling.json | 17 ++++++++++++++++- .../unicopia/tags/items/groups/earth_pony.json | 1 + 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/resources/data/unicopia/diets/food_effects/insect/raw.json b/src/main/resources/data/unicopia/diets/food_effects/insect/raw.json index 8683f240..01a176d0 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/insect/raw.json +++ b/src/main/resources/data/unicopia/diets/food_effects/insect/raw.json @@ -1,8 +1,8 @@ { "tags": [ "unicopia:food_types/raw_insect" ], "food_component": { - "hunger": 1, - "saturation": 0.1 + "hunger": 6, + "saturation": 0.3 }, "ailment": { "effects": [ diff --git a/src/main/resources/data/unicopia/diets/races/changeling.json b/src/main/resources/data/unicopia/diets/races/changeling.json index a60fb6bd..c20c7753 100644 --- a/src/main/resources/data/unicopia/diets/races/changeling.json +++ b/src/main/resources/data/unicopia/diets/races/changeling.json @@ -74,6 +74,18 @@ ] } }, + { + "tags": [ + "unicopia:food_types/raw_insect" + ], + "food_component": { + "hunger": 3, + "saturation": 2 + }, + "ailment": { + "effects": [ ] + } + }, { "tags": [ "unicopia:food_types/cooked_fish", @@ -98,11 +110,14 @@ "tags": [ "unicopia:food_types/rotten_fish", "unicopia:food_types/cooked_insect", - "unicopia:food_types/raw_insect", "unicopia:food_types/cooked_meat", "unicopia:food_types/raw_meat", "unicopia:food_types/rotten_meat" ], + "food_component": { + "hunger": 6, + "saturation": 9 + }, "ailment": { "effects": [ { diff --git a/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json b/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json index 618a0532..d88b92b7 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json +++ b/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json @@ -57,6 +57,7 @@ "unicopia:crispy_hay_fries", "unicopia:horse_shoe_fries", "unicopia:wheat_worms", + "unicopia:worm_block", "unicopia:muffin", "unicopia:acorn", "unicopia:pinecone", From 29502e7529f5ec9fa8ac4588b07ea5d638c553f8 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Mar 2024 18:11:50 +0000 Subject: [PATCH 24/73] Don't show diet information on blocks unaffected by the diet system --- .../unicopia/diet/PonyDiets.java | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java b/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java index 8e4558a9..3566bf06 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java @@ -77,21 +77,15 @@ public class PonyDiets implements DietView { @Override public void appendTooltip(ItemStack stack, @Nullable PlayerEntity user, List tooltip, TooltipContext context) { + if (initEdibility(stack, user)) { - Pony pony = Pony.of(user); + if (!((ItemDuck)stack.getItem()).getOriginalFoodComponent().isEmpty() || stack.getItem().getFoodComponent() != null) { + Pony pony = Pony.of(user); - tooltip.add(Text.translatable("unicopia.diet.information").formatted(Formatting.DARK_PURPLE)); - getEffects(stack, pony).appendTooltip(stack, tooltip, context); - - /*for (Race race : Race.REGISTRY) { - var diet = diets.get(race); - if (diet != null) { - tooltip.add(race.getDisplayName()); - diet.appendTooltip(stack, user, tooltip, context); - } - }*/ - - getDiet(pony).appendTooltip(stack, user, tooltip, context); + tooltip.add(Text.translatable("unicopia.diet.information").formatted(Formatting.DARK_PURPLE)); + getEffects(stack, pony).appendTooltip(stack, tooltip, context); + getDiet(pony).appendTooltip(stack, user, tooltip, context); + } } } From 54cbf2c238859d670c5f5d9f0f32d452d93f49f7 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Mar 2024 19:13:56 +0000 Subject: [PATCH 25/73] Add recipe to convert seashells into bonemeal --- .../datagen/providers/recipe/URecipeProvider.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index 8250dd9b..ed82fb66 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -67,9 +67,6 @@ public class URecipeProvider extends FabricRecipeProvider { createCustomBedRecipe(UItems.CLOTH_BED, Either.right(ItemTags.WOOL), Either.right(ItemTags.LOGS)).offerTo(exporter); offerBedSheetRecipes(exporter); - // worms - offerReversibleCompactingRecipes(exporter, RecipeCategory.BUILDING_BLOCKS, UItems.WHEAT_WORMS, RecipeCategory.BUILDING_BLOCKS, UBlocks.WORM_BLOCK); - // sunglasses ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.SUNGLASSES) .input('#', ConventionalItemTags.GLASS_BLOCKS).criterion("has_glass_block", conditionsFromTag(ConventionalItemTags.GLASS_BLOCKS)) @@ -452,6 +449,9 @@ public class URecipeProvider extends FabricRecipeProvider { .pattern("---") .offerTo(exporter); + // worms + offerReversibleCompactingRecipes(exporter, RecipeCategory.BUILDING_BLOCKS, UItems.WHEAT_WORMS, RecipeCategory.BUILDING_BLOCKS, UBlocks.WORM_BLOCK); + // utility ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, Items.DIRT) .input('*', UItems.WHEAT_WORMS).criterion("has_wheat_worms", conditionsFromItem(UItems.WHEAT_WORMS)) @@ -460,6 +460,8 @@ public class URecipeProvider extends FabricRecipeProvider { .pattern("#*") .offerTo(exporter, convertBetween(Items.DIRT, UItems.WHEAT_WORMS)); + offerShapelessRecipe(exporter, Items.BONE_MEAL, UTags.SHELLS, "bonemeal", 3); + offer2x2CompactingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, Items.COBBLESTONE, UItems.ROCK); offerReversibleCompactingRecipesWithReverseRecipeGroup(exporter, RecipeCategory.MISC, UItems.PEBBLES, RecipeCategory.BUILDING_BLOCKS, Blocks.GRAVEL, convertBetween(UItems.PEBBLES, Blocks.GRAVEL), "pebbles"); offerShapelessRecipe(exporter, UItems.PEBBLES, Blocks.SUSPICIOUS_GRAVEL, "pebbles", 9); From 9e329ac2f92d1b8cbacbd297eb389a47b4c5a820 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Mar 2024 19:57:21 +0000 Subject: [PATCH 26/73] #314 Reduce camera motion and apply the client setting for fov scale to the flight camera --- .../unicopia/entity/player/PlayerCamera.java | 40 ++++++++++--------- .../mixin/client/MixinGameRenderer.java | 2 +- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java index 26c6d4c7..61effece 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerCamera.java @@ -7,6 +7,7 @@ import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell; import com.minelittlepony.unicopia.client.render.spell.DarkVortexSpellRenderer; +import net.minecraft.client.MinecraftClient; import net.minecraft.util.math.Vec3d; public class PlayerCamera extends MotionCompositor { @@ -18,30 +19,28 @@ public class PlayerCamera extends MotionCompositor { } public float calculateRoll() { + return player.getInterpolator().interpolate("roll", (float)applyModifiers(-getMotionRoll()), 15); + } - double roll = 0; + public float calculateFirstPersonRoll() { + return player.getInterpolator().interpolate("roll_fp", (float)applyModifiers(-getMotionRoll() * getFovScale() * 0.25F), 25); + } - if (player.getMotion().isFlying()) { - Vec3d vel = player.asEntity().getVelocity(); - - roll -= calculateRoll(player.asEntity(), vel.x, vel.y, vel.z); - } - - if (player.getPhysics().isGravityNegative()) { - roll *= -1; - roll += 180; - } - - if (player.asEntity().age > 10) { - roll = player.getInterpolator().interpolate("roll", (float)roll, 15); + private double getMotionRoll() { + if (!player.getMotion().isFlying() || player.asEntity().hasVehicle() || player.asEntity().isOnGround()) { + return 0; } + Vec3d vel = player.asEntity().getVelocity(); + return calculateRoll(player.asEntity(), vel.x, vel.y, vel.z); + } + private double applyModifiers(double motionRoll) { if (player.getAcrobatics().isFloppy()) { - roll += 90; + motionRoll += 90; } - return (float)roll; + return player.getPhysics().isGravityNegative() ? 180 - motionRoll : motionRoll; } public float calculatePitch(float pitch) { @@ -61,13 +60,16 @@ public class PlayerCamera extends MotionCompositor { } public double calculateFieldOfView(double fov) { - fov += player.getMagicalReserves().getExertion().get() / 5F; - fov += getEnergyAddition(); + fov += (player.getMagicalReserves().getExertion().get() / 5F) * getFovScale(); + fov += getEnergyAddition() * getFovScale(); fov += DarkVortexSpellRenderer.getCameraDistortion() * 2.5F; - return fov; } + private float getFovScale() { + return MinecraftClient.getInstance().options.getFovEffectScale().getValue().floatValue(); + } + protected float getEnergyAddition() { int maxE = (int)Math.floor(player.getMagicalReserves().getEnergy().get() * 100); diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinGameRenderer.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinGameRenderer.java index d71373fb..2fe4abe2 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinGameRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinGameRenderer.java @@ -36,7 +36,7 @@ abstract class MixinGameRenderer implements AutoCloseable, SynchronousResourceRe @Inject(method = "renderWorld(FJLnet/minecraft/client/util/math/MatrixStack;)V", at = @At("HEAD")) private void beforeRenderWorld(float tickDelta, long limitTime, MatrixStack matrices, CallbackInfo info) { - UnicopiaClient.getCamera().ifPresent(c -> matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(c.calculateRoll()))); + UnicopiaClient.getCamera().ifPresent(c -> matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(c.calculateFirstPersonRoll()))); BatEyesApplicator.INSTANCE.enable(); } From 2dd7fbbb5530961f5bd25f2df72bfab81d3639bf Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 26 Mar 2024 00:04:00 +0000 Subject: [PATCH 27/73] Fix a whole bunch of gravity related issues --- .../unicopia/client/UnicopiaClient.java | 18 +++++ .../unicopia/entity/EntityPhysics.java | 10 +++ .../unicopia/entity/duck/RotatedView.java | 3 +- .../unicopia/entity/player/PlayerPhysics.java | 17 ----- .../unicopia/mixin/MixinLivingEntity.java | 10 --- .../unicopia/mixin/MixinMobEntity.java | 13 ---- .../unicopia/mixin/MixinPlayerEntity.java | 8 -- .../unicopia/mixin/MixinWorld.java | 30 -------- .../mixin/client/MixinKeyboardInput.java | 4 +- .../mixin/{ => gravity}/MixinBrain.java | 4 +- .../mixin/gravity/MixinClientWorld.java | 30 ++++++++ .../unicopia/mixin/gravity/MixinEntity.java | 76 +++++++++++++++++++ .../mixin/gravity/MixinLivingEntity.java | 22 ++++++ .../mixin/gravity/MixinMobEntity.java | 28 +++++++ .../mixin/gravity/MixinServerWorld.java | 29 +++++++ .../mixin/gravity/MixinSoundSource.java | 17 +++++ .../unicopia/mixin/gravity/MixinWorld.java | 43 +++++++++++ .../mixin/{ => gravity}/MixinWorldChunk.java | 2 +- src/main/resources/unicopia.mixin.json | 13 +++- 19 files changed, 290 insertions(+), 87 deletions(-) rename src/main/java/com/minelittlepony/unicopia/mixin/{ => gravity}/MixinBrain.java (87%) create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinClientWorld.java create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinEntity.java create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinLivingEntity.java create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinMobEntity.java create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinServerWorld.java create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinSoundSource.java create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinWorld.java rename src/main/java/com/minelittlepony/unicopia/mixin/{ => gravity}/MixinWorldChunk.java (96%) diff --git a/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java b/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java index e7face1d..c8d9bcff 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java +++ b/src/main/java/com/minelittlepony/unicopia/client/UnicopiaClient.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.client; import java.util.Optional; import org.jetbrains.annotations.Nullable; +import org.joml.Vector3f; import com.minelittlepony.common.client.gui.element.Button; import com.minelittlepony.common.event.ScreenInitCallback; @@ -33,11 +34,14 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.OpenToLanScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreens; +import net.minecraft.client.render.Camera; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.resource.ResourceType; import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; public class UnicopiaClient implements ClientModInitializer { @@ -66,6 +70,20 @@ public class UnicopiaClient implements ClientModInitializer { return Optional.empty(); } + + public static Vec3d getAdjustedSoundPosition(Vec3d pos) { + PlayerCamera cam = getCamera().orElse(null); + if (cam == null) { + return pos; + } + Camera camera = MinecraftClient.getInstance().gameRenderer.getCamera(); + + Vector3f rotated = pos.subtract(camera.getPos()).toVector3f(); + rotated = rotated.rotateAxis(cam.calculateRoll() * MathHelper.RADIANS_PER_DEGREE, 0, 1, 0); + + return new Vec3d(rotated).add(camera.getPos()); + } + public static Race getPreferredRace() { if (!Unicopia.getConfig().ignoreMineLP.get() && MinecraftClient.getInstance().player != null) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java index 1529989b..538e7e4a 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java @@ -8,7 +8,9 @@ import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; import net.minecraft.block.FenceGateBlock; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityPose; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MovementType; import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.mob.MobEntity; import net.minecraft.nbt.NbtCompound; @@ -35,6 +37,14 @@ public class EntityPhysics implements Physics, Copyable entity.getWorld().getHeight() + 64) { entity.damage(entity.getDamageSources().outOfWorld(), 4.0F); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/duck/RotatedView.java b/src/main/java/com/minelittlepony/unicopia/entity/duck/RotatedView.java index e5c60d40..0bc5855b 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/duck/RotatedView.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/duck/RotatedView.java @@ -39,7 +39,8 @@ public interface RotatedView { if (!hasTransform() || rotations.isEmpty()) { return y; } - return y - ((y - rotations.peek()) * 2); + + return (rotations.peek() * 2) - y; } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index 35116ead..f6c82b63 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -32,7 +32,6 @@ import com.minelittlepony.unicopia.util.*; import net.fabricmc.fabric.api.tag.convention.v1.ConventionalBlockTags; import net.minecraft.block.*; import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityType; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LightningEntity; @@ -253,18 +252,6 @@ public class PlayerPhysics extends EntityPhysics implements Tickab final MutableVector velocity = new MutableVector(entity.getVelocity()); - if (isGravityNegative()) { - velocity.y *= -1; - } - - if (isGravityNegative() && !entity.isSneaking() && entity.isInSneakingPose()) { - float currentHeight = entity.getDimensions(entity.getPose()).height; - float sneakingHeight = entity.getDimensions(EntityPose.STANDING).height; - - entity.setPos(entity.getX(), entity.getY() + currentHeight - sneakingHeight, entity.getZ()); - entity.setPose(EntityPose.STANDING); - } - FlightType type = recalculateFlightType(); boolean typeChanged = type != lastFlightType; @@ -396,10 +383,6 @@ public class PlayerPhysics extends EntityPhysics implements Tickab velocity.z /= heavyness; } - if (isGravityNegative()) { - velocity.y *= -1; - } - entity.setVelocity(velocity.toImmutable()); if (isFlying() && !entity.isFallFlying() && !pony.getAcrobatics().isHanging() && pony.isClient()) { diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java index f71ef863..b1e811b0 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java @@ -5,9 +5,7 @@ import java.util.Optional; import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Constant; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyConstant; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -178,14 +176,6 @@ abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equ } } - @ModifyConstant(method = "travel(Lnet/minecraft/util/math/Vec3d;)V", constant = { - @Constant(doubleValue = 0.08D), - @Constant(doubleValue = 0.01D) - }) - private double modifyGravity(double initial) { - return get().getPhysics().calcGravity(initial); - } - @Override public void updateItemUsage(Hand hand, ItemStack stack, int time) { activeItemStack = stack; diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java index d836f0fc..d9200a75 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java @@ -9,7 +9,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.minelittlepony.unicopia.entity.*; -import com.minelittlepony.unicopia.entity.duck.RotatedView; import com.minelittlepony.unicopia.item.enchantment.WantItNeedItEnchantment; import net.minecraft.entity.EntityType; @@ -33,18 +32,6 @@ abstract class MixinMobEntity extends LivingEntity implements Equine.Container info) { diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java index d61ad769..b67432fc 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPlayerEntity.java @@ -97,14 +97,6 @@ abstract class MixinPlayerEntity extends LivingEntity implements Equine.Containe get().getMotion().getDimensions().calculateActiveEyeHeight(dimensions).ifPresent(info::setReturnValue); } - /* - @Inject(method = "getDimensions(Lnet/minecraft/entity/EntityPose;)Lnet/minecraft/entity/EntityDimensions;", - at = @At("RETURN"), - cancellable = true) - private void onGetDimensions(EntityPose pose, CallbackInfoReturnable info) { - get().getMotion().getDimensions().calculateDimensions().ifPresent(info::setReturnValue); - }*/ - @Redirect(method = "getDimensions(Lnet/minecraft/entity/EntityPose;)Lnet/minecraft/entity/EntityDimensions;", at = @At( value = "INVOKE", diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java index 04db071b..99ca9150 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java @@ -1,19 +1,13 @@ package com.minelittlepony.unicopia.mixin; -import java.util.Stack; import java.util.function.Supplier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - import com.minelittlepony.unicopia.entity.duck.RotatedView; import com.minelittlepony.unicopia.server.world.BlockDestructionManager; -import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.WorldAccess; @@ -22,20 +16,8 @@ abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source private final Supplier destructions = BlockDestructionManager.create((World)(Object)this); - private int recurseCount = 0; - private final Stack rotations = new Stack<>(); private boolean mirrorEntityStatuses; - @Override - public Stack getRotations() { - return rotations; - } - - @Override - public boolean hasTransform() { - return recurseCount <= 0; - } - @Override public void setMirrorEntityStatuses(boolean enable) { mirrorEntityStatuses = enable; @@ -52,17 +34,5 @@ abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source entity.handleStatus(status); } } - - @ModifyVariable(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("HEAD")) - private BlockPos modifyBlockPos(BlockPos pos) { - pos = applyRotation(pos); - recurseCount = Math.max(0, recurseCount) + 1; - return pos; - } - - @Inject(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("RETURN")) - public void onSetBlockState(BlockPos pos, BlockState state, int flags, int maxUpdateDepth, CallbackInfoReturnable info) { - recurseCount = Math.max(0, recurseCount - 1); - } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java index 7bc83f17..55c8a70b 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java @@ -28,11 +28,11 @@ abstract class MixinKeyboardInput extends Input { movementSideways = -movementSideways; - if (player.asEntity().getAbilities().flying && !player.getPhysics().isFlying()) { + /*if (player.asEntity().getAbilities().flying && !player.getPhysics().isFlying()) { tmp = jumping; jumping = sneaking; sneaking = tmp; - } + }*/ } if (EffectUtils.getAmplifier(MinecraftClient.getInstance().player, UEffects.PARALYSIS) > 1) { diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinBrain.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinBrain.java similarity index 87% rename from src/main/java/com/minelittlepony/unicopia/mixin/MixinBrain.java rename to src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinBrain.java index 7a7a7737..4e794c6a 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinBrain.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinBrain.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.mixin; +package com.minelittlepony.unicopia.mixin.gravity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -21,7 +21,7 @@ abstract class MixinBrain { Equine eq = Equine.of(entity).orElse(null); if (eq instanceof Living && eq.getPhysics().isGravityNegative()) { - ((RotatedView)world).pushRotation((int)entity.getY()); + ((RotatedView)world).pushRotation((int)(entity.getY() + entity.getHeight() * 0.5F)); } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinClientWorld.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinClientWorld.java new file mode 100644 index 00000000..98701eec --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinClientWorld.java @@ -0,0 +1,30 @@ +package com.minelittlepony.unicopia.mixin.gravity; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.minelittlepony.unicopia.entity.Equine; +import com.minelittlepony.unicopia.entity.duck.RotatedView; + +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; + +@Mixin(ClientWorld.class) +abstract class MixinClientWorld implements RotatedView { + + @Inject(method = "tickEntity", at = @At("HEAD")) + private void beforeTickEntity(Entity entity, CallbackInfo info) { + if (entity instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + // pushRotation((int)(entity.getY() + entity.getHeight() * 0.5F)); + } + } + + @Inject(method = "tickEntity", at = @At("RETURN")) + private void afterTickEntity(Entity entity, CallbackInfo info) { + if (entity instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + // popRotation(); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinEntity.java new file mode 100644 index 00000000..c0725d94 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinEntity.java @@ -0,0 +1,76 @@ +package com.minelittlepony.unicopia.mixin.gravity; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.minelittlepony.unicopia.entity.Equine; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.MovementType; +import net.minecraft.util.math.Vec3d; + +@Mixin(value = Entity.class, priority = 29000) +abstract class MixinEntity { + + // we invert y when moving + @ModifyVariable(method = "move", at = @At("HEAD"), argsOnly = true) + private Vec3d modifyMovement(Vec3d movement) { + if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + return movement.multiply(1, -1, 1); + } + return movement; + } + + // fix on ground check + @Inject(method = "move", at = @At(value = "FIELD", target = "net/minecraft/entity/Entity.groundCollision:Z", shift = Shift.AFTER, ordinal = 0)) + private void onUpdateOnGroundFlag(MovementType movementType, Vec3d movement, CallbackInfo info) { + if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + eq.get().asEntity().groundCollision = eq.get().asEntity().verticalCollision && movement.y > 0.0; + } + } + + // invert jumping velocity so we can jump + @Inject(method = "getJumpVelocityMultiplier", at = @At("RETURN"), cancellable = true) + private void onGetJumpVelocityMultiplier(CallbackInfoReturnable info) { + if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + info.setReturnValue(-info.getReturnValue()); + } + } + + // invert offsets so it can properly find the block we're walking on + @ModifyVariable(method = "getPosWithYOffset", at = @At("HEAD"), argsOnly = true) + private float onGetPosWithYOffset(float offset) { + if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + return -(eq.get().asEntity().getHeight() + offset); + } + return offset; + } + + // fix sprinting particles + @Inject(method = "spawnSprintingParticles", at = @At("HEAD"), cancellable = true) + protected void spawnSprintingParticles(CallbackInfo info) { + if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + eq.get().getPhysics().spawnSprintingParticles(); + info.cancel(); + } + } + + // invert check for walking up a step + @ModifyVariable( + method = "adjustMovementForCollisions(Lnet/minecraft/entity/Entity;Lnet/minecraft/util/math/Vec3d;Lnet/minecraft/util/math/Box;Lnet/minecraft/world/World;Ljava/util/List;)Lnet/minecraft/util/math/Vec3d;", + at = @At("HEAD"), + argsOnly = true) + + private static Vec3d modifyMovementForStepheight(Vec3d movement, @Nullable Entity entity) { + if (entity != null && movement.getY() == entity.getStepHeight()) { + return movement.multiply(1, -1, 1); + } + return movement; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinLivingEntity.java new file mode 100644 index 00000000..2d9dfe6c --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinLivingEntity.java @@ -0,0 +1,22 @@ +package com.minelittlepony.unicopia.mixin.gravity; + +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; +import com.minelittlepony.unicopia.entity.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; + +@Mixin(LivingEntity.class) +abstract class MixinLivingEntity extends Entity implements Equine.Container> { + + private MixinLivingEntity() { super(null, null); } + + @ModifyConstant(method = "travel(Lnet/minecraft/util/math/Vec3d;)V", constant = { + @Constant(doubleValue = 0.08D), + @Constant(doubleValue = 0.01D) + }) + private double modifyGravity(double initial) { + return Math.abs(get().getPhysics().calcGravity(initial)); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinMobEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinMobEntity.java new file mode 100644 index 00000000..e72ec42a --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinMobEntity.java @@ -0,0 +1,28 @@ +package com.minelittlepony.unicopia.mixin.gravity; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import com.minelittlepony.unicopia.entity.*; +import com.minelittlepony.unicopia.entity.duck.RotatedView; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.mob.MobEntity; + +@Mixin(MobEntity.class) +abstract class MixinMobEntity extends LivingEntity implements Equine.Container { + private MixinMobEntity() { super(null, null); } + + @Inject(method = "tickNewAi", at = @At("HEAD")) + public void beforeTickAi(CallbackInfo into) { + if (get().getPhysics().isGravityNegative()) { + ((RotatedView)getWorld()).pushRotation((int)(getY() + getHeight() * 0.5F)); + } + } + + @Inject(method = "tickNewAi", at = @At("RETURN")) + public void afterTickAi(CallbackInfo into) { + ((RotatedView)getWorld()).popRotation(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinServerWorld.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinServerWorld.java new file mode 100644 index 00000000..d43d1570 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinServerWorld.java @@ -0,0 +1,29 @@ +package com.minelittlepony.unicopia.mixin.gravity; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.minelittlepony.unicopia.entity.Equine; +import com.minelittlepony.unicopia.entity.duck.RotatedView; +import net.minecraft.entity.Entity; +import net.minecraft.server.world.ServerWorld; + +@Mixin(ServerWorld.class) +abstract class MixinServerWorld implements RotatedView { + + @Inject(method = "tickEntity", at = @At("HEAD")) + private void beforeTickEntity(Entity entity, CallbackInfo info) { + if (entity instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + // pushRotation((int)(entity.getY() + entity.getHeight() * 0.5F)); + } + } + + @Inject(method = "tickEntity", at = @At("RETURN")) + private void afterTickEntity(Entity entity, CallbackInfo info) { + if (entity instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + // popRotation(); + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinSoundSource.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinSoundSource.java new file mode 100644 index 00000000..7ffbad9f --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinSoundSource.java @@ -0,0 +1,17 @@ +package com.minelittlepony.unicopia.mixin.gravity; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import com.minelittlepony.unicopia.client.UnicopiaClient; +import net.minecraft.client.sound.Source; +import net.minecraft.util.math.Vec3d; + +@Mixin(Source.class) +abstract class MixinSoundSource { + @ModifyVariable(method = "setPosition", at = @At("HEAD"), argsOnly = true) + private Vec3d modifyPosition(Vec3d pos) { + return UnicopiaClient.getAdjustedSoundPosition(pos); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinWorld.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinWorld.java new file mode 100644 index 00000000..71428388 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinWorld.java @@ -0,0 +1,43 @@ +package com.minelittlepony.unicopia.mixin.gravity; + +import java.util.Stack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.minelittlepony.unicopia.entity.duck.RotatedView; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; + +@Mixin(World.class) +abstract class MixinWorld implements WorldAccess, RotatedView { + + private int recurseCount = 0; + private final Stack rotations = new Stack<>(); + + @Override + public Stack getRotations() { + return rotations; + } + + @Override + public boolean hasTransform() { + return recurseCount <= 0; + } + + @ModifyVariable(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("HEAD")) + private BlockPos modifyBlockPos(BlockPos pos) { + pos = applyRotation(pos); + recurseCount = Math.max(0, recurseCount) + 1; + return pos; + } + + @Inject(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("RETURN")) + public void onSetBlockState(BlockPos pos, BlockState state, int flags, int maxUpdateDepth, CallbackInfoReturnable info) { + recurseCount = Math.max(0, recurseCount - 1); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinWorldChunk.java similarity index 96% rename from src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java rename to src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinWorldChunk.java index 97f137d8..4a3c2ced 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinWorldChunk.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.mixin; +package com.minelittlepony.unicopia.mixin.gravity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index d59bf63e..0d34a3bf 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -13,7 +13,6 @@ "MixinBlockEntityType", "MixinBlockItem", "MixinBoatEntity", - "MixinBrain", "MixinChunkBlockLightProvider", "MutableBlockLightStorage", "MixinDamageSource", @@ -53,8 +52,14 @@ "MixinVanillaBiomeParameters", "MixinWardenEntity", "MixinWorld", - "MixinWorldChunk", "PointOfInterestTypesAccessor", + "gravity.MixinBrain", + "gravity.MixinEntity", + "gravity.MixinLivingEntity", + "gravity.MixinMobEntity", + "gravity.MixinWorld", + "gravity.MixinServerWorld", + "gravity.MixinWorldChunk", "trinkets.MixinTrinketSurvivalSlot", "trinkets.MixinTrinketItem", "trinkets.MixinTrinketInventory", @@ -88,7 +93,9 @@ "client.MixinWorldRenderer", "client.sodium.MixinSodiumWorldRenderer", "client.minelp.MixinPonyPosture", - "trinkets.MixinTrinketCreativeSlot" + "trinkets.MixinTrinketCreativeSlot", + "gravity.MixinClientWorld", + "gravity.MixinSoundSource" ], "injectors": { "defaultRequire": 1 From b4a847e4b58407466c3306e2c73991a538999aa4 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 26 Mar 2024 17:09:36 +0000 Subject: [PATCH 28/73] Update loom --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../unicopia/client/render/shader/ViewportShader.java | 3 +-- .../com/minelittlepony/unicopia/item/EnchantedStaffItem.java | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 51a392c2..285777fc 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { } plugins { id 'java-library' - id 'fabric-loom' version '0.12-SNAPSHOT' + id 'fabric-loom' version '1.5-SNAPSHOT' id 'com.modrinth.minotaur' version '2.+' id 'org.ajoberstar.reckon' version '0.13.0' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e750102e..db9a6b82 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/shader/ViewportShader.java b/src/main/java/com/minelittlepony/unicopia/client/render/shader/ViewportShader.java index ebef6c6a..21df38bc 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/shader/ViewportShader.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/shader/ViewportShader.java @@ -2,8 +2,7 @@ package com.minelittlepony.unicopia.client.render.shader; import java.io.IOException; -import javax.annotation.Nullable; - +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import com.google.common.collect.*; diff --git a/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java b/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java index b37d4cab..08798972 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/EnchantedStaffItem.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Stream; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.ability.magic.Caster; From 692db5a0707c3731aaddf1af5daa0996f3a6084c Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 26 Mar 2024 17:11:39 +0000 Subject: [PATCH 29/73] Fix fall damage, ladders, hitbox calculations, clipping, camera offset, and unicorn's teleportation when in inverted gravity --- .../ability/UnicornTeleportAbility.java | 13 ++-- .../client/render/WorldRenderDelegate.java | 36 ++++----- .../unicopia/command/GravityCommand.java | 75 ++++++++++--------- .../unicopia/entity/EntityPhysics.java | 35 +-------- .../unicopia/entity/Living.java | 6 -- .../unicopia/entity/Physics.java | 2 - .../entity/player/PlayerDimensions.java | 6 +- .../unicopia/entity/player/PlayerPhysics.java | 4 - .../unicopia/entity/player/Pony.java | 5 +- .../unicopia/mixin/MixinLivingEntity.java | 22 ------ .../mixin/client/MixinKeyboardInput.java | 6 -- .../unicopia/mixin/gravity/MixinEntity.java | 72 ++++++++++++++---- .../mixin/gravity/MixinLivingEntity.java | 23 ++++++ .../MixinServerPlayNetworkHandler.java | 29 +++++++ .../gravity/MixinServerPlayerEntity.java | 24 ++++++ .../resources/assets/unicopia/lang/en_us.json | 1 + src/main/resources/unicopia.mixin.json | 2 + 17 files changed, 203 insertions(+), 158 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinServerPlayNetworkHandler.java create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinServerPlayerEntity.java diff --git a/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java index 3401632f..7f75d688 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/UnicornTeleportAbility.java @@ -27,6 +27,7 @@ import net.minecraft.sound.SoundCategory; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.World; @@ -89,8 +90,10 @@ public class UnicornTeleportAbility implements Ability { return trace.getBlockOrEntityPos().map(pos -> { final BlockPos originalPos = pos; + Direction globalUp = player.getPhysics().isGravityNegative() ? Direction.DOWN : Direction.UP; + boolean originalPosHasSupport = exception(w, pos, player.asEntity()); - boolean originalPosValid = enterable(w, pos.up()) && enterable(w, pos.up(2)); + boolean originalPosValid = enterable(w, pos.offset(globalUp)) && enterable(w, pos.offset(globalUp, 2)); if (w.getBlockState(pos).isOf(Blocks.POWDER_SNOW) && !PowderSnowBlock.canWalkOnPowderSnow(player.asEntity())) { return null; @@ -111,11 +114,11 @@ public class UnicornTeleportAbility implements Ability { if (pos.getX() != originalPos.getX() || pos.getZ() != originalPos.getZ()) { // check support int steps = 0; - while (enterable(w, pos.down())) { - pos = pos.down(); + while (enterable(w, pos.offset(globalUp.getOpposite()))) { + pos = pos.offset(globalUp.getOpposite()); if (++steps > 2) { if (originalPosValid) { - pos = originalPos.up(); + pos = originalPos.offset(globalUp); break; } else { return null; @@ -125,7 +128,7 @@ public class UnicornTeleportAbility implements Ability { } if ((!enterable(w, pos) && exception(w, pos, player.asEntity())) - || (!enterable(w, pos.up()) && exception(w, pos.up(), player.asEntity()))) { + || (!enterable(w, pos.offset(globalUp)) && exception(w, pos.offset(globalUp), player.asEntity()))) { return null; } diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java index ac9c3cdb..17594ba0 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java @@ -175,43 +175,39 @@ public class WorldRenderDelegate { boolean negative = pony.getPhysics().isGravityNegative(); - float roll = negative ? 180 : 0; - - roll = pony instanceof Pony ? ((Pony)pony).getInterpolator().interpolate("g_roll", roll, 15) : roll; - matrices.translate(x, y + owner.getHeight() / 2, z); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(roll)); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(roll)); - if (pony instanceof Pony p) { - roll = p.getCamera().calculateRoll(); - if (negative) { - roll -= 180; - } + float sidewaysRoll = p.getCamera().calculateRoll(); if (p.getAcrobatics().isFloppy()) { matrices.translate(0, -0.5, 0); p.asEntity().setBodyYaw(0); p.asEntity().setYaw(0); - matrices.multiply(RotationAxis.NEGATIVE_X.rotationDegrees(90)); + sidewaysRoll += 90; } - matrices.multiply(RotationAxis.NEGATIVE_Y.rotationDegrees(yaw)); - matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(roll)); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(90)); + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(sidewaysRoll)); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-90)); - float diveAngle = p.getInterpolator().interpolate("g_kdive", p.getMotion().isDiving() ? 80 : 0, 15); + float forwardPitch = p.getInterpolator().interpolate("g_kdive", p.getMotion().isDiving() ? 80 : 0, 15); - matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(diveAngle)); - matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(yaw)); + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(forwardPitch)); if (p.getCompositeRace().includes(Race.SEAPONY) && pony.asEntity().isSubmergedInWater() && MineLPDelegate.getInstance().getPlayerPonyRace(p.asEntity()) != Race.SEAPONY) { ModelPartHooks.startCollecting(); } - } else if (pony instanceof Creature creature && smittenEyesRenderer.isSmitten(creature)) { - ModelPartHooks.startCollecting(); + } else { + float roll = negative ? 180 : 0; + + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(roll)); + + if (pony instanceof Creature creature && smittenEyesRenderer.isSmitten(creature)) { + ModelPartHooks.startCollecting(); + } } matrices.translate(-x, -y - owner.getHeight() / 2, -z); @@ -224,7 +220,7 @@ public class WorldRenderDelegate { } private void flipAngles(Entity entity) { - if (entity instanceof PlayerEntity) { + if (entity instanceof PlayerEntity player) { entity.prevYaw *= -1; entity.setYaw(entity.getYaw() * -1); diff --git a/src/main/java/com/minelittlepony/unicopia/command/GravityCommand.java b/src/main/java/com/minelittlepony/unicopia/command/GravityCommand.java index c99aa75b..c5249dcb 100644 --- a/src/main/java/com/minelittlepony/unicopia/command/GravityCommand.java +++ b/src/main/java/com/minelittlepony/unicopia/command/GravityCommand.java @@ -1,15 +1,15 @@ package com.minelittlepony.unicopia.command; -import java.util.Arrays; -import java.util.stream.Stream; - -import com.google.common.collect.Streams; -import com.minelittlepony.unicopia.entity.player.Pony; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import com.minelittlepony.unicopia.entity.Living; import com.mojang.brigadier.arguments.FloatArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.command.argument.EntityArgumentType; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; @@ -22,45 +22,48 @@ class GravityCommand { return CommandManager.literal("gravity").requires(s -> s.hasPermissionLevel(2)) .then(CommandManager.literal("get") .executes(context -> get(context.getSource(), context.getSource().getPlayer(), true)) - .then(CommandManager.argument("target", EntityArgumentType.player()) - .executes(context -> get(context.getSource(), EntityArgumentType.getPlayer(context, "target"), false)) + .then(CommandManager.argument("target", EntityArgumentType.entity()) + .executes(context -> get(context.getSource(), EntityArgumentType.getEntity(context, "target"), false)) )) .then(CommandManager.literal("set") .then(CommandManager.argument("gravity", FloatArgumentType.floatArg(-99, 99)) - .executes(context -> set(context.getSource(), context.getSource().getPlayer(), FloatArgumentType.getFloat(context, "gravity"), true)) - .then(CommandManager.argument("target", EntityArgumentType.player()) - .executes(context -> set(context.getSource(), EntityArgumentType.getPlayer(context, "target"), FloatArgumentType.getFloat(context, "gravity"), false)) + .executes(context -> set(context.getSource(), List.of(context.getSource().getPlayer()), FloatArgumentType.getFloat(context, "gravity"), true)) + .then(CommandManager.argument("target", EntityArgumentType.entities()) + .executes(context -> set(context.getSource(), EntityArgumentType.getEntities(context, "target"), FloatArgumentType.getFloat(context, "gravity"), false)) ))); } - static int get(ServerCommandSource source, PlayerEntity player, boolean isSelf) throws CommandSyntaxException { - sendFeedback(source, player, "get", false, Pony.of(player).getPhysics().getGravityModifier()); - return 0; - } + static int get(ServerCommandSource source, Entity target, boolean isSelf) throws CommandSyntaxException { + Living l = Living.living(target); - static int set(ServerCommandSource source, PlayerEntity player, float gravity, boolean isSelf) { - - Pony iplayer = Pony.of(player); - - iplayer.getPhysics().setBaseGravityModifier(gravity); - iplayer.setDirty(); - - sendFeedback(source, player, "set", true, gravity); - return 0; - } - - - static void sendFeedback(ServerCommandSource source, PlayerEntity player, String key, boolean notifyTarget, Object...arguments) { - String translationKey = "commands.gravity." + key; - - if (source.getEntity() == player) { - source.sendFeedback(() -> Text.translatable(translationKey + ".self", arguments), true); + float gravity = l == null ? 1 : l.getPhysics().getGravityModifier(); + if (source.getEntity() == target) { + source.sendFeedback(() -> Text.translatable("commands.gravity.get.self", gravity), true); } else { - if (notifyTarget && source.getWorld().getGameRules().getBoolean(GameRules.SEND_COMMAND_FEEDBACK)) { - player.sendMessage(Text.translatable(translationKey, arguments)); - } - - source.sendFeedback(() -> Text.translatable(translationKey + ".other", Streams.concat(Stream.of(player.getDisplayName()), Arrays.stream(arguments)).toArray()), true); + source.sendFeedback(() -> Text.translatable("commands.gravity.get.other", target.getDisplayName(), gravity), true); } + return 0; + } + + static int set(ServerCommandSource source, Collection targets, float gravity, boolean isSelf) { + List affected = targets.stream().map(Living::living).filter(Objects::nonNull).map(l -> { + l.getPhysics().setBaseGravityModifier(gravity); + l.setDirty(); + if (l.asEntity() instanceof PlayerEntity player) { + if (source.getEntity() == player) { + player.sendMessage(Text.translatable("commands.gravity.set.self", gravity)); + } else if (source.getWorld().getGameRules().getBoolean(GameRules.SEND_COMMAND_FEEDBACK)) { + player.sendMessage(Text.translatable("commands.gravity.set.other", l.asEntity().getDisplayName(), gravity)); + } + } + return (Entity)l.asEntity(); + }).toList(); + + if (affected.size() == 1) { + source.sendFeedback(() -> Text.translatable("commands.gravity.set.other", affected.get(0).getDisplayName()), true); + } else { + source.sendFeedback(() -> Text.translatable("commands.gravity.set.multiple", affected.size()), true); + } + return 0; } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java index 538e7e4a..749ee3cf 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/EntityPhysics.java @@ -4,18 +4,13 @@ import com.minelittlepony.unicopia.entity.mob.UEntityAttributes; import com.minelittlepony.unicopia.util.Copyable; import com.minelittlepony.unicopia.util.Tickable; -import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; import net.minecraft.block.FenceGateBlock; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityPose; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.MovementType; import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.mob.MobEntity; import net.minecraft.nbt.NbtCompound; -import net.minecraft.particle.BlockStateParticleEffect; -import net.minecraft.particle.ParticleTypes; import net.minecraft.registry.tag.BlockTags; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; @@ -37,22 +32,12 @@ public class EntityPhysics implements Physics, Copyable entity.getWorld().getHeight() + 64) { entity.damage(entity.getDamageSources().outOfWorld(), 4.0F); } - - entity.setOnGround(entity.verticalCollision && entity.getVelocity().getY() > 0); } - float gravity = this.getGravityModifier(); + float gravity = getGravityModifier(); if (gravity != lastGravity) { lastGravity = gravity; @@ -87,8 +72,6 @@ public class EntityPhysics implements Physics, Copyable implements Physics, Copyable implements Equine, Caste return false; } - public void onJump() { - if (getPhysics().isGravityNegative()) { - entity.setVelocity(entity.getVelocity().multiply(1, -1, 1)); - } - } - @Nullable public final Caster getAttacker() { return attacker; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Physics.java b/src/main/java/com/minelittlepony/unicopia/entity/Physics.java index c7aff817..bbc2d1ce 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Physics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Physics.java @@ -21,8 +21,6 @@ public interface Physics extends NbtSerialisable { BlockPos getHeadPosition(); - void spawnSprintingParticles(); - default boolean isGravityNegative() { return getGravityModifier() < 0; } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerDimensions.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerDimensions.java index 70eee553..a2e5a329 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerDimensions.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerDimensions.java @@ -25,11 +25,7 @@ public final class PlayerDimensions { .or(() -> physics.isFlyingSurvival ? FLYING_EYE_HEIGHT : physics.isGravityNegative() ? Optional.of(dimensions.height) : Optional.empty()) .map(h -> { if (physics.isGravityNegative()) { - if (pony.asEntity().isSneaking()) { - h += 0.2F; - } - - return dimensions.height - h; + return dimensions.height - h + 0.1F; } return h; }); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index f6c82b63..8ac41371 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -301,10 +301,6 @@ public class PlayerPhysics extends EntityPhysics implements Tickab if (entity.isOnGround() || (!creative && entity.horizontalCollision)) { cancelFlight(false); } - - if (entity.isClimbing() && (entity.horizontalCollision || ((LivingEntityDuck)entity).isJumping())) { - velocity.y = -0.2F; - } } isFlyingSurvival = entity.getAbilities().flying && !creative; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index 3cb7f3cf..0c78666f 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -631,7 +631,7 @@ public class Pony extends Living implements Copyable, Update float max = 0.6F; return Optional.of(new Vec3d( MathHelper.clamp(speed.x * factor, -max, max), - speed.y * ((speed.y * getPhysics().getGravitySignum()) > 0 ? 1.2 : 1.101), + speed.y * (speed.y > 0 ? 1.2 : 1.101), MathHelper.clamp(speed.z * factor, -max, max) )); } @@ -715,11 +715,8 @@ public class Pony extends Living implements Copyable, Update } public Optional onImpact(float distance, float damageMultiplier, DamageSource cause) { - float originalDistance = distance; - distance *= gravity.getGravityModifier(); - boolean extraProtection = getSpellSlot().get(SpellType.SHIELD, false).isPresent(); if (!entity.isCreative() && !entity.isSpectator()) { diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java index b1e811b0..7d41f099 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinLivingEntity.java @@ -128,11 +128,6 @@ abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equ get().adjustMovementSpeedInWater(info.getReturnValue()).ifPresent(info::setReturnValue); } - @Inject(method = "jump()V", at = @At("RETURN")) - private void onJump(CallbackInfo info) { - get().onJump(); - } - @Inject(method = "tick()V", at = @At("HEAD"), cancellable = true) private void beforeTick(CallbackInfo info) { if (get().beforeUpdate()) { @@ -186,21 +181,4 @@ abstract class MixinLivingEntity extends Entity implements LivingEntityDuck, Equ setLivingFlag(2, hand == Hand.OFF_HAND); } } - - @Override - public BlockPos getBlockPos() { - if (get().getPhysics().isGravityNegative()) { - return get().getPhysics().getHeadPosition(); - } - return super.getBlockPos(); - } - - @Override - protected void spawnSprintingParticles() { - if (get().getPhysics().isGravityNegative()) { - get().getPhysics().spawnSprintingParticles(); - } else { - super.spawnSprintingParticles(); - } - } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java index 55c8a70b..6b4240d3 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/client/MixinKeyboardInput.java @@ -27,12 +27,6 @@ abstract class MixinKeyboardInput extends Input { pressingRight = tmp; movementSideways = -movementSideways; - - /*if (player.asEntity().getAbilities().flying && !player.getPhysics().isFlying()) { - tmp = jumping; - jumping = sneaking; - sneaking = tmp; - }*/ } if (EffectUtils.getAmplifier(MinecraftClient.getInstance().player, UEffects.PARALYSIS) > 1) { diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinEntity.java index c0725d94..fe2eef70 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinEntity.java @@ -5,6 +5,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At.Shift; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -12,7 +13,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.minelittlepony.unicopia.entity.Equine; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityPose; import net.minecraft.entity.MovementType; +import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; @Mixin(value = Entity.class, priority = 29000) @@ -21,7 +24,7 @@ abstract class MixinEntity { // we invert y when moving @ModifyVariable(method = "move", at = @At("HEAD"), argsOnly = true) private Vec3d modifyMovement(Vec3d movement) { - if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + if (unicopiaIsGravityInverted()) { return movement.multiply(1, -1, 1); } return movement; @@ -35,14 +38,6 @@ abstract class MixinEntity { } } - // invert jumping velocity so we can jump - @Inject(method = "getJumpVelocityMultiplier", at = @At("RETURN"), cancellable = true) - private void onGetJumpVelocityMultiplier(CallbackInfoReturnable info) { - if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { - info.setReturnValue(-info.getReturnValue()); - } - } - // invert offsets so it can properly find the block we're walking on @ModifyVariable(method = "getPosWithYOffset", at = @At("HEAD"), argsOnly = true) private float onGetPosWithYOffset(float offset) { @@ -53,12 +48,27 @@ abstract class MixinEntity { } // fix sprinting particles - @Inject(method = "spawnSprintingParticles", at = @At("HEAD"), cancellable = true) - protected void spawnSprintingParticles(CallbackInfo info) { + @ModifyArg(method = "spawnSprintingParticles", + at = @At(value = "INVOKE", + target = "net/minecraft/world/World.addParticle(Lnet/minecraft/particle/ParticleEffect;DDDDDD)V"), + index = 2) + private double modifyParticleY(double y) { if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { - eq.get().getPhysics().spawnSprintingParticles(); - info.cancel(); + Entity self = eq.get().asEntity(); + return self.getHeight() - y + (self.getY() * 2); } + return y; + } + + // fix fall damage + @ModifyArg( + method = "move", + at = @At(value = "INVOKE", target = "net/minecraft/entity/Entity.fall(DZLnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)V")) + private double modifyFallDistance(double heightDifference) { + if (unicopiaIsGravityInverted()) { + return -heightDifference; + } + return heightDifference; } // invert check for walking up a step @@ -68,9 +78,43 @@ abstract class MixinEntity { argsOnly = true) private static Vec3d modifyMovementForStepheight(Vec3d movement, @Nullable Entity entity) { - if (entity != null && movement.getY() == entity.getStepHeight()) { + if (entity instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative() && movement.getY() == entity.getStepHeight()) { return movement.multiply(1, -1, 1); } return movement; } + + @Inject(method = {"calculateBoundsForPose"}, at = @At("RETURN"), cancellable = true) + private void adjustPoseBoxForGravity(EntityPose pos, CallbackInfoReturnable info) { + unicopiaReAnchorBoundingBox(info); + } + + @Inject(method = {"calculateBoundingBox"}, at = @At("RETURN"), cancellable = true) + private void adjustPoseBoxForGravity(CallbackInfoReturnable info) { + if (unicopiaReAnchorBoundingBox(info)) { + Entity self = (Entity)(Object)this; + self.setPos(self.getX(), info.getReturnValue().minY, self.getZ()); + } + } + + private boolean unicopiaReAnchorBoundingBox(CallbackInfoReturnable info) { + if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + Entity self = eq.get().asEntity(); + Box box = info.getReturnValue(); + Box oldBox = self.getBoundingBox(); + double newHeight = box.getYLength(); + if (newHeight > oldBox.getYLength()) { + double targetMaxY = oldBox.maxY; + Vec3d min = new Vec3d(box.minX, targetMaxY - newHeight, box.minZ); + Vec3d max = new Vec3d(box.maxX, targetMaxY, box.maxZ); + info.setReturnValue(new Box(min, max)); + return true; + } + } + return false; + } + + private boolean unicopiaIsGravityInverted() { + return this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative(); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinLivingEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinLivingEntity.java index 2d9dfe6c..368eb0d8 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinLivingEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinLivingEntity.java @@ -1,11 +1,15 @@ package com.minelittlepony.unicopia.mixin.gravity; import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.ModifyConstant; import com.minelittlepony.unicopia.entity.*; + import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; +import net.minecraft.util.math.BlockPos; @Mixin(LivingEntity.class) abstract class MixinLivingEntity extends Entity implements Equine.Container> { @@ -19,4 +23,23 @@ abstract class MixinLivingEntity extends Entity implements Equine.Container Date: Tue, 26 Mar 2024 19:05:57 +0000 Subject: [PATCH 30/73] Fix quilt crash --- src/main/java/com/minelittlepony/unicopia/block/UBlocks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java index 32e48568..c5779abd 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java +++ b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java @@ -330,7 +330,7 @@ public interface UBlocks { FlammableBlockRegistry.getDefaultInstance().add(BANANAS, 5, 20); FlammableBlockRegistry.getDefaultInstance().add(CURING_JOKE, 60, 100); - CompostingChanceRegistry.INSTANCE.add(WORM_BLOCK, 8F); + CompostingChanceRegistry.INSTANCE.add(WORM_BLOCK, 1F); UBlockEntities.bootstrap(); EdibleBlock.bootstrap(); From 4a630dfcf911afeffeea1864102ebb6edccee9a7 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 26 Mar 2024 20:21:12 +0000 Subject: [PATCH 31/73] Fix slime blocks in the upside down --- .../mixin/gravity/MixinPistonBlockEntity.java | 46 +++++++++++++++++++ src/main/resources/unicopia.mixin.json | 1 + 2 files changed, 47 insertions(+) create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinPistonBlockEntity.java diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinPistonBlockEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinPistonBlockEntity.java new file mode 100644 index 00000000..279047c7 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinPistonBlockEntity.java @@ -0,0 +1,46 @@ +package com.minelittlepony.unicopia.mixin.gravity; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.block.entity.PistonBlockEntity; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +@Mixin(PistonBlockEntity.class) +abstract class MixinPistonBlockEntity { + @Shadow + private static Box offsetHeadBox(BlockPos pos, Box box, PistonBlockEntity blockEntity) { + return box; + } + + @Shadow + private static boolean canMoveEntity(Box box, Entity entity, BlockPos pos) { + return false; + } + + @Shadow + private static void moveEntity(Direction direction, Entity entity, double distance, Direction movementDirection) { + + } + + @Inject(method = "moveEntitiesInHoneyBlock", at = @At("TAIL")) + private static void moveEntitiesInHoneyBlock(World world, BlockPos pos, float ticks, PistonBlockEntity tile, CallbackInfo info) { + Direction direction = tile.getMovementDirection(); + if (!direction.getAxis().isHorizontal()) { + return; + } + double blockY = tile.getPushedBlock().getCollisionShape(world, pos).getMin(Direction.Axis.Y); + Box box = offsetHeadBox(pos, new Box(0, blockY - 1.5000010000000001F, 0, 1, blockY, 1), tile); + double distance = ticks - tile.getProgress(1); + for (Entity entity2 : world.getOtherEntities(null, box, entity -> canMoveEntity(box, entity, pos))) { + moveEntity(direction, entity2, distance, direction); + } + } +} diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 4f3227b4..530d0226 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -58,6 +58,7 @@ "gravity.MixinLivingEntity", "gravity.MixinMobEntity", "gravity.MixinWorld", + "gravity.MixinPistonBlockEntity", "gravity.MixinServerWorld", "gravity.MixinServerPlayerEntity", "gravity.MixinServerPlayNetworkHandler", From dd8bf650d55d7a49c7e298bc41c2deac5c815b38 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 26 Mar 2024 20:46:19 +0000 Subject: [PATCH 32/73] #168 Add speed boosts when performing stunts and add a stunt for flying at low altitude. --- .../entity/player/FlightStuntUtil.java | 19 +++++ .../unicopia/entity/player/PlayerPhysics.java | 73 ++++++++++++------- .../unicopia/util/MutableVector.java | 18 +++++ 3 files changed, 85 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/player/FlightStuntUtil.java diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/FlightStuntUtil.java b/src/main/java/com/minelittlepony/unicopia/entity/player/FlightStuntUtil.java new file mode 100644 index 00000000..c5975dbe --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/FlightStuntUtil.java @@ -0,0 +1,19 @@ +package com.minelittlepony.unicopia.entity.player; + +import com.minelittlepony.unicopia.entity.mob.StormCloudEntity; +import com.minelittlepony.unicopia.util.MutableVector; + +import net.minecraft.util.math.BlockPos; + +public class FlightStuntUtil { + public static boolean isPerformingDive(Pony pony, MutableVector velocity) { + double horizontalSpeed = velocity.horizontalLengthSquared(); + double verticalSpeed = velocity.y; + return horizontalSpeed != 0 && verticalSpeed < -0.3F && (verticalSpeed / horizontalSpeed) < -0.3F; + } + + public static boolean isFlyingLow(Pony pony, MutableVector velocity) { + BlockPos pos = pony.asEntity().getBlockPos(); + return velocity.horizontalLengthSquared() > 0.005F && (pos.getY() - StormCloudEntity.findSurfaceBelow(pony.asWorld(), pos).getY()) < 6; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index 8ac41371..b4db56d0 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -60,6 +60,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab private int ticksInAir; private int ticksToGlide; private int ticksDiving; + private int ticksFlyingLow; private float thrustScale = 0; private float prevThrustScale; @@ -335,28 +336,9 @@ public class PlayerPhysics extends EntityPhysics implements Tickab velocity.y /= 2F; } - double horizontalSpeed = this.getHorizontalMotion(); - double verticalSpeed = velocity.y; - - if (Abilities.RAINBOOM.canUse(pony.getCompositeRace()) && horizontalSpeed != 0 && verticalSpeed < -0.3F && (verticalSpeed / horizontalSpeed) < -0.3F) { - ticksDiving++; - } else { - ticksDiving = 0; - } - - if (ticksDiving > 0 && ticksDiving % 25 == 0) { - pony.getMagicalReserves().getCharge().addPercent(12.5F); - } + tickStunts(velocity); } else { - prevStrafe = 0; - strafe = 0; - ticksInAir = 0; - wallHitCooldown = MAX_WALL_HIT_CALLDOWN; - soundPlaying = false; - descentRate = 0; - ticksDiving = 0; - updraft.update(0, 100); - windStrength.update(0, 100); + tickGrounded(); if (Abilities.RAINBOOM.canUse(pony.getCompositeRace()) && entity.isOnGround()) { pony.getMagicalReserves().getCharge().set(0); @@ -367,10 +349,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab } } } else { - descentRate = 0; - soundPlaying = false; - updraft.update(0, 100); - windStrength.update(0, 100); + tickGrounded(); } if (!entity.isOnGround()) { @@ -379,6 +358,10 @@ public class PlayerPhysics extends EntityPhysics implements Tickab velocity.z /= heavyness; } + float maximum = 1.5F; + velocity.x = MathHelper.clamp(velocity.x, -maximum, maximum); + velocity.y = MathHelper.clamp(velocity.y, -maximum, maximum); + velocity.z = MathHelper.clamp(velocity.z, -maximum, maximum); entity.setVelocity(velocity.toImmutable()); if (isFlying() && !entity.isFallFlying() && !pony.getAcrobatics().isHanging() && pony.isClient()) { @@ -397,6 +380,46 @@ public class PlayerPhysics extends EntityPhysics implements Tickab } } + private void tickGrounded() { + prevStrafe = 0; + strafe = 0; + ticksInAir = 0; + wallHitCooldown = MAX_WALL_HIT_CALLDOWN; + soundPlaying = false; + descentRate = 0; + ticksDiving = 0; + ticksFlyingLow = 0; + updraft.update(0, 0); + windStrength.update(0, 0); + } + + private void tickStunts(MutableVector velocity) { + boolean canPerformStunts = Abilities.RAINBOOM.canUse(pony.getCompositeRace()); + ticksDiving = canPerformStunts && FlightStuntUtil.isPerformingDive(pony, velocity) ? (ticksDiving + 1) : 0; + ticksFlyingLow = canPerformStunts && FlightStuntUtil.isFlyingLow(pony, velocity) ? (ticksFlyingLow + 1) : 0; + + if (ticksDiving > 0) { + float horDiveScale = MathHelper.clamp(ticksDiving / 100F, 0, 10); + float verDiveScale = MathHelper.clamp(ticksDiving / 90F, 0, 5); + velocity.multiply(1 + horDiveScale, 1 + verDiveScale, 1 + horDiveScale); + } + + if (ticksFlyingLow > 0) { + float horDiveScale = MathHelper.clamp(ticksFlyingLow / 1000F, 0, 0.9F); + float verDiveScale = MathHelper.clamp(ticksFlyingLow / 900F, 0, 0.5F); + velocity.multiply(1 + horDiveScale, 1 + verDiveScale, 1 + horDiveScale); + } + + if (pony.asEntity().age % 2 == 0) { + if (ticksDiving > 0) { + pony.getMagicalReserves().getCharge().addPercent(1F); + } + if (ticksFlyingLow > 0) { + pony.getMagicalReserves().getCharge().addPercent(ticksFlyingLow / 200F); + } + } + } + private void tickFlight(FlightType type, MutableVector velocity) { if (type.isArtifical()) { tickArtificialFlight(velocity); diff --git a/src/main/java/com/minelittlepony/unicopia/util/MutableVector.java b/src/main/java/com/minelittlepony/unicopia/util/MutableVector.java index c76e0209..8ea4aac6 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/MutableVector.java +++ b/src/main/java/com/minelittlepony/unicopia/util/MutableVector.java @@ -20,6 +20,12 @@ public class MutableVector { z = vec.z; } + public void multiply(double x, double y, double z) { + this.x *= x; + this.y *= y; + this.z *= z; + } + public void add(Vec3d vector) { add(vector.x, vector.y, vector.z); } @@ -38,6 +44,18 @@ public class MutableVector { this.z += z; } + public double horizontalLengthSquared() { + return x * x + z * z; + } + + public double verticalLengthSquared() { + return y * y; + } + + public double lengthSquared() { + return verticalLengthSquared() + horizontalLengthSquared(); + } + public Vec3d toImmutable() { return new Vec3d(x, y, z); } From 2ae28c72d3f222487407a12acaf65096382dba10 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 26 Mar 2024 22:00:43 +0000 Subject: [PATCH 33/73] Fix edge sneaking when upside down --- .../mixin/gravity/MixinPlayerEntity.java | 43 +++++++++++++++++++ src/main/resources/unicopia.mixin.json | 1 + 2 files changed, 44 insertions(+) create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinPlayerEntity.java diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinPlayerEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinPlayerEntity.java new file mode 100644 index 00000000..e6b8b24b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/gravity/MixinPlayerEntity.java @@ -0,0 +1,43 @@ +package com.minelittlepony.unicopia.mixin.gravity; + +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.minelittlepony.unicopia.entity.Equine; + +import net.minecraft.entity.MovementType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.math.Vec3d; + +@Mixin(PlayerEntity.class) +abstract class MixinPlayerEntity { + @ModifyVariable(method = "adjustMovementForSneaking", at = @At("HEAD"), argsOnly = true) + private Vec3d flipMovementForSneaking(Vec3d movement) { + if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + return movement.multiply(1, -1, 1); + } + return movement; + } + + @Inject(method = "adjustMovementForSneaking", at = @At("RETURN"), cancellable = true) + private void unflipMovementForSneaking(Vec3d movement, MovementType type, CallbackInfoReturnable info) { + if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + info.setReturnValue(info.getReturnValue().multiply(1, -1, 1)); + } + } + + @ModifyArg(method = { "adjustMovementForSneaking", "method_30263" }, at = @At( + value = "INVOKE", + target = "net/minecraft/util/math/Box.offset(DDD)Lnet/minecraft/util/math/Box;"), + index = 1) + private double invertStepHeight(double stepHeight) { + if (this instanceof Equine.Container eq && eq.get().getPhysics().isGravityNegative()) { + return -stepHeight; + } + return stepHeight; + } +} diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 530d0226..0a82eae8 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -58,6 +58,7 @@ "gravity.MixinLivingEntity", "gravity.MixinMobEntity", "gravity.MixinWorld", + "gravity.MixinPlayerEntity", "gravity.MixinPistonBlockEntity", "gravity.MixinServerWorld", "gravity.MixinServerPlayerEntity", From f84f45c47cf7624b6112be5993521907ecd2e640 Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 27 Mar 2024 19:20:33 +0000 Subject: [PATCH 34/73] Run datagen before publish --- .github/workflows/gradle-publish.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index e93b8b24..ab6a77f9 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -17,6 +17,10 @@ jobs: uses: actions/setup-java@v1 with: java-version: 17 + - name: Prepare Datagen + uses: eskatos/gradle-command-action@v1 + with: + arguments: rundatagen - name: Publish Modrinth Jar env: MODRINTH_KEY: ${{ secrets.MODRINTH_KEY }} From e02c6f57a08d04e0095b8965b2efc3fa80b1fe3d Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 27 Mar 2024 19:22:11 +0000 Subject: [PATCH 35/73] Bump blockus --- BlockusAddon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BlockusAddon b/BlockusAddon index ec6ea81e..7170edad 160000 --- a/BlockusAddon +++ b/BlockusAddon @@ -1 +1 @@ -Subproject commit ec6ea81ed5f0862ab2dfa6201c66504287e3ef76 +Subproject commit 7170edad67426756e2383bd9464a8615e9bb4b3a From e931be3388b34154ac70d2a3fa49caca725cb85a Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 27 Mar 2024 19:23:16 +0000 Subject: [PATCH 36/73] You can now harvest pinecones and acorns from spruce and oak leaves using a hoe --- .../unicopia/InteractionManager.java | 6 ++ .../client/ClientInteractionManager.java | 7 ++ .../unicopia/item/ForageableItem.java | 93 +++++++++++++++++++ .../minelittlepony/unicopia/item/UItems.java | 5 +- 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/item/ForageableItem.java diff --git a/src/main/java/com/minelittlepony/unicopia/InteractionManager.java b/src/main/java/com/minelittlepony/unicopia/InteractionManager.java index 7c60d0d5..e0848e1a 100644 --- a/src/main/java/com/minelittlepony/unicopia/InteractionManager.java +++ b/src/main/java/com/minelittlepony/unicopia/InteractionManager.java @@ -14,6 +14,8 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.PacketByteBuf; import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.world.World; public class InteractionManager { @@ -90,4 +92,8 @@ public class InteractionManager { public void sendPlayerLookAngles(PlayerEntity player) { } + + public void addBlockBreakingParticles(BlockPos pos, Direction direction) { + + } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/ClientInteractionManager.java b/src/main/java/com/minelittlepony/unicopia/client/ClientInteractionManager.java index 837b65fd..13352054 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/ClientInteractionManager.java +++ b/src/main/java/com/minelittlepony/unicopia/client/ClientInteractionManager.java @@ -41,6 +41,8 @@ import net.minecraft.network.PacketByteBuf; import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket; import net.minecraft.sound.SoundCategory; import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; import net.minecraft.world.World; @@ -161,4 +163,9 @@ public class ClientInteractionManager extends InteractionManager { c.networkHandler.sendPacket(new PlayerMoveC2SPacket.LookAndOnGround(player.getYaw(), player.getPitch(), player.isOnGround())); } } + + @Override + public void addBlockBreakingParticles(BlockPos pos, Direction direction) { + client.particleManager.addBlockBreakingParticles(pos, direction); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/ForageableItem.java b/src/main/java/com/minelittlepony/unicopia/item/ForageableItem.java new file mode 100644 index 00000000..bb129cf6 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/ForageableItem.java @@ -0,0 +1,93 @@ +package com.minelittlepony.unicopia.item; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import com.minelittlepony.unicopia.InteractionManager; +import com.minelittlepony.unicopia.item.enchantment.EnchantmentUtil; +import com.minelittlepony.unicopia.server.world.BlockDestructionManager; + +import net.fabricmc.fabric.api.event.player.UseBlockCallback; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.HoeItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ToolMaterials; +import net.minecraft.registry.tag.BlockTags; +import net.minecraft.registry.tag.ItemTags; +import net.minecraft.sound.SoundCategory; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import net.minecraft.world.WorldEvents; + +public class ForageableItem extends Item { + private static final List REGISTRY = new ArrayList<>(); + static { + UseBlockCallback.EVENT.register((PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) -> { + if (player.shouldCancelInteraction()) { + return ActionResult.PASS; + } + + ItemStack stack = player.getStackInHand(hand); + if (!stack.isIn(ItemTags.HOES)) { + return ActionResult.PASS; + } + + BlockPos pos = hitResult.getBlockPos(); + BlockState state = world.getBlockState(pos); + + ActionResult result = ActionResult.PASS; + + if (state.isIn(BlockTags.LEAVES)) { + player.swingHand(hand); + world.playSound(player, pos, state.getSoundGroup().getHitSound(), SoundCategory.BLOCKS); + InteractionManager.instance().addBlockBreakingParticles(pos, hitResult.getSide()); + + int miningLevel = (stack.getItem() instanceof HoeItem hoe ? hoe.getMaterial().getMiningLevel() : 59); + + for (ForageableItem item : REGISTRY) { + if ((result = item.onTryForage(world, pos, state, stack, player, miningLevel)).isAccepted()) { + stack.damage(1, player, p -> p.sendToolBreakStatus(hand)); + return result; + } + } + } + + return result.isAccepted() ? ActionResult.SUCCESS : ActionResult.PASS; + }); + } + + private final Supplier targetBlock; + + public ForageableItem(Settings settings, Supplier targetBlock) { + super(settings); + this.targetBlock = targetBlock; + REGISTRY.add(this); + } + + public ActionResult onTryForage(World world, BlockPos pos, BlockState state, ItemStack stack, PlayerEntity player, int miningLevel) { + if (state.isOf(targetBlock.get())) { + int spawnChance = (int)((1F - MathHelper.clamp(miningLevel / (float)ToolMaterials.NETHERITE.getMiningLevel(), 0, 1)) * 32); + spawnChance -= EnchantmentUtil.getLuck(1, player); + + if (spawnChance <= 0 || world.random.nextInt(spawnChance) == 0) { + Block.dropStack(world, pos, new ItemStack(this, 1 + EnchantmentHelper.getLooting(player))); + world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, pos, Block.getRawIdFromState(state)); + if (BlockDestructionManager.of(world).damageBlock(pos, world.getRandom().nextBetween(3, 7)) >= BlockDestructionManager.MAX_DAMAGE) { + world.breakBlock(pos, true); + } + return ActionResult.SUCCESS; + } + return ActionResult.FAIL; + } + return ActionResult.PASS; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index b75f9a6f..0c8fdaab 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -16,6 +16,7 @@ import com.terraformersmc.terraform.boat.api.TerraformBoatType; import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; import com.terraformersmc.terraform.boat.api.item.TerraformBoatItemHelper; +import net.minecraft.block.Blocks; import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.vehicle.BoatEntity; @@ -85,8 +86,8 @@ public interface UItems { Item WHEAT_WORMS = register("wheat_worms", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.WORMS)), ItemGroups.NATURAL); Item MUFFIN = register("muffin", new MuffinItem(new Item.Settings().maxCount(32).food(FoodComponents.BREAD), 0), ItemGroups.FOOD_AND_DRINK); - Item PINECONE = register("pinecone", new Item(new Item.Settings().food(UFoodComponents.PINECONE).maxCount(3)), ItemGroups.FOOD_AND_DRINK); - Item ACORN = register("acorn", new Item(new Item.Settings().food(UFoodComponents.ACORN).maxCount(16)), ItemGroups.FOOD_AND_DRINK); + Item PINECONE = register("pinecone", new ForageableItem(new Item.Settings().food(UFoodComponents.PINECONE).maxCount(16), () -> Blocks.SPRUCE_LEAVES), ItemGroups.FOOD_AND_DRINK); + Item ACORN = register("acorn", new ForageableItem(new Item.Settings().food(UFoodComponents.ACORN).maxCount(16), () -> Blocks.OAK_LEAVES), ItemGroups.FOOD_AND_DRINK); Item MANGO = register("mango", new Item(new Item.Settings().food(UFoodComponents.MANGO)), ItemGroups.FOOD_AND_DRINK); Item BANANA = register("banana", new Item(new Item.Settings().food(UFoodComponents.BANANA)), ItemGroups.FOOD_AND_DRINK); Item CURING_JOKE = register("curing_joke", new CuringJokeItem(UBlocks.CURING_JOKE, new Item.Settings().food(UFoodComponents.POISON_JOKE)), ItemGroups.NATURAL); From c0a64a80f11ea961693711e82b590334a3125624 Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 27 Mar 2024 19:23:39 +0000 Subject: [PATCH 37/73] Fixed eating rock stew also consuming the bowl --- src/main/java/com/minelittlepony/unicopia/item/UItems.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 0c8fdaab..1f036829 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -102,7 +102,7 @@ public interface UItems { Item TOM = register("tom", new BluntWeaponItem(new Item.Settings(), ImmutableMultimap.of( EntityAttributes.GENERIC_KNOCKBACK_RESISTANCE, new EntityAttributeModifier(BluntWeaponItem.KNOCKBACK_MODIFIER_ID, "Weapon modifier", 0.9, EntityAttributeModifier.Operation.ADDITION) )), ItemGroups.NATURAL); - Item ROCK_STEW = register("rock_stew", new Item(new Item.Settings().food(FoodComponents.MUSHROOM_STEW)), ItemGroups.FOOD_AND_DRINK); + Item ROCK_STEW = register("rock_stew", new StewItem(new Item.Settings().food(FoodComponents.MUSHROOM_STEW).recipeRemainder(Items.BOWL)), ItemGroups.FOOD_AND_DRINK); Item ROCK_CANDY = register("rock_candy", new Item(new Item.Settings().food(UFoodComponents.CANDY).maxCount(16)), ItemGroups.FOOD_AND_DRINK); Item SALT_CUBE = register("salt_cube", new Item(new Item.Settings().food(UFoodComponents.SALT_CUBE)), ItemGroups.FOOD_AND_DRINK); From 7cf32cce521699ed37c03c5cdf5636fc425fcfbd Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 27 Mar 2024 19:24:06 +0000 Subject: [PATCH 38/73] Added bowl of nuts, oatmeal cookie, and pinecone cookie --- .../datagen/providers/UModelProvider.java | 6 ++--- .../UBlockAdditionsLootTableProvider.java | 22 +++++++++++++----- .../providers/recipe/URecipeProvider.java | 11 +++++++++ .../minelittlepony/unicopia/item/UItems.java | 4 ++++ .../resources/assets/unicopia/lang/en_us.json | 3 +++ .../unicopia/textures/item/bowl_of_nuts.png | Bin 0 -> 8620 bytes .../unicopia/textures/item/oatmeal_cookie.png | Bin 0 -> 9087 bytes .../textures/item/pinecone_cookie.png | Bin 0 -> 9118 bytes .../tags/items/food_types/baked_goods.json | 3 +++ .../tags/items/groups/earth_pony.json | 3 +++ 10 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 src/main/resources/assets/unicopia/textures/item/bowl_of_nuts.png create mode 100644 src/main/resources/assets/unicopia/textures/item/oatmeal_cookie.png create mode 100644 src/main/resources/assets/unicopia/textures/item/pinecone_cookie.png diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java index 64bbc4be..1c58e4f7 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java @@ -57,7 +57,7 @@ public class UModelProvider extends FabricModelProvider { public void generateItemModels(ItemModelGenerator itemModelGenerator) { ItemModels.register(itemModelGenerator, UItems.ACORN, UItems.APPLE_PIE_HOOF, UItems.APPLE_PIE_SLICE, UItems.APPLE_PIE, - UItems.BANANA, UItems.BOTCHED_GEM, UItems.BROKEN_SUNGLASSES, UItems.BURNED_JUICE, UItems.BURNED_TOAST, + UItems.BANANA, UItems.BOTCHED_GEM, UItems.BOWL_OF_NUTS, UItems.BROKEN_SUNGLASSES, UItems.BURNED_JUICE, UItems.BURNED_TOAST, UItems.CARAPACE, UItems.CLAM_SHELL, UItems.COOKED_ZAP_APPLE, UItems.CLOUD_LUMP, UItems.CRISPY_HAY_FRIES, UItems.CRYSTAL_HEART, UItems.CRYSTAL_SHARD, UItems.DAFFODIL_DAISY_SANDWICH, UItems.DRAGON_BREATH_SCROLL, UItems.EMPTY_JAR, @@ -69,8 +69,8 @@ public class UModelProvider extends FabricModelProvider { UItems.JAM_TOAST, UItems.JUICE, UItems.LIGHTNING_JAR, UItems.MANGO, UItems.MUFFIN, - UItems.OATMEAL, - UItems.PEBBLES, UItems.PEGASUS_FEATHER, UItems.PINECONE, UItems.PINEAPPLE_CROWN, + UItems.OATMEAL, UItems.OATMEAL_COOKIE, + UItems.PEBBLES, UItems.PEGASUS_FEATHER, UItems.PINECONE, UItems.PINECONE_COOKIE, UItems.PINEAPPLE_CROWN, UItems.RAIN_CLOUD_JAR, UItems.ROCK_STEW, UItems.ROCK, UItems.ROTTEN_APPLE, UItems.SALT_CUBE, UItems.SCALLOP_SHELL, UItems.SHELLY, UItems.SOUR_APPLE_SEEDS, UItems.SOUR_APPLE, UItems.SPELLBOOK, UItems.STORM_CLOUD_JAR, UItems.SWEET_APPLE_SEEDS, UItems.SWEET_APPLE, diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockAdditionsLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockAdditionsLootTableProvider.java index 9788e234..4663bd66 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockAdditionsLootTableProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockAdditionsLootTableProvider.java @@ -11,6 +11,7 @@ import net.minecraft.block.Block; import net.minecraft.block.Blocks; import net.minecraft.data.server.loottable.BlockLootTableGenerator; import net.minecraft.enchantment.Enchantments; +import net.minecraft.item.ItemConvertible; import net.minecraft.loot.LootPool; import net.minecraft.loot.LootTable; import net.minecraft.loot.condition.LootCondition; @@ -54,18 +55,29 @@ public class UBlockAdditionsLootTableProvider extends FabricBlockLootTableProvid addVanillaDrop(Blocks.PODZOL, block -> wormDrops(block, 4, 0.06F, 0.062222223F, 0.065F, 0.077777776F, 0.2F)); addVanillaDrop(Blocks.DIAMOND_ORE, this::crystalShardDrops); addVanillaDrop(Blocks.DEEPSLATE_DIAMOND_ORE, this::crystalShardDrops); + addVanillaDrop(Blocks.OAK_LEAVES, block -> chanceDropWithShears(block, UItems.ACORN, GEMSTONES_FORTUNE_CHANCE)); + addVanillaDrop(Blocks.SPRUCE_LEAVES, block -> chanceDropWithShears(block, UItems.PINECONE, GEMSTONES_FORTUNE_CHANCE)); } private void addVanillaDrop(Block block, Function lootTableFunction) { lootTables.put(new Identifier("unicopiamc", block.getLootTableId().getPath()), lootTableFunction.apply(block)); } + public LootTable.Builder chanceDropWithShears(Block block, ItemConvertible drop, float...chance) { + return LootTable.builder() + .pool(LootPool.builder() + .rolls(ConstantLootNumberProvider.create(1)) + .conditionally(WITHOUT_SILK_TOUCH.and(WITH_SHEARS)) + .with(chanceDrops(block, drop, 1, chance)) + ); + } + public LootTable.Builder wormDrops(Block block, int max, float...chance) { return LootTable.builder() .pool(LootPool.builder() .rolls(ConstantLootNumberProvider.create(1)) .conditionally(WITHOUT_SILK_TOUCH) - .with(wheatwormDrops(block, max, chance)) + .with(chanceDrops(block, UItems.WHEAT_WORMS, max, chance)) ); } @@ -75,7 +87,7 @@ public class UBlockAdditionsLootTableProvider extends FabricBlockLootTableProvid .rolls(ConstantLootNumberProvider.create(1)) .conditionally(WITHOUT_SILK_TOUCH) .with(gemstoneDrops(block, 0.1F)) - .with(wheatwormDrops(block, max, chance)) + .with(chanceDrops(block, UItems.WHEAT_WORMS, max, chance)) ); } @@ -111,16 +123,14 @@ public class UBlockAdditionsLootTableProvider extends FabricBlockLootTableProvid .conditionally(TableBonusLootCondition.builder(Enchantments.FORTUNE, GEMSTONES_FORTUNE_CHANCE)); } - public LootPoolEntry.Builder wheatwormDrops(Block block, int max, float...chance) { - return applyExplosionDecay(block, ItemEntry.builder(UItems.WHEAT_WORMS) + public LootPoolEntry.Builder chanceDrops(Block block, ItemConvertible drop, int max, float...chance) { + return applyExplosionDecay(block, ItemEntry.builder(drop) .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, max))) ) .conditionally(TableBonusLootCondition.builder(Enchantments.FORTUNE, chance)); } - public static LootTable.Builder dropsWithGemfinding(Block drop, LootPoolEntry.Builder child) { return BlockLootTableGenerator.drops(drop, WITHOUT_SILK_TOUCH_AND_GEM_FINDER, child); } - } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index ed82fb66..57340e26 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -315,6 +315,17 @@ public class URecipeProvider extends FabricRecipeProvider { .input(UItems.ROCK, 3).criterion(hasItem(UItems.ROCK), conditionsFromItem(UItems.ROCK)) .input(Items.BOWL) .offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.BOWL_OF_NUTS) + .input(UItems.ACORN, 3).criterion(hasItem(UItems.ACORN), conditionsFromItem(UItems.ACORN)) + .input(Items.BOWL) + .offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.OATMEAL_COOKIE) + .input(UItems.OATS, 3).criterion(hasItem(UItems.OATS), conditionsFromItem(UItems.OATS)) + .offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.PINECONE_COOKIE) + .input(UItems.PINECONE).criterion(hasItem(UItems.PINECONE), conditionsFromItem(UItems.PINECONE)) + .input(Items.WHEAT, 2) + .offerTo(exporter); ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.ROCK_CANDY, 3) .input(Items.SUGAR, 6).criterion(hasItem(Items.SUGAR), conditionsFromItem(Items.SUGAR)) .input(UItems.PEBBLES, 3) diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 1f036829..ce60d14b 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -75,6 +75,10 @@ public interface UItems { Item IMPORTED_OATS = register("imported_oats", new Item(new Item.Settings().food(UFoodComponents.IMPORTED_OATS)), ItemGroups.FOOD_AND_DRINK); Item OATMEAL = register("oatmeal", new OatmealItem(new Item.Settings().recipeRemainder(Items.BOWL).maxCount(1).food(UFoodComponents.OATMEAL)), ItemGroups.FOOD_AND_DRINK); + Item OATMEAL_COOKIE = register("oatmeal_cookie", new Item(new Item.Settings().food(FoodComponents.COOKIE)), ItemGroups.FOOD_AND_DRINK); + Item PINECONE_COOKIE = register("pinecone_cookie", new Item(new Item.Settings().food(FoodComponents.COOKIE)), ItemGroups.FOOD_AND_DRINK); + Item BOWL_OF_NUTS = register("bowl_of_nuts", new StewItem(new Item.Settings().food(FoodComponents.BAKED_POTATO).recipeRemainder(Items.BOWL)), ItemGroups.FOOD_AND_DRINK); + Item DAFFODIL_DAISY_SANDWICH = register("daffodil_daisy_sandwich", new Item(new Item.Settings().food(UFoodComponents.DAFODIL_DAISY_SANDWICH)), ItemGroups.FOOD_AND_DRINK); Item HAY_BURGER = register("hay_burger", new Item(new Item.Settings().maxCount(1).food(UFoodComponents.HAY_BURGER)), ItemGroups.FOOD_AND_DRINK); Item HAY_FRIES = register("hay_fries", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.HAY_FRIES)), ItemGroups.FOOD_AND_DRINK); diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 0941798f..8558c7b3 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -146,6 +146,9 @@ "item.unicopia.horse_shoe_fries": "Horse Shoe Fries", "item.unicopia.wheat_worms": "Wheat Worms", "item.unicopia.muffin": "Muffin", + "item.unicopia.oatmeal_cookie": "Oatmeal Cookie", + "item.unicopia.pinecone_cookie": "Pinecone Cookie", + "item.unicopia.bowl_of_nuts": "Bowl of Nuts", "item.unicopia.pegasus_amulet": "Wings of Icarus", "item.unicopia.pegasus_amulet.lore": "Grants temporary flight to whoever wears it", diff --git a/src/main/resources/assets/unicopia/textures/item/bowl_of_nuts.png b/src/main/resources/assets/unicopia/textures/item/bowl_of_nuts.png new file mode 100644 index 0000000000000000000000000000000000000000..8e684446c117429bfb1a6b04ce495bbffd916317 GIT binary patch literal 8620 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 Z1Z)@0k=!EON)o-*I*~Tm725d6{S$aW#=ign literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/oatmeal_cookie.png b/src/main/resources/assets/unicopia/textures/item/oatmeal_cookie.png new file mode 100644 index 0000000000000000000000000000000000000000..daa46c80f62cfae0c47d488bae33a9d8a0f1d036 GIT binary patch literal 9087 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/pinecone_cookie.png b/src/main/resources/assets/unicopia/textures/item/pinecone_cookie.png new file mode 100644 index 0000000000000000000000000000000000000000..79fb1ed76ed999e863ea7a0f4878139271f7d9f6 GIT binary patch literal 9118 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 KbD?8!{NDhhiccW` literal 0 HcmV?d00001 diff --git a/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json b/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json index 02828b2e..b28e7389 100644 --- a/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json +++ b/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json @@ -17,6 +17,9 @@ "unicopia:hay_fries", "unicopia:crispy_hay_fries", "unicopia:horse_shoe_fries", + "unicopia:oatmeal_cookie", + "unicopia:pinecone_cookie", + "unicopia:bowl_of_nuts", { "id": "farmersdelight:wheat_dough", "required": false }, { "id": "farmersdelight:raw_pasta", "required": false }, { "id": "farmersdelight:pie_crust", "required": false }, diff --git a/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json b/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json index d88b92b7..e3ec6fc3 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json +++ b/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json @@ -51,6 +51,7 @@ "unicopia:oats", "unicopia:imported_oats", "unicopia:oatmeal", + "unicopia:oatmeal_cookie", "unicopia:daffodil_daisy_sandwich", "unicopia:hay_burger", "unicopia:hay_fries", @@ -61,6 +62,8 @@ "unicopia:muffin", "unicopia:acorn", "unicopia:pinecone", + "unicopia:pinecone_cookie", + "unicopia:bowl_of_nuts", "unicopia:crystal_shard", "unicopia:pebbles", "unicopia:rock", From ff4770314046bd34f1ea5a4e80d1c5e2fd65f4c0 Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 27 Mar 2024 19:43:55 +0000 Subject: [PATCH 39/73] Update blockus --- BlockusAddon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BlockusAddon b/BlockusAddon index 7170edad..2e285380 160000 --- a/BlockusAddon +++ b/BlockusAddon @@ -1 +1 @@ -Subproject commit 7170edad67426756e2383bd9464a8615e9bb4b3a +Subproject commit 2e285380cfa55da1b858c38833f05a56666c219f From 93d11531d68aeaf91355643901024cf4c3ef9495 Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 27 Mar 2024 19:44:12 +0000 Subject: [PATCH 40/73] Use newer loom features for datagen --- build.gradle | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index 285777fc..69922b16 100644 --- a/build.gradle +++ b/build.gradle @@ -28,18 +28,13 @@ archivesBaseName = project.name loom { mixin.defaultRefmapName = 'unicopia.mixin.refmap.json' accessWidenerPath = file('src/main/resources/unicopia.aw') - runs { - datagen { - server() - name "Data Generation" - vmArg "-Dfabric-api.datagen" - vmArg "-Dfabric-api.datagen.modid=unicopia" - vmArg "-Dfabric-api.datagen.output-dir=${file("src/main/generated")}" - runDir "build/datagen" - } +} + +fabricApi { + configureDataGeneration { + modId = 'unicopia' } } -//assemble.dependsOn(runDatagen) reckon { scopeFromProp() @@ -108,14 +103,6 @@ dependencies { } } -sourceSets { - main { - resources { - srcDirs += [ "src/main/generated" ] - } - } -} - processResources { inputs.property "version", project.version.toString() From fbe444b56cd52e30383d50a92629f41c7e8c89a0 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 28 Mar 2024 12:08:06 +0000 Subject: [PATCH 41/73] Fix janky hot air balloon physics --- .../client/render/WorldRenderDelegate.java | 2 - .../unicopia/entity/Living.java | 127 +--------- .../unicopia/entity/Transportation.java | 141 +++++++++++ .../collision/MultiBoundingBoxEntity.java | 26 +- .../unicopia/entity/mob/AirBalloonEntity.java | 232 +++++++++--------- .../unicopia/mixin/MixinEntity.java | 18 ++ 6 files changed, 313 insertions(+), 233 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/Transportation.java diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java index 17594ba0..f839fef1 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/WorldRenderDelegate.java @@ -167,8 +167,6 @@ public class WorldRenderDelegate { return true; } - pony.updateSupportingEntity(); - matrices.push(); Entity owner = pony.asEntity(); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index 84dce958..86ea4261 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -20,7 +20,6 @@ import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance; import com.minelittlepony.unicopia.entity.behaviour.Guest; -import com.minelittlepony.unicopia.entity.collision.MultiBoundingBoxEntity; import com.minelittlepony.unicopia.entity.damage.MagicalDamageSource; import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck; import com.minelittlepony.unicopia.entity.effect.CorruptInfluenceStatusEffect; @@ -67,7 +66,6 @@ import net.minecraft.sound.SoundCategory; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -88,14 +86,6 @@ public abstract class Living implements Equine, Caste private boolean invisible = false; - @Nullable - private Entity supportingEntity; - - @Nullable - private Vec3d supportPositionOffset; - private int ticksOutsideVehicle; - private int ticksInVehicle; - @Nullable private Caster attacker; @Nullable @@ -109,6 +99,8 @@ public abstract class Living implements Equine, Caste private final Enchantments enchants = addTicker(new Enchantments(this)); private final ItemTracker armour = addTicker(new ItemTracker(this)); + //private final Transportation transportation = new Transportation<>(this); + private final Transportation transportation = new Transportation<>(this); protected Living(T entity, TrackedData effect) { this.entity = entity; @@ -171,6 +163,10 @@ public abstract class Living implements Equine, Caste return armour; } + public Transportation getTransportation() { + return transportation; + } + @Override public final T asEntity() { return entity; @@ -202,73 +198,6 @@ public abstract class Living implements Equine, Caste return vehicle != null && getCarrierId().filter(vehicle.getUuid()::equals).isPresent(); } - public boolean setSupportingEntity(@Nullable Entity supportingEntity) { - this.supportingEntity = supportingEntity; - if (supportingEntity != null) { - ticksOutsideVehicle = 0; - } - return true; - } - - @Nullable - public Entity getSupportingEntity() { - return supportingEntity; - } - - public int getTicksInVehicle() { - return ticksInVehicle; - } - - public void setPositionOffset(@Nullable Vec3d positionOffset) { - this.supportPositionOffset = positionOffset; - } - - public void updatePositionOffset() { - setPositionOffset(supportingEntity == null ? null : entity.getPos().subtract(supportingEntity.getPos())); - } - - public void updateRelativePosition(Box box) { - if (supportingEntity == null || supportPositionOffset == null) { - return; - } - if (getPhysics().isFlying()) { - return; - } - - Vec3d newPos = supportingEntity.getPos().add(supportPositionOffset); - Vec3d posChange = entity.getPos().subtract(newPos); - entity.setPosition(newPos); - if (isClient()) { - Vec3d newServerPos = LivingEntityDuck.serverPos(entity); - if (newServerPos.lengthSquared() != 0) { - newServerPos = newServerPos.subtract(posChange); - entity.updateTrackedPositionAndAngles( - newServerPos.x, newServerPos.y, newServerPos.z, - entity.getYaw(), entity.getPitch(), 3, true); - } - } else { - entity.updateTrackedPosition(newPos.x, newPos.y, newPos.z); - } - - if (!(entity instanceof PlayerEntity)) { - entity.lastRenderX = supportingEntity.lastRenderX + supportPositionOffset.x; - entity.lastRenderY = supportingEntity.lastRenderY + supportPositionOffset.y; - entity.lastRenderZ = supportingEntity.lastRenderZ + supportPositionOffset.z; - - if (entity.getVelocity().length() < 0.1) { - LimbAnimationUtil.resetToZero(entity.limbAnimator); - } - } - - entity.horizontalSpeed = 0; - entity.prevHorizontalSpeed = 0; - entity.speed = 0; - entity.setOnGround(true); - entity.verticalCollision = true; - entity.groundCollision = true; - entity.fallDistance = 0; - } - @Override public boolean beforeUpdate() { if (EffectUtils.getAmplifier(entity, UEffects.PARALYSIS) > 1 && entity.getVelocity().horizontalLengthSquared() > 0) { @@ -276,44 +205,10 @@ public abstract class Living implements Equine, Caste updateVelocity(); } - updateSupportingEntity(); + //transportation.updateSupportingEntity(); return false; } - public void updateSupportingEntity() { - if (supportingEntity != null) { - Box ownBox = entity.getBoundingBox() - .stretch(entity.getVelocity()) - .expand(0.1, 0.5, 0.1) - .stretch(supportingEntity.getVelocity().multiply(-2)); - - MultiBoundingBoxEntity.getBoundingBoxes(supportingEntity).stream() - .filter(box -> box.stretch(supportingEntity.getVelocity()).expand(0, 0.5, 0).intersects(ownBox)) - .findFirst() - .ifPresentOrElse(box -> { - ticksOutsideVehicle = 0; - if (supportPositionOffset == null) { - updatePositionOffset(); - } else { - updateRelativePosition(box); - } - entity.setOnGround(true); - entity.verticalCollision = true; - entity.groundCollision = true; - }, () -> { - // Rubberband passengers to try and prevent players falling out when the velocity changes suddenly - if (ticksOutsideVehicle++ > 30) { - supportingEntity = null; - supportPositionOffset = null; - Unicopia.LOGGER.info("Entity left vehicle"); - } else { - supportPositionOffset = supportPositionOffset.multiply(0.25, 1, 0.25); - } - }); - } - - } - @Override public void tick() { tickers.forEach(Tickable::tick); @@ -358,13 +253,7 @@ public abstract class Living implements Equine, Caste updateDragonBreath(); - if (ticksOutsideVehicle == 0) { - updatePositionOffset(); - - ticksInVehicle++; - } else { - ticksInVehicle = 0; - } + transportation.tick(); } public void updateAttributeModifier(UUID id, EntityAttribute attribute, float desiredValue, Float2ObjectFunction modifierSupplier, boolean permanent) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Transportation.java b/src/main/java/com/minelittlepony/unicopia/entity/Transportation.java new file mode 100644 index 00000000..14ad5346 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/Transportation.java @@ -0,0 +1,141 @@ +package com.minelittlepony.unicopia.entity; + +import java.util.ArrayList; +import java.util.List; +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.advancement.UCriteria; +import com.minelittlepony.unicopia.entity.collision.MultiBoundingBoxEntity; +import com.minelittlepony.unicopia.entity.duck.EntityDuck; +import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity; +import com.minelittlepony.unicopia.util.Tickable; + +import net.minecraft.block.ShapeContext; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MovementType; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.event.GameEvent; + +public class Transportation implements Tickable { + + private final Living living; + + @Nullable + private MultiBoundingBoxEntity vehicle; + @Nullable + private Entity vehicleEntity; + @Nullable + private Box vehicleBox; + + private int ticksInVehicle; + + private Vec3d lastVehiclePosition = Vec3d.ZERO; + + Transportation(Living living) { + this.living = living; + } + + public void setVehicle(@Nullable E vehicle) { + this.vehicle = vehicle; + this.vehicleEntity = vehicle; + updatePreviousPosition(); + } + + @Override + public void tick() { + if (vehicle != null) { + ticksInVehicle++; + } else { + ticksInVehicle = 0; + } + + if (ticksInVehicle > 20 && vehicle instanceof AirBalloonEntity) { + UCriteria.RIDE_BALLOON.trigger(living.asEntity()); + } + } + + public void updatePreviousPosition() { + vehicleBox = getVehicleBox(); + lastVehiclePosition = vehicleEntity == null ? Vec3d.ZERO : vehicleEntity.getPos(); + Entity entity = living.asEntity(); + if (vehicleBox != null && living.asEntity().getBoundingBox().intersects(vehicleBox.expand(0.001, 0.5001, 0.001))) { + entity.setOnGround(true); + entity.onLanding(); + entity.verticalCollision = true; + entity.groundCollision = true; + entity.velocityDirty = true; + entity.velocityModified = true; + } + } + + public void onMove(MovementType movementType) { + if (vehicleBox == null || vehicleEntity == null) { + return; + } + + Entity entity = living.asEntity(); + + Box passengerBox = entity.getBoundingBox().expand(0.001); + Vec3d vehicleMovement = vehicleEntity.getPos().subtract(lastVehiclePosition); + + List shapes = new ArrayList<>(); + vehicle.getCollissionShapes(ShapeContext.of(entity), shapes::add); + vehicleMovement = vehicleMovement.add(vehicleEntity.getVelocity()); + vehicleMovement = Entity.adjustMovementForCollisions(entity, vehicleMovement, passengerBox, entity.getWorld(), shapes); + + Vec3d newPos = entity.getPos().add(vehicleMovement); + + if (!vehicleEntity.isOnGround()) { + // surface check to prevent the player from floating + if (newPos.getY() > vehicleBox.minY + 0.1 || newPos.getY() < vehicleBox.minY + 0.1) { + newPos = new Vec3d(newPos.getX(), vehicleBox.minY + 0.01, newPos.getZ()); + } + // containment checks to prevent the player from falling out of the basket when in flight + if (newPos.getY() < vehicleEntity.getPos().getY() + 3) { + double maxDeviation = 0.1; + double z = MathHelper.clamp(newPos.getZ(), vehicleBox.minZ + maxDeviation, vehicleBox.maxZ - maxDeviation); + double x = MathHelper.clamp(newPos.getX(), vehicleBox.minX + maxDeviation, vehicleBox.maxX - maxDeviation); + + newPos = new Vec3d(x, newPos.getY(), z); + } + + entity.setPosition(newPos); + entity.updateTrackedPosition(newPos.x, newPos.y, newPos.z); + entity.setVelocity(Vec3d.ZERO); + } + + entity.setOnGround(true); + entity.onLanding(); + entity.verticalCollision = true; + entity.groundCollision = true; + + if (entity.distanceTraveled > ((EntityDuck)entity).getNextStepSoundDistance()) { + entity.distanceTraveled -= 0.5; + entity.playSound(vehicle.getWalkedOnSound(entity.getY()), 0.5F, 1); + if (!entity.isSneaky()) { + entity.getWorld().emitGameEvent(entity, GameEvent.STEP, entity.getBlockPos()); + } + } + } + + @Nullable + private Box getVehicleBox() { + if (vehicle == null) { + return null; + } + + Box entityBox = living.asEntity().getBoundingBox().stretch(living.asEntity().getVelocity()); + for (Box box : vehicle.getGravityZoneBoxes()) { + if (entityBox.intersects(box.expand(0.001).stretch(vehicleEntity.getVelocity().multiply(1)))) { + return box; + } + } + + setVehicle(null); + return null; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/collision/MultiBoundingBoxEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/collision/MultiBoundingBoxEntity.java index 82ab40ed..ac7b951e 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/collision/MultiBoundingBoxEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/collision/MultiBoundingBoxEntity.java @@ -1,13 +1,37 @@ package com.minelittlepony.unicopia.entity.collision; import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Stream; +import com.minelittlepony.unicopia.entity.collision.EntityCollisions.ComplexCollidable; + +import net.minecraft.block.ShapeContext; import net.minecraft.entity.Entity; +import net.minecraft.sound.SoundEvent; import net.minecraft.util.math.Box; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; -public interface MultiBoundingBoxEntity { +public interface MultiBoundingBoxEntity extends ComplexCollidable { List getBoundingBoxes(); + default List getGravityZoneBoxes() { + return getBoundingBoxes(); + } + + Map> getCollidingEntities(Stream boundingBoxes); + + SoundEvent getWalkedOnSound(double y); + + @Override + default void getCollissionShapes(ShapeContext context, Consumer output) { + for (Box box : getBoundingBoxes()) { + output.accept(VoxelShapes.cuboid(box)); + } + } + static List getBoundingBoxes(Entity entity) { return entity instanceof MultiBoundingBoxEntity multi ? multi.getBoundingBoxes() : List.of(entity.getBoundingBox()); } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java index 57cbc2ef..72bf2c6c 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java @@ -13,7 +13,9 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.NbtCompound; import net.minecraft.particle.ParticleTypes; +import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.registry.RegistryKey; +import net.minecraft.sound.SoundEvent; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; @@ -22,20 +24,22 @@ import net.minecraft.util.function.ValueLists; import net.minecraft.util.math.*; import net.minecraft.util.math.random.Random; import net.minecraft.util.shape.VoxelShape; -import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; -import java.util.Set; -import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.IntFunction; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.EquineContext; @@ -47,7 +51,6 @@ import com.minelittlepony.unicopia.entity.MagicImmune; import com.minelittlepony.unicopia.entity.collision.EntityCollisions; import com.minelittlepony.unicopia.entity.collision.MultiBoundingBoxEntity; import com.minelittlepony.unicopia.entity.collision.MultiBox; -import com.minelittlepony.unicopia.entity.duck.EntityDuck; import com.minelittlepony.unicopia.item.BasketItem; import com.minelittlepony.unicopia.item.HotAirBalloonItem; import com.minelittlepony.unicopia.item.UItems; @@ -61,13 +64,14 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp private static final TrackedData BASKET_TYPE = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.STRING); private static final TrackedData BALLOON_DESIGN = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER); + private static final Predicate RIDER_PREDICATE = EntityPredicates.EXCEPT_SPECTATOR.and(e -> { + return !(e instanceof PlayerEntity p && p.getAbilities().flying); + }); + private boolean prevBoosting; private int prevInflation; - private Vec3d oldPosition = Vec3d.ZERO; private Vec3d manualVelocity = Vec3d.ZERO; - private int ticksFlying; - public AirBalloonEntity(EntityType type, World world) { super(type, world); intersectionChecked = true; @@ -80,12 +84,12 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp dataTracker.startTracking(ASCENDING, false); dataTracker.startTracking(BOOSTING, 0); dataTracker.startTracking(INFLATION, 0); - dataTracker.startTracking(BASKET_TYPE, ""); + dataTracker.startTracking(BASKET_TYPE, BasketType.DEFAULT.id().toString()); dataTracker.startTracking(BALLOON_DESIGN, 0); } public BasketType getBasketType() { - return BasketType.REGISTRY.get(Identifier.tryParse(dataTracker.get(BASKET_TYPE))); + return BasketType.of(dataTracker.get(BASKET_TYPE)); } public void setBasketType(BasketType type) { @@ -144,14 +148,6 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp return hasBalloon() && hasBurner() && getInflation() >= getMaxInflation(); } - @Override - public List getBoundingBoxes() { - if (hasBalloon() && getInflation(1) > 0.999F) { - return List.of(getInteriorBoundingBox(), getBalloonBoundingBox()); - } - return List.of(getInteriorBoundingBox()); - } - @Override public void tick() { setAir(getMaxAir()); @@ -248,86 +244,12 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp } prevBoosting = boosting; - oldPosition = getPos(); if (getFireTicks() > 0) { setFireTicks(1); } - if (!isOnGround() && (isAirworthy() || isSubmergedInWater() || isLeashed())) { - ticksFlying++; - } else { - ticksFlying = 0; - } - - updatePassengers(false); super.tick(); - setBoundingBox(MultiBox.of(getBoundingBox(), getBoundingBoxes())); - } - - private void updatePassengers(boolean move) { - Set alreadyTicked = new HashSet<>(); - for (Box box : getBoundingBoxes()) { - for (Entity e : getWorld().getOtherEntities(this, box.stretch(getVelocity().multiply(-1)).expand(0, 0.5, 0))) { - - if (e instanceof PlayerEntity p && p.getAbilities().flying) { - continue; - } - - if (!alreadyTicked.add(e)) { - continue; - } - - updatePassenger(e, box, e.getY() > getY() + 3); - } - } - } - - private void updatePassenger(Entity e, Box box, boolean inBalloon) { - - if (e instanceof AirBalloonEntity) { - return; - } - - if (ticksFlying > 0) { - if (Living.getOrEmpty(e).filter(living -> !living.setSupportingEntity(this)).isPresent()) { - return; - } - - Vec3d vel = getVelocity(); - - double height = box.getYLength(); - - if (height < 3 || e.getBoundingBox().minY > box.minY + height / 2D) { - if (vel.y > 0 && e.getBoundingBox().minY < box.maxY + 0.02) { - e.setPos(e.getX(), box.maxY, e.getZ()); - e.setOnGround(true); - } - if (vel.y < 0 && e.getBoundingBox().minY > box.maxY) { - e.setPos(e.getX(), box.maxY, e.getZ()); - e.setOnGround(true); - } - } - - Living.getOrEmpty(e).ifPresent(living -> { - living.setPositionOffset(e.getPos().subtract(oldPosition)); - living.updateRelativePosition(box); - - if (ticksFlying > 20 && living.getTicksInVehicle() > 20) { - UCriteria.RIDE_BALLOON.trigger(e); - } - }); - } - - if (getWorld().isClient) { - if (e.distanceTraveled > ((EntityDuck)e).getNextStepSoundDistance()) { - e.distanceTraveled--; - e.playSound(inBalloon ? USounds.ENTITY_HOT_AIR_BALLOON_STEP : USounds.ENTITY_HOT_AIR_BALLOON_BASKET_STEP, 0.5F, 1); - if (!e.isSneaky()) { - getWorld().emitGameEvent(e, GameEvent.STEP, getBlockPos()); - } - } - } } @Override @@ -459,12 +381,16 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp } @Override - protected void fall(double heightDifference, boolean onGround, BlockState state, BlockPos landedPosition) { + public Race getSpecies() { + return Race.UNSET; } @Override - public Race getSpecies() { - return Race.UNSET; + public SoundEvent getWalkedOnSound(double y) { + if (y >= getBalloonBoundingBox().minY) { + return USounds.ENTITY_HOT_AIR_BALLOON_STEP; + } + return USounds.ENTITY_HOT_AIR_BALLOON_BASKET_STEP; } @Override @@ -497,6 +423,18 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp move(MovementType.SELF, getVelocity()); setVelocity(getVelocity().multiply(slipperyness)); } + } else { + Map> collidingEntities = getCollidingEntities(getBoundingBoxes().stream()); + + for (Map.Entry> passengers : collidingEntities.entrySet()) { + for (Entity passenger : passengers.getValue()) { + Living living = Living.living(passenger); + if (living != null) { + living.getTransportation().setVehicle(this); + } + + } + } } updateLimbs(false); } @@ -507,17 +445,22 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp return false; } + @Override + protected Box calculateBoundingBox() { + return MultiBox.of(super.calculateBoundingBox(), getBoundingBoxes()); + } + @Override public Box getVisibilityBoundingBox() { if (hasBalloon()) { - return MultiBox.unbox(getBoundingBox()).union(getBalloonBoundingBox()); + return getBalloonBoundingBox().withMinY(getY()); } - return MultiBox.unbox(getBoundingBox()); + return getInteriorBoundingBox(); } protected Box getInteriorBoundingBox() { Box box = MultiBox.unbox(getBoundingBox()); - return box.withMinY(box.minY - 0.2).contract(0.2, 0, 0.2); + return box.withMinY(box.minY - 0.05).contract(0.15, 0, 0.15); } protected Box getBalloonBoundingBox() { @@ -528,34 +471,96 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp } @Override - public void getCollissionShapes(ShapeContext context, Consumer output) { + public List getGravityZoneBoxes() { + Box balloon = getBalloonBoundingBox().expand(0.001); + Box interior = getInteriorBoundingBox().expand(0.001); + return List.of( + // interior - basket to top of balloon + interior.withMaxY(balloon.minY).withMinY(interior.maxY), + // balloon + balloon.withMaxY(balloon.maxY + 0.5).withMinY(balloon.maxY) + ); - Box box = MultiBox.unbox(getBoundingBox()).expand(0.3, 0, 0.3); + } - double wallheight = box.maxY + 0.7; - double wallThickness = 0.7; + @Override + public List getBoundingBoxes() { + List boxes = new ArrayList<>(); + Box box = getInteriorBoundingBox(); + boxes.add(box); + + double wallheight = box.maxY + 0.72; + double wallThickness = 0.2; if (!getBasketType().isOf(BoatEntity.Type.BAMBOO)) { // front left (next to door) - output.accept(VoxelShapes.cuboid(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness + 0.2, wallheight, box.minZ + wallThickness))); + boxes.add(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness + 0.4, wallheight, box.minZ + wallThickness)); // front right (next to door) - output.accept(VoxelShapes.cuboid(new Box(box.maxX - wallThickness - 0.2, box.minY, box.minZ, box.maxX, wallheight, box.minZ + wallThickness))); + boxes.add(new Box(box.maxX - wallThickness - 0.4, box.minY, box.minZ, box.maxX, wallheight, box.minZ + wallThickness)); // back - output.accept(VoxelShapes.cuboid(new Box(box.minX, box.minY, box.maxZ - wallThickness, box.maxX, wallheight, box.maxZ))); + boxes.add(new Box(box.minX, box.minY, box.maxZ - wallThickness, box.maxX, wallheight, box.maxZ)); // left - output.accept(VoxelShapes.cuboid(new Box(box.maxX - wallThickness, box.minY, box.minZ, box.maxX, wallheight, box.maxZ))); + boxes.add(new Box(box.maxX - wallThickness, box.minY, box.minZ, box.maxX, wallheight, box.maxZ)); // right - output.accept(VoxelShapes.cuboid(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness, wallheight, box.maxZ))); + boxes.add(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness, wallheight, box.maxZ)); } - // top of balloon - if (hasBalloon() && getInflation() > 0) { - output.accept(VoxelShapes.cuboid(getBalloonBoundingBox())); + if (hasBalloon() && getInflation(1) > 0.999F) { + boxes.add(getBalloonBoundingBox()); + } + return boxes; + } + + @Override + public void move(MovementType movementType, Vec3d movement) { + Vec3d oldPos = this.getPos(); + List boundingBoxes = getGravityZoneBoxes(); + super.move(movementType, movement); + if (movementType == MovementType.SELF) { + Vec3d actualMovement = getPos().subtract(oldPos); + Map> collidingEntities = getCollidingEntities( + boundingBoxes.stream().map(box -> box.stretch(actualMovement)) + ); + + for (Map.Entry> passengers : collidingEntities.entrySet()) { + for (Entity passenger : passengers.getValue()) { + movePassenger(passenger, actualMovement); + } + } } } + private void movePassenger(Entity passenger, Vec3d movement) { + Living living = Living.living(passenger); + if (living != null) { + if (living.getPhysics().isGravityNegative()) { + movement = movement.multiply(1, -1, 1); + } + living.getTransportation().setVehicle(this); + } + + List shapes = new ArrayList<>(); + getCollissionShapes(ShapeContext.of(passenger), shapes::add); + movement = Entity.adjustMovementForCollisions(passenger, movement, passenger.getBoundingBox(), getWorld(), shapes); + + passenger.setPosition(passenger.getPos().add(movement)); + passenger.updateTrackedPosition(passenger.getX(), passenger.getY(), passenger.getZ()); + } + + @Override + public Map> getCollidingEntities(Stream boundingBoxes) { + return boundingBoxes.collect(Collectors.toMap(Function.identity(), box -> { + return getWorld().getOtherEntities(this, box.expand(0.001).stretch(getVelocity().multiply(1)), RIDER_PREDICATE).stream().distinct().toList(); + })); + } + + @Override + protected void fall(double heightDifference, boolean onGround, BlockState state, BlockPos landedPosition) { + } + + @Override public void readCustomDataFromNbt(NbtCompound compound) { super.readCustomDataFromNbt(compound); @@ -577,6 +582,10 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp compound.putInt("inflationAmount", getInflation()); } + static boolean isBetween(double value, double min, double max) { + return value >= min && value <= max; + } + @SuppressWarnings("deprecation") public enum BalloonDesign implements StringIdentifiable { NONE, @@ -607,6 +616,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp public record BasketType(Identifier id, @Nullable BoatEntity.Type boatType) { private static final Map REGISTRY = new HashMap<>(); + public static final BasketType DEFAULT = of(BoatEntity.Type.OAK); static { Arrays.stream(BoatEntity.Type.values()).forEach(BasketType::of); } @@ -616,7 +626,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp } public static BasketType of(String name) { - Identifier id = Identifier.tryParse(name); + Identifier id = name == null || name.isEmpty() ? null : Identifier.tryParse(name); if (id == null) { return of(BoatEntity.Type.OAK); } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java index 6a9c29d3..13644fbb 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java @@ -21,11 +21,13 @@ import com.minelittlepony.unicopia.entity.duck.EntityDuck; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.ItemEntity; +import net.minecraft.entity.MovementType; import net.minecraft.entity.Entity.PositionUpdater; import net.minecraft.entity.Entity.RemovalReason; import net.minecraft.fluid.Fluid; import net.minecraft.item.ItemStack; import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; @Mixin(Entity.class) @@ -118,4 +120,20 @@ abstract class MixinEntity implements EntityDuck { info.setReturnValue(null); } } + + @Inject(method = "move", at = @At("HEAD")) + private void beforeMove(MovementType movementType, Vec3d movement, CallbackInfo info) { + Living living = Living.living((Entity)(Object)this); + if (living != null) { + living.getTransportation().updatePreviousPosition(); + } + } + + @Inject(method = "move", at = @At("RETURN")) + private void afterMove(MovementType movementType, Vec3d movement, CallbackInfo info) { + Living living = Living.living((Entity)(Object)this); + if (living != null) { + living.getTransportation().onMove(movementType); + } + } } From 3ff7466a543efffd232019421c679541d475231f Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 28 Mar 2024 13:47:54 +0000 Subject: [PATCH 42/73] Balloons now require fuel to run --- .../unicopia/entity/mob/AirBalloonEntity.java | 75 +++++++++++++++---- 1 file changed, 59 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java index 72bf2c6c..690c1a6b 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.entity.mob; import net.fabricmc.fabric.api.tag.convention.v1.ConventionalItemTags; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; +import net.minecraft.block.entity.FurnaceBlockEntity; import net.minecraft.entity.*; import net.minecraft.entity.data.*; import net.minecraft.entity.mob.MobEntity; @@ -72,6 +73,9 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp private int prevInflation; private Vec3d manualVelocity = Vec3d.ZERO; + private int maxFuel = 100; + private int fuel; + public AirBalloonEntity(EntityType type, World world) { super(type, world); intersectionChecked = true; @@ -174,6 +178,14 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp } setInflation(inflation); } + + if (fuel > -6 && age % 60 == 0) { + fuel -= boosting ? 10 : 1; + if (fuel <= -6) { + setBoostTicks(0); + setAscending(false); + } + } } else { if (inflation < getMaxInflation() && inflation > 0) { setInflation(--inflation); @@ -196,15 +208,16 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp if (hasBurner() && isAscending()) { Vec3d burnerPos = getPos().add(0, 3, 0); for (int i = 0; i < (boosting ? 6 : 1); i++) { - getWorld().addParticle( - getStackInHand(Hand.MAIN_HAND).isOf(Items.SOUL_LANTERN) + getWorld().addParticle(fuel <= 0 + ? ParticleTypes.SMOKE + : getStackInHand(Hand.MAIN_HAND).isOf(Items.SOUL_LANTERN) ? ParticleTypes.SOUL_FIRE_FLAME : ParticleTypes.FLAME, rng.nextTriangular(burnerPos.x, 0.25), rng.nextTriangular(burnerPos.y, 1), rng.nextTriangular(burnerPos.z, 0.25), 0, - Math.max(0, getVelocity().y + (boosting ? 0.1 : 0)), + (boosting ? 0.1 : 0), 0 ); } @@ -236,7 +249,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp if (leashPost.distanceTo(pos) >= 5) { Vec3d newVel = leashPost.subtract(pos).multiply(0.01); if (isAirworthy()) { - setVelocity(newVel.lengthSquared() < 0.03 ? Vec3d.ZERO : newVel); + setVelocity(newVel.lengthSquared() < 0.0001 ? Vec3d.ZERO : newVel); } else { setVelocity(getVelocity().multiply(0.9).add(newVel)); } @@ -277,11 +290,20 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp if (!getWorld().isClient) { manualVelocity = manualVelocity.add(0.3 * xPush, 0, 0.3 * zPush); } - } else if (stack.isEmpty() && isAscending()) { - setBoostTicks(50); + getWorld().playSound(null, getX() + hitPos.getX(), getY() + hitPos.getY(), getZ() + hitPos.getZ(), USounds.Vanilla.ENTITY_LEASH_KNOT_PLACE, getSoundCategory(), 1, 1); if (!player.isSneaky()) { getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos()); } + return ActionResult.SUCCESS; + } + + if (stack.isEmpty() && isAscending()) { + setBoostTicks(50); + playSound(USounds.ENTITY_HOT_AIR_BALLOON_BOOST, 1, 1); + if (!player.isSneaky()) { + getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos()); + } + return ActionResult.SUCCESS; } } } @@ -309,9 +331,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp } if (stack.isIn(ConventionalItemTags.SHEARS) && hasBalloon()) { - if (!player.getAbilities().creativeMode) { - stack.damage(1, player, p -> p.sendToolBreakStatus(hand)); - } + stack.damage(1, player, p -> p.sendToolBreakStatus(hand)); setDesign(BalloonDesign.NONE); dropItem(UItems.GIANT_BALLOON); playSound(USounds.ENTITY_HOT_AIR_BALLOON_EQUIP_CANOPY, 1, 1); @@ -336,6 +356,25 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp return ActionResult.SUCCESS; } + if (hasBurner()) { + int fuel = FurnaceBlockEntity.createFuelTimeMap().getOrDefault(stack.getItem(), 0); + if (fuel > 0) { + if (this.fuel < maxFuel) { + if (this.fuel < 0) { + this.fuel = fuel; + } else { + this.fuel += fuel; + } + if (!player.getAbilities().creativeMode) { + stack.decrement(1); + } + playSound(USounds.Vanilla.ENTITY_VILLAGER_YES, 1, 1); + return ActionResult.SUCCESS; + } + return ActionResult.FAIL; + } + } + return ActionResult.PASS; } @@ -474,13 +513,15 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp public List getGravityZoneBoxes() { Box balloon = getBalloonBoundingBox().expand(0.001); Box interior = getInteriorBoundingBox().expand(0.001); - return List.of( - // interior - basket to top of balloon - interior.withMaxY(balloon.minY).withMinY(interior.maxY), - // balloon - balloon.withMaxY(balloon.maxY + 0.5).withMinY(balloon.maxY) - ); - + if (hasBalloon() && getInflation(1) > 0.999F) { + return List.of( + // interior - basket to top of balloon + interior.withMaxY(balloon.minY).withMinY(interior.maxY), + // balloon + balloon.withMaxY(balloon.maxY + 0.5).withMinY(balloon.maxY) + ); + } + return List.of(interior.withMaxY(balloon.minY).withMinY(interior.maxY)); } @Override @@ -570,6 +611,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp setBoostTicks(compound.getInt("boostTicks")); prevInflation = compound.getInt("inflationAmount"); setInflation(prevInflation); + fuel = MathHelper.clamp(compound.getInt("fuel"), 0, maxFuel); } @Override @@ -580,6 +622,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp compound.putBoolean("burnerActive", isAscending()); compound.putInt("boostTicks", getBoostTicks()); compound.putInt("inflationAmount", getInflation()); + compound.putInt("fuel", fuel); } static boolean isBetween(double value, double min, double max) { From 101a560a012feeabef96eacbd20d4cdf9abd86e1 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 28 Mar 2024 13:48:12 +0000 Subject: [PATCH 43/73] Improve hot air balloon animations and fix formatting --- .../render/entity/AirBalloonEntityModel.java | 168 +++++++++++------- 1 file changed, 103 insertions(+), 65 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityModel.java b/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityModel.java index 5934bd8d..03c14bf9 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityModel.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityModel.java @@ -22,54 +22,50 @@ public class AirBalloonEntityModel extends EntityModel { private final List ropes; - public AirBalloonEntityModel(ModelPart root) { - this.root = root; - isBurner = root.hasChild("burner"); - isBalloon = root.hasChild("canopy"); + public AirBalloonEntityModel(ModelPart root) { + this.root = root; + isBurner = root.hasChild("burner"); + isBalloon = root.hasChild("canopy"); - if (isBurner || isBalloon) { - ModelPart part = root.getChild(isBalloon ? "canopy" : "burner"); - ropes = List.of( - part.getChild("rope_a"), - part.getChild("rope_b"), - part.getChild("rope_c"), - part.getChild("rope_d") - ); - } else { - ropes = List.of(); - } - } + if (isBurner || isBalloon) { + ModelPart part = root.getChild(isBalloon ? "canopy" : "burner"); + ropes = List.of(part.getChild("rope_a"), part.getChild("rope_b"), part.getChild("rope_c"), + part.getChild("rope_d")); + } else { + ropes = List.of(); + } + } - public static TexturedModelData getBasketModelData() { - ModelData modelData = new ModelData(); - ModelPartData root = modelData.getRoot(); - ModelPartData basket = root.addChild("basket", ModelPartBuilder.create().uv(0, 0).cuboid(-16, -1, -16, 32, 2, 30, Dilation.NONE), ModelTransform.pivot(0, 24, 0)); - basket.addChild("walls", ModelPartBuilder.create().uv(0, 66).cuboid(-17, -12, -16, 2, 11, 30, Dilation.NONE) - .uv(64, 68).cuboid(15, -12, -16, 2, 11, 30, Dilation.NONE) - .uv(80, 38).cuboid(-16, -12, -17, 32, 11, 2, Dilation.NONE) - .uv(0, 32).cuboid(8, -12, 13, 8, 11, 2, Dilation.NONE) - .uv(0, 6).cuboid(-16, -12, 13, 8, 11, 2, Dilation.NONE), ModelTransform.NONE); - basket.addChild("rim", ModelPartBuilder.create().uv(40, 34).cuboid(-18, -13, -17, 4, 2, 32, Dilation.NONE) - .uv(0, 32).cuboid(14, -13, -17, 4, 2, 32, Dilation.NONE) - .uv(80, 32).cuboid(-17, -13, -18, 34, 2, 4, Dilation.NONE) - .uv(0, 19).cuboid(7, -13, 12, 10, 2, 4, Dilation.NONE) - .uv(0, 0).cuboid(-17, -13, 12, 10, 2, 4, Dilation.NONE), ModelTransform.NONE); - return TexturedModelData.of(modelData, 256, 128); - } + public static TexturedModelData getBasketModelData() { + ModelData modelData = new ModelData(); + ModelPartData root = modelData.getRoot(); + ModelPartData basket = root.addChild("basket", ModelPartBuilder.create().uv(0, 0).cuboid(-16, -1, -16, 32, 2, 30, Dilation.NONE), ModelTransform.pivot(0, 24, 0)); + basket.addChild("walls", ModelPartBuilder.create().uv(0, 66).cuboid(-17, -12, -16, 2, 11, 30, Dilation.NONE) + .uv(64, 68).cuboid(15, -12, -16, 2, 11, 30, Dilation.NONE) + .uv(80, 38).cuboid(-16, -12, -17, 32, 11, 2, Dilation.NONE) + .uv(0, 32).cuboid(8, -12, 13, 8, 11, 2, Dilation.NONE) + .uv(0, 6).cuboid(-16, -12, 13, 8, 11, 2, Dilation.NONE), ModelTransform.NONE); + basket.addChild("rim", ModelPartBuilder.create().uv(40, 34).cuboid(-18, -13, -17, 4, 2, 32, Dilation.NONE) + .uv(0, 32).cuboid(14, -13, -17, 4, 2, 32, Dilation.NONE) + .uv(80, 32).cuboid(-17, -13, -18, 34, 2, 4, Dilation.NONE) + .uv(0, 19).cuboid(7, -13, 12, 10, 2, 4, Dilation.NONE) + .uv(0, 0).cuboid(-17, -13, 12, 10, 2, 4, Dilation.NONE), ModelTransform.NONE); + return TexturedModelData.of(modelData, 256, 128); + } - public static TexturedModelData getBurnerModelData() { + public static TexturedModelData getBurnerModelData() { ModelData modelData = new ModelData(); ModelPartData root = modelData.getRoot(); ModelPartData burner = root.addChild("burner", ModelPartBuilder.create().uv(8, 0).cuboid(-6, -47, -6, 11, 15, 11, Dilation.NONE), ModelTransform.pivot(0, 24, 0)); - burner.addChild("rope_d", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(-5, -46, -6, 0.7854F, 0, -0.7854F)); - burner.addChild("rope_c", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(-4, -44, 3, -0.7854F, 0, -0.7854F)); - burner.addChild("rope_b", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of( 5, -46, 1, -0.7854F, 0, 0.7854F)); - burner.addChild("rope_a", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of( 5, -45, -6, 0.7854F, 0, 0.7854F)); + burner.addChild("rope_d", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(-5, -46, -6, 0.7854F, 0, -0.7854F)); + burner.addChild("rope_c", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(-4, -44, 3, -0.7854F, 0, -0.7854F)); + burner.addChild("rope_b", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(5, -46, 1, -0.7854F, 0, 0.7854F)); + burner.addChild("rope_a", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(5, -45, -6, 0.7854F, 0, 0.7854F)); return TexturedModelData.of(modelData, 64, 128); } - public static TexturedModelData getCanopyModelData() { + public static TexturedModelData getCanopyModelData() { ModelData modelData = new ModelData(); ModelPartData root = modelData.getRoot(); ModelPartData balloon = root.addChild("canopy", ModelPartBuilder.create().cuboid(-54, -178, -59, 112, 120, 112, Dilation.NONE), ModelTransform.pivot(0, 24, 0)); @@ -80,40 +76,82 @@ public class AirBalloonEntityModel extends EntityModel { return TexturedModelData.of(modelData, 512, 256); } - @Override - public void setAngles(AirBalloonEntity entity, float tickDelta, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { - inflation = entity.getInflation(tickDelta); - root.roll = MathHelper.sin((float)(entity.getX() - entity.prevX)); - root.pitch = MathHelper.sin((float)(entity.getZ() - entity.prevZ)); + @Override + public void setAngles(AirBalloonEntity entity, float tickDelta, float limbSwingAmount, float ageInTicks, + float netHeadYaw, float headPitch) { + inflation = entity.getInflation(tickDelta); - if (isBurner) { - boolean lifted = inflation > 0.8F; - root.pivotY = 32 * (1 - inflation); - root.pivotX = inflation * MathHelper.sin(limbSwingAmount + entity.age / 5F) / 4F; - ropes.forEach(rope -> rope.visible = lifted); - } + if (isBurner || isBalloon) { + root.roll = MathHelper.clamp((float) (entity.getX() - entity.lastRenderX), -0.5F, 0.5F); + root.pitch = MathHelper.clamp((float) (entity.getZ() - entity.lastRenderZ), -0.5F, 0.5F); + if (entity.isLeashed()) { + root.roll *= -1; + root.pitch *= -1; + } + } else { + root.pitch = 0; + root.roll = 0; + } - if (isBalloon) { - root.pivotY = 0; - root.pivotX = inflation * MathHelper.cos(limbSwingAmount + entity.age / 5F) / 4F; - if (entity.getBasketType().isOf(BoatEntity.Type.BAMBOO)) { - ropes.forEach(rope -> rope.pivotY = 0); - } else { - ropes.forEach(ModelPart::resetTransform); - } - } - } + for (ModelPart rope : ropes) { + rope.resetTransform(); + } - @Override - public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int light, int overlay, float r, float g, float b, float a) { - if (isBalloon) { - matrices.push(); - matrices.translate(0, 1 * (1 - inflation), 0); + if (isBurner) { + boolean lifted = inflation > 0.8F; + root.pivotY = 32 * (1 - inflation); + root.pivotX = inflation * MathHelper.sin(limbSwingAmount + entity.age / 5F) / 4F; + ropes.forEach(rope -> { + rope.visible = lifted; + rope.pitch *= 0.125; + rope.roll *= 0.125; + }); + } + if (isBalloon) { + root.pivotY = 0; + root.pivotX = inflation * MathHelper.cos(limbSwingAmount + entity.age / 5F) / 4F; + if (entity.getBasketType().isOf(BoatEntity.Type.BAMBOO)) { + ropes.forEach(rope -> rope.pivotY = 0); + } else { + ropes.forEach(ModelPart::resetTransform); + } + } + + for (int i = 0; i < ropes.size(); i++) { + ModelPart rope = ropes.get(i); + float rollRatio = root.roll / rope.roll; + float pitchRatio = root.pitch / rope.pitch; + + rope.pivotY -= 5F * rollRatio; + rope.pivotY -= 5F * pitchRatio; + + if (i == 0 || i == 3) { + rope.pivotZ -= 5 * pitchRatio; + } + if (i == 2 || i == 1) { + rope.pivotZ += 5 * pitchRatio; + } + + if (i == 2 || i == 3) { + rope.pivotX -= 5 * rollRatio; + } + if (i == 0 || i == 1) { + rope.pivotX += 5 * rollRatio; + } + } + + } + + @Override + public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int light, int overlay, float r, float g, float b, float a) { + if (isBalloon) { + matrices.push(); + matrices.translate(0, 1 * (1 - inflation), 0); matrices.scale(1, MathHelper.lerp(inflation, -0.05F, 1), 1); root.render(matrices, vertexConsumer, light, overlay, r, g, b, a); matrices.pop(); } else { root.render(matrices, vertexConsumer, light, overlay, r, g, b, a); } - } + } } \ No newline at end of file From 6b3b5c7c86d817d378a30fe199f647a635255251 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 28 Mar 2024 14:51:55 +0000 Subject: [PATCH 44/73] Added baited fishing rod --- .../unicopia/UConventionalTags.java | 2 +- .../datagen/providers/UItemTagProvider.java | 2 +- .../datagen/providers/UModelProvider.java | 4 ++ .../providers/recipe/URecipeProvider.java | 7 ++++ .../unicopia/entity/mob/UEntities.java | 9 +++- .../unicopia/item/BaitedFishingRodItem.java | 39 ++++++++++++++++++ .../minelittlepony/unicopia/item/UItems.java | 1 + .../resources/assets/unicopia/lang/en_us.json | 1 + .../textures/item/baited_fishing_rod.png | Bin 0 -> 6420 bytes 9 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java create mode 100644 src/main/resources/assets/unicopia/textures/item/baited_fishing_rod.png diff --git a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java index e1a0a0b1..44e8571e 100644 --- a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java @@ -19,7 +19,7 @@ public interface UConventionalTags { TagKey MUSHROOMS = item("mushrooms"); TagKey MUFFINS = item("muffins"); TagKey MANGOES = item("mangoes"); - TagKey OEATMEALS = item("oatmeals"); + TagKey OATMEALS = item("oatmeals"); TagKey FRUITS = item("fruits"); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UItemTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UItemTagProvider.java index 058f636d..65c5d92a 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UItemTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UItemTagProvider.java @@ -169,7 +169,7 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { getOrCreateTagBuilder(UConventionalTags.SEEDS).add(Items.BEETROOT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.TORCHFLOWER_SEEDS, Items.WHEAT_SEEDS) .add(UItems.OAT_SEEDS) .forceAddTag(UTags.APPLE_SEEDS); - getOrCreateTagBuilder(UConventionalTags.OEATMEALS).add(UItems.OATMEAL); + getOrCreateTagBuilder(UConventionalTags.OATMEALS).add(UItems.OATMEAL); getOrCreateTagBuilder(UConventionalTags.GRAIN).add(Items.WHEAT, UItems.OATS); getOrCreateTagBuilder(UConventionalTags.NUTS).addOptionalTag(UConventionalTags.CROPS_PEANUTS); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java index 1c58e4f7..4a652170 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java @@ -19,6 +19,7 @@ import net.minecraft.item.Items; import net.minecraft.registry.Registries; import net.minecraft.data.client.ItemModelGenerator; import net.minecraft.data.client.ModelIds; +import net.minecraft.data.client.Models; import net.minecraft.data.client.TextureKey; import net.minecraft.data.client.TextureMap; @@ -133,5 +134,8 @@ public class UModelProvider extends FabricModelProvider { .addOverride(ModelIds.getItemSubModelId(UItems.GEMSTONE, "_pure"), "affinity", 0) .addOverride(ModelIds.getItemSubModelId(UItems.GEMSTONE, "_corrupted"), "affinity", 1) .upload(UItems.GEMSTONE, itemModelGenerator); + + // fishing rod + ItemModels.register(itemModelGenerator, Models.HANDHELD_ROD, UItems.BAITED_FISHING_ROD); } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index 57340e26..064c6493 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -76,6 +76,13 @@ public class URecipeProvider extends FabricRecipeProvider { .input(ConventionalItemTags.GLASS_BLOCKS) .input(UItems.SUNGLASSES).criterion("has_broken_sunglasses", conditionsFromItem(UItems.BROKEN_SUNGLASSES)) .offerTo(exporter, convertBetween(UItems.SUNGLASSES, UItems.BROKEN_SUNGLASSES)); + + // fishing + ShapelessRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.BAITED_FISHING_ROD) + .input(Items.FISHING_ROD).criterion(hasItem(Items.FISHING_ROD), conditionsFromItem(Items.FISHING_ROD)) + .input(UItems.WHEAT_WORMS) + .group("fishing_rod") + .offerTo(exporter); } private void generateVanillaRecipeExtensions(Consumer exporter) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java index 9200384f..8d6ea782 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/UEntities.java @@ -30,29 +30,34 @@ public interface UEntities { .dimensions(EntityDimensions.fixed(0.25F, 0.25F))); EntityType THROWN_ITEM = register("thrown_item", FabricEntityTypeBuilder.create(SpawnGroup.MISC, MagicProjectileEntity::new) .trackRangeBlocks(100) + .disableSummon() .trackedUpdateRate(2) .dimensions(EntityDimensions.fixed(0.25F, 0.25F))); EntityType MUFFIN = register("muffin", FabricEntityTypeBuilder.create(SpawnGroup.MISC, PhysicsBodyProjectileEntity::new) .trackRangeBlocks(100) + .disableSummon() .trackedUpdateRate(2) .dimensions(EntityDimensions.fixed(0.25F, 0.25F))); EntityType MAGIC_BEAM = register("magic_beam", FabricEntityTypeBuilder.create(SpawnGroup.MISC, MagicBeamEntity::new) .trackRangeBlocks(100) + .disableSummon() .trackedUpdateRate(2) .dimensions(EntityDimensions.fixed(0.25F, 0.25F))); EntityType FLOATING_ARTEFACT = register("floating_artefact", FabricEntityTypeBuilder.create(SpawnGroup.MISC, FloatingArtefactEntity::new) .trackRangeBlocks(200) + .disableSummon() .dimensions(EntityDimensions.fixed(1, 1))); EntityType CAST_SPELL = register("cast_spell", FabricEntityTypeBuilder.create(SpawnGroup.MISC, CastSpellEntity::new) .trackRangeBlocks(200) + .disableSummon() .dimensions(EntityDimensions.changing(4, 4))); EntityType TWITTERMITE = register("twittermite", FabricEntityTypeBuilder.create(SpawnGroup.MISC, FairyEntity::new) .trackRangeBlocks(200) .dimensions(EntityDimensions.fixed(0.1F, 0.1F))); EntityType FRIENDLY_CREEPER = register("friendly_creeper", FabricEntityTypeBuilder.create(SpawnGroup.MISC, FriendlyCreeperEntity::new) .trackRangeChunks(8) - .dimensions(EntityDimensions.fixed(0.6f, 1.7f)) - ); + .disableSummon() + .dimensions(EntityDimensions.fixed(0.6f, 1.7f))); EntityType SPELLBOOK = register("spellbook", FabricEntityTypeBuilder.create(SpawnGroup.MISC, SpellbookEntity::new) .trackRangeBlocks(200) .dimensions(EntityDimensions.fixed(0.9F, 0.5F))); diff --git a/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java b/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java new file mode 100644 index 00000000..6c0a03b3 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java @@ -0,0 +1,39 @@ +package com.minelittlepony.unicopia.item; + +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.FishingBobberEntity; +import net.minecraft.item.FishingRodItem; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.world.World; + +public class BaitedFishingRodItem extends FishingRodItem { + + public BaitedFishingRodItem(Settings settings) { + super(settings); + } + + @Override + public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + TypedActionResult result = super.use(world, user, hand); + if (!world.isClient) { + if (user.fishHook != null) { + user.fishHook.discard(); + ItemStack stack = user.getStackInHand(hand); + int lure = (EnchantmentHelper.getLure(stack) + 1) * 2; + int luck = (EnchantmentHelper.getLuckOfTheSea(stack) + 1) * 2; + world.spawnEntity(new FishingBobberEntity(user, world, luck, lure)); + } + + if (result.getValue().isOf(this)) { + ItemStack stack = Items.FISHING_ROD.getDefaultStack(); + stack.setDamage(result.getValue().getDamage()); + return TypedActionResult.success(stack, world.isClient()); + } + } + return result; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index ce60d14b..5e365031 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -89,6 +89,7 @@ public interface UItems { Item HORSE_SHOE_FRIES = register("horse_shoe_fries", new Item(new Item.Settings().maxCount(32).food(UFoodComponents.HAY_FRIES)), ItemGroups.FOOD_AND_DRINK); Item WHEAT_WORMS = register("wheat_worms", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.WORMS)), ItemGroups.NATURAL); + Item BAITED_FISHING_ROD = register("baited_fishing_rod", new BaitedFishingRodItem(new Item.Settings().maxDamage(64)), ItemGroups.TOOLS); Item MUFFIN = register("muffin", new MuffinItem(new Item.Settings().maxCount(32).food(FoodComponents.BREAD), 0), ItemGroups.FOOD_AND_DRINK); Item PINECONE = register("pinecone", new ForageableItem(new Item.Settings().food(UFoodComponents.PINECONE).maxCount(16), () -> Blocks.SPRUCE_LEAVES), ItemGroups.FOOD_AND_DRINK); Item ACORN = register("acorn", new ForageableItem(new Item.Settings().food(UFoodComponents.ACORN).maxCount(16), () -> Blocks.OAK_LEAVES), ItemGroups.FOOD_AND_DRINK); diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 8558c7b3..35f8c79c 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -145,6 +145,7 @@ "item.unicopia.crispy_hay_fries": "Crispy Hay Fries", "item.unicopia.horse_shoe_fries": "Horse Shoe Fries", "item.unicopia.wheat_worms": "Wheat Worms", + "item.unicopia.baited_fishing_rod": "Baited Fishing Rod", "item.unicopia.muffin": "Muffin", "item.unicopia.oatmeal_cookie": "Oatmeal Cookie", "item.unicopia.pinecone_cookie": "Pinecone Cookie", diff --git a/src/main/resources/assets/unicopia/textures/item/baited_fishing_rod.png b/src/main/resources/assets/unicopia/textures/item/baited_fishing_rod.png new file mode 100644 index 0000000000000000000000000000000000000000..90e3a7f69f651bef042d6bc552fcd7dfc54b7602 GIT binary patch literal 6420 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 Date: Thu, 28 Mar 2024 15:32:00 +0000 Subject: [PATCH 45/73] Added recipe for getting pegasus feathers from gryphon feathers --- .../providers/UAdvancementsProvider.java | 1 + .../providers/recipe/URecipeProvider.java | 22 +++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java index 994082f4..c34a107b 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java @@ -63,6 +63,7 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(), Set.of(Race.BAT))).build(consumer, "blasphemy"); p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(Race.BAT), Set.of())).build(consumer, "sweet_sweet_revenge"); }); + root.child(UItems.BAITED_FISHING_ROD).showToast().announce().criterion("has_baited_fishing_rod", hasItems(UItems.BAITED_FISHING_ROD)).build(consumer, "bait"); root.child(UItems.OATS).showToast().announce().criterion("has_oats", hasItems(UItems.OATS)).build(consumer, "oats_so_easy"); root.child(Items.HAY_BLOCK).showToast().announce().criterion("eat_hay", ConsumeItemCriterion.Conditions.item(Items.HAY_BLOCK)).build(consumer, "what_the_hay"); root.child(UItems.COPPER_HORSE_SHOE).showToast().announce().criterion("has_horseshoe", hasItems(UTags.HORSE_SHOES)).build(consumer, "blacksmith").children(p -> { diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index 064c6493..2161b97a 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -76,13 +76,6 @@ public class URecipeProvider extends FabricRecipeProvider { .input(ConventionalItemTags.GLASS_BLOCKS) .input(UItems.SUNGLASSES).criterion("has_broken_sunglasses", conditionsFromItem(UItems.BROKEN_SUNGLASSES)) .offerTo(exporter, convertBetween(UItems.SUNGLASSES, UItems.BROKEN_SUNGLASSES)); - - // fishing - ShapelessRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.BAITED_FISHING_ROD) - .input(Items.FISHING_ROD).criterion(hasItem(Items.FISHING_ROD), conditionsFromItem(Items.FISHING_ROD)) - .input(UItems.WHEAT_WORMS) - .group("fishing_rod") - .offerTo(exporter); } private void generateVanillaRecipeExtensions(Consumer exporter) { @@ -469,6 +462,12 @@ public class URecipeProvider extends FabricRecipeProvider { // worms offerReversibleCompactingRecipes(exporter, RecipeCategory.BUILDING_BLOCKS, UItems.WHEAT_WORMS, RecipeCategory.BUILDING_BLOCKS, UBlocks.WORM_BLOCK); + // fishing + ShapelessRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.BAITED_FISHING_ROD) + .input(Items.FISHING_ROD).criterion(hasItem(Items.FISHING_ROD), conditionsFromItem(Items.FISHING_ROD)) + .input(UItems.WHEAT_WORMS) + .group("fishing_rod") + .offerTo(exporter); // utility ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, Items.DIRT) @@ -480,6 +479,15 @@ public class URecipeProvider extends FabricRecipeProvider { offerShapelessRecipe(exporter, Items.BONE_MEAL, UTags.SHELLS, "bonemeal", 3); + // pegasus feathers for non pegasi + ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.PEGASUS_FEATHER) + .input('*', Items.GHAST_TEAR).criterion("has_ghast_tear", conditionsFromItem(Items.GHAST_TEAR)) + .input('#', UItems.GRYPHON_FEATHER).criterion("has_feather", conditionsFromItem(UItems.GRYPHON_FEATHER)) + .pattern("***") + .pattern("*#*") + .pattern("***") + .offerTo(exporter); + offer2x2CompactingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, Items.COBBLESTONE, UItems.ROCK); offerReversibleCompactingRecipesWithReverseRecipeGroup(exporter, RecipeCategory.MISC, UItems.PEBBLES, RecipeCategory.BUILDING_BLOCKS, Blocks.GRAVEL, convertBetween(UItems.PEBBLES, Blocks.GRAVEL), "pebbles"); offerShapelessRecipe(exporter, UItems.PEBBLES, Blocks.SUSPICIOUS_GRAVEL, "pebbles", 9); From 82b74ecb18befd405ec8c4037aadc011ed3c7339 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 28 Mar 2024 15:32:21 +0000 Subject: [PATCH 46/73] Added feather touch enchantment --- .../unicopia/EquineContext.java | 11 ++++++++- .../unicopia/block/cloud/CloudBlock.java | 2 +- .../block/cloud/CloudPillarBlock.java | 19 +-------------- .../unicopia/entity/Living.java | 7 +++++- .../unicopia/item/cloud/CloudBlockItem.java | 3 +-- .../item/enchantment/UEnchantments.java | 9 ++++++++ .../mixin/MixinEntityShapeContext.java | 23 +++---------------- .../resources/assets/unicopia/lang/en_us.json | 4 ++++ .../tags/items/groups/earth_pony.json | 1 + 9 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/EquineContext.java b/src/main/java/com/minelittlepony/unicopia/EquineContext.java index 2bd9bf0b..d9dd0a9f 100644 --- a/src/main/java/com/minelittlepony/unicopia/EquineContext.java +++ b/src/main/java/com/minelittlepony/unicopia/EquineContext.java @@ -25,11 +25,16 @@ public interface EquineContext { return getCompositeRace().canInteractWithClouds(); } + default boolean hasFeatherTouch() { + return false; + } + static EquineContext of(ShapeContext context) { if (context == ShapeContext.absent()) { return Unicopia.SIDE.getPony().map(EquineContext.class::cast).orElse(ABSENT); } - return context instanceof EquineContext c ? c : ABSENT; + EquineContext result = context instanceof Container c ? c.get() : ABSENT; + return result == null ? ABSENT : result; } static EquineContext of(ItemUsageContext context) { @@ -42,4 +47,8 @@ public interface EquineContext { } return MoreObjects.firstNonNull(Equine.of(entity).orElse(null), ABSENT); } + + interface Container { + EquineContext get(); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java index 490d7e4d..2479021c 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java @@ -171,7 +171,7 @@ public class CloudBlock extends Block implements CloudLike { } protected boolean canInteract(BlockState state, BlockView world, BlockPos pos, EquineContext context) { - return context.collidesWithClouds(); + return context.collidesWithClouds() || context.hasFeatherTouch(); } @SuppressWarnings("deprecation") diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java index baeb2f16..690cbf75 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java @@ -63,24 +63,7 @@ public class CloudPillarBlock extends CloudBlock { @Override protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context, EquineContext equineContext) { - var axis = state.get(AXIS); - - int[] offsets = { axis.choose(1, 0, 0), axis.choose(0, 1, 0), axis.choose(0, 0, 1) }; - float capOffset = 11F / 16F; - VoxelShape core = Block.createCuboidShape( - axis.choose(0, 1, 1), axis.choose(1, 0, 1), axis.choose(1, 1, 0), - 16 - axis.choose(0, 1, 1), 16 - axis.choose(1, 0, 1), 16 - axis.choose(1, 1, 0) - ); - VoxelShape foot = Block.createCuboidShape(0, 0, 0, 16 - (11 * offsets[0]), 16 - (11 * offsets[1]), 16 - (11 * offsets[2])); - VoxelShape cap = foot.offset(capOffset * offsets[0], capOffset * offsets[1], capOffset * offsets[2]); - var temp = new VoxelShape[] { - core, - VoxelShapes.union(core, foot), - VoxelShapes.union(core, cap), - VoxelShapes.union(core, cap, foot) - }; - return temp[(state.get(TOP) ? 0 : 2) + (state.get(BOTTOM) ? 0 : 1)]; - //return SHAPES.apply(state.get(AXIS))[(state.get(TOP) ? 0 : 2) + (state.get(BOTTOM) ? 0 : 1)]; + return SHAPES.apply(state.get(AXIS))[(state.get(TOP) ? 0 : 2) + (state.get(BOTTOM) ? 0 : 1)]; } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index 86ea4261..fecfe073 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -30,6 +30,7 @@ import com.minelittlepony.unicopia.input.Heuristic; import com.minelittlepony.unicopia.input.Interactable; import com.minelittlepony.unicopia.item.GlassesItem; import com.minelittlepony.unicopia.item.UItems; +import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.network.datasync.EffectSync; import com.minelittlepony.unicopia.network.datasync.Transmittable; import com.minelittlepony.unicopia.particle.ParticleUtils; @@ -198,6 +199,11 @@ public abstract class Living implements Equine, Caste return vehicle != null && getCarrierId().filter(vehicle.getUuid()::equals).isPresent(); } + @Override + public boolean hasFeatherTouch() { + return EnchantmentHelper.getEquipmentLevel(UEnchantments.FEATHER_TOUCH, entity) > 0; + } + @Override public boolean beforeUpdate() { if (EffectUtils.getAmplifier(entity, UEffects.PARALYSIS) > 1 && entity.getVelocity().horizontalLengthSquared() > 0) { @@ -205,7 +211,6 @@ public abstract class Living implements Equine, Caste updateVelocity(); } - //transportation.updateSupportingEntity(); return false; } diff --git a/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudBlockItem.java b/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudBlockItem.java index f208e723..d4b34d81 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudBlockItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudBlockItem.java @@ -19,8 +19,7 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; -public class CloudBlockItem -extends BlockItem { +public class CloudBlockItem extends BlockItem { public CloudBlockItem(Block block, Item.Settings settings) { super(block, settings); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/enchantment/UEnchantments.java b/src/main/java/com/minelittlepony/unicopia/item/enchantment/UEnchantments.java index 2085f490..a5143773 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/enchantment/UEnchantments.java +++ b/src/main/java/com/minelittlepony/unicopia/item/enchantment/UEnchantments.java @@ -40,6 +40,15 @@ public interface UEnchantments { */ Enchantment PADDED = register("padded", new SimpleEnchantment(Options.armor().rarity(Rarity.UNCOMMON).maxLevel(3).traded().table())); + /** + * Allows non-flying races to mine and interact with cloud blocks + * + * Appears in: + * - Trades + * - Enchanting Table + */ + Enchantment FEATHER_TOUCH = register("feather_touch", new SimpleEnchantment(Options.create(EnchantmentTarget.BREAKABLE, UEnchantmentValidSlots.HANDS).rarity(Rarity.UNCOMMON).traded().table())); + /** * Heavy players move more slowly but are less likely to be flung around wildly. * diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityShapeContext.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityShapeContext.java index 9e375403..b0930e75 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityShapeContext.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityShapeContext.java @@ -9,15 +9,13 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minelittlepony.unicopia.EquineContext; -import com.minelittlepony.unicopia.Race; - import net.minecraft.block.EntityShapeContext; import net.minecraft.entity.Entity; import net.minecraft.fluid.FluidState; import net.minecraft.item.ItemStack; @Mixin(EntityShapeContext.class) -abstract class MixinEntityShapeContext implements EquineContext { +abstract class MixinEntityShapeContext implements EquineContext.Container { private EquineContext equineContext; @Inject(method = "", at = @At("TAIL")) @@ -26,22 +24,7 @@ abstract class MixinEntityShapeContext implements EquineContext { } @Override - public Race getSpecies() { - return equineContext.getSpecies(); - } - - @Override - public Race.Composite getCompositeRace() { - return equineContext.getCompositeRace(); - } - - @Override - public float getCloudWalkingStrength() { - return equineContext.getCloudWalkingStrength(); - } - - @Override - public boolean collidesWithClouds() { - return equineContext.collidesWithClouds(); + public EquineContext get() { + return equineContext; } } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 35f8c79c..23edf9ea 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -1339,6 +1339,8 @@ "enchantment.unicopia.heart_bound.desc": "Causes an item to stay with you after you die", "enchantment.unicopia.consumption": "Consumption", "enchantment.unicopia.consumption.desc": "Converts drops mined using a tool into raw experience", + "enchantment.unicopia.feather_touch": "Feather Touch", + "enchantment.unicopia.feather_touch.desc": "Allows breaking and placing cloud blocks when held", "commands.race.success.self": "Set own race to %1$s", "commands.race.success": "%1$s changed race to %2$s", @@ -1615,6 +1617,8 @@ "advancements.unicopia.lightning_bug.description": "Attract 10 lightning strikes as a changeling", "advancements.unicopia.wonder_bolt.title": "Wonder Bolt", "advancements.unicopia.wonder_bolt.description": "Attract 10 lightning strikes", + "advancements.unicopia.bait.title": "Is This Bait?", + "advancements.unicopia.bait.description": "Put some worms on a hook", "advancements.unicopia.jar.title": "Oh wow. What's this?", "advancements.unicopia.jar.description": "Find an empty jar", "advancements.unicopia.gotcha.title": "Got'cha!", diff --git a/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json b/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json index e3ec6fc3..51b9f951 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json +++ b/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json @@ -58,6 +58,7 @@ "unicopia:crispy_hay_fries", "unicopia:horse_shoe_fries", "unicopia:wheat_worms", + "unicopia:baited_fishing_rod", "unicopia:worm_block", "unicopia:muffin", "unicopia:acorn", From 11f0bbc4e472f3f8119a895ad583b15d1a85b6b7 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 28 Mar 2024 16:23:12 +0000 Subject: [PATCH 47/73] Move advancements back down the tree and add some advancements for seaponies and hippogriffs --- .../unicopia/ability/ChangeFormAbility.java | 2 + .../unicopia/advancement/UCriteria.java | 1 + .../providers/AdvancementDisplayBuilder.java | 5 + .../providers/UAdvancementsProvider.java | 95 ++++++++++--------- .../resources/assets/unicopia/lang/en_us.json | 9 +- 5 files changed, 67 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangeFormAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangeFormAbility.java index 64fabfa4..67aa667f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ChangeFormAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangeFormAbility.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.ability.data.Hit; +import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.FriendshipBraceletItem; @@ -79,6 +80,7 @@ public class ChangeFormAbility implements Ability { Race actualRace = isTransforming ? target.getSpecies() : Race.UNSET; target.setSpecies(supressed.or(player.getCompositeRace().potential())); target.setSuppressedRace(actualRace); + UCriteria.SEAPONY_TRANSITION.trigger(target.asEntity()); } }); diff --git a/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java b/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java index 339c0aac..06adc40c 100644 --- a/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java +++ b/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java @@ -30,6 +30,7 @@ public interface UCriteria { CustomEventCriterion.Trigger RIDE_BALLOON = CUSTOM_EVENT.createTrigger("ride_balloon"); CustomEventCriterion.Trigger CONSTRUCT_BALLOON = CUSTOM_EVENT.createTrigger("construct_balloon"); CustomEventCriterion.Trigger TELEPORT_ABOVE_WORLD = CUSTOM_EVENT.createTrigger("teleport_above_world"); + CustomEventCriterion.Trigger SEAPONY_TRANSITION = CUSTOM_EVENT.createTrigger("seapony_transition"); static void bootstrap() { } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java index 40f5d832..cbacbcd3 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/AdvancementDisplayBuilder.java @@ -76,6 +76,11 @@ public class AdvancementDisplayBuilder { return this; } + public AdvancementDisplayBuilder doNotAnnounce() { + this.announce = false; + return this; + } + public AdvancementDisplayBuilder group(String group) { this.group = group; return this; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java index c34a107b..e0c2c349 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java @@ -51,58 +51,21 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { createTribeRootAdvancement(consumer, root, Race.EARTH).children(consumer, this::generateEarthTribeAdvancementsTree); createTribeRootAdvancement(consumer, root, Race.BAT).children(consumer, this::generateBatTribeAdvancementsTree); createTribeRootAdvancement(consumer, root, Race.PEGASUS).children(consumer, this::generatePegasusTribeAdvancementsTree); - createTribeRootAdvancement(consumer, root, Race.UNICORN).children(consumer, this::generateUnicornTribeAdvancementsTree); - - root.child(UItems.DRAGON_BREATH_SCROLL).showToast().announce().criterion("has_scroll", hasItems(UItems.DRAGON_BREATH_SCROLL)).build(consumer, "take_a_note").children(p -> { - p.child(UItems.DRAGON_BREATH_SCROLL).criterion("send_book", dragonScroll(false, Items.WRITTEN_BOOK)).build(consumer, "dear_princess") - .child(UItems.DRAGON_BREATH_SCROLL).criterion("send_scroll", dragonScroll(false, UItems.DRAGON_BREATH_SCROLL)).build(consumer, "i_await_your_reply"); - p.child(UItems.IMPORTED_OATS).hidden().frame(AdvancementFrame.CHALLENGE) - .criterion("send_oats", dragonScroll(false, UItems.OATS, UItems.IMPORTED_OATS)) - .criterion("receieve_oats", dragonScroll(true, UItems.IMPORTED_OATS)) - .criteriaMerger(CriterionMerger.OR).build(consumer, "imported_oats"); - p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(), Set.of(Race.BAT))).build(consumer, "blasphemy"); - p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(Race.BAT), Set.of())).build(consumer, "sweet_sweet_revenge"); - }); - root.child(UItems.BAITED_FISHING_ROD).showToast().announce().criterion("has_baited_fishing_rod", hasItems(UItems.BAITED_FISHING_ROD)).build(consumer, "bait"); - root.child(UItems.OATS).showToast().announce().criterion("has_oats", hasItems(UItems.OATS)).build(consumer, "oats_so_easy"); - root.child(Items.HAY_BLOCK).showToast().announce().criterion("eat_hay", ConsumeItemCriterion.Conditions.item(Items.HAY_BLOCK)).build(consumer, "what_the_hay"); - root.child(UItems.COPPER_HORSE_SHOE).showToast().announce().criterion("has_horseshoe", hasItems(UTags.HORSE_SHOES)).build(consumer, "blacksmith").children(p -> { - p.child(UItems.IRON_HORSE_SHOE).criterion("has_iron_horseshoe", hasItems(UItems.IRON_HORSE_SHOE)).build(consumer, "change_of_shoes") - .child(UItems.GOLDEN_HORSE_SHOE).criterion("has_gold_horseshoe", hasItems(UItems.GOLDEN_HORSE_SHOE)).build(consumer, "fashionably_expensive") - .child(UItems.NETHERITE_HORSE_SHOE).criterion("has_netherite_horseshoe", hasItems(UItems.NETHERITE_HORSE_SHOE)).build(consumer, "overkill"); - p.child(UItems.IRON_HORSE_SHOE).hidden().frame(AdvancementFrame.CHALLENGE).criterion("killed_entity_with_horseshoe", killWithItems(UTags.FROM_HORSESHOES)).build(consumer, "dead_ringer"); - }); - root.child(UItems.PINECONE).showToast().announce().frame(AdvancementFrame.CHALLENGE).criterion("eat_pinecone", ConsumeItemCriterion.Conditions.item(UItems.PINECONE)).build(consumer, "eat_pinecone"); - root.child(UItems.OAK_BASKET).showToast().criterion("has_basket", hasItems(UTags.BASKETS)).build(consumer, "basket_case") - .child(Items.LANTERN).showToast().criterion("construct_balloon", CustomEventCriterion.create("construct_balloon")).build(consumer, "aeronaut") - .child(UItems.GIANT_BALLOON).showToast().announce().frame(AdvancementFrame.CHALLENGE).criterion("ride_balloon", CustomEventCriterion.create("ride_balloon")).build(consumer, "travelling_in_style"); - root.child(UItems.MUFFIN).showToast().announce().hidden().criterion("has_muffin", hasItems(UItems.MUFFIN)).build(consumer, "baked_bads"); - root.child(UItems.HORSE_SHOE_FRIES).showToast().announce().criterion("has_horse_shoe_fries", hasItems(UItems.HORSE_SHOE_FRIES)).build(consumer, "lucky"); - root.child(UItems.TOAST).showToast().announce().criterion("has_toast", hasItems(UItems.TOAST)).build(consumer, "toast") - .child(UItems.BURNED_TOAST).hidden().criterion("has_burned_toast", hasItems(UItems.BURNED_TOAST)).build(consumer, "burn_toast"); - root.child(UItems.GREEN_APPLE).showToast().announce().criterion("has_apple", hasItems(UTags.FRESH_APPLES)).build(consumer, "apple_route").children(p -> { - p.child(UItems.SWEET_APPLE).criterion("has_all_apples", hasItems(Items.APPLE, UItems.GREEN_APPLE, UItems.SWEET_APPLE, UItems.SOUR_APPLE, UItems.ROTTEN_APPLE, UItems.ZAP_APPLE, UItems.COOKED_ZAP_APPLE, Items.GOLDEN_APPLE)).build(consumer, "sweet_apple_acres"); - p.child(UItems.ZAP_BULB).criterion("has_zap_apple", hasItems(UItems.ZAP_APPLE)).build(consumer, "trick_apple").children(pp -> { - pp.child(UItems.ZAP_APPLE).hidden().criterion("eat_trick_apple", CustomEventCriterion.createFlying("eat_trick_apple")).build(consumer, "eat_trick_apple"); - pp.child(UItems.ZAP_APPLE).hidden().criterion("feed_trick_apple", CustomEventCriterion.createFlying("feed_trick_apple")).build(consumer, "feed_trick_apple"); - }); - p.child(UItems.JUICE).criterion("has_juice", hasItems(UItems.JUICE)).build(consumer, "juice") - .child(UItems.BURNED_JUICE).hidden().criterion("has_burned_juice", hasItems(UItems.BURNED_JUICE)).build(consumer, "burn_juice") - .child(UItems.CIDER).visible().criterion("has_cider", hasItems(UItems.CIDER)).rewards(AdvancementRewards.Builder.experience(12)).build(consumer, "brew_cider"); - }); + createTribeRootAdvancement(consumer, root, Race.UNICORN, Race.ALICORN).children(consumer, this::generateUnicornTribeAdvancementsTree); + createTribeRootAdvancement(consumer, root, Race.HIPPOGRIFF, Race.SEAPONY).children(consumer, this::generateHippogrifTribeAdvancementsTree); }); generateEnchantmentsAdvancementsTree(consumer); } - private AdvancementDisplayBuilder.Parent createTribeRootAdvancement(Consumer consumer, AdvancementDisplayBuilder.Parent root, Race race) { + private AdvancementDisplayBuilder.Parent createTribeRootAdvancement(Consumer consumer, AdvancementDisplayBuilder.Parent root, Race race, Race...extra) { AdvancementDisplayBuilder builder = root.child(Registries.ITEM.get(race.getId().withSuffixedPath("_badge"))).showToast().announce().group(race.getId().getPath()) .criterion("be_" + race.getId().getPath(), new RaceChangeCriterion.Conditions(LootContextPredicate.EMPTY, race)); - if (race == Race.UNICORN) { - builder - .criterion("be_alicorn", new RaceChangeCriterion.Conditions(LootContextPredicate.EMPTY, Race.ALICORN)) - .criteriaMerger(CriterionMerger.OR); + if (extra.length > 0) { + for (Race r : extra) { + builder.criterion("be_" + r.getId().getPath(), new RaceChangeCriterion.Conditions(LootContextPredicate.EMPTY, r)); + } } return builder.build(consumer, race.getId().getPath() + "_route"); @@ -113,6 +76,33 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { p.child(UItems.PEBBLES).criterion("killed_entity_with_rock", killWithItems(UTags.FROM_ROCKS)).build(consumer, "sticks_and_stones"); p.child(UItems.WEIRD_ROCK).hidden().criterion("has_rock", hasItems(UItems.WEIRD_ROCK)).build(consumer, "thats_unusual"); }); + + parent.child(UItems.OATS).criterion("has_oats", hasItems(UItems.OATS)).build(consumer, "oats_so_easy"); + parent.child(Items.HAY_BLOCK).criterion("eat_hay", ConsumeItemCriterion.Conditions.item(Items.HAY_BLOCK)).build(consumer, "what_the_hay"); + parent.child(UItems.COPPER_HORSE_SHOE).criterion("has_horseshoe", hasItems(UTags.HORSE_SHOES)).build(consumer, "blacksmith").children(p -> { + p.child(UItems.IRON_HORSE_SHOE).criterion("has_iron_horseshoe", hasItems(UItems.IRON_HORSE_SHOE)).build(consumer, "change_of_shoes") + .child(UItems.GOLDEN_HORSE_SHOE).criterion("has_gold_horseshoe", hasItems(UItems.GOLDEN_HORSE_SHOE)).build(consumer, "fashionably_expensive") + .child(UItems.NETHERITE_HORSE_SHOE).criterion("has_netherite_horseshoe", hasItems(UItems.NETHERITE_HORSE_SHOE)).build(consumer, "overkill"); + p.child(UItems.IRON_HORSE_SHOE).hidden().frame(AdvancementFrame.CHALLENGE).criterion("killed_entity_with_horseshoe", killWithItems(UTags.FROM_HORSESHOES)).build(consumer, "dead_ringer"); + }); + parent.child(UItems.PINECONE).frame(AdvancementFrame.CHALLENGE).criterion("eat_pinecone", ConsumeItemCriterion.Conditions.item(UItems.PINECONE)).build(consumer, "eat_pinecone"); + parent.child(UItems.OAK_BASKET).doNotAnnounce().criterion("has_basket", hasItems(UTags.BASKETS)).build(consumer, "basket_case") + .child(Items.LANTERN).criterion("construct_balloon", CustomEventCriterion.create("construct_balloon")).build(consumer, "aeronaut") + .child(UItems.GIANT_BALLOON).announce().frame(AdvancementFrame.CHALLENGE).criterion("ride_balloon", CustomEventCriterion.create("ride_balloon")).build(consumer, "travelling_in_style"); + parent.child(UItems.MUFFIN).hidden().criterion("has_muffin", hasItems(UItems.MUFFIN)).build(consumer, "baked_bads"); + parent.child(UItems.HORSE_SHOE_FRIES).criterion("has_horse_shoe_fries", hasItems(UItems.HORSE_SHOE_FRIES)).build(consumer, "lucky"); + parent.child(UItems.TOAST).criterion("has_toast", hasItems(UItems.TOAST)).build(consumer, "toast") + .child(UItems.BURNED_TOAST).hidden().criterion("has_burned_toast", hasItems(UItems.BURNED_TOAST)).build(consumer, "burn_toast"); + parent.child(UItems.GREEN_APPLE).criterion("has_apple", hasItems(UTags.FRESH_APPLES)).build(consumer, "apple_route").children(p -> { + p.child(UItems.SWEET_APPLE).criterion("has_all_apples", hasItems(Items.APPLE, UItems.GREEN_APPLE, UItems.SWEET_APPLE, UItems.SOUR_APPLE, UItems.ROTTEN_APPLE, UItems.ZAP_APPLE, UItems.COOKED_ZAP_APPLE, Items.GOLDEN_APPLE)).build(consumer, "sweet_apple_acres"); + p.child(UItems.ZAP_BULB).criterion("has_zap_apple", hasItems(UItems.ZAP_APPLE)).build(consumer, "trick_apple").children(pp -> { + pp.child(UItems.ZAP_APPLE).hidden().criterion("eat_trick_apple", CustomEventCriterion.createFlying("eat_trick_apple")).build(consumer, "eat_trick_apple"); + pp.child(UItems.ZAP_APPLE).hidden().criterion("feed_trick_apple", CustomEventCriterion.createFlying("feed_trick_apple")).build(consumer, "feed_trick_apple"); + }); + p.child(UItems.JUICE).criterion("has_juice", hasItems(UItems.JUICE)).build(consumer, "juice") + .child(UItems.BURNED_JUICE).hidden().criterion("has_burned_juice", hasItems(UItems.BURNED_JUICE)).build(consumer, "burn_juice") + .child(UItems.CIDER).visible().criterion("has_cider", hasItems(UItems.CIDER)).rewards(AdvancementRewards.Builder.experience(12)).build(consumer, "brew_cider"); + }); } private void generatePegasusTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { @@ -169,6 +159,17 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { p.child(Items.WATER_BUCKET).criterion("split_sea", CustomEventCriterion.create("split_sea")).rewards(AdvancementRewards.Builder.experience(105)).build(consumer, "split_the_sea"); }); + parent.child(UItems.DRAGON_BREATH_SCROLL).showToast().announce().criterion("has_scroll", hasItems(UItems.DRAGON_BREATH_SCROLL)).build(consumer, "take_a_note").children(p -> { + p.child(UItems.DRAGON_BREATH_SCROLL).criterion("send_book", dragonScroll(false, Items.WRITTEN_BOOK)).build(consumer, "dear_princess") + .child(UItems.DRAGON_BREATH_SCROLL).criterion("send_scroll", dragonScroll(false, UItems.DRAGON_BREATH_SCROLL)).build(consumer, "i_await_your_reply"); + p.child(UItems.IMPORTED_OATS).hidden().frame(AdvancementFrame.CHALLENGE) + .criterion("send_oats", dragonScroll(false, UItems.OATS, UItems.IMPORTED_OATS)) + .criterion("receieve_oats", dragonScroll(true, UItems.IMPORTED_OATS)) + .criteriaMerger(CriterionMerger.OR).build(consumer, "imported_oats"); + p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(), Set.of(Race.BAT))).build(consumer, "blasphemy"); + p.child(Items.CHIPPED_ANVIL).hidden().frame(AdvancementFrame.CHALLENGE).criterion("ding_sun", dingCelestia(Set.of(Race.BAT), Set.of())).build(consumer, "sweet_sweet_revenge"); + }); + parent.child(UItems.PEGASUS_AMULET).hidden().frame(AdvancementFrame.CHALLENGE).criterion("teleport_above_world", CustomEventCriterion.create("teleport_above_world")).rewards(AdvancementRewards.Builder.experience(100)).build(consumer, "a_falling_wizard"); } @@ -182,6 +183,12 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { }); } + private void generateHippogrifTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { + parent.child(UItems.BAITED_FISHING_ROD).showToast().announce().criterion("has_baited_fishing_rod", hasItems(UItems.BAITED_FISHING_ROD)).build(consumer, "bait"); + parent.child(UItems.PEARL_NECKLACE).showToast().announce().criterion("seapony_transition", new CustomEventCriterion.Conditions(LootContextPredicate.EMPTY, "seapony_transition", RacePredicate.of(Set.of(Race.SEAPONY), Set.of()), null, 1)).build(consumer, "shoo_be_doo") + .child(UItems.PEARL_NECKLACE).showToast().announce().criterion("seapony_transition", new CustomEventCriterion.Conditions(LootContextPredicate.EMPTY, "seapony_transition", RacePredicate.of(Set.of(), Set.of(Race.SEAPONY)), null, 1)).build(consumer, "shoo_be_done"); + } + private void generateEnchantmentsAdvancementsTree(Consumer consumer) { AdvancementDisplayBuilder.create(Items.NETHERITE_SCRAP).showToast().announce() .criterion("enchant_with_consumption", enchant(UEnchantments.CONSUMPTION)) diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 23edf9ea..6b3a168b 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -1685,7 +1685,7 @@ "advancements.unicopia.blasphemy.title": "Blasphemy!", "advancements.unicopia.blasphemy.description": "Ding Celestia on the noggin. Oops!", - "advancements.unicopia.earth_route.title": "Path of the Pony", + "advancements.unicopia.earth_route.title": "Hearth of the Earth", "advancements.unicopia.earth_route.description": "Join the Apple Clan", "advancements.unicopia.sticks_and_stones.title": "Sticks and Stones", "advancements.unicopia.sticks_and_stones.description": "Kill a mob by throwing rocks at it", @@ -1766,6 +1766,13 @@ "advancements.unicopia.love_is_power.title": "Love is Power", "advancements.unicopia.love_is_power.description": "Banish King Sombra with a crystal heart", + "advancements.unicopia.hippogriff_route.title": "Splash of Seaquestria", + "advancements.unicopia.hippogriff_route.description": "Join the Hippogriff's nest", + "advancements.unicopia.shoo_be_doo.title": "Shoo Be Doo!", + "advancements.unicopia.shoo_be_doo.description": "Use a pearl necklace to turn into a sea creature", + "advancements.unicopia.shoo_be_done.title": "Shoo Be Done!", + "advancements.unicopia.shoo_be_done.description": "Use a pearl necklace to turn back to normal", + "unicopia.toast.discoveries.title": "New Discoveries!", "unicopia.toast.discoveries.description": "Check your spellbook" } From 5109b67de20943d865395e08692f232f7e791d05 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 28 Mar 2024 16:23:42 +0000 Subject: [PATCH 48/73] Revert seaponies back to normal if we're not able to respawn them underwater --- .../com/minelittlepony/unicopia/entity/player/Pony.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index 0c78666f..10efd22d 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -388,6 +388,13 @@ public class Pony extends Living implements Copyable, Update boolean mustAvoidAir = getCompositeRace().includes(Race.SEAPONY) && !sw.getFluidState(getOrigin()).isIn(FluidTags.WATER); if (mustAvoidSun || mustAvoidAir) { SpawnLocator.selectSpawnPosition(sw, entity, mustAvoidAir, mustAvoidSun); + if ((mustAvoidAir && !sw.getFluidState(getOrigin()).isIn(FluidTags.WATER)) + || (mustAvoidSun && MeteorlogicalUtil.isPositionExposedToSun(sw, getOrigin()))) { + Race suppressedRace = getSuppressedRace(); + if (suppressedRace != Race.UNSET) { + setSpecies(suppressedRace); + } + } } } ticksSunImmunity = INITIAL_SUN_IMMUNITY; From 10dc8ce6d76998e0074932d47fb63b6d1497b440 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 28 Mar 2024 17:05:04 +0000 Subject: [PATCH 49/73] Check against offline players when trying to see if a spell can modify blocks at a location. Closes #283 --- .../unicopia/ability/magic/Caster.java | 12 ++++- .../magic/spell/effect/HydrophobicSpell.java | 12 +++-- .../magic/spell/effect/InfernoSpell.java | 3 +- .../server/world/OfflinePlayerCache.java | 44 +++++++++++++++++++ 4 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/server/world/OfflinePlayerCache.java diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java index 2d662cb1..dc6f4ec3 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/Caster.java @@ -14,12 +14,14 @@ import com.minelittlepony.unicopia.entity.damage.UDamageSources; import com.minelittlepony.unicopia.particle.ParticleSource; import com.minelittlepony.unicopia.server.world.Ether; import com.minelittlepony.unicopia.server.world.ModificationType; +import com.minelittlepony.unicopia.server.world.OfflinePlayerCache; import com.minelittlepony.unicopia.util.SoundEmitter; import com.minelittlepony.unicopia.util.VecHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.GameRules; @@ -67,10 +69,18 @@ public interface Caster extends } if (getMaster() instanceof PlayerEntity player) { - if (!asWorld().canPlayerModifyAt(player, pos)) { + if (!player.canModifyBlocks() || !asWorld().canPlayerModifyAt(player, pos)) { return false; } } else { + if (asWorld() instanceof ServerWorld sw) { + @Nullable + PlayerEntity player = OfflinePlayerCache.getOfflinePlayer(sw, getMasterId().orElse(null)); + if (player != null && !player.canModifyBlocks() || !sw.canPlayerModifyAt(player, pos)) { + return false; + } + } + if (!asWorld().getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING)) { return false; } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java index d88d9dd0..ce21955f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/HydrophobicSpell.java @@ -61,7 +61,9 @@ public class HydrophobicSpell extends AbstractSpell { storedFluidPositions.removeIf(entry -> { if (!area.isPointInside(Vec3d.ofCenter(entry.pos()))) { - entry.restore(world); + if (source.canModifyAt(entry.pos())) { + entry.restore(world); + } return true; } @@ -72,7 +74,7 @@ public class HydrophobicSpell extends AbstractSpell { pos = new BlockPos(pos); BlockState state = world.getBlockState(pos); - if (state.getFluidState().isIn(affectedFluid)) { + if (source.canModifyAt(pos) && state.getFluidState().isIn(affectedFluid)) { Block block = state.getBlock(); if (block instanceof FluidBlock) { @@ -95,7 +97,7 @@ public class HydrophobicSpell extends AbstractSpell { source.spawnParticles(new Sphere(true, range), 10, pos -> { BlockPos bp = BlockPos.ofFloored(pos); - if (source.asWorld().getFluidState(bp.up()).isIn(affectedFluid)) { + if (source.canModifyAt(bp) && source.asWorld().getFluidState(bp.up()).isIn(affectedFluid)) { source.addParticle(UParticles.RAIN_DROPS, pos, Vec3d.ZERO); } }); @@ -116,7 +118,9 @@ public class HydrophobicSpell extends AbstractSpell { protected void onDestroyed(Caster caster) { Ether.get(caster.asWorld()).remove(this, caster); storedFluidPositions.removeIf(entry -> { - entry.restore(caster.asWorld()); + if (caster.canModifyAt(entry.pos())) { + entry.restore(caster.asWorld()); + } return true; }); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/InfernoSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/InfernoSpell.java index 5dc50a69..8c1869ee 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/InfernoSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/InfernoSpell.java @@ -48,8 +48,9 @@ public class InfernoSpell extends FireSpell { for (int i = 0; i < radius * 2; i++) { if (w.random.nextInt(12) == 0) { Vec3d vec = shape.computePoint(w.random).add(origin); + BlockPos pos = BlockPos.ofFloored(vec); - if (!applyBlocks(w, BlockPos.ofFloored(vec))) { + if (source.canModifyAt(pos) && !applyBlocks(w, pos)) { applyEntities(source, vec); } } diff --git a/src/main/java/com/minelittlepony/unicopia/server/world/OfflinePlayerCache.java b/src/main/java/com/minelittlepony/unicopia/server/world/OfflinePlayerCache.java new file mode 100644 index 00000000..03abf213 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/server/world/OfflinePlayerCache.java @@ -0,0 +1,44 @@ +package com.minelittlepony.unicopia.server.world; + +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.jetbrains.annotations.Nullable; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.mojang.authlib.GameProfile; + +import net.fabricmc.fabric.api.entity.FakePlayer; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; + +public class OfflinePlayerCache { + private static final LoadingCache> CACHE = CacheBuilder.newBuilder() + .expireAfterAccess(1, TimeUnit.MINUTES) + .build(CacheLoader.from(key -> { + ServerPlayerEntity offlinePlayer = FakePlayer.get(key.world(), new GameProfile(key.playerId(), "[Offline Player]")); + + if (key.world().getServer().getPlayerManager().loadPlayerData(offlinePlayer) != null) { + return Optional.of(offlinePlayer); + } + + return Optional.empty(); + })); + + @Nullable + public static ServerPlayerEntity getOfflinePlayer(ServerWorld world, UUID playerId) { + ServerPlayerEntity player = (ServerPlayerEntity)world.getPlayerByUuid(playerId); + if (player == null) { + player = world.getServer().getPlayerManager().getPlayer(playerId); + } + if (player == null) { + return CACHE.getUnchecked(new Key(world, playerId)).orElse(null); + } + return player; + } + + record Key (ServerWorld world, UUID playerId) {} +} From 3bab3c4f566ab868f053a4c17b8460b91ec5401c Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 28 Mar 2024 17:13:50 +0000 Subject: [PATCH 50/73] Add villagers to the list of entities that benefit from the crystal heart. Closes #184 --- .../minelittlepony/unicopia/item/CrystalHeartItem.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java b/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java index d1e4d3b4..17a2ebf2 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java @@ -20,6 +20,7 @@ import net.minecraft.block.BlockState; import net.minecraft.block.EndRodBlock; import net.minecraft.entity.*; import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.passive.MerchantEntity; import net.minecraft.entity.passive.TameableEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.*; @@ -34,7 +35,9 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Artifact { - static final Predicate TARGET_PREDICATE = EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.and(EntityPredicates.VALID_ENTITY).and(e -> (e instanceof PlayerEntity || e instanceof MobEntity)); + static final Predicate TARGET_PREDICATE = EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR + .and(EntityPredicates.VALID_ENTITY) + .and(e -> (e instanceof PlayerEntity || e instanceof MobEntity)); private static final Supplier> ITEM_MAP = Suppliers.memoize(() -> { return Map.of( Items.BUCKET, UItems.LOVE_BUCKET, @@ -126,7 +129,8 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art if (e instanceof PlayerEntity || (living instanceof TameableEntity && ((TameableEntity)living).isTamed()) - || (living instanceof Saddleable && ((Saddleable)living).isSaddled())) { + || (living instanceof Saddleable && ((Saddleable)living).isSaddled()) + || (living instanceof MerchantEntity)) { if (living.getHealth() < living.getMaxHealth()) { outputs.add(living); } From e65838b9434e4859dcb57d6fa82b61728d713a33 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 28 Mar 2024 21:30:28 +0000 Subject: [PATCH 51/73] Rewrite changeling ability to apply over time. Closes #312 --- .../ability/ChangelingFeedAbility.java | 111 +++--------- .../magic/spell/ChangelingFeedingSpell.java | 162 ++++++++++++++++++ .../ability/magic/spell/effect/SpellType.java | 2 + .../unicopia/entity/EntityReference.java | 8 +- .../unicopia/item/CrystalHeartItem.java | 21 +-- .../unicopia/util/NbtSerialisable.java | 2 +- 6 files changed, 202 insertions(+), 104 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ChangelingFeedingSpell.java diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java index b491bed3..7a4e1f76 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ChangelingFeedAbility.java @@ -2,26 +2,22 @@ package com.minelittlepony.unicopia.ability; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; +import java.util.function.Predicate; +import java.util.stream.Stream; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.ability.data.Hit; -import com.minelittlepony.unicopia.entity.damage.UDamageTypes; +import com.minelittlepony.unicopia.ability.magic.spell.ChangelingFeedingSpell; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.particle.FollowingParticleEffect; -import com.minelittlepony.unicopia.particle.ParticleUtils; -import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.util.TraceHelper; import com.minelittlepony.unicopia.util.VecHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.damage.DamageSource; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.mob.HostileEntity; import net.minecraft.entity.passive.CowEntity; import net.minecraft.entity.passive.MerchantEntity; @@ -34,6 +30,13 @@ import net.minecraft.particle.ParticleTypes; * Changeling ability to restore health from mobs */ public class ChangelingFeedAbility implements Ability { + private static final Predicate TARGET_PREDICATE = e -> (e instanceof LivingEntity) + && (e instanceof CowEntity + || e instanceof MerchantEntity + || e instanceof PlayerEntity + || e instanceof SheepEntity + || e instanceof PigEntity + || e instanceof HostileEntity); @Override public int getWarmupTime(Pony player) { @@ -42,7 +45,7 @@ public class ChangelingFeedAbility implements Ability { @Override public int getCooldownTime(Pony player) { - return canFeed(player) ? 15 : 80; + return !SpellType.FEED.isOn(player) && ChangelingFeedingSpell.canFeed(player) ? 15 : 80; } @Override @@ -53,22 +56,7 @@ public class ChangelingFeedAbility implements Ability { @Nullable @Override public Optional prepare(Pony player) { - return Hit.of(canFeed(player) && !getTargets(player).isEmpty()); - } - - private boolean canFeed(Pony player) { - return player.asEntity().getHealth() < player.asEntity().getMaxHealth() - || player.asEntity().canConsume(false); - } - - private boolean canDrain(Entity e) { - return (e instanceof LivingEntity) - && (e instanceof CowEntity - || e instanceof MerchantEntity - || e instanceof PlayerEntity - || e instanceof SheepEntity - || e instanceof PigEntity - || e instanceof HostileEntity); + return Hit.of(ChangelingFeedingSpell.canFeed(player) && !getTargets(player).findAny().isEmpty()); } @Override @@ -76,16 +64,6 @@ public class ChangelingFeedAbility implements Ability { return Hit.SERIALIZER; } - protected List getTargets(Pony player) { - List list = VecHelper.findInRange(player.asEntity(), player.asWorld(), player.getOriginVector(), 3, this::canDrain); - - TraceHelper.findEntity(player.asEntity(), 17, 1, - looked -> looked instanceof LivingEntity && !list.contains(looked) && canDrain(looked)) - .ifPresent(list::add); - - return list.stream().map(i -> (LivingEntity)i).collect(Collectors.toList()); - } - @Override public double getCostEstimate(Pony player) { return 0; @@ -93,7 +71,7 @@ public class ChangelingFeedAbility implements Ability { @Override public boolean apply(Pony iplayer, Hit data) { - if (!canFeed(iplayer)) { + if (!ChangelingFeedingSpell.canFeed(iplayer)) { return false; } @@ -103,64 +81,25 @@ public class ChangelingFeedAbility implements Ability { int maximumFoodGain = player.canConsume(false) ? (20 - player.getHungerManager().getFoodLevel()) : 0; if (maximumHealthGain > 0 || maximumFoodGain > 0) { + List targets = getTargets(iplayer).map(LivingEntity.class::cast).toList(); - float healAmount = 0; + if (targets.size() > 0) { + new ChangelingFeedingSpell(targets, maximumHealthGain, maximumFoodGain).apply(iplayer); - for (LivingEntity i : getTargets(iplayer)) { - healAmount += drainFrom(iplayer, i); + iplayer.playSound(USounds.ENTITY_PLAYER_CHANGELING_FEED, 0.1F, iplayer.getRandomPitch()); + return true; } - - int foodAmount = (int)Math.floor(Math.min(healAmount / 3, maximumFoodGain)); - - if (foodAmount > 0) { - healAmount -= foodAmount; - } - player.getHungerManager().add(Math.max(1, foodAmount), 0.125f); - - player.heal(Math.max(1, Math.min(healAmount, maximumHealthGain))); - } - - - if (!canFeed(iplayer)) { - iplayer.playSound(USounds.Vanilla.ENTITY_PLAYER_BURP, 1, (float)player.getWorld().random.nextTriangular(1F, 0.2F)); - } else { - iplayer.playSound(USounds.ENTITY_PLAYER_CHANGELING_FEED, 0.1F, iplayer.getRandomPitch()); } + iplayer.playSound(USounds.Vanilla.ENTITY_PLAYER_BURP, 1, (float)player.getWorld().random.nextTriangular(1F, 0.2F)); return true; } - public float drainFrom(Pony changeling, LivingEntity living) { - - DamageSource d = changeling.damageOf(UDamageTypes.LOVE_DRAINING, changeling); - - float damage = living.getHealth()/2; - - if (damage > 0) { - living.damage(d, damage); - } - - ParticleUtils.spawnParticles(UParticles.CHANGELING_MAGIC, living, 7); - ParticleUtils.spawnParticles(new FollowingParticleEffect(UParticles.HEALTH_DRAIN, changeling.asEntity(), 0.2F), living, 1); - - if (changeling.asEntity().hasStatusEffect(StatusEffects.NAUSEA)) { - StatusEffectInstance effect = changeling.asEntity().getStatusEffect(StatusEffects.NAUSEA); - changeling.asEntity().removeStatusEffect(StatusEffects.NAUSEA); - living.addStatusEffect(effect); - } else if (changeling.asWorld().random.nextInt(2300) == 0) { - living.addStatusEffect(new StatusEffectInstance(StatusEffects.WITHER, 20, 1)); - } - - if (living instanceof PlayerEntity) { - damage ++; - damage *= 1.6F; - - if (!changeling.asEntity().hasStatusEffect(StatusEffects.HEALTH_BOOST)) { - changeling.asEntity().addStatusEffect(new StatusEffectInstance(StatusEffects.HEALTH_BOOST, 13000, 1)); - } - } - - return damage; + protected Stream getTargets(Pony player) { + return Stream.concat( + VecHelper.findInRange(player.asEntity(), player.asWorld(), player.getOriginVector(), 3, TARGET_PREDICATE).stream(), + TraceHelper.findEntity(player.asEntity(), 17, 1, TARGET_PREDICATE).stream() + ).distinct(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ChangelingFeedingSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ChangelingFeedingSpell.java new file mode 100644 index 00000000..1bae80a1 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ChangelingFeedingSpell.java @@ -0,0 +1,162 @@ +package com.minelittlepony.unicopia.ability.magic.spell; + +import java.util.List; +import java.util.stream.Collectors; + +import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.ability.Abilities; +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.spell.effect.AbstractSpell; +import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.entity.EntityReference; +import com.minelittlepony.unicopia.entity.damage.UDamageTypes; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.particle.FollowingParticleEffect; +import com.minelittlepony.unicopia.particle.ParticleUtils; +import com.minelittlepony.unicopia.particle.UParticles; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.entity.effect.StatusEffects; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.util.math.MathHelper; + +public class ChangelingFeedingSpell extends AbstractSpell { + private List> targets = List.of(); + private int nextTargetIndex; + + private float healthToDrain; + private int foodToDrain; + + private float damageThisTick; + + public ChangelingFeedingSpell(CustomisedSpellType type) { + super(type); + setHidden(true); + } + + public ChangelingFeedingSpell(List feedTarget, float healthToDrain, int foodToDrain) { + this(SpellType.FEED.withTraits()); + this.targets = feedTarget.stream().map(EntityReference::new).collect(Collectors.toList() /* make mutable */); + this.healthToDrain = healthToDrain; + this.foodToDrain = foodToDrain; + } + + @Override + public boolean tick(Caster source, Situation situation) { + if (!(source instanceof Pony changeling) || situation != Situation.BODY || !source.canUse(Abilities.FEED)) { + return false; + } + + PlayerEntity player = changeling.asEntity(); + if (!canFeed(changeling)) { + changeling.playSound(USounds.Vanilla.ENTITY_PLAYER_BURP, 1, (float)player.getWorld().random.nextTriangular(1F, 0.2F)); + return false; + } + + float tickDrain = Math.min(0.05F, healthToDrain); + damageThisTick += tickDrain; + + if (damageThisTick > 1) { + damageThisTick--; + + float healAmount = drain(changeling, 1); + float foodAmount = Math.min(healAmount / 3F, foodToDrain); + if (foodAmount > 0) { + healAmount -= foodAmount; + } + + foodAmount = MathHelper.clamp(foodAmount, 0, foodToDrain); + healAmount = MathHelper.clamp(healAmount, 0, healthToDrain); + + int shanks = MathHelper.floor(foodAmount); + player.getHungerManager().add(shanks, foodAmount - shanks); + player.heal(healAmount); + + if (!canFeed(changeling)) { + changeling.playSound(USounds.Vanilla.ENTITY_PLAYER_BURP, 1, (float)player.getWorld().random.nextTriangular(1F, 0.2F)); + } else { + changeling.playSound(USounds.ENTITY_PLAYER_CHANGELING_FEED, 0.1F, changeling.getRandomPitch()); + } + + foodToDrain -= foodAmount; + healthToDrain -= healAmount; + } + + return !targets.isEmpty() && (healthToDrain > 0 || foodToDrain > 0); + } + + private float drain(Pony changeling, float max) { + List> targets = this.targets; + while (!targets.isEmpty()) { + int index = MathHelper.clamp(nextTargetIndex, 0, targets.size()); + LivingEntity l = targets.get(index).getOrEmpty(changeling.asWorld()).orElse(null); + if (l != null && !l.isRemoved() && l.distanceTo(changeling.asEntity()) < 4) { + nextTargetIndex = (nextTargetIndex + 1) % targets.size(); + return drainFrom(changeling, l, max); + } else { + targets.remove(index); + } + } + return 0; + } + + public float drainFrom(Pony changeling, LivingEntity living, float damage) { + DamageSource d = changeling.damageOf(UDamageTypes.LOVE_DRAINING, changeling); + + if (damage > 0) { + living.damage(d, damage); + } + + ParticleUtils.spawnParticles(UParticles.CHANGELING_MAGIC, living, 7); + ParticleUtils.spawnParticles(new FollowingParticleEffect(UParticles.HEALTH_DRAIN, changeling.asEntity(), 0.2F), living, 1); + + if (changeling.asEntity().hasStatusEffect(StatusEffects.NAUSEA)) { + StatusEffectInstance effect = changeling.asEntity().getStatusEffect(StatusEffects.NAUSEA); + changeling.asEntity().removeStatusEffect(StatusEffects.NAUSEA); + living.addStatusEffect(effect); + } else if (changeling.asWorld().random.nextInt(2300) == 0) { + living.addStatusEffect(new StatusEffectInstance(StatusEffects.WITHER, 20, 1)); + } + + if (living instanceof PlayerEntity) { + damage ++; + damage *= 1.6F; + + if (!changeling.asEntity().hasStatusEffect(StatusEffects.HEALTH_BOOST)) { + changeling.asEntity().addStatusEffect(new StatusEffectInstance(StatusEffects.HEALTH_BOOST, 13000, 1)); + } + } + + return damage; + } + + public static boolean canFeed(Pony player) { + return player.asEntity().getHealth() < player.asEntity().getMaxHealth() + || player.asEntity().canConsume(false); + } + + @Override + public void toNBT(NbtCompound compound) { + super.toNBT(compound); + compound.putFloat("healthToDrain", healthToDrain); + compound.putInt("foodToDrain", foodToDrain); + compound.putFloat("damageThisTick", damageThisTick); + compound.put("targets", EntityReference.getSerializer().writeAll(targets)); + } + + @Override + public void fromNBT(NbtCompound compound) { + super.fromNBT(compound); + healthToDrain = compound.getFloat("healthToDrain"); + foodToDrain = compound.getInt("foodToDrain"); + damageThisTick = compound.getFloat("damageThisTick"); + targets = compound.contains("targets", NbtElement.LIST_TYPE) + ? EntityReference.getSerializer().readAll(compound.getList("targets", NbtElement.COMPOUND_TYPE)).toList() + : List.of(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java index 63c5eddc..90bbed43 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java @@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.ability.magic.Affine; import com.minelittlepony.unicopia.ability.magic.SpellPredicate; +import com.minelittlepony.unicopia.ability.magic.spell.ChangelingFeedingSpell; import com.minelittlepony.unicopia.ability.magic.spell.DispersableDisguiseSpell; import com.minelittlepony.unicopia.ability.magic.spell.RainboomAbilitySpell; import com.minelittlepony.unicopia.ability.magic.spell.PlaceableSpell; @@ -49,6 +50,7 @@ public final class SpellType implements Affine, SpellPredicate< public static final SpellType THROWN_SPELL = register("thrown", Affinity.NEUTRAL, 0, false, SpellTraits.EMPTY, ThrowableSpell::new); public static final SpellType CHANGELING_DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, SpellTraits.EMPTY, DispersableDisguiseSpell::new); + public static final SpellType FEED = register("feed", Affinity.BAD, 0xBDBDF9, false, SpellTraits.EMPTY, ChangelingFeedingSpell::new); public static final SpellType RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, SpellTraits.EMPTY, RainboomAbilitySpell::new); public static final SpellType RAGE = register("rage", Affinity.GOOD, 0xBDBDF9, false, SpellTraits.EMPTY, RageAbilitySpell::new); public static final SpellType TIME_CONTROL = register("time_control", Affinity.GOOD, 0xBDBDF9, false, SpellTraits.EMPTY, TimeControlAbilitySpell::new); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java b/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java index b738bc85..ad6a4d4c 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/EntityReference.java @@ -11,7 +11,6 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Levelled; import com.minelittlepony.unicopia.util.NbtSerialisable; - import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtCompound; @@ -31,6 +30,13 @@ import net.minecraft.world.World; * @param The type of the entity this reference points to. */ public class EntityReference implements NbtSerialisable { + private static final Serializer SERIALIZER = Serializer.of(EntityReference::new); + + @SuppressWarnings("unchecked") + public static Serializer> getSerializer() { + return (Serializer>)SERIALIZER; + } + @Nullable private EntityValues reference; diff --git a/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java b/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java index 17a2ebf2..d4f9607c 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java @@ -128,9 +128,9 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art LivingEntity living = (LivingEntity)e; if (e instanceof PlayerEntity - || (living instanceof TameableEntity && ((TameableEntity)living).isTamed()) - || (living instanceof Saddleable && ((Saddleable)living).isSaddled()) - || (living instanceof MerchantEntity)) { + || (e instanceof TameableEntity t && t.isTamed()) + || (e instanceof Saddleable s && s.isSaddled()) + || (e instanceof MerchantEntity)) { if (living.getHealth() < living.getMaxHealth()) { outputs.add(living); } @@ -149,19 +149,8 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art return; } - float gives; - float takes; - - if (supply > demand) { - gives = supply / demand; - takes = 1; - } else if (demand > supply) { - takes = demand / supply; - gives = 1; - } else { - gives = 1; - takes = 1; - } + float gives = supply > demand ? supply / demand : 1; + float takes = demand > supply ? demand / supply : 1; inputs.forEach(input -> { input.damage(entity.damageOf(UDamageTypes.LIFE_DRAINING), takes); diff --git a/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java b/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java index a346c460..819153e5 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java +++ b/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java @@ -97,7 +97,7 @@ public interface NbtSerialisable { return read((NbtCompound)element); } - default NbtList writeAll(Collection ts) { + default NbtList writeAll(Collection ts) { NbtList list = new NbtList(); ts.stream().map(this::write).forEach(list::add); return list; From f8ff162d6c7672ca329d572d408405e5a14536cf Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 29 Mar 2024 12:31:33 +0000 Subject: [PATCH 52/73] Properly copy all stack attributes when consuming the bait from a fishing rod --- .../minelittlepony/unicopia/item/BaitedFishingRodItem.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java b/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java index 6c0a03b3..3efa7744 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/BaitedFishingRodItem.java @@ -30,7 +30,9 @@ public class BaitedFishingRodItem extends FishingRodItem { if (result.getValue().isOf(this)) { ItemStack stack = Items.FISHING_ROD.getDefaultStack(); - stack.setDamage(result.getValue().getDamage()); + if (result.getValue().hasNbt()) { + stack.setNbt(result.getValue().getNbt().copy()); + } return TypedActionResult.success(stack, world.isClient()); } } From f50095676009666cb7cdff0b9a73564e62fb08e7 Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 29 Mar 2024 20:31:49 +0000 Subject: [PATCH 53/73] - Fix hot air balloons not orienting correctly when placed - add sandbags that you interact with to steer them - fix various hitbox jankyness - exclude spectators from hot air balloon collision checks --- assets/models/hanging_sandbag.bbmodel | 1 + assets/models/hanging_sandbag.java | 33 +++ assets/models/hanging_sandbag.png | Bin 0 -> 1111 bytes assets/models/hay_bale.json | 113 ---------- .../render/entity/AirBalloonEntityModel.java | 133 +++++++++-- .../entity/AirBalloonEntityRenderer.java | 35 ++- .../unicopia/entity/Transportation.java | 4 + .../unicopia/entity/collision/MultiBox.java | 13 ++ .../unicopia/entity/mob/AirBalloonEntity.java | 211 +++++++++++++++--- .../unicopia/item/BasketItem.java | 7 +- .../entity/air_balloon/canopy/dawn.png | Bin 40513 -> 47517 bytes .../entity/air_balloon/canopy/equality.png | Bin 29128 -> 34931 bytes .../entity/air_balloon/canopy/luna.png | Bin 9462 -> 14266 bytes .../entity/air_balloon/canopy/storm.png | Bin 36277 -> 44060 bytes .../entity/air_balloon/canopy/tale.png | Bin 54492 -> 61165 bytes .../textures/entity/air_balloon/sandbags.png | Bin 0 -> 1111 bytes 16 files changed, 373 insertions(+), 177 deletions(-) create mode 100644 assets/models/hanging_sandbag.bbmodel create mode 100644 assets/models/hanging_sandbag.java create mode 100644 assets/models/hanging_sandbag.png delete mode 100644 assets/models/hay_bale.json create mode 100644 src/main/resources/assets/unicopia/textures/entity/air_balloon/sandbags.png diff --git a/assets/models/hanging_sandbag.bbmodel b/assets/models/hanging_sandbag.bbmodel new file mode 100644 index 00000000..463a3f37 --- /dev/null +++ b/assets/models/hanging_sandbag.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"4.9","model_format":"modded_entity","box_uv":true},"name":"hanging_sandbag","model_identifier":"","modded_entity_version":"Fabric 1.17+","modded_entity_flip_y":true,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"timeline_setups":[],"unhandled_root_fields":{},"resolution":{"width":32,"height":32},"elements":[{"name":"rope","box_uv":true,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[-0.5,-9,-0.5],"to":[0.5,0,0.5],"autouv":0,"color":7,"origin":[0,-22,0],"uv_offset":[16,19],"faces":{"north":{"uv":[17,20,18,29],"texture":0},"east":{"uv":[16,20,17,29],"texture":0},"south":{"uv":[19,20,20,29],"texture":0},"west":{"uv":[18,20,19,29],"texture":0},"up":{"uv":[18,20,17,19],"texture":0},"down":{"uv":[19,19,18,20],"texture":0}},"type":"cube","uuid":"023a3320-18c3-d968-3a13-56914da8e6f0"},{"name":"cube","box_uv":true,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[-3,-17,-3],"to":[3,-10,3],"autouv":0,"color":5,"origin":[0,-9,0],"faces":{"north":{"uv":[6,6,12,13],"texture":0},"east":{"uv":[0,6,6,13],"texture":0},"south":{"uv":[18,6,24,13],"texture":0},"west":{"uv":[12,6,18,13],"texture":0},"up":{"uv":[12,6,6,0],"texture":0},"down":{"uv":[18,0,12,6],"texture":0}},"type":"cube","uuid":"1ca3a675-33f5-744f-58f9-cf14867dcfb1"},{"name":"cube","box_uv":true,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[0,-22,-2],"to":[0,-18,2],"autouv":0,"color":9,"rotation":[0,-45,0],"origin":[0,-10,0],"uv_offset":[0,14],"faces":{"north":{"uv":[4,18,4,22],"texture":0},"east":{"uv":[0,18,4,22],"texture":0},"south":{"uv":[8,18,8,22],"texture":0},"west":{"uv":[4,18,8,22],"texture":0},"up":{"uv":[4,18,4,14],"texture":0},"down":{"uv":[4,14,4,18],"texture":0}},"type":"cube","uuid":"5cc3052b-c843-eec8-9326-2bfd1b1fd435"},{"name":"cube","box_uv":true,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[0,-22,-2],"to":[0,-18,2],"autouv":0,"color":9,"rotation":[0,45,0],"origin":[0,-10,0],"uv_offset":[0,14],"faces":{"north":{"uv":[4,18,4,22],"texture":0},"east":{"uv":[0,18,4,22],"texture":0},"south":{"uv":[8,18,8,22],"texture":0},"west":{"uv":[4,18,8,22],"texture":0},"up":{"uv":[4,18,4,14],"texture":0},"down":{"uv":[4,14,4,18],"texture":0}},"type":"cube","uuid":"9a732bc0-bf4d-cc97-85fb-674e15c88c5c"},{"name":"cube","box_uv":true,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[-2,-10,-2],"to":[2,-9,2],"autouv":0,"color":5,"origin":[0,-9,0],"uv_offset":[12,14],"faces":{"north":{"uv":[16,18,20,19],"texture":0},"east":{"uv":[12,18,16,19],"texture":0},"south":{"uv":[24,18,28,19],"texture":0},"west":{"uv":[20,18,24,19],"texture":0},"up":{"uv":[20,18,16,14],"texture":0},"down":{"uv":[24,14,20,18],"texture":0}},"type":"cube","uuid":"90ba7ded-8e83-43de-e4da-bb237f43bdd7"},{"name":"cube","box_uv":true,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[-2,-18,-2],"to":[2,-17,2],"autouv":0,"color":5,"origin":[0,-9,0],"uv_offset":[0,13],"faces":{"north":{"uv":[4,17,8,18],"texture":0},"east":{"uv":[0,17,4,18],"texture":0},"south":{"uv":[12,17,16,18],"texture":0},"west":{"uv":[8,17,12,18],"texture":0},"up":{"uv":[8,17,4,13],"texture":0},"down":{"uv":[12,13,8,17],"texture":0}},"type":"cube","uuid":"741187ae-e05b-4c69-1555-99303f3e9f04"}],"outliner":[{"name":"root","origin":[0,0,0],"color":0,"uuid":"ee7748d0-5b3e-59a3-7df5-d010791b2142","export":true,"mirror_uv":false,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["023a3320-18c3-d968-3a13-56914da8e6f0",{"name":"bag","origin":[0,-9,0],"color":0,"uuid":"ca7f77db-f514-0ae5-d753-742da3da9103","export":true,"mirror_uv":false,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["1ca3a675-33f5-744f-58f9-cf14867dcfb1","90ba7ded-8e83-43de-e4da-bb237f43bdd7","741187ae-e05b-4c69-1555-99303f3e9f04","5cc3052b-c843-eec8-9326-2bfd1b1fd435","9a732bc0-bf4d-cc97-85fb-674e15c88c5c"]}]}],"textures":[{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/assets/models/hanging_sandbag.png","name":"hanging_sandbag.png","folder":"block","namespace":"","id":"0","width":32,"height":32,"uv_width":32,"uv_height":32,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"b9376c08-3fa3-5dae-fbe1-2efee48a6e4b","relative_path":"../hanging_sandbag.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABEJJREFUWEftlktPW0cUx//GMTUYCLYxvn6AX7HBOA0hYAPqolLbtKqiqKpYRF100U9QqZGqLKp+gKpdpNu2yrqVomwatYryUFoEBuM6DY/EUBPbubavL2CDH4QEbFczrl3bwb4hKekms7l37plzzm/O/GfmilCnLd7zFYiJZVno9fryqMQmB5PRVuUV41g4h94U1YvV6Htdp1g8VJAc/TcxCbK7xSKX38NXF69Uxfz80w+h11heDsCsZxo3JtnDByBLoDadqEoUWpoFGw1BqTLjpyu/lW2HUoH9AOotwcfnnP+9BgiAQqFAMBiC0WhAIpGgM97eSdFnNBKDVqcpV+G5RXh76ipV++5jQNbajie5NLgYTwObLUZsJbehYbTYfryJaISDvFOOXkMPNtYy6FYrsBpcxmYyBWlzG6SyJnTJtXTnkHcS59zEJw3FKfrx8qXC2LgLybUsVIwCTU0AG45DLD4CZXcbTaTvYSA5IoXvjhe53BOYzRbw8TVIX5NBoWpDJMwhmebRbzsOlVIDr8+Dk4OnMDVzE2dOf9QYwPuHu6DtUeHBagjHrBY6kznvDFpbZLDbB7Cy4ofV2ofNNI8VfxBSqRSOgeO471+E1WpFLp9DlI2D53n0O8xYDYQh71CivbMFyY0MRk6NNwa4futqweUcw+LSn3AMDCKZ4rDOpdEkFoHRdiEcjsBkMiCX20Mssk6XRt/LgH3I0co0S1qxsHAX2cw2XC4XUtl1CjE85ML09BTeO31WGMBqNVNatVYBWUsnZj1uNDeL0W+3I/KQg+6fJZif90EslsAx8Dr8K/fRb7NTUd69s0TBSAU6ZF2YX/JBp9U9WwWoBkbfoAEy6Sw6jrZR8YhEIsiV7VjnE+jrsyOd2QIf36Dj1BoleC6BRzuZIoz/HoLhVbzz1vuYm/PQMSMjTly/+YuwCEu7gDiRxIymmwYgyh4cPIFUegsRNkq/6fRaqhXyvbKRMZO/u6FUyjHqGqemmdlp+hTcBVWRAPy8EKLbstTUu0FomOKd8CKXTm2eUv8pgRCAsWPFhO6/WMjTATRLxWX/2gOHVLCyct9+d6sq1+VLXzcW4X4VqAQ4qdyjMy+1egDErlHrcPGHa9CpGTo8EufwXAC1S1DZ3w+A2EV5CXoNvTj/5fcHA2BjgYLX68HwsJPOlKx3KBiCwWgoCo8x49FOmr63SNsx6f61qmj5Qr6cnBgIQGV7pgosL/sLNltfea08vtuFepcLuaQq/5JMRgsCgQAsFgvN+yAYoHcBaZV/UiUfh32oShO0QwDIk0CUkk9MfDB64YvP3Bc0c1UzusGcf0pUocQ16m9QvHvgv6J9HQgECUiq8Db3TWFMXTwb3HEetQCl5CXKg0IIEgsBZHfZqnNDJtELxqwsqeBgAlDp8NIrUHtO1PYPvQJCAIeuASGAVxV4VQEhjQjZBc8BoQAvav/fAf4GYEkKP0m+kyEAAAAASUVORK5CYII="}],"fabricOptions":{"header":"package com.example.mod;","entity":"Entity","render":"","members":""}} \ No newline at end of file diff --git a/assets/models/hanging_sandbag.java b/assets/models/hanging_sandbag.java new file mode 100644 index 00000000..00cf4263 --- /dev/null +++ b/assets/models/hanging_sandbag.java @@ -0,0 +1,33 @@ +// Made with Blockbench 4.9.4 +// Exported for Minecraft version 1.17+ for Yarn +// Paste this class into your mod and generate all required imports +public class hanging_sandbag extends EntityModel { + private final ModelPart root; + private final ModelPart bag; + private final ModelPart cube_r1; + private final ModelPart cube_r2; + public hanging_sandbag(ModelPart root) { + this.root = root.getChild("root"); + } + public static TexturedModelData getTexturedModelData() { + ModelData modelData = new ModelData(); + ModelPartData modelPartData = modelData.getRoot(); + ModelPartData root = modelPartData.addChild("root", ModelPartBuilder.create().uv(16, 19).cuboid(-0.5F, 0.0F, -0.5F, 1.0F, 9.0F, 1.0F, new Dilation(0.0F)), ModelTransform.pivot(0.0F, 24.0F, 0.0F)); + + ModelPartData bag = root.addChild("bag", ModelPartBuilder.create().uv(0, 0).cuboid(-3.0F, 1.0F, -3.0F, 6.0F, 7.0F, 6.0F, new Dilation(0.0F)) + .uv(12, 14).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 1.0F, 4.0F, new Dilation(0.0F)) + .uv(0, 13).cuboid(-2.0F, 8.0F, -2.0F, 4.0F, 1.0F, 4.0F, new Dilation(0.0F)), ModelTransform.pivot(0.0F, 9.0F, 0.0F)); + + ModelPartData cube_r1 = bag.addChild("cube_r1", ModelPartBuilder.create().uv(0, 14).cuboid(0.0F, 8.0F, -2.0F, 0.0F, 4.0F, 4.0F, new Dilation(0.0F)), ModelTransform.of(0.0F, 1.0F, 0.0F, 0.0F, -0.7854F, 0.0F)); + + ModelPartData cube_r2 = bag.addChild("cube_r2", ModelPartBuilder.create().uv(0, 14).cuboid(0.0F, 8.0F, -2.0F, 0.0F, 4.0F, 4.0F, new Dilation(0.0F)), ModelTransform.of(0.0F, 1.0F, 0.0F, 0.0F, 0.7854F, 0.0F)); + return TexturedModelData.of(modelData, 32, 32); + } + @Override + public void setAngles(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + } + @Override + public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int light, int overlay, float red, float green, float blue, float alpha) { + root.render(matrices, vertexConsumer, light, overlay, red, green, blue, alpha); + } +} \ No newline at end of file diff --git a/assets/models/hanging_sandbag.png b/assets/models/hanging_sandbag.png new file mode 100644 index 0000000000000000000000000000000000000000..fdee304fced6b73eca79fd27366c421052dfb625 GIT binary patch literal 1111 zcmV-d1gQIoP)$|J~es&z#>q=iGa)g+sLb zY{>*r6oq6mxjSC2sGLrn>sy;s6{e?dS`PcyQ99Hpw~;l4v1H#^r>fBHZSnDEU-ylF zc=r~`So%Z&)?p167Z*s`j7I}lt>6-U*lc!!VK+95!FVKqV2@MNn{2jQbh|y;ojSz=q*5u?tSVY9Pcm_l z@nDR6QRULbH!$im10!HPd-^;M!AYZKAP54o4x->fH;VMSCX&-b zz!wJK)I=PoC?iR3?6|QDRu-2Q@Oy)lwLFnvYA}FSEg?%jEEaG&+-SPWm?wZJI%%|Y zx@M2fP6LPFB;XI>lH7EsGWCW5fL9K2COv_smlzMmDV2(Y0RXg09!d02 zZ&vVoqiEFI$N8Ff{SKLr*1R=(CbCKatNE52q+&G^z+Tk*CW)BZ(e- zJ}(u$h+7IWKR-{?=-~5?v$Fc@KmdC*7AEt@?*OQ|Jki*8ek+XqvNJeqkh&^a8?3%+@pHTQl;IvHZo?Vd17 z(>Y8BUPRZdQ}#1RmIoCR3AxmH^x7v-AW2 z5|Jp0Nc32C2S#A-#a}x<&OINEg|YMmCMGA2<+Kk#$*q`+iwj)7JWWnjhy}OEX0p3G zPegCfY}EjeoF0C7@}RFqdS-8*^R*52*Z>xQ=g)sL&z*a1H&+Wwv*uyNw)||#-1|y8 zol3K^vO+qY24FR_f}(6kZSPBJ$L7NMslNa2reFtR$NBBsZ(qIl(ff1vVn6i(T!>EX z1Iv~lnuTV8$-rAfpO6C$7M5mBfa$55mN(T;&1;eE3ZL7^^KJBlKAUX$VP8syg*dPX zhdJvZ&+EhZJ08H_HMfyJbgo$YWh8)+Z?$?y=}UnuBu7udFd8)iBLn;=HE@((MPSqj dywd-!KLG}Nq;LyKVrBpU002ovPDHLkV1ken1&9Cu literal 0 HcmV?d00001 diff --git a/assets/models/hay_bale.json b/assets/models/hay_bale.json deleted file mode 100644 index a2ce1538..00000000 --- a/assets/models/hay_bale.json +++ /dev/null @@ -1,113 +0,0 @@ -{ - "textures": { - "top": "blocks/hay_block_top", - "particle": "blocks/hay_block_side", - "side": "blocks/hay_block_side" - }, - "elements": [ - { - "name": "bottom_south_east", - "from": [8, 0, 8], - "to": [16, 8, 16], - "faces": { - "north": {"uv": [0, 8, 8, 16], "texture": "#top"}, - "east": {"uv": [0, 8, 8, 16], "texture": "#side"}, - "south": {"uv": [8, 8, 16, 16], "texture": "#side"}, - "west": {"uv": [8, 8, 16, 16], "texture": "#top"}, - "up": {"uv": [8, 8, 16, 16], "texture": "#top"}, - "down": {"uv": [8, 0, 16, 8], "texture": "#top"} - } - }, - { - "name": "top_south_east", - "from": [8, 8, 8], - "to": [16, 16, 16], - "faces": { - "north": {"uv": [0, 0, 8, 8], "texture": "#top"}, - "east": {"uv": [0, 0, 8, 8], "texture": "#side"}, - "south": {"uv": [8, 0, 16, 8], "texture": "#side"}, - "west": {"uv": [8, 0, 16, 8], "texture": "#top"}, - "up": {"uv": [8, 8, 16, 16], "texture": "#top"}, - "down": {"uv": [8, 0, 16, 8], "texture": "#top"} - } - }, - { - "name": "bottom_north_east", - "from": [8, 0, 0], - "to": [16, 8, 8], - "faces": { - "north": {"uv": [0, 8, 8, 16], "texture": "#side"}, - "east": {"uv": [8, 8, 16, 16], "texture": "#side"}, - "south": {"uv": [8, 8, 16, 16], "texture": "#top"}, - "west": {"uv": [0, 8, 8, 16], "texture": "#top"}, - "up": {"uv": [8, 0, 16, 8], "texture": "#top"}, - "down": {"uv": [8, 8, 16, 16], "texture": "#top"} - } - }, - { - "name": "top_north_east", - "from": [8, 8, 0], - "to": [16, 16, 8], - "faces": { - "north": {"uv": [0, 0, 8, 8], "texture": "#side"}, - "east": {"uv": [8, 0, 16, 8], "texture": "#side"}, - "south": {"uv": [8, 0, 16, 8], "texture": "#top"}, - "west": {"uv": [0, 0, 8, 8], "texture": "#top"}, - "up": {"uv": [8, 0, 16, 8], "texture": "#top"}, - "down": {"uv": [8, 8, 16, 16], "texture": "#top"} - } - }, - { - "name": "bottom_south_west", - "from": [0, 0, 8], - "to": [8, 8, 16], - "faces": { - "north": {"uv": [8, 8, 16, 16], "texture": "#top"}, - "east": {"uv": [0, 8, 8, 16], "texture": "#top"}, - "south": {"uv": [0, 8, 8, 16], "texture": "#side"}, - "west": {"uv": [8, 8, 16, 16], "texture": "#side"}, - "up": {"uv": [0, 8, 8, 16], "texture": "#top"}, - "down": {"uv": [0, 0, 8, 8], "texture": "#top"} - } - }, - { - "name": "top_south_west", - "from": [0, 8, 8], - "to": [8, 16, 16], - "faces": { - "north": {"uv": [8, 0, 16, 8], "texture": "#top"}, - "east": {"uv": [0, 0, 8, 8], "texture": "#top"}, - "south": {"uv": [0, 0, 8, 8], "texture": "#side"}, - "west": {"uv": [8, 0, 16, 8], "texture": "#side"}, - "up": {"uv": [0, 8, 8, 16], "texture": "#top"}, - "down": {"uv": [0, 0, 8, 8], "texture": "#top"} - } - }, - { - "name": "bottom_north_west", - "from": [0, 0, 0], - "to": [8, 8, 8], - "faces": { - "north": {"uv": [8, 8, 16, 16], "texture": "#side"}, - "east": {"uv": [8, 8, 16, 16], "texture": "#top"}, - "south": {"uv": [0, 8, 8, 16], "texture": "#top"}, - "west": {"uv": [0, 8, 8, 16], "texture": "#side"}, - "up": {"uv": [0, 0, 8, 8], "texture": "#top"}, - "down": {"uv": [0, 8, 8, 16], "texture": "#top"} - } - }, - { - "name": "top_north_west", - "from": [0, 8, 0], - "to": [8, 16, 8], - "faces": { - "north": {"uv": [8, 0, 16, 8], "texture": "#side"}, - "east": {"uv": [8, 0, 16, 8], "texture": "#top"}, - "south": {"uv": [0, 0, 8, 8], "texture": "#top"}, - "west": {"uv": [0, 0, 8, 8], "texture": "#side"}, - "up": {"uv": [0, 0, 8, 8], "texture": "#top"}, - "down": {"uv": [0, 8, 8, 16], "texture": "#top"} - } - } - ] -} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityModel.java b/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityModel.java index 03c14bf9..1a543310 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityModel.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityModel.java @@ -4,6 +4,7 @@ import java.util.List; import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.model.*; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.entity.model.EntityModel; @@ -14,26 +15,37 @@ import net.minecraft.util.math.MathHelper; public class AirBalloonEntityModel extends EntityModel { private final ModelPart root; + private ModelPart main; private float inflation; private boolean isBurner; private boolean isBalloon; + private boolean isSandbags; private final List ropes; + private final List sandbags; public AirBalloonEntityModel(ModelPart root) { this.root = root; isBurner = root.hasChild("burner"); + isSandbags = root.hasChild("sandbag_ne"); isBalloon = root.hasChild("canopy"); if (isBurner || isBalloon) { - ModelPart part = root.getChild(isBalloon ? "canopy" : "burner"); - ropes = List.of(part.getChild("rope_a"), part.getChild("rope_b"), part.getChild("rope_c"), - part.getChild("rope_d")); + main = root.getChild(isBalloon ? "canopy" : "burner"); + ropes = List.of( + (isBurner ? root : main).getChild("rope_a"), (isBurner ? root : main).getChild("rope_b"), + (isBurner ? root : main).getChild("rope_c"), (isBurner ? root : main).getChild("rope_d") + ); } else { ropes = List.of(); } + + sandbags = isSandbags ? List.of( + root.getChild("sandbag_nw"), root.getChild("sandbag_sw"), + root.getChild("sandbag_ne"), root.getChild("sandbag_se") + ) : List.of(); } public static TexturedModelData getBasketModelData() { @@ -56,12 +68,34 @@ public class AirBalloonEntityModel extends EntityModel { public static TexturedModelData getBurnerModelData() { ModelData modelData = new ModelData(); ModelPartData root = modelData.getRoot(); + root.addChild("burner", ModelPartBuilder.create().uv(8, 0).cuboid(-5.5F, -47, -5.5F, 11, 15, 11, Dilation.NONE), ModelTransform.pivot(0, 24, 0)); + float angle = 0.37854F; + float half = MathHelper.HALF_PI; + root.addChild("rope_d", ModelPartBuilder.create().cuboid(0, -68, 0, 2, 66, 2, Dilation.NONE), ModelTransform.of(-0, -20, -0, angle, 0, -angle)); + root.addChild("rope_c", ModelPartBuilder.create().cuboid(0, -68, 0, 2, 66, 2, Dilation.NONE), ModelTransform.of(-0, -20, -0, -angle, 0, -angle)); + root.addChild("rope_b", ModelPartBuilder.create().cuboid(0, -68, 0, 2, 66, 2, Dilation.NONE), ModelTransform.of( 0, -20, 0, -angle, 0, angle)); + root.addChild("rope_a", ModelPartBuilder.create().cuboid(0, -68, 0, 2, 66, 2, Dilation.NONE), ModelTransform.of( 0, -20, 0, angle, 0, angle)); - ModelPartData burner = root.addChild("burner", ModelPartBuilder.create().uv(8, 0).cuboid(-6, -47, -6, 11, 15, 11, Dilation.NONE), ModelTransform.pivot(0, 24, 0)); - burner.addChild("rope_d", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(-5, -46, -6, 0.7854F, 0, -0.7854F)); - burner.addChild("rope_c", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(-4, -44, 3, -0.7854F, 0, -0.7854F)); - burner.addChild("rope_b", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(5, -46, 1, -0.7854F, 0, 0.7854F)); - burner.addChild("rope_a", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(5, -45, -6, 0.7854F, 0, 0.7854F)); + root.addChild("strut_a", ModelPartBuilder.create() + .cuboid(-27, -40, -30, 2, 40, 2, Dilation.NONE) + .cuboid(-27, 0, -30, 2, 40, 2, Dilation.NONE) + .cuboid( 27, -40, -30, 2, 40, 2, Dilation.NONE) + .cuboid( 27, 0, -30, 2, 40, 2, Dilation.NONE) + + .cuboid(-27, -40, 26, 2, 40, 2, Dilation.NONE) + .cuboid(-27, 0, 26, 2, 40, 2, Dilation.NONE) + .cuboid( 27, -40, 26, 2, 40, 2, Dilation.NONE) + .cuboid( 27, 0, 26, 2, 40, 2, Dilation.NONE), ModelTransform.of(0, -80, 0, half, 0, 0)); + root.addChild("strut_b", ModelPartBuilder.create() + .cuboid(-27, -40, -20, 2, 40, 2, Dilation.NONE) + .cuboid(-27, 0, -20, 2, 40, 2, Dilation.NONE) + .cuboid( 27, -40, -20, 2, 40, 2, Dilation.NONE) + .cuboid( 27, 0, -20, 2, 40, 2, Dilation.NONE) + + .cuboid(-27, -40, 30, 2, 40, 2, Dilation.NONE) + .cuboid(-27, 0, 30, 2, 40, 2, Dilation.NONE) + .cuboid( 27, -40, 30, 2, 40, 2, Dilation.NONE) + .cuboid( 27, 0, 30, 2, 40, 2, Dilation.NONE), ModelTransform.of(0, -80, 0, half, half, 0)); return TexturedModelData.of(modelData, 64, 128); } @@ -76,14 +110,40 @@ public class AirBalloonEntityModel extends EntityModel { return TexturedModelData.of(modelData, 512, 256); } + public static TexturedModelData getSandbagsModelData() { + ModelData modelData = new ModelData(); + ModelPartData root = modelData.getRoot(); + float offset = 40; + getHangingBagModelData("sandbag_ne", root, -offset, -offset); + getHangingBagModelData("sandbag_nw", root, -offset, offset); + getHangingBagModelData("sandbag_se", root, offset, -offset); + getHangingBagModelData("sandbag_sw", root, offset, offset); + return TexturedModelData.of(modelData, 32, 32); + } + + public static void getHangingBagModelData(String name, ModelPartData root, float x, float z) { + ModelPartData bag = root.addChild(name, ModelPartBuilder.create() + .uv(16, 19).cuboid(-0.5F, 0, -0.5F, 1, 9, 1, Dilation.NONE), ModelTransform.pivot(x, -35, z)); + ModelPartData knot = bag.addChild("knot", ModelPartBuilder.create() + .uv(0, 0).cuboid(-3, 1, -3, 6, 7, 6, Dilation.NONE) + .uv(12, 14).cuboid(-2, 0, -2, 4, 1, 4, Dilation.NONE) + .uv(0, 13).cuboid(-2, 8, -2, 4, 1, 4, Dilation.NONE), ModelTransform.pivot(0, 9, 0)); + knot.addChild("cube_r1", ModelPartBuilder.create().uv(8, 14).cuboid(0, 8, -2, 0, 4, 4, Dilation.NONE), ModelTransform.of(0, 1, 0, 0, -0.7854F, 0)); + knot.addChild("cube_r2", ModelPartBuilder.create().uv(8, 14).cuboid(0, 8, -2, 0, 4, 4, Dilation.NONE), ModelTransform.of(0, 1, 0, 0, 0.7854F, 0)); + } + @Override - public void setAngles(AirBalloonEntity entity, float tickDelta, float limbSwingAmount, float ageInTicks, - float netHeadYaw, float headPitch) { + public void setAngles(AirBalloonEntity entity, float limbDistance, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + float tickDelta = MinecraftClient.getInstance().getTickDelta(); inflation = entity.getInflation(tickDelta); - if (isBurner || isBalloon) { - root.roll = MathHelper.clamp((float) (entity.getX() - entity.lastRenderX), -0.5F, 0.5F); - root.pitch = MathHelper.clamp((float) (entity.getZ() - entity.lastRenderZ), -0.5F, 0.5F); + root.yaw = MathHelper.PI; + + float burnerWiggleProgress = entity.getBurner().getPullProgress(tickDelta); + + if (isBurner || isBalloon || isSandbags) { + root.roll = MathHelper.clamp(entity.getXVelocity(tickDelta), -0.5F, 0.5F); + root.pitch = MathHelper.clamp(entity.getZVelocity(tickDelta), -0.5F, 0.5F); if (entity.isLeashed()) { root.roll *= -1; root.pitch *= -1; @@ -93,27 +153,44 @@ public class AirBalloonEntityModel extends EntityModel { root.roll = 0; } - for (ModelPart rope : ropes) { - rope.resetTransform(); - } + ropes.forEach(ModelPart::resetTransform); if (isBurner) { boolean lifted = inflation > 0.8F; - root.pivotY = 32 * (1 - inflation); + root.pivotY = 32 * (1 - inflation) - (9 * inflation); root.pivotX = inflation * MathHelper.sin(limbSwingAmount + entity.age / 5F) / 4F; ropes.forEach(rope -> { rope.visible = lifted; - rope.pitch *= 0.125; - rope.roll *= 0.125; }); + + root.pivotX += burnerWiggleProgress * MathHelper.sin((entity.age + tickDelta)) * 2.5F; + root.pivotX += burnerWiggleProgress * MathHelper.cos((entity.age + tickDelta)) * 2.5F; + root.pivotY += burnerWiggleProgress * 7; } - if (isBalloon) { - root.pivotY = 0; + if (isBalloon || isSandbags) { + root.pivotY = burnerWiggleProgress * 3; root.pivotX = inflation * MathHelper.cos(limbSwingAmount + entity.age / 5F) / 4F; if (entity.getBasketType().isOf(BoatEntity.Type.BAMBOO)) { ropes.forEach(rope -> rope.pivotY = 0); - } else { - ropes.forEach(ModelPart::resetTransform); + } + } + + if (isSandbags) { + float cosWiggle = MathHelper.cos(limbSwingAmount + entity.age / 5F) / 80F; + float sinWiggle = MathHelper.sin(limbSwingAmount + entity.age / 5F) / 80F; + for (int i = 0; i < sandbags.size(); i++) { + ModelPart bag = sandbags.get(i); + float pullProgress = entity.getSandbag(i).getPullProgress(tickDelta); + bag.resetTransform(); + bag.pitch -= root.pitch * 2.5F * (1 + pullProgress) + cosWiggle; + bag.roll -= root.roll * 2.5F * (1 + pullProgress) + sinWiggle; + if (entity.isLeashed()) { + bag.roll *= -1; + bag.pitch *= -1; + } + float pullAmount = 2 + (2 * pullProgress); + bag.yScale = pullAmount; + bag.getChild("knot").yScale = 1/pullAmount; } } @@ -138,6 +215,16 @@ public class AirBalloonEntityModel extends EntityModel { if (i == 0 || i == 1) { rope.pivotX += 5 * rollRatio; } + + if (isBalloon) { + double speed = Math.abs(entity.getVelocity().getY()) * 3F; + + rope.zScale = MathHelper.clamp((float)speed, 0.25F, 1F); + rope.xScale = 0.001F; + } else { + rope.xScale = 0.3F; + rope.zScale = 0.3F; + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityRenderer.java index 5466f5f4..ad31e128 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityRenderer.java @@ -1,9 +1,11 @@ package com.minelittlepony.unicopia.client.render.entity; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.entity.collision.MultiBox; import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity; import net.minecraft.client.MinecraftClient; @@ -17,15 +19,22 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.Items; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; -import net.minecraft.util.math.Box; public class AirBalloonEntityRenderer extends MobEntityRenderer { public AirBalloonEntityRenderer(EntityRendererFactory.Context context) { super(context, new AirBalloonEntityModel(AirBalloonEntityModel.getBasketModelData().createModel()), 0); - addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getBurnerModelData().createModel()), this, AirBalloonEntity::hasBurner, e -> { + addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getBurnerModelData().createModel()), this, + AirBalloonEntity::hasBurner, e -> { return getComponentTexture(e.getStackInHand(Hand.MAIN_HAND).isOf(Items.SOUL_LANTERN) ? "soul_burner" : "burner"); - })); - addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getCanopyModelData().createModel()), this, AirBalloonEntity::hasBalloon, e -> getComponentTexture("canopy/" + e.getDesign().asString()))); + }, (light, entity) -> entity.isAscending() ? 0xFF00FF : light)); + addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getCanopyModelData().createModel()), this, + AirBalloonEntity::hasBalloon, + e -> getComponentTexture("canopy/" + e.getDesign().asString()), + (light, entity) -> entity.hasBurner() && entity.isAscending() ? light | 0x00005F : light) + ); + addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getSandbagsModelData().createModel()), + this, e -> e.hasBalloon() && e.getInflation(1) >= 1, e -> getComponentTexture("sandbags"), + (light, entity) -> entity.hasBurner() && entity.isAscending() ? light | 0x00003F : light)); } @Override @@ -33,9 +42,9 @@ public class AirBalloonEntityRenderer extends MobEntityRenderer { + WorldRenderer.drawBox(matrices, vertices.getBuffer(RenderLayer.getLines()), box.offset(entity.getPos().multiply(-1)), 1, 1, 1, 1); + }); } } @@ -57,22 +66,30 @@ public class AirBalloonEntityRenderer extends MobEntityRenderer visibilityTest; private final Function textureFunc; + private final BiFunction lightFunc; public BalloonFeature(AirBalloonEntityModel model, FeatureRendererContext context, Predicate visibilityTest, - Function textureFunc) { + Function textureFunc, + BiFunction lightFunc) { super(context); this.model = model; this.visibilityTest = visibilityTest; this.textureFunc = textureFunc; + this.lightFunc = lightFunc; } @Override public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, AirBalloonEntity entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float yaw, float pitch) { if (visibilityTest.test(entity)) { - render(getModel(), model, textureFunc.apply(entity), matrices, vertices, light, entity, limbAngle, limbDistance, 0, yaw, pitch, tickDelta, 1, 1, 1); + Identifier texture = textureFunc.apply(entity); + var model = this.model; + if (texture.getPath().indexOf("sandbags") != -1) { + model = new AirBalloonEntityModel(AirBalloonEntityModel.getSandbagsModelData().createModel()); + } + render(getModel(), model, texture, matrices, vertices, lightFunc.apply(light, entity), entity, limbAngle, limbDistance, 0, yaw, pitch, tickDelta, 1, 1, 1); } } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Transportation.java b/src/main/java/com/minelittlepony/unicopia/entity/Transportation.java index 14ad5346..34632a16 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Transportation.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Transportation.java @@ -14,6 +14,7 @@ import net.minecraft.block.ShapeContext; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.MovementType; +import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.util.math.Box; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -124,6 +125,9 @@ public class Transportation implements Tickable { @Nullable private Box getVehicleBox() { + if (!EntityPredicates.EXCEPT_SPECTATOR.test(living.asEntity())) { + return null; + } if (vehicle == null) { return null; } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/collision/MultiBox.java b/src/main/java/com/minelittlepony/unicopia/entity/collision/MultiBox.java index 921cafbe..e39b6ffc 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/collision/MultiBox.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/collision/MultiBox.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.entity.collision; import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -24,6 +25,12 @@ public final class MultiBox extends Box { return box instanceof MultiBox m ? m.first : box; } + public static void forEach(Box box, Consumer consumer) { + if (box instanceof MultiBox m) { + m.children.forEach(consumer); + } + } + private MultiBox(Box first, BoxChildren children) { super(first.minX, first.minY, first.minZ, first.maxX, first.maxY, first.maxZ); this.first = unbox(first); @@ -148,6 +155,12 @@ public final class MultiBox extends Box { return false; } + public void forEach(Consumer consumer) { + for (int i = 0; i < children.length; i++) { + consumer.accept(children[i]); + } + } + @Override public String toString() { return toString.get(); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java index 690c1a6b..b9d5943d 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/AirBalloonEntity.java @@ -39,10 +39,10 @@ import java.util.function.Function; import java.util.function.IntFunction; import java.util.function.Predicate; import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; import org.jetbrains.annotations.Nullable; - import com.minelittlepony.unicopia.EquineContext; import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.USounds; @@ -65,6 +65,8 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp private static final TrackedData BASKET_TYPE = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.STRING); private static final TrackedData BALLOON_DESIGN = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER); + public static final byte STATUS_BURNER_INTERACT = (byte)105; + private static final Predicate RIDER_PREDICATE = EntityPredicates.EXCEPT_SPECTATOR.and(e -> { return !(e instanceof PlayerEntity p && p.getAbilities().flying); }); @@ -73,9 +75,17 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp private int prevInflation; private Vec3d manualVelocity = Vec3d.ZERO; - private int maxFuel = 100; + private int maxFuel = 10000; private int fuel; + private final Animatable[] sandbags = IntStream.range(0, 5).mapToObj(Animatable::new).toArray(Animatable[]::new); + private final Animatable burner = new Animatable(5); + + private double prevXDelta; + private double xDelta; + private double prevZDelta; + private double zDelta; + public AirBalloonEntity(EntityType type, World world) { super(type, world); intersectionChecked = true; @@ -108,12 +118,20 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp dataTracker.set(BALLOON_DESIGN, design.ordinal()); } + public Animatable getSandbag(int index) { + return sandbags[MathHelper.clamp(index, 0, sandbags.length - 1)]; + } + + public Animatable getBurner() { + return burner; + } + public boolean hasBalloon() { return getDesign() != BalloonDesign.NONE; } public boolean hasBurner() { - return !getStackInHand(Hand.MAIN_HAND).isEmpty(); + return getHandItems() != null && !getStackInHand(Hand.MAIN_HAND).isEmpty(); } public float getInflation(float tickDelta) { @@ -152,6 +170,14 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp return hasBalloon() && hasBurner() && getInflation() >= getMaxInflation(); } + public float getXVelocity(float tickDelta) { + return (float)MathHelper.lerp(tickDelta, prevXDelta, xDelta); + } + + public float getZVelocity(float tickDelta) { + return (float)MathHelper.lerp(tickDelta, prevZDelta, zDelta); + } + @Override public void tick() { setAir(getMaxAir()); @@ -179,8 +205,8 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp setInflation(inflation); } - if (fuel > -6 && age % 60 == 0) { - fuel -= boosting ? 10 : 1; + if (fuel > -6 && age % 2 == 0) { + fuel -= boosting ? 50 : 1; if (fuel <= -6) { setBoostTicks(0); setAscending(false); @@ -262,15 +288,26 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp setFireTicks(1); } + for (Animatable bag : sandbags) { + bag.tick(); + } + burner.tick(); + super.tick(); + + prevXDelta = xDelta; + prevZDelta = zDelta; + xDelta = getX() - prevX; + zDelta = getZ() - prevZ; } @Override public ActionResult interactAt(PlayerEntity player, Vec3d hitPos, Hand hand) { ItemStack stack = player.getStackInHand(hand); - if (hitPos.y > (3 * getInflation(1))) { - if (hasBalloon() && hasBurner()) { + if (hasBalloon() && hasBurner()) { + + if (getBurnerBoundingBox().expand(0.7).contains(getPos().add(hitPos))) { if (stack.isOf(Items.FLINT_AND_STEEL)) { setAscending(!isAscending()); if (isAscending()) { @@ -281,31 +318,45 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp if (!player.isSneaky()) { getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos()); } - return ActionResult.SUCCESS; - } - - if (stack.isEmpty() && Math.abs(hitPos.x) > 1 && Math.abs(hitPos.z) > 1) { - double xPush = Math.signum(hitPos.x); - double zPush = Math.signum(hitPos.z); - if (!getWorld().isClient) { - manualVelocity = manualVelocity.add(0.3 * xPush, 0, 0.3 * zPush); - } - getWorld().playSound(null, getX() + hitPos.getX(), getY() + hitPos.getY(), getZ() + hitPos.getZ(), USounds.Vanilla.ENTITY_LEASH_KNOT_PLACE, getSoundCategory(), 1, 1); - if (!player.isSneaky()) { - getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos()); - } + burner.setPulling(); return ActionResult.SUCCESS; } if (stack.isEmpty() && isAscending()) { setBoostTicks(50); playSound(USounds.ENTITY_HOT_AIR_BALLOON_BOOST, 1, 1); + burner.setPulling(); if (!player.isSneaky()) { getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos()); } return ActionResult.SUCCESS; } } + + if (getInflation(1) >= 1) { + int xPush = (int)Math.signum(hitPos.x); + int zPush = (int)Math.signum(hitPos.z); + + Vec3d absHitPos = getPos().add(hitPos); + + if (stack.isEmpty() && MultiBox.unbox(getBoundingBox()).expand(0.5, 1, 0.5).offset(2 * xPush, 3, 2 * zPush).contains(absHitPos)) { + if (!getWorld().isClient) { + manualVelocity = manualVelocity.add(1.7 * xPush, 0, 1.7 * zPush); + } + getWorld().playSound(null, getX() + hitPos.getX(), getY() + hitPos.getY(), getZ() + hitPos.getZ(), USounds.Vanilla.ENTITY_LEASH_KNOT_PLACE, getSoundCategory(), 1, 1); + if (!player.isSneaky()) { + getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos()); + } + + Vec3d interactCoordinate = new Vec3d(xPush, 0, zPush) + .rotateY((180 + getHorizontalFacing().asRotation()) * MathHelper.RADIANS_PER_DEGREE) + ; + + getSandbag(MathHelper.clamp((int)interactCoordinate.getX(), 0, 1) + MathHelper.clamp((int)interactCoordinate.getZ(), 0, 1) * 2).setPulling(); + + return ActionResult.SUCCESS; + } + } } return ActionResult.PASS; @@ -368,6 +419,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp if (!player.getAbilities().creativeMode) { stack.decrement(1); } + burner.setPulling(); playSound(USounds.Vanilla.ENTITY_VILLAGER_YES, 1, 1); return ActionResult.SUCCESS; } @@ -486,7 +538,26 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp @Override protected Box calculateBoundingBox() { - return MultiBox.of(super.calculateBoundingBox(), getBoundingBoxes()); + List boxes = getBoundingBoxes(); + Box box = super.calculateBoundingBox(); + + if (hasBalloon() && getInflation(1) > 0.999F) { + double horScale = -0.5; + // x+ z+ + boxes.add(box.expand(horScale, 1, horScale).offset(2, 3, 2)); + // x- z+ + boxes.add(box.expand(horScale, 1, horScale).offset(-2, 3, 2)); + + // x+ z- + boxes.add(box.expand(horScale, 1, horScale).offset(2, 3, -2)); + // x- z- + boxes.add(box.expand(horScale, 1, horScale).offset(-2, 3, -2)); + } + if (hasBurner()) { + boxes.add(getBurnerBoundingBox()); + } + + return MultiBox.of(box, boxes); } @Override @@ -509,6 +580,14 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp .expand(2.25, 3.7 * inflation, 2.25); } + protected Box getBurnerBoundingBox() { + float inflation = getInflation(1); + float horScale = -0.9F; + return MultiBox.unbox(getBoundingBox()) + .offset(0, 2.6F * inflation + 0.4F, 0) + .expand(horScale, 0.4, horScale); + } + @Override public List getGravityZoneBoxes() { Box balloon = getBalloonBoundingBox().expand(0.001); @@ -528,29 +607,55 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp public List getBoundingBoxes() { List boxes = new ArrayList<>(); Box box = getInteriorBoundingBox(); + Box mainBox = MultiBox.unbox(getBoundingBox()); + boxes.add(box); double wallheight = box.maxY + 0.72; - double wallThickness = 0.2; + double wallThickness = 0.3; + double halfDoorWidth = 0.5; if (!getBasketType().isOf(BoatEntity.Type.BAMBOO)) { + // front left (next to door) - boxes.add(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness + 0.4, wallheight, box.minZ + wallThickness)); + boxes.add(new Box(mainBox.minX, mainBox.minY, mainBox.minZ, mainBox.minX + wallThickness + halfDoorWidth, wallheight, box.minZ + wallThickness)); // front right (next to door) - boxes.add(new Box(box.maxX - wallThickness - 0.4, box.minY, box.minZ, box.maxX, wallheight, box.minZ + wallThickness)); + boxes.add(new Box(mainBox.maxX - wallThickness - halfDoorWidth, mainBox.minY, mainBox.minZ, mainBox.maxX, wallheight, box.minZ + wallThickness)); // back - boxes.add(new Box(box.minX, box.minY, box.maxZ - wallThickness, box.maxX, wallheight, box.maxZ)); + boxes.add(new Box(mainBox.minX, mainBox.minY, box.maxZ - wallThickness, mainBox.maxX, wallheight, mainBox.maxZ)); // left - boxes.add(new Box(box.maxX - wallThickness, box.minY, box.minZ, box.maxX, wallheight, box.maxZ)); + boxes.add(new Box(box.maxX - wallThickness, mainBox.minY, mainBox.minZ, mainBox.maxX, wallheight, mainBox.maxZ)); // right - boxes.add(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness, wallheight, box.maxZ)); + boxes.add(new Box(mainBox.minX, mainBox.minY, mainBox.minZ, box.minX + wallThickness, wallheight, mainBox.maxZ)); } - if (hasBalloon() && getInflation(1) > 0.999F) { - boxes.add(getBalloonBoundingBox()); + if (hasBalloon() && getInflation(1) >= 1) { + Box balloonBox = getBalloonBoundingBox(); + boxes.add(balloonBox.withMinY(balloonBox.maxY - 0.5)); + boxes.add(balloonBox.withMaxX(balloonBox.minX + 0.5)); + boxes.add(balloonBox.withMinX(balloonBox.maxX - 0.5)); + boxes.add(balloonBox.withMaxZ(balloonBox.minZ + 0.5)); + boxes.add(balloonBox.withMinZ(balloonBox.maxZ - 0.5)); + + boxes.add(balloonBox.withMaxX(balloonBox.minX + 2).withMaxY(balloonBox.minY + 0.2)); + boxes.add(balloonBox.withMinX(balloonBox.maxX - 2).withMaxY(balloonBox.minY + 0.2)); + boxes.add(balloonBox.withMaxZ(balloonBox.minZ + 2).withMaxY(balloonBox.minY + 0.2)); + boxes.add(balloonBox.withMinZ(balloonBox.maxZ - 2).withMaxY(balloonBox.minY + 0.2)); } + + float yaw = (180 - getHorizontalFacing().asRotation()) * MathHelper.RADIANS_PER_DEGREE; + if (yaw != 0) { + Vec3d center = getPos(); + for (int i = 0; i < boxes.size(); i++) { + Box b = boxes.get(i); + Vec3d min = new Vec3d(b.minX, b.minY, b.minZ).subtract(center).rotateY(yaw).add(center); + Vec3d max = new Vec3d(b.maxX, b.maxY, b.maxZ).subtract(center).rotateY(yaw).add(center); + boxes.set(i, new Box(min.x, min.y, min.z, max.x, max.y, max.z)); + } + } + return boxes; } @@ -574,6 +679,10 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp } private void movePassenger(Entity passenger, Vec3d movement) { + if (!EntityPredicates.EXCEPT_SPECTATOR.test(passenger)) { + return; + } + Living living = Living.living(passenger); if (living != null) { if (living.getPhysics().isGravityNegative()) { @@ -625,10 +734,54 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp compound.putInt("fuel", fuel); } + @Override + public void handleStatus(byte status) { + if (status >= 100 && status < 100 + sandbags.length) { + getSandbag(status % sandbags.length).setPulling(); + } else if (status == STATUS_BURNER_INTERACT) { + } else { + super.handleStatus(status); + } + } + static boolean isBetween(double value, double min, double max) { return value >= min && value <= max; } + public class Animatable { + private final int id; + private int pullTicks; + private int prevPullTicks; + private boolean pulling; + + public Animatable(int id) { + this.id = id; + } + + public void setPulling() { + if (!getWorld().isClient) { + getWorld().sendEntityStatus(AirBalloonEntity.this, (byte)(100 + id)); + } + pulling = true; + } + + public float getPullProgress(float tickDelta) { + return MathHelper.lerp(tickDelta, (float)prevPullTicks, pullTicks) / 6F; + } + + public void tick() { + prevPullTicks = pullTicks; + if (pulling && pullTicks < 6) { + pullTicks++; + } else { + pulling = false; + if (pullTicks > 0) { + pullTicks--; + } + } + } + } + @SuppressWarnings("deprecation") public enum BalloonDesign implements StringIdentifiable { NONE, diff --git a/src/main/java/com/minelittlepony/unicopia/item/BasketItem.java b/src/main/java/com/minelittlepony/unicopia/item/BasketItem.java index beb93ee4..9e7a8e86 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/BasketItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/BasketItem.java @@ -68,7 +68,7 @@ public class BasketItem extends Item implements Dispensable { } if (hit.getType() == HitResult.Type.BLOCK) { - return placeEntity(stack, world, hit.getPos().x, hit.getPos().y, hit.getPos().z, user.getYaw() + 180, user); + return placeEntity(stack, world, hit.getPos().x, hit.getPos().y, hit.getPos().z, user.getHorizontalFacing().asRotation(), user); } return TypedActionResult.pass(stack); @@ -76,9 +76,11 @@ public class BasketItem extends Item implements Dispensable { private TypedActionResult placeEntity(ItemStack stack, World world, double x, double y, double z, float yaw, @Nullable PlayerEntity user) { AirBalloonEntity entity = UEntities.AIR_BALLOON.create(world); - entity.updatePositionAndAngles(x, y, z, 0, 0); + yaw += 180; + entity.updatePositionAndAngles(x, y, z, yaw, 0); entity.setHeadYaw(yaw); entity.setBodyYaw(yaw); + entity.setYaw(yaw); entity.setBasketType(type); if (!world.isSpaceEmpty(entity, entity.getBoundingBox())) { return TypedActionResult.fail(stack); @@ -92,7 +94,6 @@ public class BasketItem extends Item implements Dispensable { stack.decrement(1); } } - return TypedActionResult.success(stack, world.isClient()); } } \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/textures/entity/air_balloon/canopy/dawn.png b/src/main/resources/assets/unicopia/textures/entity/air_balloon/canopy/dawn.png index 0a17fef92fbcbb9408d3126c870f0b2804ea8131..64d8bf42b06728599f09018bd9847edad3027699 100644 GIT binary patch literal 47517 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 I`aI(Q08c~7`2YX_ delta 36866 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 GoAGb;!@dFl diff --git a/src/main/resources/assets/unicopia/textures/entity/air_balloon/canopy/equality.png b/src/main/resources/assets/unicopia/textures/entity/air_balloon/canopy/equality.png index c87606b9f058500327e3829c8627414ab029aff8..6f7e62be64867c0b49ae32c607f8d83ef7ffcc7a 100644 GIT binary patch literal 34931 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 Uo)m4u_^_(6k;T>W%eP|w4+eA^)Bpeg delta 25392 zcmZsDc{r5s`}R;$DO#-AimYP^*|+)#MT>1r_979o@7tr0vX(VjCM3)-Lb4m%5Q>yB z2xFU+!OV~h#?1TZ`}zKU?|U5YKjt{hxaYpF``XU)Iv*R)SwAkYJQrt${Cpwtgaz`V z@;vWF2t@gUvWnIPO)aI1XO)$;E-GuOs=W9CJ*eF@;ho`nQVfvYJWzRd{&|tsgrT93 zCr_f;xzVFlS}*N)*lwIj=jJo+te>6jbH;UIZQ$(i%O~g%zaT%0z!#^OIo!5Ap}tdT zAzLCLWC+mq$*NBLQ28s@H>dp0WjOFWuKsBx`s4xx(Q`fOCU*u!$Z3m0-BcK;YaQOx z4A08%hafHqxikZJPx_n~_OjJlikiOwH91Pvq{dz5J0HE+ys|F1^td~^P(bZ#McDj> z8Z&p7rWBhIvu9<`#1oO`?fMI~U13Rew&>a)y4xHEnh#xbNf(V@bcki2{U;__)}F_$T3z0^06XE4%#~r2AI$y{oC*uYV0MJ=#*) zc`J7zl;d}0Q=96R-wxzW1#0oQukYbxKIw?*g=vS?w!MhA69g`mJ^z$s)>6#_X6xpw8URp{hu)S$PJP4McqbXi=_!vo$O zjDrSmtR#+1!(2NIE229npX#)!Q%?SOyA5{P*DCke#3~LYqm3*rcqBR-F|*zW6t-TQ zisgp*`h87G@?1Ur;#2ackK=-8uSlqfiw|j~?b%2C`HW#A!j3EgSSR{wSkV#P{#ex`|4A2M2j{RCKiC z+H?#2&!0a7eQBbDZiuMhg$R-^Znt}Pf-AEzo00Izl{NIf zW>m!|38ocM`j&{8hboMx#Ldmk`NEt|CLe}oxRxeUk`>F`%)lHbP{jJ&QSs_mrb4T$ ztBFsZ2nsU@!X9hdq_k$PXnjm7!cx#@`sMZsV2-@l{giAvZQLfQuift0$4SoXJIGx1 zzq7GKBKP(6sdGXZt%5B((LKkhaCULM4HUe3U~hNJRHl?pTSy~P7y5VsoyG0fRqP}j z4wtgj5!TqyAjNaa3PQ0N?X-8&*Vk9vKi|f7Yb2dkqZ73=Dht`&-BoYTKpa5;WsKw0 z>gt8PQNr-hkpBS_fd*CzhUs&2UWvmlrSaL^-JUTa(dM9qp4iwdHaaK00?}t+B>cY0 zfWJCTuuAK9XvxxzNg0;V*@e!xYmYE_ecXN5QedVpx=5`NTWe2Bw<&YocA>Mnvvmqd z`okqV;c)u)Msi;>r5aco{@n>6+Rn?<3GGo43lSoEk^JEy78XWD5c=<7rkwHJp2vC7 z^*z2WK?w$X1?u`A-kN8^KC#P++}#Cvf>B7g!2W1V;QES^|-0y+)$ej57$?=LH8H$JG(7k3zL%hAzsV3_&@ z84dRi|8Q}nd5NU8)e>H1`&IT>7umq@DIxagslJ$&Q2tC~NOcMUh>CJhP*C7yzj^VH ztj-7@5HveIN7iu>bd013fIDX+xVTcVq%WVPlp`-{MKu6~owQtv!o#8`hcbH{PxFM#) zxx(F>=hKcv4ISv9=||Gufj8+*o!Q&l`we-M?8Nd>C}#Q{L-WPas=)Uiw3vTPpXtXU zx(^(ZKYRU$GhR`uNRwm6=1b%kWH%}ZA`_w@dLs0>^w#^tXHc#q(8H0G3r3-P%QI-E zEE{VdkS;&wO6j}ThC-p(3b{md8aE4$0zHr9S7CF^pCcvyK|w*D-qSpQmDmLtr7q@3 zi7`iVb6lx~#RtdzjZj4y3Q#B4rwjL2o!@u_z?kr?1CgOc#pd!xLxu2(y_bd}P2qMx znk?^^&6#FE?*c8x62`x*$)6Wa(c&0&1!&c*z!D4p0mfPxl<`9O8xK<&e@?=c`{*Uk zP8yrKFV9AgvRp$&MWt7C%IWWvIxupQ(xJgs{=I71aWaNIO|b=C#hel_4zzvSG9^GF zGE#rd*J`)~{ph8J{S>YG0HDfwk|A`aL-t7#1-_+wo*^Ss0eR!~o3ivdyZ;{0h<3E0 zn}62KnWl!gC<{8JsVs)61fg9*2#J^&eLidtjwSX;K%_f$Zbaf(4BkQ_XDw!lP>?0! z+CX3fa^^(ms^xy3qrwrS$NFg#wY0J~$+j#X&v*DG`ES4ifr&_*#>>P5PlM|+YpzET11V#MRPg@e{R{*xUb#H z?i$v7sxuqcKm1lhAV2<>dqECX)X(7%(CdDk26Zh~1g%{Hhxi}v1!h~GNWRd{@O;Y? zE9~ZOY%@Qk)tfR3WYx=%lBa7=V!cPDUYp);EavTv=&JO&Z*s**@BJ%bKqpOrAlS0u zVDTz3V+$)fxPg?2;-icI=n9$_jej)u40r;uuwc15QGUg$zR|`%mM2xULG8we7|J_e z`|YYv4}CumD%cTImu?7?OKTUJg8N5`ULSV3y=_*=|7W0aCCu>h6g$%c>wNe% z7ej-SJkwUUP~CbyYXPvKD{;lQ@f*y6-W1Mu769EzKL6LMv`bcto^xbCW_kVudgoBN z*8|ro)GH6e)b2HS2zhy1=$5{dWeQ7sZ|=%6#E380%J$g|WX(XdUMx5Yl8r^=Ztu)j zbGM;s0d>WCH0=gJl+MHZUzbg|GgZ8tKJwUV%yKasmcQEiLRMXE>|32gUk%`va{^!b z%`qpqX`uUrP2SqOHUH_Sk{Uaaiz5{XpL&8T{KYT|q22EQC6441g`+awPs;j9^ zj^O}R6r;mLjGXA-IG(2;y)^wR~0b%y;-$o`2znJOL<+kc__3l-Xnp;WD7#gg-n%Jn$Qf(B<`_daE$d)1Wg< zWQ_4KGc(PhklceB-go&TlS~Wcr2;4Xzh)vY_-1o87!%{{7XGqtPLAYTy9;zT&J*xdK!~i-{b9-B{VKuv0z}W8`85q zvwVwOSRmiW3#+aD$Kg*avY^kvezVd^mGR=AZ)^bE_1!8Bb!EVna_ic^4#tZcxTqCp zKODSt4wz+@;JPoinm^9;+#4Xz&8(z8K;M7YFxg{NL;Km5dOWRfCjK1dY#=}N?&58l zhF46MAgaqLOv#p3;!pXr`rX2$X#{?m2(d~Q)eR4nqI*WnwagE@jQ(q~Ds`}WPk5=B z28AT)Ld*qij7PiI0t~y6YB~yA0an!jJu3e&Zw-5MazIY!@U+Kn9cgz0yt!yLWpKN zTkAF2SrR&x1;yF8+aKw0_+?e>*mIdIXB6Z#bfaoVu-vUHBDgxE1pfDef zJk>uGc6Hn(#`=#WwJ$E`ca%dg>H z!BJGVv`bF(EHSO~jGF=^AQ2;&r$8$^^?W}XGaw<|94By23y0DYbef|kWPfaF^7-Jc zTN9tg*S)h-unFEp1vi*a>#NKtojlR}MmV;>MB2)J<7cn+#QacImB$a9hBjZAD7{Il zN10~KzN1B58f%N9z(+g4ScE}jTyokFjBP~LPbpWSV*3^35#YET%v^3tLSKmo>XUri zsaj*ShEp49xfClY_RM_k!H3a&&#AD3wC67CLii%|;JFI9;g8M913PPvnE+!6$R_Nq zh43;nGEQ&jOG!x;Pyp(DybvZMBV&CYo1}~w9{ly|*Srrc3hdvLc00E~Z&?3MV0@te zX~0a&(k%fCqa~J)=f+dI5e_BDLj`rHELUv*9rgEEqovEi4a%#PCbyGntHsHWzmJQz z2V3jqLq+6QtixVvUEJPn3~QrnGEv!I?*(&92eVYEjsF1 zP*4!G-jQEWFwL)$@3c9&zmW)CO--9oDx$CuP(V8XeKoYX1kr*1{%g6P?-OaXMiquR zA{I?6WBr>}?mKAo!hYGmMjkmX1+VsypNVU0t2v8(mZvAq@JYhe;gF0f?k( zjQ4!?k1l1J8_&NrSO~L8@c1#`TsrsTtx4Y(6X#wvw<6;jmnGLbJGMG6^XseS)Llzu zd=80vEWd_T-78UU;?=z%`f)R=K3*A+N?$II)4v%_N(A=yKwN~qS>On4r~@kGM9l84 z!+shl{aa_UH#Rl^!8~~V{gF+3E}!e|$ULEMgX=|=a)px@-v+y)$Ps%xLASNyk6vo) zotc@LXIS0Pk8aOo`WfJd7Xn7zV9DWLBVx}!ZEtU+|UUaTxg@x zM#+e5%Vg}?q3^1CCuSz( ztxFxV&+R!T9BF0lfU^2FdW%_#$+~_cO z;5C$?Pp24oUy@m{-tSXRJ0-p3oeS)#6`;E?Box=Gpk@(x*OjA??&q zF-_fjHs}*~L(9?J*$u<2!<9d0H8yS=Wu0*ML%JD8f(bBT4qbIXweLxfzJvr%Oy*_c zLSLG?TF|G_;IVU}f364nhlMqbb1Sg}uWhG8Q(|LdmGeIDV`ziHqw3awxZfo_mRE(H z7Trr7PDr>E^&y;4nz_D^raz-~sd(qlnGa_D0q&b{Pf-J5**A||;Q9-Nj|@0<3gzic zS{k#FjtBPeH>Ilg7NzuMMD-%w=c^}qwy^pVuD_37l4MD>E7Xe$Uzqia(-#6-D%XC5 zk3(7WcJzXzKi{ug|M59baBL?->ehL`8>6p{vQR-VNG6_@>%MCgez$iiYJKrp3Tk0* zqiEpxGukE+LJ64Pb!?Bc*O*;vK^MpQ|`VE*Sk51~zs=9d=U%5vP6oRVxd0hwU((@alba3&i{l&edSyKDu zwBExWen|WVeJpBNV#j2HrOGbhYb-mLxA5;oj4PDzZ?^mQhAUsaCqfrb^9c}X5RmZjhy3b^_t*O~(jX$y0hn|_L7?NoA zd#httS9Sa0!&`PHGGqdV>)B)O9Nkpmy3GnI>>@B&g=EiZawN0VEKh_w&%4f`);%LWRooCrT3;pE(+_GX00ar6(>8t;*NXBStZjR^7iBp zWjVT|+XQuQBcO2|`w>>%YaV|{Ol!8hK{s_UQqQSz4|K(G)W{cQ8o8Fw3r7Rta28-O zAQt!Lhoi}W^k4KL%+?{y8F>MZ&mBq58`W3~IL0wbla=bNX&DVNbIH+&PBrB>H#=u8 zsHNZF5gli8%qi)JOTKf*#2$SQ=@zpv4d41{KXje&pIlq;@UC6o^6%g8g+xWSx|~MX zLOS)qXdL-ZD`)=DEEhQVq{_hUSuGs0%~UE%o&N3>CL$s-Gak9EodvZ%NxML3n{QZZ zXB!|oo<1>ADhJTDUnTb~tmqMLD_w1F+J=o|X0wIcp^oOC3BTddO02f#o1sPu`s;)0SIEE18 z>3gz~bG-&K=US=8y!DAAC``TWrqS?PVQ1KlDUA>;z=!XY1XK7mwzIA!f(Y$5D3p^h zFIrNh%A)>cGoi^jM&2ptQd7$Nq$JgFZ)+nfqqc$kzM5ysJKH{-r-}Yc%ZGvSu^lzxqGOc(0sYY{b*vA%_+y13a(xXErm0-|2l6Y_X4mr#Fu_zQlb0 zlu3Fie~5Zrj?Ko(|J=j6>t%gd=tN>=As z`xM66m=4*z45TjQZ_xrtm}@aDe&ZXDesMkw?pr8ArZbQ^MeR?l)5VTCdz#oVuIG@P z-$lmMXgf$KAw6rh9uH!zT(6KWEE)95@Y+kn49_Wln&yB1^r0;cEd3_fJ2_)O=dWK6 zws%O?5p!wy+lRoSRAcf3vJz9@t)EpyUS1w(&S~m7vVb!$7PV~|sG7#kdo^`WxR|Ld z!&-Ic8{oeikwmoRJu90xE{2r?%#nIZkmR4aE$bCZNaW}Glc^MdL2t6E40aXHwBWti z@fUV^aP4y&@}hcPSrLHf;EzUw{5okIORDNlmKZJwVs+3!$c-5Oa5F3zp^eh4&9qx6 zYZZ4dt+RMc=r*yw_qjzwzi%TeL@c}=O*3BjfO4!Eizo=Gw#heE{D zzUdN6|1{E+GmaLuf@S#=SP^DBV+8@Q7(0L@F0pP{&(3~#ak0l*a;2-t2~p$Evi}*7 z2Ci*rXt=Y1B1bV9Q8J}d?#&rkHMxHhMKjPB}T?s9BQABZQ@lp?%95g@8K&v0aX$E>SH0ufpmTX)npA`sFfS zqE9V%4UQctnG6oPgY%6U2!$u)CuX#y5)>%N1yDhtK}oqyP(+twed=c4@VN z1f{-QQqc0<$7791yfOA4n~#Z-w}n&J!t9=<40YYdvK>inzPEt#@*^sBl0D2>jNjLl zAD+D(f@MzBxoO+6y?z?=g@lbd#h>xlU9{NFCfuP5A|`)N)B_ccaNbPq+c-CFGSK5x z&7F!An$>l-$*X-gfkUa?hiSgvIWzlqc&oIwuRwKeauB&|dCGMex(0CKeq#ar!2tLP z;Lmeude&AY7w9)GS-fB| zQLaC>kQa^AZ&`*#wIeSt9WZnK889y*vRF?y(T&wQs40LR45(`n>JLy*RP?zW^RoJc zt{_wdchuEBlV>fHJLgw*VXpo{D2ciRT86l|cn@&HUzTw_$#g50?BSudw6?bTjsNWw zNB?$;gk^Y~3hvc?j$YxbvOoHH(f(wVfhZyAD4W!&T2uY`#y(G2h@uZ;YV-5njg$h5 zix+f?Yz0sU9-+<&z2I`xE{6W-xr~?1C0B`rCo|E1Sl#RIIkGcy55D{t?gB0gmb^z= zm|-q~!h4yU)f&4Ftb*3Z%dZ1V5@u@;cy9H%Rq4=auS}&Yx8m+;d~$uAzRA6(lq04U zqLNx#eAhcmuU2&!56~z@JkHR`Yzkl)J0!t{Zl%2mFKZEyojA}3 zk{}?_IW7Skf5EZwD&#>ukmT*sce5{Qg{m9bXngO|GUZ3NFhDk`{hGLeJQkI+H=Ngw ztnr}^HYj)7umpr1OGb&6n-7n$F{?3*@TEFD;{R#J>|@38O^F8rEKZMIL|q3WF=B_h z4h-Yw8lL)Uq{TSk<(-8;lox!RYvqrW4k$0iVSpH>NEpj)89#wvshT5xhsq;X6Pf7h z*uy|+#|+Ot?IgQTJ4O3tm%GRX+_+~ilNW)oICfj$j^P0=eOUVsbnMn@^YomgXbMdC z;02>K4fcH2$7J)V4f7w-R`cT?8r=ytqIA#0cXGlYj;*17u^e}%|A(Ze`T&vW4S}58 z3X4mI1d_+rgmYC*;Qj3dgIpA3d^u#a0X>75_&)Cc!_Aeo1RN3g`})3X#D9!E+4MUr zA?~y=?ydv*R=jp&_+??E>xNT2Op}A}QJN5NmZt+ST2C{|uWF{ogY?F~q&PK6>rNJK zNOkC^Q5yeZCbmirxW1%18(|*CzIi9D@SJ~t@%(%%&sEOYM8nnOa(jxqgz}N=qv)62 zf~n1TS4Q0_;?x-OQ!NLhrJ0i-9*;3;x99y2H>b#$_xaYK>OWXER=;q!YT&EY)k`+B z=9q|0;geDFz#$ax)MnFpbJx32M~ESowALvjy|xj_1t9l)2bBZ&eu?|AIA!qE>(LPT z`B$^C4mRxL9Ir_-h&zId$T0VJ-`vu+P(=Vz4GLX^khBy zL%aR$viu3%y2&>s)=gP{W=aBD5{ANKH_iRG61GH@n0`0eqJ2c^X=!O8dJ%hI_{Gj4 zj$Q%=e(FLr4~pYwukdLEhad?rwm;bvBkK^_<&<~PyMG>nm9)Imo5=UBzPff6N67k) z0D%2c3=$QcvFz#j2@c!*>S(I7p{-Tb15OrccmPV2RaS@Rbm>Yt+5QmI!Jb|AV8?<5 z6<+kXeLuZQ=t5)!d0dH&>pJhxjsU^~^6{FToKDr*rvMDH#7F_y(p%w(Ay@0NXqXRe z3ixJ=Fm7b2Yq52^;u`*e3~-#>ls9upI-0R8d7D5goSp;1!@~z_r%Qv(Ol*F$@*f55 zWd*TNlT_dw7R(dZx(qFE-cq`ITwsIZlX@!1$ER9INGNk}FUn40Hl1J(hzms{ig~P4 zQg1)FrU;N%yRKz4V;f)gF29l$}>Wmsny|!XKzhwENz5^{r)*p zl^m!uE^Z<8)*}VD8oEqqXEGv8<5#Y_SP@u*^H6FXI>Gs{q3VT~MgMdU@F}Zm9i0#F z2*M(ErB@QK5G#MyTa=bMP~2RbGV?woEG)hrcwYM=W!QCUV|SFK5R63slCyAqX3SgL ztiZGbte!&D0}cIzM&_D*St6_`%t-RGw$(p2Ib>_UNFp$2p5Wj_4`~wijauVVbUc;_ zn3#lv_G|uCF&Xt?Eel3YAEo)4iyUy1z!^cko*@_CgM&c31PM{!)FEq|McPDncefyK z2_)q6caOm@3gzAYI3N75UBU?|q+u&_Z8tS74Hz8E zQ4Fy@sZg4^G>jmeVK1XAljFO=R9e1I)q%rfvwoAmXhU2C5^`z2_w6Lre^p0it*H{w zI}1DBUgtsGz@;Qo;doZOZtPJ(Uq@E`(>WLBql!6lr&mt0JP&txaj?SUu!s*Ha|cEv z&ujfm)OSIdD7VZb($kLumj-$laVYqovy}<5={*>)9t;Hk^HiT zB_h97gGFAj%(a#8-WwD`z$JbbAP|I5&QGXIY;0WYdbjhtx`)$nys9EjeJNRNs;QyO ze5(m|rbEU~CC}htK)p9=f5K%V3z5lVqs-1)J81hPN0u*;+<~C^2x?4cvpbLCG^lI< z2lY95vQjehMRBTlkgwGpr?!*oHaaUR{o!LlzP`RBU6UhsoyDT9^FYEG~ zJ{1gV6a&ABH@-!c%~!x-kY&fw`q2pcIx(DO3_=hA_UFH+)*wcP65%(0WG=Z`X0g9? z>m0_j0kB6krX)zWiNP%5T+H8SlNHsE&P;fr<(?_=xd|eB-(lj5RsURD#FmLnX(Wwu z_bzd4tHxCHm$jmzVyWw=nZv=mCHTwn$0USNx~`!CJ~TY+W54k0TUlvl?YoXqxAE0s_Co&ZmMAvklY)Rm7`E9-eQ`>roHP9WpsZ3*TIx#o%$;L7~vVPwr z9Azca+l-Qr%gRJn4;&z7UPA{yrNFP441!*)e82zf*he-lxZwd3r%_Nj6m^t~%3E~Y z(Q-P6bTTHdYDdpnl3OWhzSqt5vWzx*Ay52_#X$Owen_S#uzA{yzGu$G9^~V&-_MI2 z1o|%5+@$ZfE}i=p1>2Qg9>`Q?sEZp)dh)CTpDK^ur5#)RpBxnX1(_;Wne`{Dwk!eS z;%+I%>@^!t%Pak|_NrSU<`yLbpYO08?=z5KXnttnWz@@4Ncd_#O&0y_{#yeezsGy` z*+2yV1P5Ce>I07G>gqv7V0#ctR&;8Y8%F3m#qogofe#OCue)xeFgvLDyw+%^wlUBr zKnk4*vQaW%;?2*`&-7{EehcOnMaOE4e#D=ZG1Ah~5^)Q|+?#JlfTW-lT|DhJ$KNu# z^Ug?t`TG|0BD{XH{A_uwUDaRdUPIKb2c6%ma-dX-u5ZtSvnt#}{7iEDiFO_ zZh@)h@NmW4qLp$ny+-6{t~kA5%UJ;AmiA}hFB>b}TwzM6TuVv&Zw1?t?c*P}eSKS* zp}w<{Lu8o1(#Ym0p*XmU7NT>>L&V_TT>P~(4l|8(Q(TQ)#0rkyrz~`^J&I1h&$cbdd zGC2IuhBiPMmCwObc0-~l)jS71=sWYGs+G%+!GZ|pZNbwpg;LI=-r|F6mLEDA7X&g6 z$#`1U;Od*l{SIMTvez}PJaZrLx7J~oO?$)@%(De!cY|)HnEnxqzY24bJ|$5a7l=jl zl_@fw_V0_5F1lH4&9(9XQB<&F;$ke%fZ#dn-()J=pE$UXnUp2(!S}uAfN|69>H7jF zm&(2VC--mxBCN}hx$Le1Ts5cOG1ap^QBcOv-Grx|Xf8(N&rPgT ze9V&$Q3H)+b3S?)=ef_|F!{e1bzkq~_A~#mTA<~2kcDOTOaCZsMi8g4MtodVK+eZf z&a=d!G~^-5%xLKPoQMRA77gF6`hrs>@m3 zhjz(n#KoIE)i0@pyWTZqe@!~^aX8+pZeY4nk6eoz`6tC>PlzSO#PQy-f}m8g4-l_l zOAC;rgG|!QtDt#;#Z57~aFZ3^ziXFksMm1XD`Q}Z>OH7Wb%+W z|8b4d%xP&3!5?jsd|g3xo(ZGp4e&2%=!zCEcXSzWW6GYei?Pir&``%{?KC`oUuMRk za=mrIQ&?D7J_V$AxPWJXEX!X(PL*?qV1fUVmgn`Rs1lkNUwYBgFOuu`W|!q zYXT73AswvyVSvZAN|vLQgF$OWa#zO#+#(jTJ=gH}m55mB)IStNuUWUSO5f?*% z^>3#G<&J4?G89ab@ zY3qfzvj-7meJ+QcF7{V%{i95Sa)Id-hVA=8+qg{VBFIGTSKNJL8(k6Z3gt(|rpcHI z*V&G~c_M%N{i!g^kT^xJlO?R3=P#Onf@gWikT~m>p{7$H``ESlec6*-ejld)=&2+> zSI*9!d94kQ39GK9@6L(_jeCMhu7x6MwF`j{D82X_t8W1L>zGqJ@a)oBcYBx9AHLdN z#Efi7L$7U~n7zSUrC@a-ABLLzy1qnJ8J~TNyK%EEp~?xq`P!Z~WEzv%v*wGf49mIF zC`&I0TBE@4rktZJrABHLg7c~^`B(sK^DO`{Z8x%hkr>Pse1F9Xh4ecvDxH5lVeF;9 zTM2foxPrLrZ(UXEj_d3vyE*QCtS63PG3rTYf$dxT2VNUTVNPWST^o zz-=mmvd{b-g|SM`Z$Y!ny)8lxxqTNMxiuXk*vACs=bfo_59r{BOk`aB6lMN)0_EkY z-alE<0zX=*O23Y{QBmEWg|((=hw7GFem@V{TpnuszRcZ+K`~fDzs%l#2R}I7t*~1N zxRK-hqfiEixL)nUtU>`Er;xSZ3bc()51Bbo8$Bin2$5j(Kxk;_U~S*9T#`QF7Qn#- zce7?Rb4)hiKf=UM>r2Ncu-C<9ZQe5`maTGEH}CkNA8Z0Sv|gJjS-U9*r_CHV`-SMT z!7Cw&huq?gOG8)gFC8>c2tXy`8I0(C;dPpbZaVuL|I1MC9X%S&;!kh=&=4U9}LeWn&)V4Hfz1MonqMM46z>;ZB!`ygzp>1>H%))%-#()Q|r{8VWV-ZL8qURH13$ z7kr!yZD)V`nV7t#M_Z`3I$R!)vG9M=;Z*ggod!K7PKWBDSN;BW6R}C+1?IVg)G6Ri z&|dkA>zM+d*;)Mupq9ZF4OB^5K51AU^SlSH5tbo4T?QQlsrOH#{DUMTDK+pN;P~*PWf6 zT^TVw`u3-6$YnodDSMO+5Mcv`(FddTP!J2FY6!hspWbc%V4k03Nwl6S=2nN=`!>qd zm~PYQty35PlW8#^%Ah2y|Ndnus1ig70J*sFvnV#-u&^-H^n)C&t@8VV>d!$@$NH}_ zL^g>;TA%AqSg%9ut&IJ6tFeT_meB~?D)cZt$TI1rFV>n5^R^OLDvw7x=Pr0{S?jh~ zh*&jV!u}9uTrV%FR1;F%noj+KZF&LAbCN;^-mrNIq5_NxLsjJSCL{Cma-6@W^3aBJT#<}DcX^R|nV<92)qhNbxFmcIGqA_p*YQYIVTGmPA`H=K4|xtt8#7tEiKea5 zb3NHb+WBH4!Sx>-**vdEb`cE+49hvy-Y*ybDP9?ZE7>n~^&H@GsX94##Iej)ZE%*b zY)a_D;1E#`w34o_I9rIa*fyss5EC- zT_1OaLhpmba7BP1wBgQg0pdA71vkmaXC4i(rBCOeHj6d_I!| z&^9qg=?+69CrH5h(U_wwz7KN!cPXA4U(Bb~LM&ZE{70$Ru?5R+?-XpBT8nL+Hd}SV zG%K#UX4L(tRC{XOpIOWKGQrbH+y+j~9@NZ$r zzK&DiM>}tiVMtsTe(w-2G7?$CKW<{=7%yD)7a96tY#sGK0&QhmJnYAyo;@C{qi5WS zj}4!DNLG+muy>q|r13g+hX&{?E2pe@69QuEmvP%ZCK)NV{p-78TOzk2qoe!gK_zFo zQF}b5_G3Z^g1mvI0U<=_xEg)>t=8y{6EA@CypyqiG^kO}IXttLR@dkJaWjop#(wF1 zLtxG8(63Ow=L4fw-p*ODwdIy9iP@=^@&~9>3Z=vk&XLGRNBsMZc~kvIYUWGc`z{Um z-#x5qjf^Oqe6urK-8{3|sXuwA?=dFHC6xupI-E=PV=D$vB2e=oPvwirVy^&;mh zPqHNL+=Qc0nOx`PA7Cff5;60i2*GrR$5wEm9@=EE+hl)2|5 zP-R-+1^6=&fv3)T`Xar$Zj4@Ca0$s6xO89r`EqZ(#k97^yx8S9sONk?YHC7Zh^L8R zC$#8M2g|6>@oZ>TZe9Qf^1kNHjnwh&P#2$?xAmcTKYFo$kshr@iJYkKQ*JOzK$d#XiDKXP zJz>7xzqN%n-y4i(JoCfsFgsmxjHygpSker+`*RPBluK40=F=}XOD4X*c#oLw3^WL} zXcSlvt~rd|nP_`EURk`(!^nFzHU9Zi(~;Z@=jRRJ92r~=lC^%r{Z*z83$OHO#??Vs zC#(rRMc>U7%J(o%-|eZmJoz>?BorO7r)!6{aNe)yH0{YT5LYQgxb!$-pC;Hd2SGXf@r2vp7XzyY z=B9pv_v}hpS~TQbI@ZR#W%I{M;Lw5B7bW}nd9aVoTws3kA3o(nP1^thZmYSmB&kYM z?1-GU#c3-g2bm=7gBAsuw}VT?i)ZlIVXReI45qn3kJhk$`xJB9k@<|dHjB`N9LL+{ zRNg49Xf~)Ns`;OBw5morkDym8zS41T?!T35(6Fj{2%Y(KPnf^Y!upbxa<_HX;Kkt2 zI^2?jvuXT3+6?*LT0MXU4OzZTfm6q7ssOxWc=;yg8oh?&&CU=Qe+nzi3@eC`K{|=7 zFnxFwI{nZJec<-*mZZ|6cb)^-tex|_<%=T5*U=WeRne-4;wg;`Odge6V$Fz%Z3xgVZDMyroN9 zaWHi}#q80i-lCU1W@6}rnCp|r-}O!2%Uu0+alzWYbWm07l}(wU%XM#oCklM0ExhX# z&a~N1nJWW{f~KxTS0WF}9+5m_uoP}eKfS*W;tZn#5+kUdco&Cn40ei|$)eRn^h?Aw z($0^uXdCIZ@~NNO4qp}-C7D;&*Z(Z&70wcEB7+Z9RfXRPs(uE{BWO|#%Why@6C!K* z?SYw)r{95Pt)2>v*T`yE&}WD8vpnkW?aZo90RpX}4Y!+gdTS!@ZgZv9c&v{UA0=Y$ z^2&|vI6qVd4gv5R%KtrD9P=Iz1o!!wi&MD-`25w(E9s$9?j|35rYCyDOQNUoj5(gt z(?k$rlTbJTlN|keLA*hvg+$r5Dr=MGv~Iay5zpO3`tM?i%tamu55RFZTicLeW71UW z*Zh`mNEqi|QGuPU&B@C97*yaNRAq8HI50imtGL$9uIe!iI;sFZK-FN%r&4dO8FJ_E zF`qH5D2Phdm{+IzGR<84KU;BM9l&+P9d}5-ZsjJeULL*KjwLQ9!*D5?N16inBt|iU3w~2-RUe0TiG%dB0{&~mk z*oHjr9Fm*y(lAvw(KGqiDOef5Sfp3~Q`m5{If&pH*5m;FC^Ir`iI`(vh$#>7(G zgU}XhXK@nHM82jWXQVE&`A~?6r2r~&_>=MKz`fA9@+Aw79EYf(tb|HC1p%3VZ6yn8 zq|G7?4hz|rscIfIxp`&oLk(TeQ0@^K#+_>t5t89_L+<98yXhQ(=6>YRXvfm&mX(Q* z4?ku&;IK$CTtOL#k2SgY-}8wvGT@MxeXmI7CE+(xv+56@7ji8PFsvXye6~EaBzYM% z690-``6Bq29FKVl@|C@tjC7%YyVLdGchw#5m7Zt(_4`{q%zjW;yqyDtdA@Vl;ONUH zHY?U-|9a(C-fWX~4(Wcue6ZJoH|KIvzf}D%;GjntdgP$paUJvR2wHTga`6-NS_+~Q z+irCv%_P)sIF6|K-*D<;BADBVvMPx0gvoD3#!yXld6jfaQ=@48tH3Fnqf*evj(mP^ zCj6$WzZKUcWkpC54_Vzit1%JwqG?fNQ#kdu_`Fnz>burUzW=!gFj+hSz~`5GuH0|n zzIjDm#%iq8Kcu365PhyR%P1%xdBw1)O~dq}Y{eXwRQ}KO75}8SdMWa%f9QFk+yzJhUxWH7O&;mLs_@x9*krO|N7>$$gsv2->Za%xh9C z%1*V3f)#I%OTSF1IHjCv`Tzi!M*kdb?#+BM1i&RULsy?_=kc|P;qT-W4tfyrB{X|z zNsfwrSVq^gVS&K`-HP;kzSkRdB>yKeZaMs!ic6hx4Vu3&Tt`}db5+JR3T3wfNAtaJ zF&ahKs;;_^z=7s*`+LV5LlIv?c{p;@c^%4jkJ(B6*WY1}0e`=?_Tw7ZEk7hq`<%Ns1y5-=R^3%yK#)*jU5~u3RuL$32 zbUwYnf2Qw4<_FSGlZmKou$+LK(s!jxRe(>Yah0k1)js{!tYO~WcFXl8V;PQ--G3ge}`s6oTiqFFEi$L;> z7H{e%bRZ^3X9m^7#A6usJqXW4&1jqHc%CHK0+X2IWZQMhO{rpQMT9EE8**=!CU!`t_n?nL0@Ko4euJSTPKX9ewKdCVJ zC)4g$eSh*9bBbr8)D*7KXw?Yt3kdMLymbtHE95;3sCrX@23Nvn$y0I9n12??oRk~Y zfa?oMMuQU*R~?PZbwN?B%NqmnWwkd7>`X_VAc5l@O&>#DI&avh zZg))1_2~B!sI{Q2nQC*xHPnaTH00Fx$ILf8kkMxDt4GbO&+tRWK4l6fPAgT#u)aHvTW;P8bBu5E`L$4y05KYh8%pw81)HKfV z9({SH;5o?6kG@{kfP;)m)}h`bszL|u!EY`m1}EXLX9~1On&!>AgI!e>ELP$W5QymZ z{y!#|xT4yBY54LRYO_$h^?gsMcCP$MSmJvVIxNcDi9Q{2p7A}6DLV!Rl{$SQqUe>t z@f6?+zU3NS3QU>I2gF*-esS}*iXEk&&Wg`*xt z71ltydG7Tj5i1E!s&3tn)JfS}w}-A+uc=}Adl5GOr;Cq=|AKoz z?uYArx~|vh`FOo{ajA8KyMV}}BniM%Je-2{)LT~K4xqpGZ$z<;bn-iZW?Jjp0?`)% z4m{bd>MG$4#}!nY(Txo?#Pk4_+7&&@|Pc#D@;Y6K%aO<4+aTi>SUtEHy6Yh)kx1M=7hXW!a~98U`hQH2BvGH)1Me=b~L z02G7)+R8a$1$2gIQTm^FrtAKnt8d%IIbf^_QLH4zl-(TU)qa^?nY&&CWnXsLayMGt z2u1E=Y=l#7(KX5gR}K|th|NH3E6`UzXr{u~ngZ*DDdwam2bKfGFHXNty{7>f_l}Wz z{z`Mbu-5EvWEcmgzvsRp7L_DLOL~T)#;OoEF3?6ARZ8ZCDEoS$7d*FUpfW;PgrWT3 z)-=Sx>B1fKQQLGQYb&OG=!1D7DM$Ig_VW!t;ft6n3%q;)1)niBc!aFzQlT0^t*p%E zmf!`*e=`7%3*}YiUH$$XgLPuGRKsn9T$_94g*|D`?wotnf#=j4pB7PAkc+(ZpV;XL zKSntqzPafwU+bX_5vO6V$R=Es!Y)E?(_dE0=OFLUU??3igm!noCU@`;E2`_Z0 zF3L&Co%9tqwNn2SF{7@EtlgDeR+MoKyOkrn)OfkdS6C%9!HK_Gf-JxIW-+sLJPuTYkZ#>}V zYNgY>%g^Y_Os?IDa`>ROm%rW8>6TsL0UBr&(sBV4v5@7Y%WdVZRRvW;iJ^x(F9+-_ z?*Mpn#ys--cahpwofG1j3vygZW8HC~U6RGK{Q8!r@juxPufo>Uxbs+E)EG~88)XKp zHyq!7=)^nqx5$VJH|Ph?=WcPrw-jr-3QJ4nJYQy*vVS2w3$ zQj=WeB=l4KiE+!Gr7Q?m50nHu2DK_wXu^|J~y_OW*J7XZamxs3Q$`d$H zP$e{4PcJwu0FPp_DNi&nsdNV0rYb|=+vP7A#63(-01%i~?8SyhiWN@=aY+k%N~ z_R;&TwbVf}uesx&1Y^yk3$s{BFx1~WBGdd9u56OOa(9a+6H|iGPQQ_AZg|Y+A~{Au z@ugDwq<4o^lKU0nlM>(8w#!?(RSnJ$omPt~4?QUUT8#EEeR~IatAb-EWF^YpQkwIm z`2<#;wG&^*yytkhIVg29CB2#S3i~4D^{b1Ns zkQyCOZd&SVh0I94ak=LMtt7R~(#%aiM`|lVQ^#x3sk;3aJ~MjkwdM1Ns1Y-F zwIAN-7C*NVaSfE>22>|U@o-_+s8$T{HJ42)@%F&02Vm>AS#j1q<_9zwRT%>Ncp;Nj zj72D?7zj*jz6UCC>MrFclQi6fX3|n#Vohu4O{Zdh&15&|AiZnB@@Y%UT2oO2VvJxw z>I`r{#9+sK zO_^>_n$!N+&+@PXjJPS{i|{Z{Np=))I2fMn-$IH~04Ud_>AlG}=7)F+K6{sWXo$S=E8sp_^nt*JHL63OBi?aMp>nUYd`ptE#9ZRXJOj0V9KoI2 z`F_jNC=M#^kllHZ>MTq79Sm3b6T02vv~pH0hu;f!<;zQxTXxmwIZB9KM^f-t-9`%2Bh( zPj+*J*mv!7p)B;9xUZ{rrLkic^zIEcT^mKTXj!zw-3tXz_n$*9g27Pj-yD3h;GjU; z)e|iBDZ^#+CqInF7z2s!R=~o~sm6!C-h>*nCpWCE?B{gsKIj)ooJ8U< zJ_f&{iAV0c-}>uKD8`urJANYzy!Kkp2MoAGnmaH8Z7g~a=1T8nN}5dTED%N4Y!UM1 zQWvM0wt<>>!w>GIm@AbPvu5&tLUFLHqr(LYT8MiozcP!r3(aQO=K&MMiAdb)An28> zLvCFzsR%dRGYYjPKU)dH)D)e$uc8LAr;yZ;jP?T~*3Dj`&Yr5xS{^qO(R&{K=arlC z!>h90N!o|=t`N`kQHa+hE{qT?m6B`pmG$MCV-Bp9P!l6eB=RWbXjF|C5t9O8sS)QQ zz+5l$jVG|BoUP=&`)~dz%Inq?;Qb8ZMV>E?(0u}NjsJQ()W6i));a_Jih)$RyES)N z)F@Y@U4nB-B?AuCF(h}bL8BHCP9z9^dq;=K#{?PIH}b-R>ohIwku!{YBY!^wqrg12 zs823whe4VI*`2u@!Ei-sNo!%If|bpS9+dj6*rC7qPw@G$Sf%&2bq zYzpZm#DP|H!rwX;E^J4BxxcC|G+D#y(HOci>#+gED z&q?Q(e5_>V0$o2Tee@o5IOh{lQD+)Ukjd(MI(9BBGkFX_O(>O;=<{i!EJ~dMGE!D_ zm57!RR&!jt155w6)g%S(o(>T)^J&6_wu{(NH#?H$1*f@Ou4q(N=;gyNS`6^B-Nt1z z%?U}Vmmfxc$dq?>KCo`PWI9*x){x5(L-kgiSf?4NH^`vR{av)(SW*Bj2!H>M9F^CT zqI=T%h$|Er9jL8|bnrX%8Je_o3e;}i_m;tTzyt@W4grGTcL==^B2`^nj*z8NRXXn| z>;CHWVFW7w4TglkDrHX2zIYPmxV7cm3ON4z_m?Kf+(Mmj!ztvz#Lr}Tf`p`W{8Vp9 zMso27#Ab!_>`P^S?kr-*>zWi!d&VK*myGlTCOylJ&|{bD~o`f78BLdmCUqxWR!-^K3m7o+7h z9!PXQZSYRgW6rjr+gIf}Jw8;{! zzow3aHr+t7j&W_fGn61beaJC^vr0r(v-;f%d_|KJ#;&PKPeV%XG5Tj{69 zv+A2`Oe7z7rv5J%tZw{!xYt5s#vW%;GE>vp^XPfXi#U0Y#_>`1uck8JzGS`xy|Fg` zM~()^eBI)(_zJO|>|^3%p&!wMI$0Ze0H?X;9D8_Z(_vXmT7ovW8ur4gRfJoGZH0j> zHg<9yRFqxVKQ6pYwWKBRq9$TcXTUqKwa@^8XDx74-1h|I?Axr`v>kt-PX_?}OEw%- zVfgwp7381!x0;=ut-o~R?piC94HBf;V6#0q)d~rgDX4Q`GsT&2pzz1j4;p_MAJ1F9 z$z7qJzs_N^p3Y;_p;l+M$D&nzF9}{zFc{FFlGBT>NvXw8`i<_%$UKSY(wc)!=@q0* zef3#o=0e8z<0;|EP+~73@xX$ff9ek7=ZrI;rbsEO*WzBAnD11~%+3ieIm(3>(dwsq zm&c|zmT>^E|FL4|=6zXSGl_?!_qxUwuJg<_1@Z(7shEd92^p7VUVgh0+@H$~`fOqo zsJL#_ur&R9Hu9;(@r(K+Anw5rPU=F`QFa|kshI~W_uz-ol|t5~aF||%aSJ_A0;pq& zCbTjI8$`IwNf~7>r1*viyLhG{nJ=`kR)CJ*2fl6ut%*6z@g-J)HdCC`KU2?y{MX7d z?DzkQw?MQd_jGG4oN?3NKcVRt4S|*D*c3mLi#$zMoUyo91~H7!>7tQGkD2e5CZ$Z! z*(=Kx0Y`Dh-t#(3F{~)D`!nINvi}9_s2WhFTO}DU|CpE`aIoC0UKbx2M zdUD>y7vR&2vZrbT+AzlQiGxct{VskAcEUP5t208wd&!Desc}{MMhM~lsnLsxh zBrSlTBY9H{+iLxcnPDd^T$}PM0)MGk4?7TI3Dxt`wR`WJb}XL7#2Fj+)UY)-`XU(1 z7EhZdmm3GV5`kyIVz0Qr8TZ%EfWo#ahjnPQgReH*pG^W>crd`D27LH?&rcXqv`Wkl z8R#X3=iYP#!6fvnjh%Xn7$h0F@*(jr6$H5Nkr59PVOIm^lff*OXNNu}COsC2% zD6Um`%XgeHS`I{~w30w=)TBmxN--d1-h~&l(j^*WHxEd&CO{ee-;Lf|0@GWr4md(8 z@9SCuG>73CN&$gZTl6TLL@uLm+cuudA*$(l)9cO7V0Knhy{`srhvmPkYk;W^duGB} zADbr?9WObrpq3iJv1hzxoN?e&_x6G=v$Y+L>wMY1926mAffLd+GB>-em7DgPr&qx< zhX{;@$GO|X=KBVe8@?U+736>}dR>qS*dZ*;-g&1@YSmv z{7nB2;MTYX0~qA*tZQardK{a1V;1%x&;m;e)2rrPMsJx6G*5f$2seoI8T+RCj7kfC zh==TX_R=%|F2ow>+LtPQs%wLoNMb}sNYJOJy=@;q4jUxc%HWX|F9UU@8qJP%c9MEL z!NMch+PpHC(72l;-VAEHIgFf@ioXXKIS?h_-ZTjE-3*cgM&om)ZjJGYjpi5a zsz3SW1O^)*;_r=MA>;n2#CDig6cqmtGZ(3D4fr&;u6Uy{pUvJBj=sxNFMFqc&40iH z^{A5QW%T9Sb<9BLb!o7+2a5*~`Sre>^`AebNZuXQnq1#_StG7<1ucTa^JJk+bikeV zHKo;0x`o7l6BclV&`s|J>>UA2fV!VEER*Kr0*{k$a;vyq~If6&;ejnonPgwIVlH&23=Q)J8b{ygIMgsG*u-6g6O#a`iZt`G6^72vQ+-;DBW zc{o??`6nqs5sT)F7#mWS0~9#p6=HWpaV=OaP(n&41e_Q~;7ZFrEWqDOIQK zISOg#EBOzZ(hG7gU~XC%3yRaFE7&zISR8OwU_DDy4?*hW;P4u$w7PHp5k3v;Y!NxV}X72TYZ6U7jv7wSUkZeO~lJ1dL*TEKMbAV0>1YK6O5ZSwSSK70+1JU zFK`+>LH7mpDDdB706S`T!t}-EbMdpMkL4x($1g53GC2iUt{ljn9ry=!=5K5E^zbhc!Pgli1B@ruJl2 zPIu{Dp3Got%9M4;CQ9N-w1FG%_McsI@!!$&%RGX>L$`UIW)5~h3NUIA_j@o(%Pbd= zS$VfsDiJ+&x?k7vInMIIywCMQ)5F_zU6zcLg^@9(C8o{Vn4N&GRLn}$fxYJ$isErE zbsD?U0GyWR|DLvA$2$0YltLB7hQB4Nzz74R{wkSORu$mR6wFRdF|1Z4GB5`3az^16 zjt>xxBLE<|)h0x%#UnR@=mECC%7Dz<#pogM-j zTW-Hc6UcOWH5^`v3i(K&R}lpg`Si#A--+dm1??MMs=hMzGQOMOSWS^_B6ZxpRW&hz z<_PDQt0jTqi^qm{bnZ)Xk6k$FzKZ)6%?twIM&@aaFkn}Geqf6XoN8um7 z%_Sm#;A^%NFGCD|5@E+qqP9t`PSl*wV#6 zBr`m3PH8>YsXGZYK0S=y!B4BAS0YZ~5B z+oGvRJfZ6QL@wlA`L%3IV0%gpQu6zb+K1JTNp%F}e7Ku6$eZgRupGnqC_#>_F}_cn zzP#sSHNAI=?^;B-P!yjn(xWfSWr|jFQFXlLJ8gwOd6%||WSk9d*T^n*(h?8ZsfKOL zxgxz)aBic*v5@J)meaj~2r)C-6O{kPS!zpdN_8ZY5!7M> z_h{RpQPWG?2olfxOT{B%Y%Ap@(|0?0!_v=Noh=zQm92u^cvx#z?4djd3m>j$?nTNH zDnGiyf#YIH@creAazMl3N_jvfnb)`yWvFh4=B0PJePva(YD)7!7Xm8kq}eazGz`P~ z*#OzYxc|zph+W5mV&OslH!Er5t7`|yCex3uWM`sZ+#I_qf)x4S=zUELI;a~|Pi?yD z!-!c45>HX*NM@a9EHmFfk2UV9(Ffn%Z2*`L9+_EFOwdT=2P)o5PpvA!p&=(SoRq%o zOdBIV+Y5ucE}mT7S>~}16cQFNDd8qiW^OFwu7Qmo#k@i%Q8Kk8MRfHX{m7$etT@)7 zi(!yIE9Y;b(6qt0zxmGD|9Ja^?)*?B2RY2=3mxarSAkqq)UMV3mAREEkhJ5&Vfmje zTn@Nxg04Dvq%rij3F}eWrkkea!+%m1#8GL;_415B^mav9ppTOYimqz5O)E>x<8sP1g!rmWT9lc#JMdRi$dJ1AHe;QO(_ujS~$ofF+hk>QDFl- zEFxQSOoX4C67Dn*SpXzk4A?n!CWmdC>@n&Q$-D3CI}j6!vxwlq#-|P1Sg*18Pt7|1DgZdsa?hfYuz4<`n;=*g5iU zz7u@~USDxNdYUd1y7^=D@yo4~Ob6tG8O6F7hJds^w_F8Mzd(i)WVFv}qz+If5G|H) z+Y1wt0WuZjlRDDBcP!>reu@84Ho^;i) za_|8@k)#?P@-%jZE}e|1g8vdu%Vr488I(DVLVnKPJ&L$mB%J(Cb;UcIFkb>dJ-^8pCnfkK#=jUfMhQ`*8>+qbyTw6=BEQ3X_qXe-1V&J!eMIeUFwsSk)g+LQj@-ZTZ#krC;8I>#p{W*V5$Jr9S zL#F4%DI5eL?aPvOxqX1#sYeJetth%%;Cxo;qHk!iN3nXjJ(-7aEcqI2uxET1KpV&F ziqosyV$RdCj_o7>6zl&L2hDjlJyn)h_I4aJZJ@v!wF-JLC$J4q>*E9T`UZ9f*J6t- zh>EsseG^}#ijl6@pkP60gmZAFvu#_aqb?Du0vt4s7lkS5OHQa^ar%OTw{iRK^v}N8 zZQ>geGGMY_(JnK0ELtn74I9(zuyVhtyKcq1w~Yi$E?4{raN;%oM98xus=)7Qys9Pg z=h&Rr-_v>+G(DOE(132A;sx$MRu1Iap?1`6CCKMA-B~iTjrC5b0=JoVIC}6 z@Gq%uGOwuEKM1R}%sTFpZRrjolaJHEA4vCzoDr3~jl->v1aTWfPn zrbScr*b(GoZw2|$GK{%Jd7bAp#C<(?(TIK+t;Ufw#Y=9p%XB%DNcs2QuzKg!T1Ym$;P!ffK0`P*8sGrYp0F9ypba412 zyxHM1B7@vpQ1rCV)9`ugkLOhQEdE0VS%XKR!6x{b4sSX5jDw$d;q88E-BtyBZiY7l z?T-?)j7a?a)YUgK6_k_4%Sy{D!u7Ip1Ql6%6*;0HUO`1cSw&V6+DBdc(<8VPFoHF( zuA7GC7aTt^QJ~aMOnada-4A~eW;Xot%=rrr6nb5!9+XG_c#hZz7r<-Xcj^afFJLv$ z(bs|GAq2sHs2yM*WPAg513d#4i)CbFVA_b=w2_&4BQHA#3vSyM0sd`U`1k}xq{Re< zb_w(Gi7V~gC5tBz2m)e6b!9m;4v%06df8vM^BHzz}YA`4=`-> z?A!5sHgK3ZVuk#0a>veHXAs_7@Ql;E<-3SH$^SSb6BjoR@0J~+V&Xd`2nvcy%0!iY zTG~3gdin+jEDl;)9kRA@awfaDy15?>2n-4i2@MO6{q4lbQ*rSL=TlNIT)cGoN?KO- zjhnY_-^scAu<+62Cq>02PoKZ2uBokiS>N#XU29wW`wt&KeeUc3GVpb9=-cq*)bz~k z-2B4g5`qiC`SV&w_7Aw&ATBfpLx;g4xKQX21UMUpemi~x`yMl_qaTNm+%X2+-gDOr zo-qo`n}6pd`L{4}i4Z>Tm_(q_kp0hq9shqq_6M*(aeV?C=}<6ubZkHabd)wfy6RA! zhI@K-rrF_RqigimY9M*K4cjWdBwn-+3i^IK=FvplS`F9tq#yqr|~ zv6%IlKhGR*UvXwUzesDD{O)tom$t{gnJ%k3u=P9Z<~=WK`-g*UA#+f1%x%Kl5VE+M#Na1yh;V~4Q@H!Vi7r?+_@B7YPJ0Cd%WY5 zpkR9?B(lrIvl4*h$9uINAHPR!3OQ2o{^g{6a>4W}2*PP}6M(-m;r{0Sn&4SAkBDsd z0~1WLQJW-Ui~Wp7*=(+}9MCt|Q{USXJLJY;+-IJYby~o{L#6tpK97+2D|tSE4cNb* zb0UDnr_B8g$FAo>I-|!H+ao--Sd(HNd1*{cQNbBwwS708Rqd?_*L=If*D$ABb80)% zR1O}F9$8M@YVgux7P}!WJnfc3u588E)?7JblZi_!N8dheIIj0WMYiE#`f(ONBjuuO zT()xEK}Qc73dvf@WZpTG!(!#PV`N$(zR&8{vJ%9>FE?FVg*+9!<`}f30*7XqRr#3* zJ0DmsGzYB4PaRvU%%-CPwN?5sBkX3owK0Lrug??2uZ=T_XHl5uqQ*w-@%C@*KJ1u` zOy*Yh@;}@(!^iuOc++KjGNGl_lnO%MdtGSSdSz;SYe#$f{r#KWQ*-7|Y?8z{k3Ys0 zI#27Dm%FJO?cmz$A61t(r);V}gT6DOeKPTmq_aR_{WB^EY+Jaf<1ZwlsLFRRhBamN zL}1>tn_LgQ)nk6^Y) z%=CkuGv6RPO)0}3rP#R&-Nf|6ot2qG;+8M_E~H*mJFthymu4yE_q8;rq<^_A%hSie zKWC%ztuISy2gQ89o{C^nE7CmpF!aWU?o@XFFoN?^ngYiFxBJXpmFMTO9KOW7D$87A zyjQaOQM>kqjsD_+jwda7G5obDMzytPQ=Jr~>&}?jKMAyxt!R7aC1;Esw_1^K`aCAN zgR8OrCf$W8?n%&By!*EFV9{!>$)a_C+eo;$W7fCP671;YltvdWG5Z^tvex*B3MwVn zIK9kBd-#sB;T#X@0J{9#A=3*)#g8>-YG1Hn&PSYAoFkI-XGP0w$}`2<%SaDv9lBKf z6K#U0Rw09V!XIgTAQ|)Xmi(BbYi8GDzBb<*n%N=Hxf0XMkJpY+UG3N3`z$8n`_{%? zWAzJEP^IRQFc-M|JhruER%0R>wOVjd)lhdOxs5%`C&y-$+Oe7QLdM|9zSR` zqh(yPN`k<|mX4hIIjx%}WjlAmI`whX?b8fTGdR%t)>Nz**5>)tARI2Oc&x^Gqe|>K zgNF}alYw`=##Q{<(p{>{!-?AC0*&V)BdSwjqfZxS>@L1^X}%H_;~5h$Nd=V9H#jp}u_rh)Z4ebjcB~v-41i+M=^zFbH007aJZw8;nGoQU-|&!j?O2b zz7bU6#6^|t^}G=Ut7+WOugNs=tTLyOGHq&u?!#By|D2t2{ z`}m(bYV&3j0;<)2dw$>AAm3hBc(vI#>LLE%w2s?g-0JDZN35EHU-)NVcYP|qU&FKQ z_IS~q8%a~4myQ}di;_1y?=I@~7Vk8E)Z(p##f_znh}OK&bEBd-vov{KwS6B9#j^=6 zNuj6ynPr#L%t$T?C^Nd^PlMa3`_8&)b*M9q)qc+YI z8%70;ZOJQ3oiY8D{hE_qaT=2&epHYIcQxNYE8X_HA!<}G`dY)Mdg5?hut>_>{^XUA z6?cu#Dg{)Kc^LWP5u25qYk|G!*ke*XVO19_82dwrC23Tj3X*>j5}0%0Z!hW#$^3rx z5EV4#)~%_o5n`SPIZ?sxB7ud8h4)x(0h^pohmV(|d*ZuUwta}D0)E=e+sthrQZgUf zB7WL(;-ZdTi*a$B`$t{b(EQ-&C7LRFsOk>$t`~Wk@!bM&@lQ=Hze2X%_CwWjwAg>i zh1u-gt1p)2Svn?F+b6r?MOM%EQ^7VW*kZC^d_QKe{l~Z7q3n@^sDaBN?3s(nM#4I(YfATKy3ponUT96oU&$$RdsId?o71XWMmJ9Xi zFYiDoRCs0vrLg~u+JG`+g( zc!Em11n&CYJDfH_vL!RjX#|m-(n-fXo;^#hxf`2Un729axZnb+Z?yNukkF1bnVpZ~ zCVPtoCdSpryHRU8Cvse@_)HaE>4|adRVz z!m_4S;!DLbA9T_=EG{@W1}({)yE*I&ooJ#yu627B>KzK(W$M2Sudh9c=2-I z!ul8rOh=ED#9G&z#@~+1PPl7Up)vCCd01khO-@0(`XckbFfa0z5yGjn)j}5q_fk%8 zX}D9h_q6319EbZSlh6h1wn{zeE4E}=|6SLZIM4TEsj)p>X(#F#m3F3rrw*RWP8f!9 z^qZ$%F#;XI(-;OdIxCwF2QN^VdEF*`XCU8d$4ZlZj8h7&BG*Mb9B2I7w%6!5N>SY6z<_fbQaRs&7>Bp0u^|X104lJy*#}GR6^B-XnIxPGcqhA zBuEnp^iUT%1mB(a`S_Cs3DN{@ zAt52sA@b5b{;o23B9SN~D<>l-Cj}*>0>Zol9YdwO1B4M3>pHZ^0Z#tzzJcyO-hzlu zN0Luapt_I{oEQA*pO>$Z(I4u)1Aedo`H%^9^p(L&%gT6p$^5z^AW%CPD*55iKV1=E z5#~#lF((K31o=CWwS&ptfx^G4aCZ7*y>F1eCk>9XlMLCD>;**wpjG@|Od`KB{ILR| zz}4N$m$nL${TInVcb7lO`ipPK3=Ph&j=<%A=>3cIPwX^dC}m`%qUGZhgt(`#r7ncn zS8?`na(7mtJ>tpoB(kHktduf=>?lQWRF;z>D!`z~DmcnJ%Q-nY!RcRA>3atRI(j>i z5mivRv^&%zt3V_w$&!_%6yz0&QUp0=B`IZDyn>X1vI|KTFYiRcD>?t7!o=SlW~HO& zuU;XloS`ZwSy?AVCj|v5lCzVt6hYR7EJc!Y#!D&4k!78TaBq=MaBD?NBqRz<2+1(}VzmrCa zM^FvQ!;tH_2SEE_w4wEiIzaYY|F-_s)16jIf`YW7P;qoxhY;WxOkQUg>RO+2a&z={ zCByFVBVB)vyZ^IPAS=l_;}u9!1Tvm1MIb83!&H!0mckR9oJeG6Jf27((OCFHdw`Ei zV2GnXd5h%8-qMV!xK~Y6P@&67Y zfdp$%PDxHmiA;u}RCXpx5nTw1Qc5Hz1%jLs-i3r;&&~gB6bVwY@=|ide@y!yQB;#b zI{(kSRg?KonY}LX%T@uSzdi=HAh@H+{IR9|NDJuizw-J~QU6L4f`b1x^0)Z?H(mdx z>u)jew}k(lUH_)*Z!z$UY-+s2}@0e5ogJ^(yd^|kg`gnk<9dgEg| z7*sd;;`3RYzP`u~>nyig^XD(macX~OPA$^5C1{qv6w;$3>^%P5ZS5FPVBMO-?M~wH zGn09%tw?VhYK0Sj=oVY$KHR?ZY_Xpw^YLAhq|{G4rHtIHh0Xg+`(7DxH#FZcY}}Z0 z<#T6*M&+9({>g#QMEQAQ(|pEYiCs+Oc&3EeJ{kViqwm8XR8D>!xeynZlas?EAm9+T z+R(N)a^ZWqN5!1EqlEG9@4i;1?-b@pFz}(LYunh|=MyD7Lyg+*C46*UCCZ%T z9dbz`$;(;XxWomk&si!>bsb7^UaQ#@ZNK>0@EAN^PKJl1(s=;L`+Va+)m^ZgMc;!ovdq2Mf z7sywVxU`_EOQ~Sd6yE7^E+3#xA z)0*mTD2w=aLdT>vQ%BK9dWMckMfG2hwCbz!!u0m3atjOfHC4=%EDQ>)83uM-8!O{U z&V9;o>Ef$`$|6-Z$(P1k=2zaHR~8BE%w8;GX5C>^; z?397Wk_F#x+!s`J>s(zdL&O=tjtrpoblL5VOlU!ErBtI~&0(MNZKqfS5+tqiw6wIo z)q1YfSQ*#Wghg&wH@_`3T%wwD z7@0FtB3^Fmq00}yv&helA_UeSP-^#P%-Sb%+1p$L*V$9lbu1CtIYR8!; zx!xVte7Q5{jzad98ii)D7p`I+EcdlF0Ml4>F*>@FU|a8QnQSdqHw1;JIqc<}vvR~?=AS2udp ze4eR#`NVkbajlt5%+}TNT=DKW_9*6S_8doS!^IM;Zf95eSiOGZaOPZBHhyuWD66PQ zb$p!vOn0P%me%M{2k-kq(d^PvvGD2Dg5p5=rSJ_|fli8F^DYSqk%GtlNBKLsyB4X5 zAw8u$5%c3I2odU_5w#Gj;XmqD<~!GUt72l|T)eV;*fS!~>Np5mJdG6YD!O3mjH!vuu=CMa%LB6jrH0C$9WVmtjMqRDy*|&x>f%7$2l#J`@lB0x9 zo(icuT)FHuI;z22xiTOlEJO;Ox0}4@uxhY@-4M(GW$ZPTMVX6ACg$P(B~qNIMwH-D zbCl@=M&CyvR%NrL^>J}X0kp&xjZZj8HP%+Fie<&PnymE2c#kbtMnvvfn=kUI>n;th z$%s-FCb`;PjZ#_)nX8VN;OxIGv!=Xzw!TSAtJ=h2rC>-HrW_MP6{&bK!3FB|0nwbS$v~jNm@ZHL*(_ za;Ogt^V@-zmjq~kcUvQTgrWCRj65f^(nXJqnfbR(F&5TFo7dI^)&kyCQeSDTT|JIM zX#%*Oa;J;F>S{WMhs|&3`}LDaOHvSAEOxvi=w5G?o0eAD^zw0}Gys|c(@z(bf8jQ& zV&(UFu@xOrYD?^L_PtJydA_H*)ojTBKhgwoD%ZiC_Za1%Z+i#YtQ_J`@vHD&VmjdG zJ7He7+TMW}Iec%irKx7+j0YQAOQn<5%Dhapt@Y~afWabNO63I&^by$6(3+3l&}){< z@MtKv1g)(+kc3^^a=fi_YH7d6TFm3_(COKR)>ezt$vwjy3*SG-7yEwRJKCef#m3gN z`1L*M=rET8++&g_BBwpzjx#(Txl)0h!5}4$W~_2~GIOwKGc4(Cw!ng>eZG6SAkWG^ zCdYs3*s0PAm>1E*@nY2B0kO?_U9YHY4pk zUTVG2t{Se7DLjRRAu!qnwz#9q=DU+~4LijILW@T(ymz>3L0z6c;VPNA+xOlJ>OhZ4 zU3dz0m}*ILX~`Jv`G}$TUA+KI01~8Fv?_%~t@FD`h0lAunGRs3;5aB}5-7v!YqOE} zQZ&$-t<`9x1chyU1{~T3JY2PTA@%0Qpj{GegI^S;IWaziU8x&#vZIAg5Zp_o?E1oj zy7rnI%>D)tCW09>FV>y`rhUv5RdvSv444f7^+65A12;fIrq8#4v4IB_?;GgQn(;E= z$y-buTxEGSR~YQ8**h~hjjw!!6Emo}$cdV=ikW(F0gIuqI{-p9BP;afzToe=K!+;( z%|a~mBBy}TV1H|s-sr?wl0gCMvaXI(cv#pQXC;eWTAqEgs;g@{_C0Q$x#EpS2T-VM z)!ZO=jh^PVXA(%~=ZS~=@M{^V8bfB$B8m3AJkNV6wuH~KmaCmQ_CAU`b1p&CI1u!u zR{#MJ$)b5LpL+EERYjkgvGX<>5Hq6D8!ZB7htlmp8|Mr>HK-jtu^4Nz`>^}`MFR}w zd|n<0b#~PtS4MeNwda?L zDkkDxB@VJTH-_GlN=n6}n}m2 ziu-n8j28K%MKiAn&hG*I#9#u~tAU~Vf%aMX6z);9+mtkHjBj_T0|p8|1v3L$e_x64 zFHw$mey&dmMzJawgWr%|r;-Wa7G?V;MkCspbd%wZHu|kG5be-3X9WgEKjE$LQ=rme zE|m30deeJs`DW+e>akIfs)M}4BtM&E2WAr}_b1SY)ED0iOE3U(7HFmw+qaMO`A-@0 znXd&QHSc~FvI7C^RAtOhC@d^yK62-f+p8}VBAVvF^a&%y4r~i!KN9q?kokz0S{e~{ zfz*V<0LBpRs2>G^br-#`~-AXgj>*^ER9Vi2xQ^HWr>K6<#ei_(!uQQdh9PQ@ZtgHbm|MXJIpWfGgv zhwLz&-@I@biupc(%rR&_ZA5)|S(wi(m~bL4Xbb9h{l5e#F9j$~-5*E0ktcOhhiHjH z0nV`qF`ANzN?BUm0C|78B#ZRSB}UDQAt*thC6KxvjV?&7yl{4o7#K@ixr)(a0u73& zeC8@?%4T6OCfyB_73sD{JCLrKF3vfI{vd)nG+_-w!aJO^Y1JbLbKXq?btvjV#TD(U zZ^zEHa!_2x(RbF{+K<(3`nNd`sg7Z;aTe`YM0zq4*b6s?TkMoJ$yv)>w|54>M%%Fc z)t@u-Nb7W8x~>?E@`UGTaTW%!6EMJtj-rQHk{v9zLKf5#J;xfXI{Lz=j*!c(#~AD8u4jrd5W$yyOgkXburR*>7&V-s8MF@=ceej zjy5|m*3h#swRgBr4>nc3jJt#Gl;2mQ;M><^Z%UJ;rGS45R}nMij^8(wo(d{Iv%3&H z2`x7IRQ7RD6m}nk2;a?`5*hTq%byk7^b2ipg#I5JO3fD-oiAKqI~ZB`Fedq}+nJRD z-_61?M;;j+itwB_4U~G_m7wcDZ5SyyDrXn<&|dgK&$oG{sU@9$@3yh?XQpHm04rJ( z$=BapQ7V=1gK*7pVFO~A0x8ayfTX~-P|tlME?@r2kgz>^2{MB!lj>eGH* zQOg91>JAhGV58a3f8*!oJe6s0p9EV_nhvZaSiC3ffO{AH+2522DvL^`3`40aAL)N& zlOa3hjp5n|Csc3_4Xt7XkNMqETzEXPOk24f766uw5*#If*1Q3bv_+1Pw0^MT405EP zA)_5D0ZP!EHUf{0uv(aqqlG3&!<`zwSdq(0dE>cF3;ZaJZCs~v`9>ndkRG?L^}}y0 zoXmb%7M{wRN1|4PL&cJ}A}NNL*X5vGCv9JvUcBsJV;2hN%PSZ}| z6hThNJB;o2p7k8ajLv&#$KAi|A<=U%h2X2DTG-mB1IZ;P&Hb4v1+Ezn zJm1&&ggSZ~?TC>G=O{qy4;R<$S^HwLc6vF=VX6JSyj|5m=c`wZe~vaqvQQ$zKJpeR zzsy{z&-AODxFQ2Aj#~;&iN(Ob5aqSwkJ0Be7UjMDkVtUe=Zr(-66v6OcaG$0BFYc* z!Psijd(aETOu2UUAt91DB+1%;QKO#=3nOLv%;p$Rkuv-XgGym)XR4+-zyd>Pk#8wj zE4BGgQ+RK`vl@&0Xr_=A&@C7!3X>%tGy{#%EJ-2@kTq3Tb4H$tW#+=;oOaA^f%JgJ zFw2!U6YAX;+|j*8Rm4HH#Eiwmpc?~c3Wp%HGDhXWba>bXgXsZD&`&r{gh+fFiGvU; zT<|}fd^GK-xp+JCp7X4`4WfI5TOfwe!9q7B+M6Dbq20711$@v@sr3vzAk)mVQAT%8 z7*(mZ3H)(B*fIs{sQS#b>UUUbTh_{EzxYo+{}@m|j(Qo6>NRRgiDtVSKD&HA+N`ha zUE3z^e% z>_v|_yBH`ej3M|w+ZLpZ(@S~$@`m7R2WYfAt!x!Yvn{QYF8LI`<52>*g&W}l$bCs7 z+hBq>Oqbrynz#UMB_u54r0SBatuRlD6U{hQ&N=DUT$onm>Z(gNMB2k(M-1M7D}>9{ z1{yi#^V`+3;bRoKJMDk0h|Mbd?RUT#IyNwPPdE83VsbN;rob{6EX{EO5# zZGi55@$A4uAv26`xBb+`86klB{<${+G;*SNcfmF%z?AV;sA?QEb{xit|247HWGr}q!+L<_QvA>*nY}_{W z;wyaf)x-lWzsKFy+Y!{+Cx}#N?P`Tg)X2!kXrAWa3SP@fMuS%a)sYM5RcK|NqR}7S zBOk+jL^ZZ@$w;>O>i*ZKWO88BSWJN(XMA2A9wH5znY54=246PU+XbRkYV+UhOr*}g zbS5tBUpmvzCi7o(CQf7pbc@!`5@P)lV^``0U{2jRvfg27?ya||FHOae%&MPF7D?Z~ zOfYF7jqHci{{^`Jw(b5MaI_ZuUx2%j6D<+me{`ZZVQUfR4P>Lxgufa8t1hW#D&2)w Vx`jP_W8wf_`r5`?d3%o>{|^dZ5!nC$ delta 5488 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 diff --git a/src/main/resources/assets/unicopia/textures/entity/air_balloon/canopy/storm.png b/src/main/resources/assets/unicopia/textures/entity/air_balloon/canopy/storm.png index 65f049a52e1deec76489ada6b81af711523da071..49d2cee390085769387c15a5c2051fa1b61c1edb 100644 GIT binary patch literal 44060 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
<*TpGB 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

~m;8}e}a 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 delta 32642 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 JPDHLkV1k@gkI(=B delta 49937 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

Cj-!EN{5G?KfM--A|R0 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 literal 0 HcmV?d00001 From 1fd17820517f6fe2959bf95df059cc0a406ece3e Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 29 Mar 2024 20:32:50 +0000 Subject: [PATCH 54/73] Added chocolate oatmeal cookie Added scone Added recipe to craft bread from oats Changed hay fried recipe to be vertical --- .../datagen/providers/UModelProvider.java | 4 +-- .../providers/recipe/URecipeProvider.java | 25 ++++++++++++++++-- .../unicopia/item/UFoodComponents.java | 11 ++++++-- .../minelittlepony/unicopia/item/UItems.java | 8 +++--- .../resources/assets/unicopia/lang/en_us.json | 2 ++ .../item/chocolate_oatmeal_cookie.png | Bin 0 -> 9392 bytes .../assets/unicopia/textures/item/scone.png | Bin 0 -> 6751 bytes .../tags/items/food_types/baked_goods.json | 2 ++ 8 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 src/main/resources/assets/unicopia/textures/item/chocolate_oatmeal_cookie.png create mode 100644 src/main/resources/assets/unicopia/textures/item/scone.png diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java index 4a652170..8dd5d9c5 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java @@ -59,7 +59,7 @@ public class UModelProvider extends FabricModelProvider { ItemModels.register(itemModelGenerator, UItems.ACORN, UItems.APPLE_PIE_HOOF, UItems.APPLE_PIE_SLICE, UItems.APPLE_PIE, UItems.BANANA, UItems.BOTCHED_GEM, UItems.BOWL_OF_NUTS, UItems.BROKEN_SUNGLASSES, UItems.BURNED_JUICE, UItems.BURNED_TOAST, - UItems.CARAPACE, UItems.CLAM_SHELL, UItems.COOKED_ZAP_APPLE, UItems.CLOUD_LUMP, UItems.CRISPY_HAY_FRIES, UItems.CRYSTAL_HEART, UItems.CRYSTAL_SHARD, + UItems.CARAPACE, UItems.CLAM_SHELL, UItems.COOKED_ZAP_APPLE, UItems.CHOCOLATE_OATMEAL_COOKIE, UItems.CLOUD_LUMP, UItems.CRISPY_HAY_FRIES, UItems.CRYSTAL_HEART, UItems.CRYSTAL_SHARD, UItems.DAFFODIL_DAISY_SANDWICH, UItems.DRAGON_BREATH_SCROLL, UItems.EMPTY_JAR, UItems.FRIENDSHIP_BRACELET, @@ -70,7 +70,7 @@ public class UModelProvider extends FabricModelProvider { UItems.JAM_TOAST, UItems.JUICE, UItems.LIGHTNING_JAR, UItems.MANGO, UItems.MUFFIN, - UItems.OATMEAL, UItems.OATMEAL_COOKIE, + UItems.OATMEAL, UItems.OATMEAL_COOKIE, UItems.SCONE, UItems.PEBBLES, UItems.PEGASUS_FEATHER, UItems.PINECONE, UItems.PINECONE_COOKIE, UItems.PINEAPPLE_CROWN, UItems.RAIN_CLOUD_JAR, UItems.ROCK_STEW, UItems.ROCK, UItems.ROTTEN_APPLE, UItems.SALT_CUBE, UItems.SCALLOP_SHELL, UItems.SHELLY, UItems.SOUR_APPLE_SEEDS, UItems.SOUR_APPLE, UItems.SPELLBOOK, UItems.STORM_CLOUD_JAR, diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index 2161b97a..3a95e32e 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.datagen.providers.recipe; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; +import java.util.stream.Stream; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.UConventionalTags; @@ -320,16 +321,28 @@ public class URecipeProvider extends FabricRecipeProvider { .input(Items.BOWL) .offerTo(exporter); ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.OATMEAL_COOKIE) - .input(UItems.OATS, 3).criterion(hasItem(UItems.OATS), conditionsFromItem(UItems.OATS)) + .input(UItems.OATS, 2).criterion(hasItem(UItems.OATS), conditionsFromItem(UItems.OATS)) + .offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.CHOCOLATE_OATMEAL_COOKIE) + .input(UItems.OATS, 2) + .input(Items.COCOA_BEANS).criterion(hasItem(Items.COCOA_BEANS), conditionsFromItem(Items.COCOA_BEANS)) .offerTo(exporter); ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.PINECONE_COOKIE) .input(UItems.PINECONE).criterion(hasItem(UItems.PINECONE), conditionsFromItem(UItems.PINECONE)) .input(Items.WHEAT, 2) .offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.SCONE) + .input(UItems.OATS).criterion(hasItem(UItems.OATS), conditionsFromItem(UItems.OATS)) + .input(Items.WHEAT, 2) + .offerTo(exporter); ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.ROCK_CANDY, 3) .input(Items.SUGAR, 6).criterion(hasItem(Items.SUGAR), conditionsFromItem(Items.SUGAR)) .input(UItems.PEBBLES, 3) .offerTo(exporter); + ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, Items.BREAD) + .input('#', UItems.OATS).criterion("has_oats", conditionsFromItem(UItems.OATS)) + .pattern("###") + .offerTo(exporter, convertBetween(UItems.OATS, Items.WHEAT)); ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.JUICE) .input(Ingredient.fromTag(UTags.FRESH_APPLES), 6).criterion(hasItem(Items.APPLE), conditionsFromTag(UTags.FRESH_APPLES)) .input(Items.GLASS_BOTTLE) @@ -349,7 +362,9 @@ public class URecipeProvider extends FabricRecipeProvider { ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.HAY_FRIES) .input('#', UItems.OATS).criterion(hasItem(UItems.OATS), conditionsFromItem(UItems.OATS)) - .pattern("###") + .pattern("#") + .pattern("#") + .pattern("#") .offerTo(exporter); ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.HAY_BURGER) .input('~', Items.BREAD).criterion(hasItem(Items.BREAD), conditionsFromItem(Items.BREAD)) @@ -717,4 +732,10 @@ public class URecipeProvider extends FabricRecipeProvider { .traits(traits) .offerTo(exporter); } + + public static InventoryChangedCriterion.Conditions conditionsFromMultipleItems(ItemConvertible... items) { + return conditionsFromItemPredicates( + Stream.of(items).map(item -> ItemPredicate.Builder.create().items(item).build()).toArray(ItemPredicate[]::new) + ); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java b/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java index a7ff322a..ee093b08 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.item; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffects; import net.minecraft.item.FoodComponent; +import net.minecraft.item.FoodComponents; public interface UFoodComponents { FoodComponent OATS = builder(1, 0.7F).build(); @@ -12,8 +13,8 @@ public interface UFoodComponents { .statusEffect(new StatusEffectInstance(StatusEffects.STRENGTH, 1200, 1), 0.3F) .statusEffect(new StatusEffectInstance(StatusEffects.SPEED, 1200, 1), 0.2F) .build(); - FoodComponent DAFODIL_DAISY_SANDWICH = builder(3, 2).build(); - FoodComponent HAY_BURGER = builder(7, 1.4F).build(); + FoodComponent DAFODIL_DAISY_SANDWICH = builder(3, 1.4F).build(); + FoodComponent BURGER = builder(7, 1.4F).build(); FoodComponent HAY_FRIES = builder(4, 2).build(); FoodComponent CRISPY_HAY_FRIES = builder(6, 7).build(); @@ -23,6 +24,12 @@ public interface UFoodComponents { FoodComponent JUICE = builder(2, 1.8F).alwaysEdible().build(); FoodComponent BURNED_JUICE = builder(3, 1).build(); + FoodComponent NUT_BOWL = FoodComponents.BAKED_POTATO; //builder(4, 0.6F).build(); + + FoodComponent OATMEAL_COOKIE = FoodComponents.COOKIE; //builder(2, 0.1F).build(); + FoodComponent CHOCOLATE_OATMEAL_COOKIE = builder(3, 0.4F).build(); + FoodComponent SCONE = builder(2, 0.2F).build(); + @Deprecated FoodComponent RANDOM_FOLIAGE = builder(2, 1).build(); @Deprecated diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 5e365031..242e9a13 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -75,12 +75,14 @@ public interface UItems { Item IMPORTED_OATS = register("imported_oats", new Item(new Item.Settings().food(UFoodComponents.IMPORTED_OATS)), ItemGroups.FOOD_AND_DRINK); Item OATMEAL = register("oatmeal", new OatmealItem(new Item.Settings().recipeRemainder(Items.BOWL).maxCount(1).food(UFoodComponents.OATMEAL)), ItemGroups.FOOD_AND_DRINK); - Item OATMEAL_COOKIE = register("oatmeal_cookie", new Item(new Item.Settings().food(FoodComponents.COOKIE)), ItemGroups.FOOD_AND_DRINK); + Item OATMEAL_COOKIE = register("oatmeal_cookie", new Item(new Item.Settings().food(UFoodComponents.OATMEAL_COOKIE)), ItemGroups.FOOD_AND_DRINK); + Item CHOCOLATE_OATMEAL_COOKIE = register("chocolate_oatmeal_cookie", new Item(new Item.Settings().food(UFoodComponents.CHOCOLATE_OATMEAL_COOKIE)), ItemGroups.FOOD_AND_DRINK); Item PINECONE_COOKIE = register("pinecone_cookie", new Item(new Item.Settings().food(FoodComponents.COOKIE)), ItemGroups.FOOD_AND_DRINK); - Item BOWL_OF_NUTS = register("bowl_of_nuts", new StewItem(new Item.Settings().food(FoodComponents.BAKED_POTATO).recipeRemainder(Items.BOWL)), ItemGroups.FOOD_AND_DRINK); + Item BOWL_OF_NUTS = register("bowl_of_nuts", new StewItem(new Item.Settings().food(UFoodComponents.NUT_BOWL).recipeRemainder(Items.BOWL)), ItemGroups.FOOD_AND_DRINK); + Item SCONE = register("scone", new MuffinItem(new Item.Settings().maxCount(32).food(UFoodComponents.SCONE), 0), ItemGroups.FOOD_AND_DRINK); Item DAFFODIL_DAISY_SANDWICH = register("daffodil_daisy_sandwich", new Item(new Item.Settings().food(UFoodComponents.DAFODIL_DAISY_SANDWICH)), ItemGroups.FOOD_AND_DRINK); - Item HAY_BURGER = register("hay_burger", new Item(new Item.Settings().maxCount(1).food(UFoodComponents.HAY_BURGER)), ItemGroups.FOOD_AND_DRINK); + Item HAY_BURGER = register("hay_burger", new Item(new Item.Settings().maxCount(1).food(UFoodComponents.BURGER)), ItemGroups.FOOD_AND_DRINK); Item HAY_FRIES = register("hay_fries", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.HAY_FRIES)), ItemGroups.FOOD_AND_DRINK); Item CRISPY_HAY_FRIES = register("crispy_hay_fries", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.CRISPY_HAY_FRIES)), ItemGroups.FOOD_AND_DRINK); /** diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 6b3a168b..22f18738 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -147,7 +147,9 @@ "item.unicopia.wheat_worms": "Wheat Worms", "item.unicopia.baited_fishing_rod": "Baited Fishing Rod", "item.unicopia.muffin": "Muffin", + "item.unicopia.scone": "Scone", "item.unicopia.oatmeal_cookie": "Oatmeal Cookie", + "item.unicopia.chocolate_oatmeal_cookie": "Chocolate Oatmeal Cookie", "item.unicopia.pinecone_cookie": "Pinecone Cookie", "item.unicopia.bowl_of_nuts": "Bowl of Nuts", diff --git a/src/main/resources/assets/unicopia/textures/item/chocolate_oatmeal_cookie.png b/src/main/resources/assets/unicopia/textures/item/chocolate_oatmeal_cookie.png new file mode 100644 index 0000000000000000000000000000000000000000..d3396a3a71ef6a0d413dd0e6b587d53f83047d8d GIT binary patch literal 9392 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json b/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json index b28e7389..e9ac11e8 100644 --- a/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json +++ b/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json @@ -4,6 +4,7 @@ "minecraft:bread", "minecraft:cookie", "unicopia:muffin", + "unicopia:scone", "#c:grain", "unicopia:cooked_zap_apple", "minecraft:pumpkin_pie", @@ -18,6 +19,7 @@ "unicopia:crispy_hay_fries", "unicopia:horse_shoe_fries", "unicopia:oatmeal_cookie", + "unicopia:chocolate_oatmeal_cookie", "unicopia:pinecone_cookie", "unicopia:bowl_of_nuts", { "id": "farmersdelight:wheat_dough", "required": false }, From f0b2a8a550b51e5a2d1465af2d9d136603e72937 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 30 Mar 2024 02:19:54 +0000 Subject: [PATCH 55/73] Made jars placeable --- assets/models/body.png | Bin 0 -> 220 bytes assets/models/cork.png | Bin 0 -> 136 bytes assets/models/jar.bbmodel | 1 + assets/models/jar_body.png | Bin 0 -> 220 bytes assets/models/jar_cloud.bbmodel | 1 + assets/models/jar_cork.png | Bin 0 -> 136 bytes assets/models/jar_lightning.bbmodel | 1 + assets/models/jar_storm.bbmodel | 1 + assets/models/jar_zap.bbmodel | 1 + .../com/minelittlepony/unicopia/UTags.java | 1 + .../unicopia/block/ItemJarBlock.java | 216 ++++++++++++++++++ .../unicopia/block/JarBlock.java | 82 +++++++ .../unicopia/block/UBlockEntities.java | 1 + .../unicopia/block/UBlocks.java | 10 +- .../unicopia/client/URenderers.java | 1 + .../entity/ItemJarBlockEntityRenderer.java | 49 ++++ .../datagen/providers/BlockModels.java | 1 + .../providers/UBlockStateModelGenerator.java | 13 ++ .../datagen/providers/UBlockTagProvider.java | 4 +- .../loot/UBlockLootTableProvider.java | 5 + .../unicopia/item/EmptyJarItem.java | 60 +++++ .../unicopia/item/FilledJarItem.java | 27 +-- .../unicopia/item/HeavyProjectileItem.java | 22 +- .../unicopia/item/HorseShoeItem.java | 4 +- .../unicopia/item/JarInsertRecipe.java | 2 +- .../minelittlepony/unicopia/item/JarItem.java | 150 ------------ .../unicopia/item/MuffinItem.java | 3 +- .../unicopia/item/ProjectileItem.java | 52 +---- .../minelittlepony/unicopia/item/UItems.java | 10 +- .../unicopia/item/WeatherJarItem.java | 136 +++++++++++ .../unicopia/projectile/Projectile.java | 73 ++++++ .../resources/assets/unicopia/lang/en_us.json | 7 +- .../models/block/cloud_jar_filling.json | 56 +++++ .../models/block/lightning_jar_filling.json | 34 +++ .../models/block/storm_jar_filling.json | 140 ++++++++++++ .../unicopia/models/block/template_jar.json | 57 +++++ .../models/block/zap_jar_filling.json | 20 ++ .../unicopia/textures/block/jar_body.png | Bin 0 -> 220 bytes .../unicopia/textures/block/jar_cork.png | Bin 0 -> 136 bytes .../textures/block/lightning_jar_filling.png | Bin 0 -> 8868 bytes .../textures/block/zap_jar_filling.png | Bin 0 -> 9511 bytes 41 files changed, 996 insertions(+), 245 deletions(-) create mode 100644 assets/models/body.png create mode 100644 assets/models/cork.png create mode 100644 assets/models/jar.bbmodel create mode 100644 assets/models/jar_body.png create mode 100644 assets/models/jar_cloud.bbmodel create mode 100644 assets/models/jar_cork.png create mode 100644 assets/models/jar_lightning.bbmodel create mode 100644 assets/models/jar_storm.bbmodel create mode 100644 assets/models/jar_zap.bbmodel create mode 100644 src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/JarBlock.java create mode 100644 src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java create mode 100644 src/main/java/com/minelittlepony/unicopia/item/EmptyJarItem.java delete mode 100644 src/main/java/com/minelittlepony/unicopia/item/JarItem.java create mode 100644 src/main/java/com/minelittlepony/unicopia/item/WeatherJarItem.java create mode 100644 src/main/java/com/minelittlepony/unicopia/projectile/Projectile.java create mode 100644 src/main/resources/assets/unicopia/models/block/cloud_jar_filling.json create mode 100644 src/main/resources/assets/unicopia/models/block/lightning_jar_filling.json create mode 100644 src/main/resources/assets/unicopia/models/block/storm_jar_filling.json create mode 100644 src/main/resources/assets/unicopia/models/block/template_jar.json create mode 100644 src/main/resources/assets/unicopia/models/block/zap_jar_filling.json create mode 100644 src/main/resources/assets/unicopia/textures/block/jar_body.png create mode 100644 src/main/resources/assets/unicopia/textures/block/jar_cork.png create mode 100644 src/main/resources/assets/unicopia/textures/block/lightning_jar_filling.png create mode 100644 src/main/resources/assets/unicopia/textures/block/zap_jar_filling.png diff --git a/assets/models/body.png b/assets/models/body.png new file mode 100644 index 0000000000000000000000000000000000000000..99e38ba24890f8e16bf666d92423a27976ea16d6 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`i#=T&Lo9lqPBi3eG2mf2&cUgb z5_jPL{X_ac8rF6&X~mbm(2Hqed78WP-rR^j7ngvGn{;>%H>|4r`OeRa^UN9!gUtq; ze|+_DX_@IdS-LVHR8a6_t)O7&Q-&SZk1ggkg1zn2~F{Gzq% z^QJrByC1>I;Bz@-ukYq{*@Y3aWgAW(X^m>AoR@st>{~7Sg4b5R_SK*IC%u>9n1A%D UD+M)kfX-#`boFyt=akR{0BKxVumAu6 literal 0 HcmV?d00001 diff --git a/assets/models/cork.png b/assets/models/cork.png new file mode 100644 index 0000000000000000000000000000000000000000..c87771fa5160cfd8fa23f3d102300603e7f8df57 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`{+=$5Ar`&KF*eGd?V05SW*g2G zoNpt{%*@=p!oVDaV+7{*_y eaJeytGBAYC;ahToeNq9?Xa-MLKbLh*2~7aemL*~U literal 0 HcmV?d00001 diff --git a/assets/models/jar.bbmodel b/assets/models/jar.bbmodel new file mode 100644 index 00000000..39fe3bb8 --- /dev/null +++ b/assets/models/jar.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"4.9","model_format":"java_block","box_uv":false},"name":"jar","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":16,"height":16},"elements":[{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[4,0,4],"to":[12,12,12],"autouv":0,"color":3,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,8,12],"texture":0},"east":{"uv":[0,0,8,12],"texture":0},"south":{"uv":[0,0,8,12],"texture":0},"west":{"uv":[0,0,8,12],"texture":0},"up":{"uv":[8,0,16,8],"texture":0},"down":{"uv":[8,0,16,8],"texture":0}},"type":"cube","uuid":"c02d32c0-74ac-27ba-627e-83de2a9500f7"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,13,6],"to":[10,16,10],"autouv":0,"color":3,"origin":[0,0,0],"faces":{"north":{"uv":[0,4,4,7],"texture":1},"east":{"uv":[0,4,4,7],"texture":1},"south":{"uv":[0,4,4,7],"texture":1},"west":{"uv":[0,4,4,7],"texture":1},"up":{"uv":[0,0,4,4],"texture":1},"down":{"uv":[4,0,8,4],"texture":1}},"type":"cube","uuid":"147c96d5-ae15-7e40-dcb7-c635e6e80eed"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[5,13,5],"to":[11,14,11],"autouv":0,"color":3,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,8,1],"texture":0},"east":{"uv":[0,0,8,1],"texture":0},"south":{"uv":[0,0,8,1],"texture":0},"west":{"uv":[0,0,8,1],"texture":0},"up":{"uv":[8,0,16,8],"texture":0},"down":{"uv":[8,0,16,8],"texture":0}},"type":"cube","uuid":"7642fef8-ce7e-d79f-f450-01de2526fca5"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,12,6],"to":[10,13,10],"autouv":0,"color":3,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,8,1],"texture":0},"east":{"uv":[0,0,8,1],"texture":0},"south":{"uv":[0,0,8,1],"texture":0},"west":{"uv":[0,0,8,1],"texture":0},"up":{"uv":[8,0,16,8],"texture":0},"down":{"uv":[8,0,16,8],"texture":0}},"type":"cube","uuid":"e1e878a3-7fdb-79f6-e2c8-b591a94cec41"}],"outliner":["c02d32c0-74ac-27ba-627e-83de2a9500f7","7642fef8-ce7e-d79f-f450-01de2526fca5","e1e878a3-7fdb-79f6-e2c8-b591a94cec41","147c96d5-ae15-7e40-dcb7-c635e6e80eed"],"textures":[{"path":"","name":"body","folder":"block","namespace":"","id":"0","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":true,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":false,"uuid":"c3fc3ff5-2bb6-a5d1-88ff-7d0d48a4200c","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAKxJREFUOE/Nk70NxCAMhe0qiCKCCRiA/UdhAFgARIGg8sknJbpI/CS6K47Sz/54fggkIoLJCSHAvu+glLp0pZQg5wwYYyStNfYYrHGdhxHx0sMXM+QEHIVPGAN6w8dlPHMCek4eAUYrLB1478kYM8zga8AyxJkD1hgwfcYVYLTekRk658ha281gpv0WUEqBWiu01t7gbdtACAFSShi5Ox3M/sEdrbv7ncH/cfACoGWX3cV5e7AAAAAASUVORK5CYII="},{"path":"","name":"cork","folder":"block","namespace":"","id":"1","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":false,"uuid":"1faf1369-230e-ed4a-f210-037c1820f194","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAFJJREFUOE9jXDwj8z8DHhCbMZ0RnzwjyABRYW6wmtdvv4JpZD59DKDICztWl6CEgUdoD14/o1sGDgNkQUJ+pr4B+PxPjBxJ/sVm4KgBDAzDIAwAlBIoEQohE0IAAAAASUVORK5CYII="}]} \ No newline at end of file diff --git a/assets/models/jar_body.png b/assets/models/jar_body.png new file mode 100644 index 0000000000000000000000000000000000000000..99e38ba24890f8e16bf666d92423a27976ea16d6 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`i#=T&Lo9lqPBi3eG2mf2&cUgb z5_jPL{X_ac8rF6&X~mbm(2Hqed78WP-rR^j7ngvGn{;>%H>|4r`OeRa^UN9!gUtq; ze|+_DX_@IdS-LVHR8a6_t)O7&Q-&SZk1ggkg1zn2~F{Gzq% z^QJrByC1>I;Bz@-ukYq{*@Y3aWgAW(X^m>AoR@st>{~7Sg4b5R_SK*IC%u>9n1A%D UD+M)kfX-#`boFyt=akR{0BKxVumAu6 literal 0 HcmV?d00001 diff --git a/assets/models/jar_cloud.bbmodel b/assets/models/jar_cloud.bbmodel new file mode 100644 index 00000000..eafb6e23 --- /dev/null +++ b/assets/models/jar_cloud.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"4.9","model_format":"java_block","box_uv":false},"name":"jar_cloud","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":16,"height":16},"elements":[{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[5,6,5],"to":[10,9,9],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"e15b3907-6195-1f3b-0c48-23c6b4642fc6"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,4,7],"to":[12,7,11],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"e61fcd01-8143-912a-1b70-663d7f7ec80b"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,8,7],"to":[10,10,10],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"f61cf32c-8485-4809-93a4-7eca7767fc5f"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,7,8],"to":[11,9,11],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"a073f455-b48b-6520-5323-081195bb2d1c"}],"outliner":["e15b3907-6195-1f3b-0c48-23c6b4642fc6","e61fcd01-8143-912a-1b70-663d7f7ec80b","f61cf32c-8485-4809-93a4-7eca7767fc5f","a073f455-b48b-6520-5323-081195bb2d1c"],"textures":[{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/assets/models/body.png","name":"body.png","folder":"","namespace":"","id":"0","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":true,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"c3fc3ff5-2bb6-a5d1-88ff-7d0d48a4200c","relative_path":"../body.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAKxJREFUOE/Nk70NxCAMhe0qiCKCCRiA/UdhAFgARIGg8sknJbpI/CS6K47Sz/54fggkIoLJCSHAvu+glLp0pZQg5wwYYyStNfYYrHGdhxHx0sMXM+QEHIVPGAN6w8dlPHMCek4eAUYrLB1478kYM8zga8AyxJkD1hgwfcYVYLTekRk658ha281gpv0WUEqBWiu01t7gbdtACAFSShi5Ox3M/sEdrbv7ncH/cfACoGWX3cV5e7AAAAAASUVORK5CYII="},{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/assets/models/cork.png","name":"cork.png","folder":"","namespace":"","id":"1","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"1faf1369-230e-ed4a-f210-037c1820f194","relative_path":"../cork.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAFJJREFUOE9jXDwj8z8DHhCbMZ0RnzwjyABRYW6wmtdvv4JpZD59DKDICztWl6CEgUdoD14/o1sGDgNkQUJ+pr4B+PxPjBxJ/sVm4KgBDAzDIAwAlBIoEQohE0IAAAAASUVORK5CYII="},{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/src/main/resources/assets/unicopia/textures/block/cloud.png","name":"cloud.png","folder":"block","namespace":"unicopia","id":"2","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"4b51168a-586d-848e-b665-d127c0ae4c59","relative_path":"../../../src/main/resources/assets/unicopia/textures/block/cloud.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAhdJREFUOE8tk9tu3DAMRIc3OQ36/5+YAt3nNLZ4K6gEC+waWmpInhnT/XX/JaYwMasuUBNICHEHmtpRABjU3HrZBSRQ86FyFTVy95ffDhFxWUIM1hGYi02N7vaf/01FAQVih+tSmxq6v+4XAFxvl+eTAE2TBIPnGBWFlkZmCjA/iWtdtK6lR6CiXqe2gO3buxvMjGULn/8+Rxh1F9bvZRGB+75dVfXN3ggNUHj8FRaasZr6jElEszciw/feeH9/n2Fsvvbe4e4tJDZMqLM/Gg1/nMzs7D+bjzoIIzxgU990VsBMUVXu26GmdlYgJi+vAaTuTpdeh8WcsfGZBgmHfE/h7gfuPFM88WeA7dg9HUmolyx79oPruhAemLUGXiL9wMupBB5/mqrqYxTXWqM+VVJZEYg2Ma2uMRNMjKw8nY3NzhkzqHa9PP1buUAQIJ5wEpL0TL10LOVCMYNpnFJWY+Xj3EB8RURkZ49y1eSxYlJ2nqpcSPDEg4WFkjrTUJNiDBsBAD32DFUW7ngiVNVmz0M+A5XlUXG4nMA1EAhQer6mk7IO7dx7zyJYuqyrkZ0Qlv76/Irr18UiInP5uR/fvkGZ+TovzITRy8cyXToFZmaoXZHI7mzQomOjsJxMT2rPy9QDgLoO1SYWFex71wnTCJqio42MhslpNraeKP8EKbuaJwZjzxRN0tg4qCbXkHHjXAAdJsSEgfsfRk6kufetOaoAAAAASUVORK5CYII="}]} \ No newline at end of file diff --git a/assets/models/jar_cork.png b/assets/models/jar_cork.png new file mode 100644 index 0000000000000000000000000000000000000000..c87771fa5160cfd8fa23f3d102300603e7f8df57 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`{+=$5Ar`&KF*eGd?V05SW*g2G zoNpt{%*@=p!oVDaV+7{*_y eaJeytGBAYC;ahToeNq9?Xa-MLKbLh*2~7aemL*~U literal 0 HcmV?d00001 diff --git a/assets/models/jar_lightning.bbmodel b/assets/models/jar_lightning.bbmodel new file mode 100644 index 00000000..f39c2696 --- /dev/null +++ b/assets/models/jar_lightning.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"4.9","model_format":"java_block","box_uv":false},"name":"jar","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":16,"height":16},"elements":[{"name":"cube","box_uv":false,"rescale":true,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,1,7.5],"to":[11,11,7.5],"autouv":0,"color":5,"rotation":[0,-45,0],"origin":[8,5,7],"faces":{"north":{"uv":[3,0,13,16],"texture":0},"east":{"uv":[0,0,0,8],"texture":0},"south":{"uv":[3,0,13,16],"texture":0},"west":{"uv":[0,0,0,8],"texture":0},"up":{"uv":[0,0,6,0],"texture":0},"down":{"uv":[0,0,6,0],"texture":0}},"type":"cube","uuid":"52fdb109-7055-1f3c-d1a1-788daf976643"},{"name":"cube","box_uv":false,"rescale":true,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[5,1,7.5],"to":[10,11,7.5],"autouv":0,"color":5,"rotation":[0,45,0],"origin":[8,5,7],"faces":{"north":{"uv":[3,0,13,16],"texture":0},"east":{"uv":[0,0,0,8],"texture":0},"south":{"uv":[3,0,13,16],"texture":0},"west":{"uv":[0,0,0,8],"texture":0},"up":{"uv":[0,0,6,0],"rotation":180,"texture":0},"down":{"uv":[0,0,6,0],"rotation":180,"texture":0}},"type":"cube","uuid":"67ba2407-52e4-4b13-579c-0e7675265bb9"}],"outliner":["52fdb109-7055-1f3c-d1a1-788daf976643","67ba2407-52e4-4b13-579c-0e7675265bb9"],"textures":[{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/src/main/resources/assets/unicopia/textures/block/lightning_jar_filling.png","name":"lightning_jar_filling.png","folder":"block","namespace":"unicopia","id":"2","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"2c8fdd18-9bd4-2276-cdc1-d86d0605d22d","relative_path":"../../../src/main/resources/assets/unicopia/textures/block/lightning_jar_filling.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAN9JREFUOE9jZCASOH7T/L+f6zojunIMAWzmObxR/c/IxcJAlgE+3/X+f/j7l4GV6R/pBnh/0vv/59d/hl9cf7BqBrkWrxdABnxj+Y1TM14DQJq//vrOwMfLz7CJ/QxOi7BKgEKc5wcLw3u2fwxHeK6C1YDEuP6wMqC7CKcB2GIDZMBWvksoejAMANmErBnkEhD4zP6bgZGRESM88BoA1/zvBzi8D4jcwp+QkG0HJRrfd7pg14DCgqh0ADMApBnEZvsGcT5Z6QBXqBOVF9C9gi+/4Y1GbJmHoAuQw4GYnA4AMBBxEZobGUEAAAAASUVORK5CYII="}]} \ No newline at end of file diff --git a/assets/models/jar_storm.bbmodel b/assets/models/jar_storm.bbmodel new file mode 100644 index 00000000..3ee878d8 --- /dev/null +++ b/assets/models/jar_storm.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"4.9","model_format":"java_block","box_uv":false},"name":"jar_storm_filling","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":16,"height":16},"elements":[{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[4,3,4],"to":[12,12,12],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"e15b3907-6195-1f3b-0c48-23c6b4642fc6"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[7,11,6],"to":[13,14,10],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"e61fcd01-8143-912a-1b70-663d7f7ec80b"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,10,7],"to":[10,12,10],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"f61cf32c-8485-4809-93a4-7eca7767fc5f"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,11,9],"to":[11,13,12],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"a073f455-b48b-6520-5323-081195bb2d1c"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,2,5],"to":[11,3,11],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"270a4b70-37c8-136b-85d0-e186bd708f62"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[11,10,9],"to":[13,12,11],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"3a116052-9d62-8f73-d2d8-837d1d62034d"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[3,10,7],"to":[9,13,11],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"b44d335b-bf61-43f1-716a-96162ec518e1"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[3,9,10],"to":[5,11,12],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"1ff98e2a-8af2-ce16-f77f-722bfbd4e54d"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[9,13,7],"to":[11,15,9],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"82323752-a2cf-00dd-ded9-484b51159718"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[5,13,7],"to":[7,15,9],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"371b718c-e1ab-72e8-dd9b-d371f2376c2d"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[3,8,5],"to":[5,10,7],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"74432963-3560-b367-6fc7-5b692d8d346d"}],"outliner":["e15b3907-6195-1f3b-0c48-23c6b4642fc6","270a4b70-37c8-136b-85d0-e186bd708f62","e61fcd01-8143-912a-1b70-663d7f7ec80b","1ff98e2a-8af2-ce16-f77f-722bfbd4e54d","b44d335b-bf61-43f1-716a-96162ec518e1","3a116052-9d62-8f73-d2d8-837d1d62034d","82323752-a2cf-00dd-ded9-484b51159718","371b718c-e1ab-72e8-dd9b-d371f2376c2d","74432963-3560-b367-6fc7-5b692d8d346d","f61cf32c-8485-4809-93a4-7eca7767fc5f","a073f455-b48b-6520-5323-081195bb2d1c"],"textures":[{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/assets/models/body.png","name":"body.png","folder":"","namespace":"","id":"0","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":true,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"c3fc3ff5-2bb6-a5d1-88ff-7d0d48a4200c","relative_path":"../body.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAKxJREFUOE/Nk70NxCAMhe0qiCKCCRiA/UdhAFgARIGg8sknJbpI/CS6K47Sz/54fggkIoLJCSHAvu+glLp0pZQg5wwYYyStNfYYrHGdhxHx0sMXM+QEHIVPGAN6w8dlPHMCek4eAUYrLB1478kYM8zga8AyxJkD1hgwfcYVYLTekRk658ha281gpv0WUEqBWiu01t7gbdtACAFSShi5Ox3M/sEdrbv7ncH/cfACoGWX3cV5e7AAAAAASUVORK5CYII="},{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/assets/models/cork.png","name":"cork.png","folder":"","namespace":"","id":"1","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"1faf1369-230e-ed4a-f210-037c1820f194","relative_path":"../cork.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAFJJREFUOE9jXDwj8z8DHhCbMZ0RnzwjyABRYW6wmtdvv4JpZD59DKDICztWl6CEgUdoD14/o1sGDgNkQUJ+pr4B+PxPjBxJ/sVm4KgBDAzDIAwAlBIoEQohE0IAAAAASUVORK5CYII="},{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/src/main/resources/assets/unicopia/textures/block/cloud.png","name":"cloud.png","folder":"block","namespace":"unicopia","id":"2","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"4b51168a-586d-848e-b665-d127c0ae4c59","relative_path":"../../../src/main/resources/assets/unicopia/textures/block/cloud.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAhdJREFUOE8tk9tu3DAMRIc3OQ36/5+YAt3nNLZ4K6gEC+waWmpInhnT/XX/JaYwMasuUBNICHEHmtpRABjU3HrZBSRQ86FyFTVy95ffDhFxWUIM1hGYi02N7vaf/01FAQVih+tSmxq6v+4XAFxvl+eTAE2TBIPnGBWFlkZmCjA/iWtdtK6lR6CiXqe2gO3buxvMjGULn/8+Rxh1F9bvZRGB+75dVfXN3ggNUHj8FRaasZr6jElEszciw/feeH9/n2Fsvvbe4e4tJDZMqLM/Gg1/nMzs7D+bjzoIIzxgU990VsBMUVXu26GmdlYgJi+vAaTuTpdeh8WcsfGZBgmHfE/h7gfuPFM88WeA7dg9HUmolyx79oPruhAemLUGXiL9wMupBB5/mqrqYxTXWqM+VVJZEYg2Ma2uMRNMjKw8nY3NzhkzqHa9PP1buUAQIJ5wEpL0TL10LOVCMYNpnFJWY+Xj3EB8RURkZ49y1eSxYlJ2nqpcSPDEg4WFkjrTUJNiDBsBAD32DFUW7ngiVNVmz0M+A5XlUXG4nMA1EAhQer6mk7IO7dx7zyJYuqyrkZ0Qlv76/Irr18UiInP5uR/fvkGZ+TovzITRy8cyXToFZmaoXZHI7mzQomOjsJxMT2rPy9QDgLoO1SYWFex71wnTCJqio42MhslpNraeKP8EKbuaJwZjzxRN0tg4qCbXkHHjXAAdJsSEgfsfRk6kufetOaoAAAAASUVORK5CYII="}]} \ No newline at end of file diff --git a/assets/models/jar_zap.bbmodel b/assets/models/jar_zap.bbmodel new file mode 100644 index 00000000..e0feb017 --- /dev/null +++ b/assets/models/jar_zap.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"4.9","model_format":"java_block","box_uv":false},"name":"jar","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":16,"height":16},"elements":[{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[4,0,4],"to":[12,10,12],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"e15b3907-6195-1f3b-0c48-23c6b4642fc6"}],"outliner":["e15b3907-6195-1f3b-0c48-23c6b4642fc6"],"textures":[{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/assets/models/body.png","name":"body.png","folder":"","namespace":"","id":"0","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":true,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"c3fc3ff5-2bb6-a5d1-88ff-7d0d48a4200c","relative_path":"../body.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAKxJREFUOE/Nk70NxCAMhe0qiCKCCRiA/UdhAFgARIGg8sknJbpI/CS6K47Sz/54fggkIoLJCSHAvu+glLp0pZQg5wwYYyStNfYYrHGdhxHx0sMXM+QEHIVPGAN6w8dlPHMCek4eAUYrLB1478kYM8zga8AyxJkD1hgwfcYVYLTekRk658ha281gpv0WUEqBWiu01t7gbdtACAFSShi5Ox3M/sEdrbv7ncH/cfACoGWX3cV5e7AAAAAASUVORK5CYII="},{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/assets/models/cork.png","name":"cork.png","folder":"","namespace":"","id":"1","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"1faf1369-230e-ed4a-f210-037c1820f194","relative_path":"../cork.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAFJJREFUOE9jXDwj8z8DHhCbMZ0RnzwjyABRYW6wmtdvv4JpZD59DKDICztWl6CEgUdoD14/o1sGDgNkQUJ+pr4B+PxPjBxJ/sVm4KgBDAzDIAwAlBIoEQohE0IAAAAASUVORK5CYII="},{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/src/main/resources/assets/unicopia/textures/item/jar_filling_zap.png","name":"jar_filling_zap.png","folder":"item","namespace":"unicopia","id":"2","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":false,"uuid":"62c06d20-77c5-befb-bb95-8e5da5394d9c","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAudJREFUOE8dkUlrXWUYgJ/3G849J7dJSxZuG2s6aMDaUsWWNjVpBS2luHDtyp1UcOhfEKTZ1LYIURQXjQYkEkwduhVd6S8oxUXAJpCBeO/NGb7hlfgPnkHOmvfUiMepBwJ3ph0ej3YRPew5+9UnSN9CY4gnL0FpcBo5vzjCeEHOmA9UJaBJuTftKHAUGeoqc/7BPTgUyPsgJ+boTEEkU6rj3OJTysIiZ/37moPly5mSnjEgBYN2n5d/+RSXgAQ5QDw5R2GFQWOZ/WIL6Ql2lJFz9iNdfM4zsg3jFAy6louP7kMRyZ2AgfqZWXAlRlsuLw7wpdDEQH10Ffnj+C31PY+2LT4Lp79fgBIkQZICfeEyQSsYNlxZ3mX4b83EkYqm6Rge/wn569SHqjZRq+fC6gK66Vgff5ep9A3MzLLTBY5UgVcXa1KKRBImQH5xDVGH/Pn8LTUkXvr5M1I0uKbj73yTZ48/IfmEsZFXvt6jGAniDYOwTz72A9rvQzbI76c+1gs/3icMa/wERAE3dYOailwPmFvbxu5kJBz0F0ZnVkl1S9Xr0wWD6GOUCCogCvnYWxjfgkZeX27Y3tzDO0cMGTPzkNh3tHVNUULvtbtIfoKKeNLUVYwYJEW6kePGbyM2Hm9RVI5oDGlqhewMgsWKoXd1gUiH1GFeSyvQjJGrhjeWO/55uoVTh+9bjGTs9K80YmhDTRk69PodnPW0MSIarimu4NrKiO31baJP9IqCHJV4Yol8gC8lsR5Qjo1Tzt2mIRNjwHhF3vzuinaaECvs7uxgjaE6+pCNPGRsYpxcJ9QbNAYmr37Org7pmTFaavyB8vzSrDpbsbe5RVNF3NEVovXQtPjeIVpa3t7cYO2dbzHqyKYhqSekfUpXIReXLqlJke3JB7geqHdIryDWSmkjxlYcnr/NXmhIVrCq/H/NZBwVcvrRunYSKLGkImOi4LynDcrk9bsMm33koIFrKUIP1Y7sWqz0ydLyH7DGczPZHbGfAAAAAElFTkSuQmCC","relative_path":"../../../src/main/resources/assets/unicopia/textures/item/jar_filling_zap.png"}]} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index 34a9f654..71120481 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -43,6 +43,7 @@ public interface UTags { TagKey FRAGILE = block("fragile"); TagKey INTERESTING = block("interesting"); TagKey CATAPULT_IMMUNE = block("catapult_immune"); + TagKey JARS = block("jars"); TagKey CRYSTAL_HEART_BASE = block("crystal_heart_base"); TagKey CRYSTAL_HEART_ORNAMENT = block("crystal_heart_ornament"); diff --git a/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java new file mode 100644 index 00000000..68c9b9ba --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java @@ -0,0 +1,216 @@ +package com.minelittlepony.unicopia.block; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.IntStream; + +import net.minecraft.block.BlockEntityProvider; +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.block.InventoryProvider; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.SidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; + +public class ItemJarBlock extends JarBlock implements BlockEntityProvider, InventoryProvider { + + public ItemJarBlock(Settings settings) { + super(settings); + } + + @Override + public BlockRenderType getRenderType(BlockState state) { + return BlockRenderType.MODEL; + } + + @Override + public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { + if (hand == Hand.OFF_HAND) { + return ActionResult.PASS; + } + return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> { + ItemStack stack = player.getStackInHand(hand); + if (stack.isEmpty()) { + return data.removeItem(world, pos); + } + + return data.insertItem(world, pos, player.isCreative() ? stack.copyWithCount(1) : stack.split(1)); + }).orElse(ActionResult.PASS); + } + + @Deprecated + @Override + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { + if (!moved && !state.isOf(newState.getBlock())) { + world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).ifPresent(data -> { + data.getStacks().forEach(stack -> { + dropStack(world, pos, stack); + }); + }); + } + super.onStateReplaced(state, world, pos, newState, moved); + } + + @Override + public boolean hasComparatorOutput(BlockState state) { + return true; + } + + @Override + public int getComparatorOutput(BlockState state, World world, BlockPos pos) { + return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> Math.min(16, data.getStacks().size())).orElse(0); + } + + @Deprecated + @Override + public boolean onSyncedBlockEvent(BlockState state, World world, BlockPos pos, int type, int data) { + super.onSyncedBlockEvent(state, world, pos, type, data); + BlockEntity blockEntity = world.getBlockEntity(pos); + return blockEntity != null && blockEntity.onSyncedBlockEvent(type, data); + } + + @Override + public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + return new TileData(pos, state); + } + + + @Override + public SidedInventory getInventory(BlockState state, WorldAccess world, BlockPos pos) { + return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).orElse(null); + } + + public static class TileData extends BlockEntity implements SidedInventory { + private static final int[] SLOTS = IntStream.range(0, 16).toArray(); + private final List stacks = new ArrayList<>(); + + public TileData(BlockPos pos, BlockState state) { + super(UBlockEntities.ITEM_JAR, pos, state); + } + + public ActionResult insertItem(World world, BlockPos pos, ItemStack stack) { + if (stacks.size() >= size()) { + return ActionResult.FAIL; + } + stacks.add(stack); + markDirty(); + + return ActionResult.SUCCESS; + } + + public ActionResult removeItem(World world, BlockPos pos) { + if (stacks.isEmpty()) { + return ActionResult.FAIL; + } + dropStack(world, pos, stacks.remove(0)); + markDirty(); + return ActionResult.SUCCESS; + } + + public List getStacks() { + return stacks; + } + + @Override + public int size() { + return 15; + } + + @Override + public boolean isEmpty() { + return stacks.isEmpty(); + } + + @Override + public ItemStack getStack(int slot) { + return slot < 0 || slot >= stacks.size() ? ItemStack.EMPTY : stacks.get(slot); + } + + @Override + public ItemStack removeStack(int slot, int amount) { + if (slot < 0 || slot >= stacks.size()) { + try { + ItemStack stack = stacks.get(slot); + ItemStack removed = stack.split(1); + if (stack.isEmpty()) { + stacks.remove(slot); + } + return removed; + } finally { + markDirty(); + } + } + return ItemStack.EMPTY; + } + + @Override + public ItemStack removeStack(int slot) { + if (slot < 0 || slot >= stacks.size()) { + try { + return stacks.remove(slot); + } finally { + markDirty(); + } + } + return ItemStack.EMPTY; + } + + @Override + public void setStack(int slot, ItemStack stack) { + if (slot >= stacks.size()) { + if (stacks.size() >= size()) { + dropStack(getWorld(), getPos(), stack); + } else { + stacks.add(stack); + } + } else { + ItemStack existing = stacks.get(slot); + if (!ItemStack.canCombine(existing, stack)) { + dropStack(getWorld(), getPos(), stack); + } else { + existing.setCount(existing.getCount() + stack.split(Math.max(0, existing.getMaxCount() - existing.getCount())).getCount()); + if (!stack.isEmpty()) { + dropStack(getWorld(), getPos(), stack); + } + } + } + } + + @Override + public boolean canPlayerUse(PlayerEntity player) { + return false; + } + + @Override + public void clear() { + stacks.clear(); + markDirty(); + } + + @Override + public int[] getAvailableSlots(Direction side) { + return SLOTS; + } + + @Override + public boolean canInsert(int slot, ItemStack stack, Direction dir) { + return (slot >= 0 && slot < size()) && (slot >= stacks.size() || ( + ItemStack.canCombine(stacks.get(slot), stack) + && (stacks.get(slot).getCount() + stack.getCount()) <= Math.min(stacks.get(slot).getMaxCount(), stack.getMaxCount()) + )); + } + + @Override + public boolean canExtract(int slot, ItemStack stack, Direction dir) { + return true; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java new file mode 100644 index 00000000..80f24c7e --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java @@ -0,0 +1,82 @@ +package com.minelittlepony.unicopia.block; + +import java.util.Optional; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.item.WeatherJarItem; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; + +import net.minecraft.block.AbstractGlassBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; +import net.minecraft.world.explosion.Explosion; + +public class JarBlock extends AbstractGlassBlock { + private static final VoxelShape SHAPE = VoxelShapes.union( + Block.createCuboidShape(4, 0, 4, 12, 12, 12), + Block.createCuboidShape(6, 12, 6, 10, 16, 10), + Block.createCuboidShape(5, 13, 5, 11, 14, 11) + ); + + public JarBlock(Settings settings) { + super(settings); + } + + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return SHAPE; + } + + @Override + public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) { + return super.isSideInvisible(state, stateFrom, direction); + } + + @Override + public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) { + if (this == UBlocks.LIGHTNING_JAR) { + world.addParticle(new LightningBoltParticleEffect(true, 10, 1, 0.6F, Optional.empty()), pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 0, 0, 0); + } + } + + @Deprecated + @Override + public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { + super.onStateReplaced(state, world, pos, newState, moved); + } + + @Override + public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) { + super.onBreak(world, pos, state, player); + } + + @Override + public void onDestroyedByExplosion(World world, BlockPos pos, Explosion explosion) { + if (asItem() instanceof WeatherJarItem jar) { + jar.releaseContents(world, pos); + } + } + + @Override + public void afterBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { + super.afterBreak(world, player, pos, state, blockEntity, tool); + if (!EnchantmentHelper.hasSilkTouch(tool) && !player.shouldCancelInteraction()) { + if (asItem() instanceof WeatherJarItem jar) { + jar.releaseContents(world, pos); + } + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/UBlockEntities.java b/src/main/java/com/minelittlepony/unicopia/block/UBlockEntities.java index 47a64397..87b25155 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/UBlockEntities.java +++ b/src/main/java/com/minelittlepony/unicopia/block/UBlockEntities.java @@ -15,6 +15,7 @@ public interface UBlockEntities { BlockEntityType FANCY_BED = create("fancy_bed", BlockEntityType.Builder.create(CloudBedBlock.Tile::new, UBlocks.CLOTH_BED, UBlocks.CLOUD_BED)); BlockEntityType CLOUD_CHEST = create("cloud_chest", BlockEntityType.Builder.create(CloudChestBlock.TileData::new, UBlocks.CLOUD_CHEST)); BlockEntityType HIVE_STORAGE = create("hive_storage", BlockEntityType.Builder.create(HiveBlock.TileData::new, UBlocks.HIVE)); + BlockEntityType ITEM_JAR = create("item_jar", BlockEntityType.Builder.create(ItemJarBlock.TileData::new, UBlocks.JAR)); static BlockEntityType create(String id, Builder builder) { return Registry.register(Registries.BLOCK_ENTITY_TYPE, id, builder.build(null)); diff --git a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java index c5779abd..33c5f576 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java +++ b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java @@ -253,6 +253,11 @@ public interface UBlocks { Block CLOUD_DOOR = register("cloud_door", new CloudDoorBlock(Settings.copy(CLOUD), CLOUD.getDefaultState(), UWoodTypes.CLOUD), ItemGroups.FUNCTIONAL); Block SPECTRAL_FIRE = register("spectral_fire", new SpectralFireBlock(Settings.copy(Blocks.SOUL_FIRE))); + Block JAR = register("jar", new ItemJarBlock(Settings.copy(Blocks.GLASS))); + Block CLOUD_JAR = register("cloud_jar", new JarBlock(Settings.copy(Blocks.GLASS))); + Block STORM_JAR = register("storm_jar", new JarBlock(Settings.copy(Blocks.GLASS))); + Block LIGHTNING_JAR = register("lightning_jar", new JarBlock(Settings.copy(Blocks.GLASS))); + Block ZAP_JAR = register("zap_jar", new JarBlock(Settings.copy(Blocks.GLASS))); Block WORM_BLOCK = register("worm_block", new FallingBlock(Settings.create().hardness(0.1F).resistance(0).requiresTool().sounds(BlockSoundGroup.MUD)), ItemGroups.NATURAL); EdibleBlock HAY_BLOCK = register("hay_block", new EdibleBlock(new Identifier("hay_block"), new Identifier("wheat"), true)); @@ -305,7 +310,10 @@ public interface UBlocks { OxidizableBlocksRegistry.registerWaxableBlockPair(ZAP_SLAB, WAXED_ZAP_SLAB); OxidizableBlocksRegistry.registerWaxableBlockPair(ZAP_FENCE, WAXED_ZAP_FENCE); OxidizableBlocksRegistry.registerWaxableBlockPair(ZAP_FENCE_GATE, WAXED_ZAP_FENCE_GATE); - Collections.addAll(TRANSLUCENT_BLOCKS, WEATHER_VANE, CHITIN_SPIKES, PLUNDER_VINE, PLUNDER_VINE_BUD, CLAM_SHELL, SCALLOP_SHELL, TURRET_SHELL, CURING_JOKE, SPECTRAL_FIRE); + Collections.addAll(TRANSLUCENT_BLOCKS, + WEATHER_VANE, CHITIN_SPIKES, PLUNDER_VINE, PLUNDER_VINE_BUD, CLAM_SHELL, SCALLOP_SHELL, TURRET_SHELL, CURING_JOKE, SPECTRAL_FIRE, + JAR, CLOUD_JAR, STORM_JAR, LIGHTNING_JAR, ZAP_JAR + ); TintedBlock.REGISTRY.add(PALM_LEAVES); FlammableBlockRegistry.getDefaultInstance().add(GREEN_APPLE_LEAVES, 30, 60); diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index e5896bd6..747465b5 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -116,6 +116,7 @@ public interface URenderers { BlockEntityRendererFactories.register(UBlockEntities.WEATHER_VANE, WeatherVaneBlockEntityRenderer::new); BlockEntityRendererFactories.register(UBlockEntities.FANCY_BED, CloudBedBlockEntityRenderer::new); BlockEntityRendererFactories.register(UBlockEntities.CLOUD_CHEST, CloudChestBlockEntityRenderer::new); + BlockEntityRendererFactories.register(UBlockEntities.ITEM_JAR, ItemJarBlockEntityRenderer::new); register(URenderers::renderJarItem, UItems.FILLED_JAR); register(URenderers::renderBedItem, UItems.CLOTH_BED, UItems.CLOUD_BED); diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java new file mode 100644 index 00000000..85bec08a --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java @@ -0,0 +1,49 @@ +package com.minelittlepony.unicopia.client.render.entity; + +import java.util.List; + +import com.minelittlepony.unicopia.block.ItemJarBlock; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.block.entity.BlockEntityRenderer; +import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; +import net.minecraft.client.render.model.json.ModelTransformationMode; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.RotationAxis; +import net.minecraft.util.math.random.Random; + +public class ItemJarBlockEntityRenderer implements BlockEntityRenderer { + + public ItemJarBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) { + } + + @Override + public void render(ItemJarBlock.TileData entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light, int overlay) { + + List stacks = entity.getStacks(); + + float itemScale = 0.35F; + + matrices.push(); + matrices.translate(0.5, 0, 0.5); + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90)); + matrices.scale(itemScale, itemScale, itemScale); + + Random rng = Random.create(entity.getPos().asLong()); + + float y = 0; + for (ItemStack stack : stacks) { + matrices.push(); + + matrices.translate((rng.nextFloat() - 0.5F) * 0.5F, (rng.nextFloat() - 0.5F) * 0.8F, -0.05 + y); + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees((rng.nextFloat() * 360) - 180)); + matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((rng.nextFloat() * 360) - 180)); + y -= 0.1F; + MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformationMode.FIXED, light, overlay, matrices, vertices, entity.getWorld(), 0); + matrices.pop(); + } + matrices.pop(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/BlockModels.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/BlockModels.java index 68344833..26a78354 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/BlockModels.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/BlockModels.java @@ -34,6 +34,7 @@ public interface BlockModels { Model DOOR_RIGHT = block("door_right", TextureKey.BOTTOM, TextureKey.TOP); Model TEMPLATE_PILLAR = block("template_pillar", TextureKey.SIDE); Model TEMPLATE_PILLAR_END = block("template_pillar_end", "_end", TextureKey.BOTTOM, TextureKey.TOP, TextureKey.END); + Identifier TEMPLATE_JAR = Unicopia.id("block/template_jar"); Factory CROP = Factory.of(TextureMap::crop, Models.CROP); Factory CUBE_ALL = Factory.of(TextureMap::all, Models.CUBE_ALL); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java index 45274e75..048c3ad6 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java @@ -35,6 +35,7 @@ import net.minecraft.data.client.Models; import net.minecraft.data.client.MultipartBlockStateSupplier; import net.minecraft.data.client.TextureMap; import net.minecraft.data.client.TexturedModel; +import net.minecraft.data.client.VariantSettings; import net.minecraft.data.client.VariantsBlockStateSupplier; import net.minecraft.data.client.When; import net.minecraft.item.Item; @@ -177,6 +178,18 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator { registerWithStagesBuiltinModels(UBlocks.MYSTERIOUS_EGG, PileBlock.COUNT, 1, 2, 3); excludeFromSimpleItemModelGeneration(UBlocks.MYSTERIOUS_EGG); FireModels.registerSoulFire(this, UBlocks.SPECTRAL_FIRE, Blocks.SOUL_FIRE); + + blockStateCollector.accept(createSingletonBlockState(UBlocks.JAR, BlockModels.TEMPLATE_JAR)); + registerWeatherJar(UBlocks.CLOUD_JAR); + registerWeatherJar(UBlocks.STORM_JAR); + registerWeatherJar(UBlocks.ZAP_JAR); + registerWeatherJar(UBlocks.LIGHTNING_JAR); + } + + public void registerWeatherJar(Block jar) { + blockStateCollector.accept(MultipartBlockStateSupplier.create(jar) + .with(BlockStateVariant.create().put(VariantSettings.MODEL, BlockModels.TEMPLATE_JAR)) + .with(BlockStateVariant.create().put(VariantSettings.MODEL, ModelIds.getBlockSubModelId(jar, "_filling")))); } @SafeVarargs diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java index cc6d6411..50a752c3 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java @@ -40,11 +40,12 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { }; getOrCreateTagBuilder(UTags.CATAPULT_IMMUNE).add(Blocks.BEDROCK).forceAddTag(BlockTags.DOORS).forceAddTag(BlockTags.TRAPDOORS); + getOrCreateTagBuilder(UTags.JARS).add(UBlocks.JAR, UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.ZAP_JAR); getOrCreateTagBuilder(BlockTags.CROPS).add(crops); getOrCreateTagBuilder(BlockTags.BEE_GROWABLES).add(crops); getOrCreateTagBuilder(BlockTags.MAINTAINS_FARMLAND).add(crops); getOrCreateTagBuilder(BlockTags.NEEDS_DIAMOND_TOOL).add(UBlocks.FROSTED_OBSIDIAN); - getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE).add(UBlocks.ROCKS, UBlocks.FROSTED_OBSIDIAN, UBlocks.WEATHER_VANE); + getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE).add(UBlocks.ROCKS, UBlocks.FROSTED_OBSIDIAN, UBlocks.WEATHER_VANE).forceAddTag(UTags.JARS); getOrCreateTagBuilder(BlockTags.DRAGON_IMMUNE).add(UBlocks.FROSTED_OBSIDIAN, UBlocks.GOLDEN_OAK_LOG, UBlocks.GOLDEN_OAK_LEAVES); getOrCreateTagBuilder(BlockTags.FIRE).add(UBlocks.SPECTRAL_FIRE); getOrCreateTagBuilder(BlockTags.HOE_MINEABLE).add(UBlocks.HAY_BLOCK).addOptional(Unicopia.id("rice_block")).addOptional(Unicopia.id("straw_block")); @@ -67,6 +68,7 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { getOrCreateTagBuilder(UTags.FRAGILE) .forceAddTag(ConventionalBlockTags.GLASS_BLOCKS) .forceAddTag(ConventionalBlockTags.GLASS_PANES) + .forceAddTag(UTags.JARS) .add(Blocks.VINE, Blocks.LILY_PAD); getOrCreateTagBuilder(UTags.INTERESTING).add( diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java index fba77f65..77b0d94e 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java @@ -81,6 +81,11 @@ public class UBlockLootTableProvider extends FabricBlockLootTableProvider { tree.pot().ifPresent(this::addPottedPlantDrops); }); + // jars + List.of( + UBlocks.JAR, UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.STORM_JAR + ).forEach(jar -> addDrop(jar, UBlockLootTableProvider::dropsWithSilkTouch)); + // doors List.of( UBlocks.CLOUD_DOOR, UBlocks.CRYSTAL_DOOR, diff --git a/src/main/java/com/minelittlepony/unicopia/item/EmptyJarItem.java b/src/main/java/com/minelittlepony/unicopia/item/EmptyJarItem.java new file mode 100644 index 00000000..e156ccb5 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/EmptyJarItem.java @@ -0,0 +1,60 @@ +package com.minelittlepony.unicopia.item; + +import com.minelittlepony.unicopia.block.UBlocks; +import com.minelittlepony.unicopia.entity.IItemEntity; +import com.minelittlepony.unicopia.entity.ItemImpl; + +import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; +import net.minecraft.block.Block; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.ItemEntity; +import net.minecraft.entity.LightningEntity; +import net.minecraft.entity.Entity.RemovalReason; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; + +public class EmptyJarItem extends BlockItem implements ItemImpl.GroundTickCallback { + public EmptyJarItem(Block block, Settings settings) { + super(block, settings); + } + + @Override + public ActionResult onGroundTick(IItemEntity item) { + ItemEntity entity = item.get().asEntity(); + + BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.ZAP_JAR); + + entity.setInvulnerable(true); + + if (!entity.getWorld().isClient + && !entity.isRemoved() + && entity.getItemAge() > 100 + && entity.getWorld().isThundering() + && entity.getWorld().isSkyVisible(entity.getBlockPos()) + && entity.getWorld().random.nextInt(130) == 0) { + LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(entity.getWorld()); + lightning.refreshPositionAfterTeleport(entity.getX(), entity.getY(), entity.getZ()); + + entity.remove(RemovalReason.DISCARDED); + entity.getWorld().spawnEntity(lightning); + + ItemEntity neu = EntityType.ITEM.create(entity.getWorld()); + neu.copyPositionAndRotation(entity); + neu.setStack(new ItemStack(this == UItems.RAIN_CLOUD_JAR ? UItems.STORM_CLOUD_JAR : UItems.LIGHTNING_JAR)); + neu.setInvulnerable(true); + + entity.getWorld().spawnEntity(neu); + + ItemEntity copy = EntityType.ITEM.create(entity.getWorld()); + copy.copyPositionAndRotation(entity); + copy.setInvulnerable(true); + copy.setStack(entity.getStack()); + copy.getStack().decrement(1); + + entity.getWorld().spawnEntity(copy); + } + return ActionResult.PASS; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java b/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java index ee6dc0dc..f11c401a 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java @@ -1,10 +1,11 @@ package com.minelittlepony.unicopia.item; -import com.minelittlepony.unicopia.entity.IItemEntity; +import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.mob.ButterflyEntity; import com.minelittlepony.unicopia.entity.mob.UEntities; import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; +import com.minelittlepony.unicopia.projectile.ProjectileDelegate; import net.minecraft.block.Block; import net.minecraft.block.Blocks; @@ -20,16 +21,20 @@ import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.item.ItemStack; import net.minecraft.particle.ParticleTypes; import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundEvent; import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.math.MathHelper; import net.minecraft.world.WorldEvents; -public class FilledJarItem extends JarItem implements ChameleonItem { - +public class FilledJarItem extends ProjectileItem implements ProjectileDelegate.HitListener, ChameleonItem { public FilledJarItem(Settings settings) { - super(settings, false, false, false); + super(settings, 0); + } + + @Override + public SoundEvent getThrowSound(ItemStack stack) { + return USounds.ENTITY_JAR_THROW; } @Override @@ -42,20 +47,8 @@ public class FilledJarItem extends JarItem implements ChameleonItem { return false; } - @Override - public ActionResult onGroundTick(IItemEntity item) { - return ActionResult.PASS; - } - - @Override - protected float getProjectileDamage(ItemStack stack) { - return 0; - } - @Override public void onImpact(MagicProjectileEntity projectile, EntityHitResult hit) { - super.onImpact(projectile, hit); - Entity entity = hit.getEntity(); if (!entity.isAttackable() || !(projectile instanceof FlyingItemEntity)) { diff --git a/src/main/java/com/minelittlepony/unicopia/item/HeavyProjectileItem.java b/src/main/java/com/minelittlepony/unicopia/item/HeavyProjectileItem.java index 01d268d6..16797e43 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/HeavyProjectileItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/HeavyProjectileItem.java @@ -5,37 +5,19 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.projectile.PhysicsBodyProjectileEntity; -import net.minecraft.block.DispenserBlock; -import net.minecraft.block.dispenser.ProjectileDispenserBehavior; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.PersistentProjectileEntity; -import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.item.ItemStack; import net.minecraft.sound.SoundEvent; -import net.minecraft.util.math.Position; import net.minecraft.world.World; public class HeavyProjectileItem extends ProjectileItem { - public HeavyProjectileItem(Settings settings, float projectileDamage) { super(settings, projectileDamage); - DispenserBlock.registerBehavior(this, new ProjectileDispenserBehavior(){ - @Override - protected ProjectileEntity createProjectile(World world, Position position, ItemStack stack) { - ProjectileEntity projectile = HeavyProjectileItem.this.createProjectile(stack, world, null); - projectile.setPosition(position.getX(), position.getY(), position.getZ()); - return projectile; - } - - @Override - protected float getVariation() { - return 0; - } - }); } @Override - protected PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) { + public PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) { PhysicsBodyProjectileEntity projectile = player == null ? new PhysicsBodyProjectileEntity(world) : new PhysicsBodyProjectileEntity(world, player); if (player != null) { projectile.setVelocity(player, player.getPitch(), player.getYaw(), 0, 1.5F, 1); @@ -46,7 +28,7 @@ public class HeavyProjectileItem extends ProjectileItem { } @Override - protected SoundEvent getThrowSound(ItemStack stack) { + public SoundEvent getThrowSound(ItemStack stack) { return USounds.ENTITY_JAR_THROW; } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/HorseShoeItem.java b/src/main/java/com/minelittlepony/unicopia/item/HorseShoeItem.java index a9ed6129..d21f7fd2 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/HorseShoeItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/HorseShoeItem.java @@ -74,7 +74,7 @@ public class HorseShoeItem extends HeavyProjectileItem { } @Override - protected PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) { + public PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) { PhysicsBodyProjectileEntity projectile = super.createProjectile(stack, world, player); projectile.setDamageType(UDamageTypes.HORSESHOE); @@ -99,7 +99,7 @@ public class HorseShoeItem extends HeavyProjectileItem { } @Override - protected SoundEvent getThrowSound(ItemStack stack) { + public SoundEvent getThrowSound(ItemStack stack) { return USounds.Vanilla.ITEM_TRIDENT_THROW; } diff --git a/src/main/java/com/minelittlepony/unicopia/item/JarInsertRecipe.java b/src/main/java/com/minelittlepony/unicopia/item/JarInsertRecipe.java index 17636087..776a8bc3 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/JarInsertRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/item/JarInsertRecipe.java @@ -29,7 +29,7 @@ public class JarInsertRecipe extends ItemCombinationRecipe { @Override protected boolean isInsertItem(ItemStack stack) { - return !(stack.getItem() instanceof JarItem); + return !(stack.getItem() instanceof EmptyJarItem); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/item/JarItem.java b/src/main/java/com/minelittlepony/unicopia/item/JarItem.java deleted file mode 100644 index 6943d0c5..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/JarItem.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.minelittlepony.unicopia.item; - -import com.minelittlepony.unicopia.AwaitTickQueue; -import com.minelittlepony.unicopia.USounds; -import com.minelittlepony.unicopia.entity.IItemEntity; -import com.minelittlepony.unicopia.entity.ItemImpl; -import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; -import com.minelittlepony.unicopia.particle.ParticleUtils; -import com.minelittlepony.unicopia.particle.UParticles; -import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; -import com.minelittlepony.unicopia.projectile.ProjectileDelegate; - -import net.minecraft.block.Block; -import net.minecraft.block.Blocks; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.ItemEntity; -import net.minecraft.entity.LightningEntity; -import net.minecraft.entity.Entity.RemovalReason; -import net.minecraft.item.ItemStack; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.sound.SoundEvent; -import net.minecraft.util.ActionResult; -import net.minecraft.util.math.ChunkSectionPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.Heightmap; -import net.minecraft.world.WorldEvents; - -public class JarItem extends ProjectileItem implements ItemImpl.GroundTickCallback, ProjectileDelegate.HitListener { - - private final boolean rain; - private final boolean thunder; - private final boolean lightning; - - public JarItem(Settings settings, boolean rain, boolean thunder, boolean lightning) { - super(settings, 0.5F); - this.rain = rain; - this.thunder = thunder; - this.lightning = lightning; - } - - @Override - public ActionResult onGroundTick(IItemEntity item) { - ItemEntity entity = item.get().asEntity(); - - entity.setInvulnerable(true); - - if (!lightning - && !entity.getWorld().isClient - && !entity.isRemoved() - && entity.getItemAge() > 100 - && entity.getWorld().isThundering() - && entity.getWorld().isSkyVisible(entity.getBlockPos()) - && entity.getWorld().random.nextInt(130) == 0) { - LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(entity.getWorld()); - lightning.refreshPositionAfterTeleport(entity.getX(), entity.getY(), entity.getZ()); - - entity.remove(RemovalReason.DISCARDED); - entity.getWorld().spawnEntity(lightning); - - ItemEntity neu = EntityType.ITEM.create(entity.getWorld()); - neu.copyPositionAndRotation(entity); - neu.setStack(new ItemStack(this == UItems.RAIN_CLOUD_JAR ? UItems.STORM_CLOUD_JAR : UItems.LIGHTNING_JAR)); - neu.setInvulnerable(true); - - entity.getWorld().spawnEntity(neu); - - ItemEntity copy = EntityType.ITEM.create(entity.getWorld()); - copy.copyPositionAndRotation(entity); - copy.setInvulnerable(true); - copy.setStack(entity.getStack()); - copy.getStack().decrement(1); - - entity.getWorld().spawnEntity(copy); - } - return ActionResult.PASS; - } - - @Override - protected SoundEvent getThrowSound(ItemStack stack) { - return USounds.ENTITY_JAR_THROW; - } - - @Override - public void onImpact(MagicProjectileEntity projectile) { - if (!projectile.getWorld().isClient()) { - ServerWorld world = (ServerWorld)projectile.getWorld(); - - if (rain || thunder) { - // clear weather time = number of ticks for which the weather is clear - // rain time = ticks until rain gets toggled (reset the tick after toggling) - // thunder time = ticks until thundering gets toggled (reset the tick after toggling) - - // clear weather time - // Number of ticks weather must stay clear. - // Raining and thundering, and raining/thundering times are kept to false and 0 - // when clear weather time is <= 0 - // - wait for thunder time to reach zero then toggle thundering - // - wait for rain time to reach zero then toggle raining - // when thunder time is <= 0 - // - randomly pick a new value for thunder time - // when rain time is <= 0 - // - randomly pick a new value for rain time - - world.setWeather(0, 0, rain, thunder); - - if (thunder) { - for (int i = world.random.nextInt(7); i > 0; i--) { - AwaitTickQueue.scheduleTask(world, w -> { - LightningEntity bolt = EntityType.LIGHTNING_BOLT.create(world); - bolt.setCosmetic(true); - bolt.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(world.getTopPosition(Heightmap.Type.MOTION_BLOCKING, world.getRandomPosInChunk( - ChunkSectionPos.getBlockCoord(ChunkSectionPos.getSectionCoord(projectile.getX())), - 0, - ChunkSectionPos.getBlockCoord(ChunkSectionPos.getSectionCoord(projectile.getZ())), - 15 - )).up(32))); - world.spawnEntity(bolt); - }, 15 + world.random.nextInt(12)); - } - } - } - - if (lightning) { - LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(world); - lightning.refreshPositionAfterTeleport(projectile.getX(), projectile.getY(), projectile.getZ()); - - world.spawnEntity(lightning); - } - } - - if (lightning) { - ParticleUtils.spawnParticle(projectile.getWorld(), LightningBoltParticleEffect.DEFAULT, projectile.getPos(), Vec3d.ZERO); - } - - if (rain || thunder) { - projectile.getWorld().syncWorldEvent(WorldEvents.SPLASH_POTION_SPLASHED, projectile.getBlockPos(), thunder ? 0x888888 : 0xF8F8F8); - - for (int i = projectile.getWorld().random.nextInt(3) + 1; i >= 0; i--) { - ParticleUtils.spawnParticle(projectile.getWorld(), UParticles.CLOUDS_ESCAPING, - projectile.getX(), projectile.getY(), projectile.getZ(), - projectile.getWorld().random.nextFloat() - 0.5, - 0, - projectile.getWorld().random.nextFloat() - 0.5 - ); - } - } - - projectile.getWorld().syncWorldEvent(WorldEvents.BLOCK_BROKEN, projectile.getBlockPos(), Block.getRawIdFromState(Blocks.GLASS.getDefaultState())); - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/MuffinItem.java b/src/main/java/com/minelittlepony/unicopia/item/MuffinItem.java index 3fb05b3d..260f7360 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/MuffinItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/MuffinItem.java @@ -10,13 +10,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.world.World; public class MuffinItem extends HeavyProjectileItem { - public MuffinItem(Settings settings, float projectileDamage) { super(settings, projectileDamage); } @Override - protected PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) { + public PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) { PhysicsBodyProjectileEntity projectile = super.createProjectile(stack, world, player); projectile.setBouncy(); projectile.setDamage(0); diff --git a/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java b/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java index 5e7a643d..43c3608a 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java @@ -1,72 +1,34 @@ package com.minelittlepony.unicopia.item; -import org.jetbrains.annotations.Nullable; - -import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; -import com.minelittlepony.unicopia.util.SoundEmitter; - +import com.minelittlepony.unicopia.projectile.Projectile; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.sound.SoundCategory; -import net.minecraft.sound.SoundEvent; -import net.minecraft.stat.Stats; import net.minecraft.util.Hand; import net.minecraft.util.TypedActionResult; import net.minecraft.world.World; -abstract class ProjectileItem extends Item { +abstract class ProjectileItem extends Item implements Projectile { private final float projectileDamage; public ProjectileItem(Settings settings, float projectileDamage) { super(settings); this.projectileDamage = projectileDamage; + Projectile.makeDispensable(this); } @Override public TypedActionResult use(World world, PlayerEntity player, Hand hand) { - - if (isFood() && !player.isSneaking()) { + if (isFood() && !player.shouldCancelInteraction()) { return super.use(world, player, hand); } - ItemStack stack = player.getStackInHand(hand); - - SoundEmitter.playSoundAt(player, - getThrowSound(stack), SoundCategory.NEUTRAL, - 0.5F, - 0.4F / (world.random.nextFloat() * 0.4F + 0.8F)); - - if (!world.isClient) { - world.spawnEntity(createProjectile(stack.copyWithCount(1), world, player)); - } - - player.incrementStat(Stats.USED.getOrCreateStat(this)); - - if (!player.isCreative()) { - stack.decrement(1); - } - - return TypedActionResult.success(stack, world.isClient()); + return triggerThrow(world, player, hand); } - protected ProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) { - MagicProjectileEntity projectile = player == null ? new MagicProjectileEntity(world) : new MagicProjectileEntity(world, player); - projectile.setItem(stack); - projectile.setThrowDamage(getProjectileDamage(stack)); - projectile.setMaxAge(-1); - if (player != null) { - projectile.setVelocity(player, player.getPitch(), player.getYaw(), 0, 1.5F, 1); - } - return projectile; - } - - protected abstract SoundEvent getThrowSound(ItemStack stack); - - protected float getProjectileDamage(ItemStack stack) { + @Override + public float getProjectileDamage(ItemStack stack) { return projectileDamage; } - } diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 242e9a13..be2973db 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -50,12 +50,12 @@ public interface UItems { FriendshipBraceletItem FRIENDSHIP_BRACELET = register("friendship_bracelet", new FriendshipBraceletItem(new FabricItemSettings().rarity(Rarity.UNCOMMON)), ItemGroups.TOOLS); Item PLUNDER_VINE = register("plunder_vine", new BlockItem(UBlocks.PLUNDER_VINE_BUD, new Item.Settings())); - Item EMPTY_JAR = register("empty_jar", new JarItem(new Item.Settings().fireproof(), false, false, false), ItemGroups.FUNCTIONAL); + Item EMPTY_JAR = register("empty_jar", new EmptyJarItem(UBlocks.JAR, new Item.Settings().fireproof()), ItemGroups.FUNCTIONAL); FilledJarItem FILLED_JAR = register("filled_jar", new FilledJarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR))); - Item RAIN_CLOUD_JAR = register("rain_cloud_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), true, false, false), ItemGroups.FUNCTIONAL); - Item STORM_CLOUD_JAR = register("storm_cloud_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), true, true, false), ItemGroups.FUNCTIONAL); - Item LIGHTNING_JAR = register("lightning_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), false, false, true), ItemGroups.FUNCTIONAL); - Item ZAP_APPLE_JAM_JAR = register("zap_apple_jam_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), false, false, true), ItemGroups.FUNCTIONAL); + Item RAIN_CLOUD_JAR = register("rain_cloud_jar", new WeatherJarItem(UBlocks.CLOUD_JAR, new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), WeatherJarItem.Type.RAIN), ItemGroups.FUNCTIONAL); + Item STORM_CLOUD_JAR = register("storm_cloud_jar", new WeatherJarItem(UBlocks.STORM_JAR, new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), WeatherJarItem.Type.THUNDER), ItemGroups.FUNCTIONAL); + Item LIGHTNING_JAR = register("lightning_jar", new WeatherJarItem(UBlocks.LIGHTNING_JAR, new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), WeatherJarItem.Type.LIGHTNING), ItemGroups.FUNCTIONAL); + Item ZAP_APPLE_JAM_JAR = register("zap_apple_jam_jar", new WeatherJarItem(UBlocks.ZAP_JAR, new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), WeatherJarItem.Type.LIGHTNING), ItemGroups.FUNCTIONAL); Item TOAST = register("toast", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.TOAST)), ItemGroups.FOOD_AND_DRINK); Item BURNED_TOAST = register("burned_toast", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.BURNED_TOAST)), ItemGroups.FOOD_AND_DRINK); diff --git a/src/main/java/com/minelittlepony/unicopia/item/WeatherJarItem.java b/src/main/java/com/minelittlepony/unicopia/item/WeatherJarItem.java new file mode 100644 index 00000000..2708e6cf --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/WeatherJarItem.java @@ -0,0 +1,136 @@ +package com.minelittlepony.unicopia.item; + +import com.minelittlepony.unicopia.AwaitTickQueue; +import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect; +import com.minelittlepony.unicopia.particle.ParticleUtils; +import com.minelittlepony.unicopia.particle.UParticles; +import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; +import com.minelittlepony.unicopia.projectile.Projectile; +import com.minelittlepony.unicopia.projectile.ProjectileDelegate; + +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LightningEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.AliasedBlockItem; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkSectionPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.Heightmap; +import net.minecraft.world.World; +import net.minecraft.world.WorldEvents; + +public class WeatherJarItem extends AliasedBlockItem implements Projectile, ProjectileDelegate.HitListener { + private final Type type; + + public WeatherJarItem(Block block, Settings settings, Type type) { + super(block, settings); + this.type = type; + Projectile.makeDispensable(this); + } + + @Override + public SoundEvent getThrowSound(ItemStack stack) { + return USounds.ENTITY_JAR_THROW; + } + + @Override + public float getProjectileDamage(ItemStack stack) { + return 0.5F; + } + + @Override + public TypedActionResult use(World world, PlayerEntity player, Hand hand) { + if (player.shouldCancelInteraction()) { + return super.use(world, player, hand); + } + return triggerThrow(world, player, hand); + } + + @Override + public void onImpact(MagicProjectileEntity projectile) { + releaseContents(projectile.getWorld(), projectile.getBlockPos()); + } + + public void releaseContents(World world, BlockPos pos) { + if (!world.isClient()) { + ServerWorld sw = (ServerWorld)world; + + if (type == Type.RAIN || type == Type.THUNDER) { + // clear weather time = number of ticks for which the weather is clear + // rain time = ticks until rain gets toggled (reset the tick after toggling) + // thunder time = ticks until thundering gets toggled (reset the tick after toggling) + + // clear weather time + // Number of ticks weather must stay clear. + // Raining and thundering, and raining/thundering times are kept to false and 0 + // when clear weather time is <= 0 + // - wait for thunder time to reach zero then toggle thundering + // - wait for rain time to reach zero then toggle raining + // when thunder time is <= 0 + // - randomly pick a new value for thunder time + // when rain time is <= 0 + // - randomly pick a new value for rain time + + sw.setWeather(0, 0, type == Type.RAIN, type == Type.THUNDER); + + if (type == Type.THUNDER) { + for (int i = world.random.nextInt(7); i > 0; i--) { + AwaitTickQueue.scheduleTask(world, w -> { + LightningEntity bolt = EntityType.LIGHTNING_BOLT.create(world); + bolt.setCosmetic(true); + bolt.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(world.getTopPosition(Heightmap.Type.MOTION_BLOCKING, world.getRandomPosInChunk( + ChunkSectionPos.getBlockCoord(ChunkSectionPos.getSectionCoord(pos.getX())), + 0, + ChunkSectionPos.getBlockCoord(ChunkSectionPos.getSectionCoord(pos.getZ())), + 15 + )).up(32))); + world.spawnEntity(bolt); + }, 15 + world.random.nextInt(12)); + } + } + } + + if (type == Type.LIGHTNING) { + LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(world); + lightning.refreshPositionAfterTeleport(pos.getX(), pos.getY(), pos.getZ()); + + world.spawnEntity(lightning); + } + } + + Vec3d centerPos = pos.toCenterPos(); + + if (type == Type.LIGHTNING) { + ParticleUtils.spawnParticle(world, LightningBoltParticleEffect.DEFAULT, centerPos, Vec3d.ZERO); + } + + if (type == Type.RAIN || type == Type.THUNDER) { + world.syncWorldEvent(WorldEvents.SPLASH_POTION_SPLASHED, pos, type == Type.THUNDER ? 0x888888 : 0xF8F8F8); + + for (int i = world.random.nextInt(3) + 1; i >= 0; i--) { + ParticleUtils.spawnParticle(world, UParticles.CLOUDS_ESCAPING, + centerPos.getX(), centerPos.getY(), centerPos.getZ(), + world.random.nextFloat() - 0.5, + 0, + world.random.nextFloat() - 0.5 + ); + } + } + + world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, pos, Block.getRawIdFromState(Blocks.GLASS.getDefaultState())); + } + + public enum Type { + RAIN, + THUNDER, + LIGHTNING + } +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/Projectile.java b/src/main/java/com/minelittlepony/unicopia/projectile/Projectile.java new file mode 100644 index 00000000..c8b0c2a2 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/projectile/Projectile.java @@ -0,0 +1,73 @@ +package com.minelittlepony.unicopia.projectile; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.util.SoundEmitter; + +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.dispenser.ProjectileDispenserBehavior; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.item.ItemConvertible; +import net.minecraft.item.ItemStack; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.stat.Stats; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.math.Position; +import net.minecraft.world.World; + +public interface Projectile extends ItemConvertible { + static void makeDispensable(Projectile projectile) { + DispenserBlock.registerBehavior(projectile.asItem(), new ProjectileDispenserBehavior(){ + @Override + protected ProjectileEntity createProjectile(World world, Position position, ItemStack stack) { + ProjectileEntity p = projectile.createProjectile(stack, world, null); + p.setPosition(position.getX(), position.getY(), position.getZ()); + return p; + } + + @Override + protected float getVariation() { + return 0; + } + }); + } + + default TypedActionResult triggerThrow(World world, PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + + SoundEmitter.playSoundAt(player, + getThrowSound(stack), SoundCategory.NEUTRAL, + 0.5F, + 0.4F / (world.random.nextFloat() * 0.4F + 0.8F)); + + if (!world.isClient) { + world.spawnEntity(createProjectile(stack.copyWithCount(1), world, player)); + } + + player.incrementStat(Stats.USED.getOrCreateStat(asItem())); + + if (!player.isCreative()) { + stack.decrement(1); + } + + return TypedActionResult.success(stack, world.isClient()); + } + + default ProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) { + MagicProjectileEntity projectile = player == null ? new MagicProjectileEntity(world) : new MagicProjectileEntity(world, player); + projectile.setItem(stack); + projectile.setThrowDamage(getProjectileDamage(stack)); + projectile.setMaxAge(-1); + if (player != null) { + projectile.setVelocity(player, player.getPitch(), player.getYaw(), 0, 1.5F, 1); + } + return projectile; + } + + SoundEvent getThrowSound(ItemStack stack); + + float getProjectileDamage(ItemStack stack); +} diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 22f18738..54133a8a 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -81,12 +81,17 @@ "item.unicopia.plunder_vine": "Plunder Vine", "item.unicopia.empty_jar": "Glass Jar", + "block.unicopia.jar": "Glass Jar", "item.unicopia.filled_jar": "%s in a Jar", "item.unicopia.rain_cloud_jar": "Rain in a Jar", + "item.unicopia.cloud_jar": "Rain in a Jar", "item.unicopia.storm_cloud_jar": "Storm in a Jar", + "block.unicopia.storm_jar": "Storm in a Jar", "item.unicopia.lightning_jar": "Lightning in a Jar", + "block.unicopia.lightning_jar": "Lightning in a Jar", "item.unicopia.zap_apple_jam_jar": "Zap Apple Jam", - + "block.unicopia.zap_jar": "Jar of Zap Apple Jam", + "item.unicopia.toast": "Toast", "item.unicopia.burned_toast": "Burned Toast", "item.unicopia.jam_toast": "Toast with Zap Apple Jam", diff --git a/src/main/resources/assets/unicopia/models/block/cloud_jar_filling.json b/src/main/resources/assets/unicopia/models/block/cloud_jar_filling.json new file mode 100644 index 00000000..2470653c --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/cloud_jar_filling.json @@ -0,0 +1,56 @@ +{ + "textures": { + "cloud": "unicopia:block/cloud", + "particle": "#cloud" + }, + "elements": [ + { + "from": [5.1, 6.1, 5.1], + "to": [9.9, 8.9, 8.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [6.1, 4.1, 7.1], + "to": [11.9, 6.9, 10.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [6.1, 8.1, 7.1], + "to": [9.9, 9.9, 9.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [6.1, 7.1, 8.1], + "to": [10.9, 8.9, 10.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/lightning_jar_filling.json b/src/main/resources/assets/unicopia/models/block/lightning_jar_filling.json new file mode 100644 index 00000000..d8fdd3ec --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/lightning_jar_filling.json @@ -0,0 +1,34 @@ +{ + "textures": { + "filling": "unicopia:block/lightning_jar_filling", + "particle": "#filling" + }, + "elements": [ + { + "from": [6, 1, 7.5], + "to": [11, 11, 7.5], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 5, 7], "rescale": true}, + "faces": { + "north": {"uv": [3, 0, 13, 16], "texture": "#filling"}, + "east": {"uv": [0, 0, 0, 8], "texture": "#filling"}, + "south": {"uv": [3, 0, 13, 16], "texture": "#filling"}, + "west": {"uv": [0, 0, 0, 8], "texture": "#filling"}, + "up": {"uv": [0, 0, 6, 0], "texture": "#filling"}, + "down": {"uv": [0, 0, 6, 0], "texture": "#filling"} + } + }, + { + "from": [5, 1, 7.5], + "to": [10, 11, 7.5], + "rotation": {"angle": 45, "axis": "y", "origin": [8, 5, 7], "rescale": true}, + "faces": { + "north": {"uv": [3, 0, 13, 16], "texture": "#filling"}, + "east": {"uv": [0, 0, 0, 8], "texture": "#filling"}, + "south": {"uv": [3, 0, 13, 16], "texture": "#filling"}, + "west": {"uv": [0, 0, 0, 8], "texture": "#filling"}, + "up": {"uv": [0, 0, 6, 0], "rotation": 180, "texture": "#filling"}, + "down": {"uv": [0, 0, 6, 0], "rotation": 180, "texture": "#filling"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/storm_jar_filling.json b/src/main/resources/assets/unicopia/models/block/storm_jar_filling.json new file mode 100644 index 00000000..b5eeffd6 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/storm_jar_filling.json @@ -0,0 +1,140 @@ +{ + "textures": { + "cloud": "unicopia:block/cloud", + "particle": "#cloud" + }, + "elements": [ + { + "from": [4.1, 3.1, 4.1], + "to": [11.9, 11.9, 11.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [6.1, 2.1, 5.1], + "to": [10.9, 2.9, 10.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [7.1, 11.1, 6.1], + "to": [12.9, 13.9, 9.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [3, 9, 10], + "to": [5, 11, 12], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [3.1, 10.1, 7.1], + "to": [8.9, 12.9, 10.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [11, 10, 9], + "to": [13, 12, 11], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [9, 13, 7], + "to": [11, 15, 9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [5, 13, 7], + "to": [7, 15, 9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [3, 8, 5], + "to": [5, 10, 7], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [6.1, 10.1, 7.1], + "to": [9.9, 11.9, 9.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + }, + { + "from": [6.1, 11.1, 9.1], + "to": [10.9, 12.9, 11.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#cloud"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#cloud"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#cloud"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#cloud"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#cloud"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#cloud"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/template_jar.json b/src/main/resources/assets/unicopia/models/block/template_jar.json new file mode 100644 index 00000000..0133ab21 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/template_jar.json @@ -0,0 +1,57 @@ +{ + "textures": { + "body": "unicopia:block/jar_body", + "cork": "unicopia:block/jar_cork", + "particle": "#body" + }, + "elements": [ + { + "from": [4, 0, 4], + "to": [12, 12, 12], + "faces": { + "north": {"uv": [0, 0, 8, 12], "texture": "#body"}, + "east": {"uv": [0, 0, 8, 12], "texture": "#body"}, + "south": {"uv": [0, 0, 8, 12], "texture": "#body"}, + "west": {"uv": [0, 0, 8, 12], "texture": "#body"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#body"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#body"} + } + }, + { + "from": [5, 13, 5], + "to": [11, 14, 11], + "faces": { + "north": {"uv": [0, 0, 8, 1], "texture": "#body"}, + "east": {"uv": [0, 0, 8, 1], "texture": "#body"}, + "south": {"uv": [0, 0, 8, 1], "texture": "#body"}, + "west": {"uv": [0, 0, 8, 1], "texture": "#body"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#body"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#body"} + } + }, + { + "from": [6, 12, 6], + "to": [10, 13, 10], + "faces": { + "north": {"uv": [0, 0, 8, 1], "texture": "#body"}, + "east": {"uv": [0, 0, 8, 1], "texture": "#body"}, + "south": {"uv": [0, 0, 8, 1], "texture": "#body"}, + "west": {"uv": [0, 0, 8, 1], "texture": "#body"}, + "up": {"uv": [8, 0, 16, 8], "texture": "#body"}, + "down": {"uv": [8, 0, 16, 8], "texture": "#body"} + } + }, + { + "from": [6, 13, 6], + "to": [10, 16, 10], + "faces": { + "north": {"uv": [0, 4, 4, 7], "texture": "#cork"}, + "east": {"uv": [0, 4, 4, 7], "texture": "#cork"}, + "south": {"uv": [0, 4, 4, 7], "texture": "#cork"}, + "west": {"uv": [0, 4, 4, 7], "texture": "#cork"}, + "up": {"uv": [0, 0, 4, 4], "texture": "#cork"}, + "down": {"uv": [4, 0, 8, 4], "texture": "#cork"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/zap_jar_filling.json b/src/main/resources/assets/unicopia/models/block/zap_jar_filling.json new file mode 100644 index 00000000..8516e5c6 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/zap_jar_filling.json @@ -0,0 +1,20 @@ +{ + "textures": { + "filling": "unicopia:block/zap_jar_filling", + "particle": "#filling" + }, + "elements": [ + { + "from": [4.1, 0.1, 4.1], + "to": [11.9, 9.9, 11.9], + "faces": { + "north": {"uv": [0, 2, 8, 12], "texture": "#filling"}, + "east": {"uv": [0, 6, 8, 16], "texture": "#filling"}, + "south": {"uv": [8, 6, 16, 16], "texture": "#filling"}, + "west": {"uv": [8, 0, 16, 10], "texture": "#filling"}, + "up": {"uv": [4, 3, 12, 11], "texture": "#filling"}, + "down": {"uv": [8, 4, 16, 12], "texture": "#filling"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/textures/block/jar_body.png b/src/main/resources/assets/unicopia/textures/block/jar_body.png new file mode 100644 index 0000000000000000000000000000000000000000..99e38ba24890f8e16bf666d92423a27976ea16d6 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`i#=T&Lo9lqPBi3eG2mf2&cUgb z5_jPL{X_ac8rF6&X~mbm(2Hqed78WP-rR^j7ngvGn{;>%H>|4r`OeRa^UN9!gUtq; ze|+_DX_@IdS-LVHR8a6_t)O7&Q-&SZk1ggkg1zn2~F{Gzq% z^QJrByC1>I;Bz@-ukYq{*@Y3aWgAW(X^m>AoR@st>{~7Sg4b5R_SK*IC%u>9n1A%D UD+M)kfX-#`boFyt=akR{0BKxVumAu6 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/block/jar_cork.png b/src/main/resources/assets/unicopia/textures/block/jar_cork.png new file mode 100644 index 0000000000000000000000000000000000000000..c87771fa5160cfd8fa23f3d102300603e7f8df57 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`{+=$5Ar`&KF*eGd?V05SW*g2G zoNpt{%*@=p!oVDaV+7{*_y eaJeytGBAYC;ahToeNq9?Xa-MLKbLh*2~7aemL*~U literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/block/lightning_jar_filling.png b/src/main/resources/assets/unicopia/textures/block/lightning_jar_filling.png new file mode 100644 index 0000000000000000000000000000000000000000..588a0b0eccf1f3405ebdc908d994d49689848b01 GIT binary patch literal 8868 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 a1c5xh@3i_MR1@?)+J?TyB4?FX?0*3n=8BmB literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/block/zap_jar_filling.png b/src/main/resources/assets/unicopia/textures/block/zap_jar_filling.png new file mode 100644 index 0000000000000000000000000000000000000000..78d8a21f150a3ee65560848c6e474a207cbf3b00 GIT binary patch literal 9511 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 II`8=Z0)A+yfdBvi literal 0 HcmV?d00001 From 2784627adcfdfd261a1012c650d9c187262a5933 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sat, 30 Mar 2024 21:22:36 +0000 Subject: [PATCH 56/73] Fix bugs and allow for storing bucketed entities in jars --- .../unicopia/block/ItemJarBlock.java | 325 ++++++++++++++---- .../unicopia/block/JarBlock.java | 38 +- .../unicopia/client/render/RenderUtil.java | 72 ++++ .../entity/ItemJarBlockEntityRenderer.java | 93 ++++- .../unicopia/mixin/MixinEntityBucketItem.java | 16 + .../unicopia/util/NbtSerialisable.java | 3 + .../unicopia/util/PosHelper.java | 2 +- src/main/resources/unicopia.mixin.json | 1 + 8 files changed, 474 insertions(+), 76 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityBucketItem.java diff --git a/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java index 68c9b9ba..1c726165 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java @@ -2,18 +2,38 @@ package com.minelittlepony.unicopia.block; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.mixin.MixinEntityBucketItem; +import com.minelittlepony.unicopia.util.NbtSerialisable; + import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.block.InventoryProvider; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.Bucketable; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.SidedInventory; import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.network.listener.ClientPlayPacketListener; +import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket; +import net.minecraft.registry.Registries; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.TypedActionResult; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -36,14 +56,7 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven if (hand == Hand.OFF_HAND) { return ActionResult.PASS; } - return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> { - ItemStack stack = player.getStackInHand(hand); - if (stack.isEmpty()) { - return data.removeItem(world, pos); - } - - return data.insertItem(world, pos, player.isCreative() ? stack.copyWithCount(1) : stack.split(1)); - }).orElse(ActionResult.PASS); + return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> data.interact(player, hand)).orElse(ActionResult.PASS); } @Deprecated @@ -51,9 +64,7 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { if (!moved && !state.isOf(newState.getBlock())) { world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).ifPresent(data -> { - data.getStacks().forEach(stack -> { - dropStack(world, pos, stack); - }); + data.getContents().onDestroyed(); }); } super.onStateReplaced(state, world, pos, newState, moved); @@ -66,7 +77,10 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven @Override public int getComparatorOutput(BlockState state, World world, BlockPos pos) { - return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> Math.min(16, data.getStacks().size())).orElse(0); + return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR) + .map(TileData::getItems) + .map(data -> Math.min(16, data.getStacks().size())) + .orElse(0); } @Deprecated @@ -85,34 +99,210 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven @Override public SidedInventory getInventory(BlockState state, WorldAccess world, BlockPos pos) { - return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).orElse(null); + return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(TileData::getItems).orElse(null); } - public static class TileData extends BlockEntity implements SidedInventory { - private static final int[] SLOTS = IntStream.range(0, 16).toArray(); - private final List stacks = new ArrayList<>(); + public static class TileData extends BlockEntity { + + private JarContents contents = new ItemsJarContents(this); public TileData(BlockPos pos, BlockState state) { super(UBlockEntities.ITEM_JAR, pos, state); } - public ActionResult insertItem(World world, BlockPos pos, ItemStack stack) { - if (stacks.size() >= size()) { - return ActionResult.FAIL; - } - stacks.add(stack); - markDirty(); - - return ActionResult.SUCCESS; + public ActionResult interact(PlayerEntity player, Hand hand) { + TypedActionResult result = contents.interact(player, hand); + contents = result.getValue(); + return result.getResult(); } - public ActionResult removeItem(World world, BlockPos pos) { - if (stacks.isEmpty()) { - return ActionResult.FAIL; + public JarContents getContents() { + return contents; + } + + @Nullable + public ItemsJarContents getItems() { + return getContents() instanceof ItemsJarContents c ? c : null; + } + + @Nullable + public EntityJarContents getEntity() { + return getContents() instanceof EntityJarContents c ? c : null; + } + + @Override + public Packet toUpdatePacket() { + return BlockEntityUpdateS2CPacket.create(this); + } + + @Override + public NbtCompound toInitialChunkDataNbt() { + return createNbt(); + } + + @Override + public void markDirty() { + super.markDirty(); + if (getWorld() instanceof ServerWorld sw) { + sw.getChunkManager().markForUpdate(getPos()); } - dropStack(world, pos, stacks.remove(0)); + } + + @Override + public void readNbt(NbtCompound nbt) { + if (nbt.contains("items", NbtElement.COMPOUND_TYPE)) { + contents = new ItemsJarContents(this); + contents.fromNBT(nbt.getCompound("items")); + } else if (nbt.contains("entity", NbtElement.COMPOUND_TYPE)) { + contents = new EntityJarContents(this); + contents.fromNBT(nbt.getCompound("entity")); + } + } + + @Override + protected void writeNbt(NbtCompound nbt) { + var items = getItems(); + if (items != null) { + nbt.put("items", items.toNBT()); + } else if (getEntity() != null) { + nbt.put("entity", getEntity().toNBT()); + } + } + } + + + public interface JarContents extends NbtSerialisable { + TypedActionResult interact(PlayerEntity player, Hand hand); + + void onDestroyed(); + } + + public static class EntityJarContents implements JarContents { + @Nullable + private EntityType entityType; + @Nullable + private Entity renderEntity; + + private final TileData tile; + + public EntityJarContents(TileData tile) { + this(tile, null); + } + + public EntityJarContents(TileData tile, EntityType entityType) { + this.tile = tile; + this.entityType = entityType; + } + + @Nullable + public Entity getOrCreateEntity() { + if (entityType == null && tile.getWorld() != null) { + return null; + } + + if (renderEntity == null || renderEntity.getType() != entityType) { + renderEntity = entityType.create(tile.getWorld()); + } + return renderEntity; + } + + @Override + public TypedActionResult interact(PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + if (stack.isOf(Items.BUCKET)) { + if (getOrCreateEntity() instanceof Bucketable bucketable) { + if (!player.isCreative()) { + stack.decrement(1); + if (stack.isEmpty()) { + player.setStackInHand(hand, bucketable.getBucketItem()); + } else { + player.giveItemStack(bucketable.getBucketItem()); + } + } + player.playSound(bucketable.getBucketFillSound(), 1, 1); + } + tile.markDirty(); + return TypedActionResult.success(new ItemsJarContents(tile)); + } + return TypedActionResult.pass(this); + } + + @Override + public void onDestroyed() { + tile.getWorld().setBlockState(tile.getPos(), Blocks.WATER.getDefaultState()); + Entity entity = getOrCreateEntity(); + if (entity != null) { + entity.refreshPositionAfterTeleport(tile.getPos().toCenterPos()); + tile.getWorld().spawnEntity(entity); + } + } + + @Override + public void toNBT(NbtCompound compound) { + compound.putString("entity", EntityType.getId(entityType).toString()); + } + + @Override + public void fromNBT(NbtCompound compound) { + entityType = Registries.ENTITY_TYPE.getOrEmpty(Identifier.tryParse(compound.getString("entity"))).orElse(null); + } + + } + + public static class ItemsJarContents implements JarContents, SidedInventory { + private static final int[] SLOTS = IntStream.range(0, 16).toArray(); + + private final TileData tile; + private List stacks = new ArrayList<>(); + + public ItemsJarContents(TileData tile) { + this.tile = tile; + } + + @Override + public TypedActionResult interact(PlayerEntity player, Hand hand) { + ItemStack handStack = player.getStackInHand(hand); + + if (handStack.isEmpty()) { + if (stacks.isEmpty()) { + return TypedActionResult.fail(this); + } + dropStack(tile.getWorld(), tile.getPos(), stacks.remove(0)); + markDirty(); + return TypedActionResult.success(this); + } + + if (stacks.isEmpty()) { + if (handStack.getItem() instanceof MixinEntityBucketItem bucket) { + if (!player.isCreative()) { + handStack.decrement(1); + if (handStack.isEmpty()) { + player.setStackInHand(hand, Items.BUCKET.getDefaultStack()); + } else { + player.giveItemStack(Items.BUCKET.getDefaultStack()); + } + } + + player.playSound(bucket.getEmptyingSound(), 1, 1); + markDirty(); + return TypedActionResult.success(new EntityJarContents(tile, bucket.getEntityType())); + } + } + + if (stacks.size() >= size()) { + return TypedActionResult.fail(this); + } + stacks.add(player.isCreative() ? handStack.copyWithCount(1) : handStack.split(1)); markDirty(); - return ActionResult.SUCCESS; + + return TypedActionResult.success(this); + } + + @Override + public void onDestroyed() { + stacks.forEach(stack -> { + dropStack(tile.getWorld(), tile.getPos(), stack); + }); } public List getStacks() { @@ -137,51 +327,42 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven @Override public ItemStack removeStack(int slot, int amount) { if (slot < 0 || slot >= stacks.size()) { - try { - ItemStack stack = stacks.get(slot); - ItemStack removed = stack.split(1); - if (stack.isEmpty()) { - stacks.remove(slot); - } - return removed; - } finally { - markDirty(); - } + return ItemStack.EMPTY; + } + + try { + ItemStack stack = stacks.get(slot); + ItemStack removed = stack.split(1); + if (stack.isEmpty()) { + stacks.remove(slot); + } + return removed; + } finally { + markDirty(); } - return ItemStack.EMPTY; } @Override public ItemStack removeStack(int slot) { if (slot < 0 || slot >= stacks.size()) { - try { - return stacks.remove(slot); - } finally { - markDirty(); - } + return ItemStack.EMPTY; + } + + try { + return stacks.remove(slot); + } finally { + markDirty(); } - return ItemStack.EMPTY; } @Override public void setStack(int slot, ItemStack stack) { if (slot >= stacks.size()) { - if (stacks.size() >= size()) { - dropStack(getWorld(), getPos(), stack); - } else { - stacks.add(stack); - } + stacks.add(stack); } else { - ItemStack existing = stacks.get(slot); - if (!ItemStack.canCombine(existing, stack)) { - dropStack(getWorld(), getPos(), stack); - } else { - existing.setCount(existing.getCount() + stack.split(Math.max(0, existing.getMaxCount() - existing.getCount())).getCount()); - if (!stack.isEmpty()) { - dropStack(getWorld(), getPos(), stack); - } - } + stacks.set(slot, stack); } + markDirty(); } @Override @@ -202,15 +383,29 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven @Override public boolean canInsert(int slot, ItemStack stack, Direction dir) { - return (slot >= 0 && slot < size()) && (slot >= stacks.size() || ( - ItemStack.canCombine(stacks.get(slot), stack) - && (stacks.get(slot).getCount() + stack.getCount()) <= Math.min(stacks.get(slot).getMaxCount(), stack.getMaxCount()) - )); + return slot >= 0 && slot < size() && slot >= stacks.size(); } @Override public boolean canExtract(int slot, ItemStack stack, Direction dir) { - return true; + return slot >= 0 && slot < size() && slot < stacks.size(); + } + + @Override + public void toNBT(NbtCompound compound) { + compound.put("items", NbtSerialisable.ITEM_STACK.writeAll(stacks)); + } + + @Override + public void fromNBT(NbtCompound compound) { + stacks = NbtSerialisable.ITEM_STACK.readAll(compound.getList("items", NbtElement.COMPOUND_TYPE)) + .limit(size()) + .collect(Collectors.toList()); + } + + @Override + public void markDirty() { + tile.markDirty(); } } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java index 80f24c7e..2bf5777b 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/JarBlock.java @@ -11,10 +11,17 @@ import net.minecraft.block.AbstractGlassBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; +import net.minecraft.block.Waterloggable; import net.minecraft.block.entity.BlockEntity; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.BooleanProperty; +import net.minecraft.state.property.Properties; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; @@ -22,17 +29,25 @@ import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.BlockView; import net.minecraft.world.World; +import net.minecraft.world.WorldAccess; import net.minecraft.world.explosion.Explosion; -public class JarBlock extends AbstractGlassBlock { +public class JarBlock extends AbstractGlassBlock implements Waterloggable { private static final VoxelShape SHAPE = VoxelShapes.union( Block.createCuboidShape(4, 0, 4, 12, 12, 12), Block.createCuboidShape(6, 12, 6, 10, 16, 10), Block.createCuboidShape(5, 13, 5, 11, 14, 11) ); + private static final BooleanProperty WATERLOGGED = Properties.WATERLOGGED; public JarBlock(Settings settings) { super(settings); + setDefaultState(getDefaultState().with(WATERLOGGED, false)); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(WATERLOGGED); } @Override @@ -40,9 +55,26 @@ public class JarBlock extends AbstractGlassBlock { return SHAPE; } + @Deprecated @Override - public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) { - return super.isSideInvisible(state, stateFrom, direction); + public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { + if (state.get(WATERLOGGED)) { + world.scheduleFluidTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + } + + return super.getStateForNeighborUpdate(state, direction, neighborState, world, pos, neighborPos); + } + + @Nullable + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + return getDefaultState().with(WATERLOGGED, ctx.getWorld().getFluidState(ctx.getBlockPos()).getFluid() == Fluids.WATER); + } + + @Deprecated + @Override + public FluidState getFluidState(BlockState state) { + return state.get(WATERLOGGED) ? Fluids.WATER.getStill(false) : super.getFluidState(state); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java b/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java index cb43a128..c2795b11 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java @@ -5,10 +5,16 @@ import org.joml.Vector3f; import org.joml.Vector4f; import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexFormat; import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.ColorHelper; +import net.minecraft.util.math.Direction; public class RenderUtil { public static final Vector4f TEMP_VECTOR = new Vector4f(); @@ -25,6 +31,72 @@ public class RenderUtil { new Vertex(1, 0, 0, 1, 1), new Vertex(0, 0, 0, 0, 1) }; + private static final Vertex[][] CUBE_VERTICES = { + new Vertex[] { // down + new Vertex(0, 0, 0, 0, 0), + new Vertex(1, 0, 0, 1, 0), + new Vertex(1, 0, 1, 1, 1), + new Vertex(0, 0, 1, 0, 1) + }, + new Vertex[] { //up + new Vertex(0, 1, 0, 0, 0), + new Vertex(0, 1, 1, 0, 1), + new Vertex(1, 1, 1, 1, 1), + new Vertex(1, 1, 0, 1, 0) + }, + new Vertex[] { //north + new Vertex(0, 0, 0, 0, 0), + new Vertex(0, 1, 0, 0, 1), + new Vertex(1, 1, 0, 1, 1), + new Vertex(1, 0, 0, 1, 0) + }, + new Vertex[] { //south + new Vertex(0, 0, 1, 0, 0), + new Vertex(1, 0, 1, 1, 0), + new Vertex(1, 1, 1, 1, 1), + new Vertex(0, 1, 1, 0, 1) + }, + new Vertex[] { //west + new Vertex(0, 0, 0, 0, 0), + new Vertex(0, 0, 1, 1, 0), + new Vertex(0, 1, 1, 1, 1), + new Vertex(0, 1, 0, 0, 1) + }, + new Vertex[] { //east + new Vertex(1, 0, 0, 0, 0), + new Vertex(1, 1, 0, 1, 0), + new Vertex(1, 1, 1, 1, 1), + new Vertex(1, 0, 1, 0, 1) + } + }; + + public static void renderSpriteCubeFaces(MatrixStack matrices, VertexConsumerProvider provider, Sprite sprite, + float width, float height, float length, + int color, int light, int overlay, + Direction... directions) { + float r = ColorHelper.Abgr.getRed(color), + g = ColorHelper.Abgr.getGreen(color), + b = ColorHelper.Abgr.getBlue(color), + a = ColorHelper.Abgr.getAlpha(color); + float u0 = sprite.getMinU(), uDelta = sprite.getMaxU() - u0; + float v0 = sprite.getMinV(), vDelta = sprite.getMaxV() - v0; + RenderLayer layer = RenderLayer.getEntitySolid(sprite.getAtlasId()); + VertexConsumer buffer = provider.getBuffer(layer); + Matrix4f position = matrices.peek().getPositionMatrix(); + for (Direction direction : directions) { + for (Vertex vertex : CUBE_VERTICES[direction.ordinal()]) { + Vector4f pos = position.transform(TEMP_VECTOR.set(vertex.position(), 1).mul(width, height, length, 1)); + buffer.vertex( + pos.x, pos.y, pos.z, + r, g, b, a, + u0 + vertex.texture().x * uDelta, + v0 + vertex.texture().y * vDelta, + overlay, light, + direction.getOffsetX(), direction.getOffsetY(), direction.getOffsetZ() + ); + } + } + } public static void renderFace(MatrixStack matrices, Tessellator te, BufferBuilder buffer, float r, float g, float b, float a, int light) { renderFace(matrices, te, buffer, r, g, b, a, light, 1, 1); diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java index 85bec08a..e0b4883c 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java @@ -1,29 +1,61 @@ package com.minelittlepony.unicopia.client.render.entity; -import java.util.List; - import com.minelittlepony.unicopia.block.ItemJarBlock; +import com.minelittlepony.unicopia.block.ItemJarBlock.EntityJarContents; +import com.minelittlepony.unicopia.block.ItemJarBlock.ItemsJarContents; +import com.minelittlepony.unicopia.client.render.RenderUtil; +import com.minelittlepony.unicopia.util.PosHelper; +import net.minecraft.block.Blocks; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.color.world.BiomeColors; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; +import net.minecraft.client.render.entity.EntityRenderDispatcher; +import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.model.json.ModelTransformationMode; +import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.command.argument.EntityAnchorArgumentType.EntityAnchor; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RotationAxis; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.random.Random; +import net.minecraft.world.World; public class ItemJarBlockEntityRenderer implements BlockEntityRenderer { + private final ItemRenderer itemRenderer; + private final EntityRenderDispatcher dispatcher; + + private final Sprite waterSprite; + public ItemJarBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) { + itemRenderer = ctx.getItemRenderer(); + dispatcher = ctx.getEntityRenderDispatcher(); + waterSprite = MinecraftClient.getInstance().getBakedModelManager().getBlockModels().getModel(Blocks.WATER.getDefaultState()).getParticleSprite(); } @Override - public void render(ItemJarBlock.TileData entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light, int overlay) { + public void render(ItemJarBlock.TileData data, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light, int overlay) { - List stacks = entity.getStacks(); + ItemsJarContents items = data.getItems(); + if (items != null) { + renderItemStacks(data, items, tickDelta, matrices, vertices, light, overlay); + } + EntityJarContents entity = data.getEntity(); + if (entity != null) { + renderEntity(data, entity, tickDelta, matrices, vertices, light, overlay); + } + } + + private void renderItemStacks(ItemJarBlock.TileData data, ItemsJarContents items, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light, int overlay) { float itemScale = 0.35F; matrices.push(); @@ -31,19 +63,66 @@ public class ItemJarBlockEntityRenderer implements BlockEntityRenderer getEntityType(); + @Accessor + SoundEvent getEmptyingSound(); +} diff --git a/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java b/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java index 819153e5..54093f51 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java +++ b/src/main/java/com/minelittlepony/unicopia/util/NbtSerialisable.java @@ -8,12 +8,14 @@ import java.util.stream.Stream; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.*; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; public interface NbtSerialisable { Serializer BLOCK_POS = Serializer.of(NbtHelper::toBlockPos, NbtHelper::fromBlockPos); + Serializer ITEM_STACK = Serializer.of(ItemStack::fromNbt, stack -> stack.writeNbt(new NbtCompound())); /** * Called to save this to nbt to persist state on file or to transmit over the network @@ -44,6 +46,7 @@ public interface NbtSerialisable { } static Vec3d readVector(NbtList list) { + return new Vec3d(list.getDouble(0), list.getDouble(1), list.getDouble(2)); } diff --git a/src/main/java/com/minelittlepony/unicopia/util/PosHelper.java b/src/main/java/com/minelittlepony/unicopia/util/PosHelper.java index 7e203abd..2cb644e4 100644 --- a/src/main/java/com/minelittlepony/unicopia/util/PosHelper.java +++ b/src/main/java/com/minelittlepony/unicopia/util/PosHelper.java @@ -21,7 +21,7 @@ import net.minecraft.world.BlockView; import net.minecraft.world.World; public interface PosHelper { - + Direction[] ALL = Direction.values(); Direction[] HORIZONTAL = Arrays.stream(Direction.values()).filter(d -> d.getAxis().isHorizontal()).toArray(Direction[]::new); static Vec3d offset(Vec3d a, Vec3i b) { diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 0a82eae8..855a75b7 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -19,6 +19,7 @@ "MixinEnchantmentHelper", "MixinFallLocation", "MixinEntity", + "MixinEntityBucketItem", "MixinEntityView", "MixinEntityShapeContext", "MixinFallingBlock", From 1503cb57735be8af8411592d01d8144dbd2ee50d Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 31 Mar 2024 02:38:59 +0100 Subject: [PATCH 57/73] Set butterfly spawn conditions to include more blocks --- src/main/java/com/minelittlepony/unicopia/UTags.java | 2 ++ .../unicopia/datagen/providers/UBlockTagProvider.java | 1 + .../minelittlepony/unicopia/entity/mob/ButterflyEntity.java | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index 71120481..687d389d 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -83,6 +83,8 @@ public interface UTags { TagKey CLOUD_STAIRS = block("cloud_stairs"); TagKey CLOUD_BLOCKS = block("cloud_blocks"); TagKey CHITIN_BLOCKS = block("chitin_blocks"); + + TagKey BUTTERFLIES_SPAWNABLE_ON = block("butterflies_spawn_on"); } static TagKey item(String name) { diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java index 50a752c3..d30b68de 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java @@ -40,6 +40,7 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { }; getOrCreateTagBuilder(UTags.CATAPULT_IMMUNE).add(Blocks.BEDROCK).forceAddTag(BlockTags.DOORS).forceAddTag(BlockTags.TRAPDOORS); + getOrCreateTagBuilder(UTags.Blocks.BUTTERFLIES_SPAWNABLE_ON).forceAddTag(BlockTags.ANIMALS_SPAWNABLE_ON).forceAddTag(BlockTags.LEAVES).forceAddTag(BlockTags.FLOWERS).forceAddTag(BlockTags.FLOWER_POTS); getOrCreateTagBuilder(UTags.JARS).add(UBlocks.JAR, UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.ZAP_JAR); getOrCreateTagBuilder(BlockTags.CROPS).add(crops); getOrCreateTagBuilder(BlockTags.BEE_GROWABLES).add(crops); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java index d1a43978..6a0731b4 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/ButterflyEntity.java @@ -11,6 +11,7 @@ import java.util.stream.Collectors; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.item.ButterflyItem; import com.minelittlepony.unicopia.util.NbtSerialisable; @@ -73,7 +74,7 @@ public class ButterflyEntity extends AmbientEntity { } public static boolean canSpawn(EntityType type, WorldAccess world, SpawnReason spawnReason, BlockPos pos, Random random) { - return world.getBlockState(pos.down()).isIn(BlockTags.ANIMALS_SPAWNABLE_ON); + return world.getBlockState(pos.down()).isIn(UTags.Blocks.BUTTERFLIES_SPAWNABLE_ON); } @Override From ea9c3bfaf96cdf1389212d9daa3b1ec10c93ab40 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 31 Mar 2024 14:01:52 +0100 Subject: [PATCH 58/73] Move more tags to datagen --- .../unicopia/UConventionalTags.java | 10 +++ .../unicopia/datagen/Datagen.java | 20 ++--- .../{ => tag}/UBlockTagProvider.java | 12 ++- .../providers/tag/UDamageTypeProvider.java | 30 +++++++ .../providers/{ => tag}/UItemTagProvider.java | 0 .../unicopia/entity/damage/UDamageTypes.java | 22 +----- .../util/registry/DynamicRegistry.java | 45 +++++++++++ .../data/c/tags/blocks/concrete_powders.json | 21 ----- .../data/c/tags/blocks/glass_blocks.json | 24 ------ .../data/c/tags/blocks/glass_panes.json | 22 ------ .../resources/data/c/tags/blocks/ores.json | 78 ------------------- .../data/c/tags/items/concrete_powders.json | 21 ----- .../tags/damage_type/breaks_sunglasses.json | 7 -- .../tags/damage_type/from_horseshoes.json | 6 -- .../unicopia/tags/damage_type/from_rocks.json | 6 -- .../tags/damage_type/spellbook_immune_to.json | 16 ---- 16 files changed, 110 insertions(+), 230 deletions(-) rename src/main/java/com/minelittlepony/unicopia/datagen/providers/{ => tag}/UBlockTagProvider.java (94%) create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UDamageTypeProvider.java rename src/main/java/com/minelittlepony/unicopia/datagen/providers/{ => tag}/UItemTagProvider.java (100%) create mode 100644 src/main/java/com/minelittlepony/unicopia/util/registry/DynamicRegistry.java delete mode 100644 src/main/resources/data/c/tags/blocks/concrete_powders.json delete mode 100644 src/main/resources/data/c/tags/blocks/glass_blocks.json delete mode 100644 src/main/resources/data/c/tags/blocks/glass_panes.json delete mode 100644 src/main/resources/data/c/tags/blocks/ores.json delete mode 100644 src/main/resources/data/c/tags/items/concrete_powders.json delete mode 100644 src/main/resources/data/unicopia/tags/damage_type/breaks_sunglasses.json delete mode 100644 src/main/resources/data/unicopia/tags/damage_type/from_horseshoes.json delete mode 100644 src/main/resources/data/unicopia/tags/damage_type/from_rocks.json delete mode 100644 src/main/resources/data/unicopia/tags/damage_type/spellbook_immune_to.json diff --git a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java index 44e8571e..603c900e 100644 --- a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java @@ -35,4 +35,14 @@ public interface UConventionalTags { static TagKey block(String name) { return TagKey.of(RegistryKeys.BLOCK, new Identifier("c", name)); } + + interface Blocks { + TagKey CONCRETE_POWDERS = block("concrete_powders"); + TagKey CONCRETES = block("concretes"); + } + + interface Items { + TagKey CONCRETE_POWDERS = item("concrete_powders"); + TagKey CONCRETES = item("concretes"); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java index 972699d1..f8d103a6 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java @@ -5,33 +5,32 @@ import org.apache.logging.log4j.Logger; import com.minelittlepony.unicopia.datagen.providers.SeasonsGrowthRatesProvider; import com.minelittlepony.unicopia.datagen.providers.UAdvancementsProvider; -import com.minelittlepony.unicopia.datagen.providers.UBlockTagProvider; -import com.minelittlepony.unicopia.datagen.providers.UItemTagProvider; import com.minelittlepony.unicopia.datagen.providers.UModelProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UBlockAdditionsLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UBlockLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UChestAdditionsLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.recipe.URecipeProvider; +import com.minelittlepony.unicopia.datagen.providers.tag.UBlockTagProvider; +import com.minelittlepony.unicopia.datagen.providers.tag.UDamageTypeProvider; +import com.minelittlepony.unicopia.datagen.providers.tag.UItemTagProvider; +import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.server.world.UWorldGen; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; import net.minecraft.registry.RegistryBuilder; -import net.minecraft.registry.RegistryEntryLookup; import net.minecraft.registry.RegistryKeys; import net.minecraft.world.biome.OverworldBiomeCreator; -import net.minecraft.world.gen.carver.ConfiguredCarver; -import net.minecraft.world.gen.feature.PlacedFeature; public class Datagen implements DataGeneratorEntrypoint { public static final Logger LOGGER = LogManager.getLogger(); @Override public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { - final FabricDataGenerator.Pack pack = fabricDataGenerator.createPack(); - - UBlockTagProvider blockTags = pack.addProvider(UBlockTagProvider::new); + final var pack = fabricDataGenerator.createPack(); + final var blockTags = pack.addProvider(UBlockTagProvider::new); pack.addProvider((output, registries) -> new UItemTagProvider(output, registries, blockTags)); + pack.addProvider(UDamageTypeProvider::new); pack.addProvider(UModelProvider::new); pack.addProvider(URecipeProvider::new); @@ -45,9 +44,10 @@ public class Datagen implements DataGeneratorEntrypoint { @Override public void buildRegistry(RegistryBuilder builder) { builder.addRegistry(RegistryKeys.BIOME, registerable -> { - RegistryEntryLookup placedFeatureLookup = registerable.getRegistryLookup(RegistryKeys.PLACED_FEATURE); - RegistryEntryLookup> carverLookup = registerable.getRegistryLookup(RegistryKeys.CONFIGURED_CARVER); + final var placedFeatureLookup = registerable.getRegistryLookup(RegistryKeys.PLACED_FEATURE); + final var carverLookup = registerable.getRegistryLookup(RegistryKeys.CONFIGURED_CARVER); registerable.register(UWorldGen.SWEET_APPLE_ORCHARD, OverworldBiomeCreator.createNormalForest(placedFeatureLookup, carverLookup, false, false, false)); }); + builder.addRegistry(RegistryKeys.DAMAGE_TYPE, UDamageTypes.REGISTRY); } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java similarity index 94% rename from src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java rename to src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java index d30b68de..f4c583a4 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java @@ -1,7 +1,9 @@ -package com.minelittlepony.unicopia.datagen.providers; +package com.minelittlepony.unicopia.datagen.providers.tag; +import java.util.Arrays; import java.util.concurrent.CompletableFuture; +import com.minelittlepony.unicopia.UConventionalTags; import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.block.UBlocks; @@ -12,12 +14,14 @@ import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; import net.fabricmc.fabric.api.tag.convention.v1.ConventionalBlockTags; import net.minecraft.block.Block; import net.minecraft.block.Blocks; +import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryWrapper; import net.minecraft.registry.RegistryWrapper.WrapperLookup; import net.minecraft.registry.tag.BlockTags; import net.minecraft.registry.tag.TagBuilder; import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.DyeColor; import net.minecraft.util.Identifier; public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { @@ -32,6 +36,7 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { @Override protected void configure(WrapperLookup registries) { + populateConventionalTags(); Block[] crops = { UBlocks.OATS, UBlocks.OATS_STEM, UBlocks.OATS_CROWN, UBlocks.ROCKS, UBlocks.PINEAPPLE, @@ -205,4 +210,9 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { getOrCreateTagBuilder(BlockTags.CEILING_HANGING_SIGNS).add(hanging); getOrCreateTagBuilder(BlockTags.WALL_HANGING_SIGNS).add(wallHanging); } + + private void populateConventionalTags() { + getOrCreateTagBuilder(UConventionalTags.Blocks.CONCRETES).add(Arrays.stream(DyeColor.values()).map(i -> Registries.BLOCK.get(new Identifier(i.getName() + "_concrete"))).toArray(Block[]::new)); + getOrCreateTagBuilder(UConventionalTags.Blocks.CONCRETE_POWDERS).add(Arrays.stream(DyeColor.values()).map(i -> Registries.BLOCK.get(new Identifier(i.getName() + "_concrete_powder"))).toArray(Block[]::new)); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UDamageTypeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UDamageTypeProvider.java new file mode 100644 index 00000000..e4170071 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UDamageTypeProvider.java @@ -0,0 +1,30 @@ +package com.minelittlepony.unicopia.datagen.providers.tag; + +import java.util.concurrent.CompletableFuture; + +import com.minelittlepony.unicopia.UTags; +import com.minelittlepony.unicopia.entity.damage.UDamageTypes; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider; +import net.minecraft.entity.damage.DamageType; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryWrapper.WrapperLookup; +import net.minecraft.registry.tag.DamageTypeTags; + +public class UDamageTypeProvider extends FabricTagProvider { + public UDamageTypeProvider(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, RegistryKeys.DAMAGE_TYPE, registriesFuture); + } + + @Override + protected void configure(WrapperLookup lookup) { + getOrCreateTagBuilder(UTags.SPELLBOOK_IMMUNE_TO).add( + UDamageTypes.ZAP_APPLE, UDamageTypes.LOVE_DRAINING, UDamageTypes.LIFE_DRAINING, + UDamageTypes.RAINBOOM, UDamageTypes.SUN, UDamageTypes.SUNLIGHT, UDamageTypes.SMASH + ).forceAddTag(DamageTypeTags.IS_FALL).forceAddTag(DamageTypeTags.IS_FREEZING).forceAddTag(DamageTypeTags.IS_LIGHTNING).forceAddTag(DamageTypeTags.IS_PROJECTILE); + getOrCreateTagBuilder(UTags.FROM_ROCKS).add(UDamageTypes.ROCK); + getOrCreateTagBuilder(UTags.FROM_HORSESHOES).add(UDamageTypes.HORSESHOE); + getOrCreateTagBuilder(UTags.BREAKS_SUNGLASSES).add(UDamageTypes.BAT_SCREECH, UDamageTypes.RAINBOOM); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UItemTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java similarity index 100% rename from src/main/java/com/minelittlepony/unicopia/datagen/providers/UItemTagProvider.java rename to src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java diff --git a/src/main/java/com/minelittlepony/unicopia/entity/damage/UDamageTypes.java b/src/main/java/com/minelittlepony/unicopia/entity/damage/UDamageTypes.java index eae9bb47..3bdc4a8f 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/damage/UDamageTypes.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/damage/UDamageTypes.java @@ -1,18 +1,14 @@ package com.minelittlepony.unicopia.entity.damage; -import java.util.ArrayList; -import java.util.List; - import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.util.registry.DynamicRegistry; -import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback; import net.minecraft.entity.damage.DamageType; -import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; public interface UDamageTypes { - List> REGISTRY = new ArrayList<>(); + DynamicRegistry REGISTRY = new DynamicRegistry<>(RegistryKeys.DAMAGE_TYPE, key -> new DamageType(key.getValue().getNamespace() + "." + key.getValue().getPath(), 0)); RegistryKey EXHAUSTION = register("magical_exhaustion"); RegistryKey ALICORN_AMULET = register("alicorn_amulet"); @@ -34,18 +30,8 @@ public interface UDamageTypes { RegistryKey SPIKES = register("spikes"); private static RegistryKey register(String name) { - var key = RegistryKey.of(RegistryKeys.DAMAGE_TYPE, Unicopia.id(name)); - REGISTRY.add(key); - return key; + return REGISTRY.register(Unicopia.id(name)); } - static void bootstrap() { - DynamicRegistrySetupCallback.EVENT.register(registries -> { - registries.getOptional(RegistryKeys.DAMAGE_TYPE).ifPresent(registry -> { - REGISTRY.forEach(key -> { - Registry.register(registry, key.getValue(), new DamageType(key.getValue().getNamespace() + "." + key.getValue().getPath(), 0)); - }); - }); - }); - } + static void bootstrap() {} } diff --git a/src/main/java/com/minelittlepony/unicopia/util/registry/DynamicRegistry.java b/src/main/java/com/minelittlepony/unicopia/util/registry/DynamicRegistry.java new file mode 100644 index 00000000..0dd2949a --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/util/registry/DynamicRegistry.java @@ -0,0 +1,45 @@ +package com.minelittlepony.unicopia.util.registry; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback; +import net.minecraft.registry.Registerable; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryBuilder; +import net.minecraft.registry.RegistryKey; +import net.minecraft.util.Identifier; + +public class DynamicRegistry implements RegistryBuilder.BootstrapFunction { + private final RegistryKey> registry; + private final Map, Entry> keys = new HashMap<>(); + private final Function, T> valueFactory; + + public DynamicRegistry(RegistryKey> registry, Function, T> valueFactory) { + this.registry = registry; + this.valueFactory = valueFactory; + + DynamicRegistrySetupCallback.EVENT.register(registries -> { + registries.getOptional(registry).ifPresent(r -> { + keys.forEach((key, entry)-> Registry.register(r, key.getValue(), entry.factory().apply(key))); + }); + }); + } + + @Override + public void run(Registerable registerable) { + keys.forEach((key, entry) -> registerable.register(key, entry.factory().apply(key))); + } + + public RegistryKey register(Identifier id) { + return register(id, valueFactory); + } + + public RegistryKey register(Identifier id, Function, T> valueFactory) { + return keys.computeIfAbsent(RegistryKey.of(registry, id), k -> new Entry<>(k, valueFactory)).key(); + } + + record Entry(RegistryKey key, Function, T> factory) {} + +} diff --git a/src/main/resources/data/c/tags/blocks/concrete_powders.json b/src/main/resources/data/c/tags/blocks/concrete_powders.json deleted file mode 100644 index e3142856..00000000 --- a/src/main/resources/data/c/tags/blocks/concrete_powders.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:white_concrete_powder", - "minecraft:orange_concrete_powder", - "minecraft:magenta_concrete_powder", - "minecraft:light_blue_concrete_powder", - "minecraft:yellow_concrete_powder", - "minecraft:lime_concrete_powder", - "minecraft:pink_concrete_powder", - "minecraft:gray_concrete_powder", - "minecraft:light_gray_concrete_powder", - "minecraft:cyan_concrete_powder", - "minecraft:purple_concrete_powder", - "minecraft:blue_concrete_powder", - "minecraft:brown_concrete_powder", - "minecraft:green_concrete_powder", - "minecraft:red_concrete_powder", - "minecraft:black_concrete_powder" - ] -} diff --git a/src/main/resources/data/c/tags/blocks/glass_blocks.json b/src/main/resources/data/c/tags/blocks/glass_blocks.json deleted file mode 100644 index f55e9719..00000000 --- a/src/main/resources/data/c/tags/blocks/glass_blocks.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:glass", - "minecraft:white_stained_glass", - "minecraft:orange_stained_glass", - "minecraft:magenta_stained_glass", - "minecraft:light_blue_stained_glass", - "minecraft:yellow_stained_glass", - "minecraft:lime_stained_glass", - "minecraft:pink_stained_glass", - "minecraft:gray_stained_glass", - "minecraft:light_gray_stained_glass", - "minecraft:cyan_stained_glass", - "minecraft:purple_stained_glass", - "minecraft:blue_stained_glass", - "minecraft:brown_stained_glass", - "minecraft:green_stained_glass", - "minecraft:red_stained_glass", - "minecraft:black_stained_glass", - { "id": "#c:glass", "required": false }, - { "id": "#c:glass_blocks", "required": false } - ] -} diff --git a/src/main/resources/data/c/tags/blocks/glass_panes.json b/src/main/resources/data/c/tags/blocks/glass_panes.json deleted file mode 100644 index ff9176f7..00000000 --- a/src/main/resources/data/c/tags/blocks/glass_panes.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:glass_pane", - "minecraft:white_stained_glass_pane", - "minecraft:orange_stained_glass_pane", - "minecraft:magenta_stained_glass_pane", - "minecraft:light_blue_stained_glass_pane", - "minecraft:yellow_stained_glass_pane", - "minecraft:lime_stained_glass_pane", - "minecraft:pink_stained_glass_pane", - "minecraft:gray_stained_glass_pane", - "minecraft:light_gray_stained_glass_pane", - "minecraft:cyan_stained_glass_pane", - "minecraft:purple_stained_glass_pane", - "minecraft:blue_stained_glass_pane", - "minecraft:brown_stained_glass_pane", - "minecraft:green_stained_glass_pane", - "minecraft:red_stained_glass_pane", - "minecraft:black_stained_glass_pane" - ] -} diff --git a/src/main/resources/data/c/tags/blocks/ores.json b/src/main/resources/data/c/tags/blocks/ores.json deleted file mode 100644 index 1a53e7a3..00000000 --- a/src/main/resources/data/c/tags/blocks/ores.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:coal_ore", - "minecraft:iron_ore", - "minecraft:gold_ore", - "minecraft:emerald_ore", - "minecraft:lapis_ore", - "minecraft:copper_ore", - "minecraft:diamond_ore", - "minecraft:nether_gold_ore", - "minecraft:nether_quartz_ore", - { "id": "#c:iron_ores", "required": false }, - { "id": "#c:gold_ores", "required": false }, - { "id": "#c:diamond_ores", "required": false }, - { "id": "#c:emerald_ores", "required": false }, - { "id": "#c:copper_ores", "required": false }, - { "id": "#c:quartz_ores", "required": false }, - { "id": "#c:lapis_ores", "required": false }, - { "id": "#c:aluminium_ores", "required": false }, - { "id": "#c:methyst_ores", "required": false }, - { "id": "#c:antimony_ores", "required": false }, - { "id": "#c:aquarium_ores", "required": false }, - { "id": "#c:asterite_ores", "required": false }, - { "id": "#c:banglum_ores", "required": false }, - { "id": "#c:bauxite_ores", "required": false }, - { "id": "#c:carmot_ores", "required": false }, - { "id": "#c:certus_quartz_ores", "required": false }, - { "id": "#c:cinnabar_ores", "required": false }, - { "id": "#c:cobalt_ores", "required": false }, - { "id": "#c:galaxium_ores", "required": false }, - { "id": "#c:galena_ores", "required": false }, - { "id": "#c:iridium_ores", "required": false }, - { "id": "#c:kyber_ores", "required": false }, - { "id": "#c:lunum_ores", "required": false }, - { "id": "#c:lutetium_ores", "required": false }, - { "id": "#c:menganese_ores", "required": false }, - { "id": "#c:metite_ores", "required": false }, - { "id": "#c:midas_gold_ores", "required": false }, - { "id": "#c:moon_lunum_ores", "required": false }, - { "id": "#c:mozanite_ores", "required": false }, - { "id": "#c:mythril_ores", "required": false }, - { "id": "#c:nickle_ores", "required": false }, - { "id": "#c:nikolite_ores", "required": false }, - { "id": "#c:orichalcum_ores", "required": false }, - { "id": "#c:osmium_ores", "required": false }, - { "id": "#c:palladium_ores", "required": false }, - { "id": "#c:peridot_ores", "required": false }, - { "id": "#c:platinum_ores", "required": false }, - { "id": "#c:plutonium_blocks", "required": false }, - { "id": "#c:prometheum_ores", "required": false }, - { "id": "#c:pyrite_ores", "required": false }, - { "id": "#c:quadrillium_ores", "required": false }, - { "id": "#c:ruby_ores", "required": false }, - { "id": "#c:runite_ores", "required": false }, - { "id": "#c:sapphire_ores", "required": false }, - { "id": "#c:sheldonite_ores", "required": false }, - { "id": "#c:silver_ores", "required": false }, - { "id": "#c:sodalite_ores", "required": false }, - { "id": "#c:sphalerite_ores", "required": false }, - { "id": "#c:starrite_ores", "required": false }, - { "id": "#c:stellum_ores", "required": false }, - { "id": "#c:stormyx_ores", "required": false }, - { "id": "#c:sulfur_ores", "required": false }, - { "id": "#c:tantalite_ores", "required": false }, - { "id": "#c:tin_ore", "required": false }, - { "id": "#c:tin_ores", "required": false }, - { "id": "#c:titanium_ores", "required": false }, - { "id": "#c:topaz_ores", "required": false }, - { "id": "#c:truesilver_ores", "required": false }, - { "id": "#c:tungsten_ores", "required": false }, - { "id": "#c:unobtainium_ores", "required": false }, - { "id": "#c:ur_ores", "required": false }, - { "id": "#c:uranium_ores", "required": false }, - { "id": "#c:vermiculite_ores", "required": false }, - { "id": "#c:zinc_ores", "required": false } - ] -} diff --git a/src/main/resources/data/c/tags/items/concrete_powders.json b/src/main/resources/data/c/tags/items/concrete_powders.json deleted file mode 100644 index e3142856..00000000 --- a/src/main/resources/data/c/tags/items/concrete_powders.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:white_concrete_powder", - "minecraft:orange_concrete_powder", - "minecraft:magenta_concrete_powder", - "minecraft:light_blue_concrete_powder", - "minecraft:yellow_concrete_powder", - "minecraft:lime_concrete_powder", - "minecraft:pink_concrete_powder", - "minecraft:gray_concrete_powder", - "minecraft:light_gray_concrete_powder", - "minecraft:cyan_concrete_powder", - "minecraft:purple_concrete_powder", - "minecraft:blue_concrete_powder", - "minecraft:brown_concrete_powder", - "minecraft:green_concrete_powder", - "minecraft:red_concrete_powder", - "minecraft:black_concrete_powder" - ] -} diff --git a/src/main/resources/data/unicopia/tags/damage_type/breaks_sunglasses.json b/src/main/resources/data/unicopia/tags/damage_type/breaks_sunglasses.json deleted file mode 100644 index 3c832cc1..00000000 --- a/src/main/resources/data/unicopia/tags/damage_type/breaks_sunglasses.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:bat_screech", - "unicopia:rainboom" - ] -} diff --git a/src/main/resources/data/unicopia/tags/damage_type/from_horseshoes.json b/src/main/resources/data/unicopia/tags/damage_type/from_horseshoes.json deleted file mode 100644 index 276d2073..00000000 --- a/src/main/resources/data/unicopia/tags/damage_type/from_horseshoes.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:horseshoe" - ] -} diff --git a/src/main/resources/data/unicopia/tags/damage_type/from_rocks.json b/src/main/resources/data/unicopia/tags/damage_type/from_rocks.json deleted file mode 100644 index 9ab866dd..00000000 --- a/src/main/resources/data/unicopia/tags/damage_type/from_rocks.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:rock" - ] -} diff --git a/src/main/resources/data/unicopia/tags/damage_type/spellbook_immune_to.json b/src/main/resources/data/unicopia/tags/damage_type/spellbook_immune_to.json deleted file mode 100644 index f270bd7e..00000000 --- a/src/main/resources/data/unicopia/tags/damage_type/spellbook_immune_to.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "replace": false, - "values": [ - "#minecraft:is_fall", - "#minecraft:is_freezing", - "#minecraft:is_lightning", - "#minecraft:is_projectile", - "unicopia:zap", - "unicopia:love_draining", - "unicopia:life_draining", - "unicopia:rainboom", - "unicopia:sun", - "unicopia:sunlight", - "unicopia:smash" - ] -} From ec9a12bdf9547a331abae8876c36d43cdfff26f6 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 31 Mar 2024 14:35:04 +0100 Subject: [PATCH 59/73] Clean up tags and fix some recipe unlock conditions --- .../com/minelittlepony/unicopia/Debug.java | 2 +- .../unicopia/UConventionalTags.java | 58 +++---- .../com/minelittlepony/unicopia/UTags.java | 150 ++++++++++-------- .../ability/EarthPonyGrowAbility.java | 2 +- .../ability/EarthPonyStompAbility.java | 4 +- .../unicopia/ability/ScreechAbility.java | 2 +- .../magic/spell/RainboomAbilitySpell.java | 2 +- .../magic/spell/effect/CatapultSpell.java | 2 +- .../spell/effect/TransformationSpell.java | 2 +- .../unicopia/block/PieBlock.java | 4 +- .../unicopia/client/render/PlayerPoser.java | 4 +- .../providers/UAdvancementsProvider.java | 14 +- .../UChestAdditionsLootTableProvider.java | 22 +-- .../recipe/BedSheetPatternRecipeBuilder.java | 2 +- .../providers/recipe/URecipeProvider.java | 43 +++-- .../providers/tag/UBlockTagProvider.java | 22 +-- .../providers/tag/UDamageTypeProvider.java | 8 +- .../providers/tag/UItemTagProvider.java | 94 +++++------ .../unicopia/entity/ItemImpl.java | 4 +- .../unicopia/entity/Living.java | 4 +- .../effect/SunBlindnessStatusEffect.java | 4 +- .../unicopia/entity/mob/SpellbookEntity.java | 2 +- .../unicopia/entity/mob/UTradeOffers.java | 4 +- .../unicopia/entity/player/PlayerPhysics.java | 4 +- .../unicopia/entity/player/Pony.java | 4 +- .../unicopia/item/CrystalHeartItem.java | 4 +- .../unicopia/item/PineappleItem.java | 2 +- .../unicopia/item/PolearmItem.java | 2 +- .../minelittlepony/unicopia/item/UItems.java | 2 +- .../unicopia/item/ZapAppleItem.java | 2 +- .../enchantment/GemFindingEnchantment.java | 2 +- .../item/group/ItemGroupRegistry.java | 6 +- .../unicopia/item/group/UItemGroups.java | 15 +- .../PhysicsBodyProjectileEntity.java | 8 +- 34 files changed, 267 insertions(+), 239 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/Debug.java b/src/main/java/com/minelittlepony/unicopia/Debug.java index 8cc8847e..2e3533df 100644 --- a/src/main/java/com/minelittlepony/unicopia/Debug.java +++ b/src/main/java/com/minelittlepony/unicopia/Debug.java @@ -51,7 +51,7 @@ public interface Debug { )).forEach((namespace, entries) -> { @SuppressWarnings("deprecation") var unregistered = entries.stream() - .filter(entry -> !entry.getValue().getRegistryEntry().isIn(UTags.HAS_NO_TRAITS) && SpellTraits.of(entry.getValue()).isEmpty()) + .filter(entry -> !entry.getValue().getRegistryEntry().isIn(UTags.Items.HAS_NO_TRAITS) && SpellTraits.of(entry.getValue()).isEmpty()) .map(entry -> { String id = entry.getKey().getValue().toString(); diff --git a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java index 603c900e..bb55a662 100644 --- a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java @@ -7,42 +7,42 @@ import net.minecraft.registry.tag.TagKey; import net.minecraft.util.Identifier; public interface UConventionalTags { - TagKey APPLES = item("apples"); - TagKey ACORNS = item("acorns"); - TagKey PINECONES = item("pinecones"); - TagKey PINEAPPLES = item("pineapples"); - TagKey BANANAS = item("bananas"); - TagKey STICKS = item("sticks"); - TagKey SEEDS = item("seeds"); - TagKey GRAIN = item("grain"); - TagKey NUTS = item("nuts"); - TagKey MUSHROOMS = item("mushrooms"); - TagKey MUFFINS = item("muffins"); - TagKey MANGOES = item("mangoes"); - TagKey OATMEALS = item("oatmeals"); - - TagKey FRUITS = item("fruits"); - - TagKey COOKED_FISH = item("cooked_fish"); - - TagKey CROPS_PEANUTS = item("crops/peanuts"); - TagKey TOOL_KNIVES = item("tools/knives"); - - static TagKey item(String name) { - return TagKey.of(RegistryKeys.ITEM, new Identifier("c", name)); - } - - static TagKey block(String name) { - return TagKey.of(RegistryKeys.BLOCK, new Identifier("c", name)); - } - interface Blocks { TagKey CONCRETE_POWDERS = block("concrete_powders"); TagKey CONCRETES = block("concretes"); + + private static TagKey block(String name) { + return TagKey.of(RegistryKeys.BLOCK, new Identifier("c", name)); + } } interface Items { TagKey CONCRETE_POWDERS = item("concrete_powders"); TagKey CONCRETES = item("concretes"); + + TagKey APPLES = item("apples"); + TagKey ACORNS = item("acorns"); + TagKey PINECONES = item("pinecones"); + TagKey PINEAPPLES = item("pineapples"); + TagKey BANANAS = item("bananas"); + TagKey STICKS = item("sticks"); + TagKey SEEDS = item("seeds"); + TagKey GRAIN = item("grain"); + TagKey NUTS = item("nuts"); + TagKey MUSHROOMS = item("mushrooms"); + TagKey MUFFINS = item("muffins"); + TagKey MANGOES = item("mangoes"); + TagKey OATMEALS = item("oatmeals"); + + TagKey FRUITS = item("fruits"); + + TagKey COOKED_FISH = item("cooked_fish"); + + TagKey CROPS_PEANUTS = item("crops/peanuts"); + TagKey TOOL_KNIVES = item("tools/knives"); + + private static TagKey item(String name) { + return TagKey.of(RegistryKeys.ITEM, new Identifier("c", name)); + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index 687d389d..82bd5417 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -11,58 +11,6 @@ import net.minecraft.util.Identifier; import net.minecraft.world.dimension.DimensionType; public interface UTags { - TagKey FRESH_APPLES = item("fresh_apples"); - - TagKey FALLS_SLOWLY = item("falls_slowly"); - TagKey PIES = item("pies"); - TagKey CAN_CUT_PIE = item("can_cut_pie"); - - TagKey MAGIC_FEATHERS = item("magic_feathers"); - - TagKey SHADES = item("shades"); - TagKey CHANGELING_EDIBLE = item("food_types/changeling_edible"); - TagKey SPOOKED_MOB_DROPS = item("spooked_mob_drops"); - TagKey HAS_NO_TRAITS = item("has_no_traits"); - TagKey IS_DELIVERED_AGGRESSIVELY = item("is_delivered_aggressively"); - TagKey FLOATS_ON_CLOUDS = item("floats_on_clouds"); - TagKey COOLS_OFF_KIRINS = item("cools_off_kirins"); - TagKey LOOT_BUG_HIGH_VALUE_DROPS = item("loot_bug_high_value_drops"); - - TagKey SHELLS = item("food_types/shells"); - - TagKey POLEARMS = item("polearms"); - TagKey HORSE_SHOES = item("horse_shoes"); - TagKey APPLE_SEEDS = item("apple_seeds"); - - TagKey BASKETS = item("baskets"); - TagKey BADGES = item("badges"); - TagKey WOOL_BED_SHEETS = item("wool_bed_sheets"); - TagKey BED_SHEETS = item("bed_sheets"); - TagKey CLOUD_JARS = item("cloud_jars"); - - TagKey FRAGILE = block("fragile"); - TagKey INTERESTING = block("interesting"); - TagKey CATAPULT_IMMUNE = block("catapult_immune"); - TagKey JARS = block("jars"); - - TagKey CRYSTAL_HEART_BASE = block("crystal_heart_base"); - TagKey CRYSTAL_HEART_ORNAMENT = block("crystal_heart_ornament"); - TagKey UNAFFECTED_BY_GROW_ABILITY = block("unaffected_by_grow_ability"); - TagKey KICKS_UP_DUST = block("kicks_up_dust"); - - TagKey POLEARM_MINEABLE = block("mineable/polearm"); - - TagKey> TRANSFORMABLE_ENTITIES = entity("transformable"); - - TagKey PINEAPPLE_EFFECTS = effect("pineapple_effects"); - - TagKey BREAKS_SUNGLASSES = damage("breaks_sunglasses"); - TagKey SPELLBOOK_IMMUNE_TO = damage("spellbook_immune_to"); - TagKey FROM_ROCKS = damage("from_rocks"); - TagKey FROM_HORSESHOES = damage("from_horseshoes"); - - TagKey HAS_NO_ATMOSPHERE = dimension("has_no_atmosphere"); - interface Items { TagKey ZAP_LOGS = item("zap_logs"); TagKey WAXED_ZAP_LOGS = item("waxed_zap_logs"); @@ -72,6 +20,47 @@ public interface UTags { TagKey CLOUD_STAIRS = item("cloud_stairs"); TagKey CLOUD_BLOCKS = item("cloud_blocks"); TagKey CHITIN_BLOCKS = item("chitin_blocks"); + + TagKey FRESH_APPLES = item("fresh_apples"); + + TagKey FALLS_SLOWLY = item("falls_slowly"); + TagKey PIES = item("pies"); + TagKey CAN_CUT_PIE = item("can_cut_pie"); + + TagKey MAGIC_FEATHERS = item("magic_feathers"); + + TagKey SHADES = item("shades"); + TagKey CHANGELING_EDIBLE = item("food_types/changeling_edible"); + TagKey SPOOKED_MOB_DROPS = item("spooked_mob_drops"); + TagKey HAS_NO_TRAITS = item("has_no_traits"); + TagKey IS_DELIVERED_AGGRESSIVELY = item("is_delivered_aggressively"); + TagKey FLOATS_ON_CLOUDS = item("floats_on_clouds"); + TagKey COOLS_OFF_KIRINS = item("cools_off_kirins"); + TagKey LOOT_BUG_HIGH_VALUE_DROPS = item("loot_bug_high_value_drops"); + + TagKey SHELLS = item("food_types/shells"); + + TagKey POLEARMS = item("polearms"); + TagKey HORSE_SHOES = item("horse_shoes"); + TagKey APPLE_SEEDS = item("apple_seeds"); + + TagKey BASKETS = item("baskets"); + TagKey BADGES = item("badges"); + TagKey WOOL_BED_SHEETS = item("wool_bed_sheets"); + TagKey BED_SHEETS = item("bed_sheets"); + TagKey CLOUD_JARS = item("cloud_jars"); + + TagKey GROUP_FORAGING = item("groups/foraging"); + TagKey GROUP_EARTH_PONY = item("groups/earth_pony"); + TagKey GROUP_UNICORN = item("groups/unicorn"); + TagKey GROUP_PEGASUS = item("groups/pegasus"); + TagKey GROUP_BAT_PONY = item("groups/bat_pony"); + TagKey GROUP_SEA_PONY = item("groups/sea_pony"); + TagKey GROUP_CHANGELING = item("groups/changeling"); + + private static TagKey item(String name) { + return TagKey.of(RegistryKeys.ITEM, Unicopia.id(name)); + } } interface Blocks { @@ -84,30 +73,57 @@ public interface UTags { TagKey CLOUD_BLOCKS = block("cloud_blocks"); TagKey CHITIN_BLOCKS = block("chitin_blocks"); + TagKey FRAGILE = block("fragile"); + TagKey INTERESTING = block("interesting"); + TagKey CATAPULT_IMMUNE = block("catapult_immune"); + TagKey JARS = block("jars"); + + TagKey CRYSTAL_HEART_BASE = block("crystal_heart_base"); + TagKey CRYSTAL_HEART_ORNAMENT = block("crystal_heart_ornament"); + TagKey UNAFFECTED_BY_GROW_ABILITY = block("unaffected_by_grow_ability"); + TagKey KICKS_UP_DUST = block("kicks_up_dust"); + + TagKey POLEARM_MINEABLE = block("mineable/polearm"); + TagKey BUTTERFLIES_SPAWNABLE_ON = block("butterflies_spawn_on"); + + private static TagKey block(String name) { + return TagKey.of(RegistryKeys.BLOCK, Unicopia.id(name)); + } } - static TagKey item(String name) { - return TagKey.of(RegistryKeys.ITEM, Unicopia.id(name)); + interface Entities { + TagKey> TRANSFORMABLE = entity("transformable"); + + private static TagKey> entity(String name) { + return TagKey.of(RegistryKeys.ENTITY_TYPE, Unicopia.id(name)); + } } - static TagKey block(String name) { - return TagKey.of(RegistryKeys.BLOCK, Unicopia.id(name)); + interface DamageTypes { + TagKey BREAKS_SUNGLASSES = damage("breaks_sunglasses"); + TagKey SPELLBOOK_IMMUNE_TO = damage("spellbook_immune_to"); + TagKey FROM_ROCKS = damage("from_rocks"); + TagKey FROM_HORSESHOES = damage("from_horseshoes"); + + private static TagKey damage(String name) { + return TagKey.of(RegistryKeys.DAMAGE_TYPE, Unicopia.id(name)); + } } - static TagKey> entity(String name) { - return TagKey.of(RegistryKeys.ENTITY_TYPE, Unicopia.id(name)); + interface DimensionTypes { + TagKey HAS_NO_ATMOSPHERE = dimension("has_no_atmosphere"); + + private static TagKey dimension(String name) { + return TagKey.of(RegistryKeys.DIMENSION_TYPE, new Identifier("c", name)); + } } - static TagKey effect(String name) { - return TagKey.of(RegistryKeys.STATUS_EFFECT, Unicopia.id(name)); - } + interface StatusEffects { + TagKey PINEAPPLE_EFFECTS = effect("pineapple_effects"); - static TagKey damage(String name) { - return TagKey.of(RegistryKeys.DAMAGE_TYPE, Unicopia.id(name)); - } - - static TagKey dimension(String name) { - return TagKey.of(RegistryKeys.DIMENSION_TYPE, new Identifier("c", name)); + private static TagKey effect(String name) { + return TagKey.of(RegistryKeys.STATUS_EFFECT, Unicopia.id(name)); + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java index 61ab54d5..75cd435f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java @@ -108,7 +108,7 @@ public class EarthPonyGrowAbility implements Ability { } } - if (w.getBlockState(pos).isIn(UTags.UNAFFECTED_BY_GROW_ABILITY)) { + if (w.getBlockState(pos).isIn(UTags.Blocks.UNAFFECTED_BY_GROW_ABILITY)) { return 0; } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java index b702400f..285266c9 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyStompAbility.java @@ -162,7 +162,7 @@ public class EarthPonyStompAbility implements Ability { ParticleUtils.spawnParticle(player.getWorld(), UParticles.GROUND_POUND, player.getX(), player.getY() - 1, player.getZ(), 0, 0, 0); BlockState steppingState = player.getSteppingBlockState(); - if (steppingState.isIn(UTags.KICKS_UP_DUST)) { + if (steppingState.isIn(UTags.Blocks.KICKS_UP_DUST)) { ParticleUtils.spawnParticle(player.getWorld(), new BlockStateParticleEffect(UParticles.DUST_CLOUD, steppingState), player.getBlockPos().down().toCenterPos(), Vec3d.ZERO); } @@ -227,7 +227,7 @@ public class EarthPonyStompAbility implements Ability { w.syncWorldEvent(WorldEvents.BLOCK_BROKEN, pos, Block.getRawIdFromState(state)); } - if (state.isIn(UTags.KICKS_UP_DUST)) { + if (state.isIn(UTags.Blocks.KICKS_UP_DUST)) { if (w.random.nextInt(4) == 0 && w.isAir(pos.up()) && w.getFluidState(pos.up()).isEmpty()) { ParticleUtils.spawnParticle(w, new BlockStateParticleEffect(UParticles.DUST_CLOUD, state), pos.up().toCenterPos(), VecHelper.supply(() -> w.random.nextTriangular(0, 0.1F))); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/ScreechAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/ScreechAbility.java index ac244ea0..60319ba1 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/ScreechAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/ScreechAbility.java @@ -110,7 +110,7 @@ public class ScreechAbility implements Ability { if (living.getWorld().random.nextInt(MOB_SPOOK_PROBABILITY) == 0) { - RegistryUtils.pickRandom(living.getWorld(), UTags.SPOOKED_MOB_DROPS).ifPresent(drop -> { + RegistryUtils.pickRandom(living.getWorld(), UTags.Items.SPOOKED_MOB_DROPS).ifPresent(drop -> { living.dropStack(drop.getDefaultStack()); living.playSound(USounds.Vanilla.ENTITY_ITEM_PICKUP, 1, 0.1F); UCriteria.SPOOK_MOB.trigger(player.asEntity()); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RainboomAbilitySpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RainboomAbilitySpell.java index a3339212..13445ea2 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RainboomAbilitySpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RainboomAbilitySpell.java @@ -64,7 +64,7 @@ public class RainboomAbilitySpell extends AbstractSpell { }); EFFECT_RANGE.translate(source.getOrigin()).getBlockPositions().forEach(pos -> { BlockState state = source.asWorld().getBlockState(pos); - if (state.isIn(UTags.FRAGILE) && source.canModifyAt(pos, ModificationType.PHYSICAL)) { + if (state.isIn(UTags.Blocks.FRAGILE) && source.canModifyAt(pos, ModificationType.PHYSICAL)) { source.asWorld().breakBlock(pos, true); } }); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CatapultSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CatapultSpell.java index ec5cbf3e..ce440570 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CatapultSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/CatapultSpell.java @@ -86,7 +86,7 @@ public class CatapultSpell extends AbstractSpell implements ProjectileDelegate.B } BlockState state = world.getBlockState(bpos); - if (state.isIn(UTags.CATAPULT_IMMUNE)) { + if (state.isIn(UTags.Blocks.CATAPULT_IMMUNE)) { return; } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TransformationSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TransformationSpell.java index e26152f0..4d507d1d 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TransformationSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/TransformationSpell.java @@ -66,7 +66,7 @@ public class TransformationSpell extends AbstractSpell implements ProjectileDele @SuppressWarnings("unchecked") private Optional> pickType(EntityType except, World world) { - Set> options = RegistryUtils.valuesForTag(world, UTags.TRANSFORMABLE_ENTITIES).collect(Collectors.toSet()); + Set> options = RegistryUtils.valuesForTag(world, UTags.Entities.TRANSFORMABLE).collect(Collectors.toSet()); if (except.getSpawnGroup() == SpawnGroup.MONSTER) { options.removeIf(t -> t.getSpawnGroup() == SpawnGroup.MONSTER); } else { diff --git a/src/main/java/com/minelittlepony/unicopia/block/PieBlock.java b/src/main/java/com/minelittlepony/unicopia/block/PieBlock.java index b7c2be5b..33c85df0 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/PieBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/PieBlock.java @@ -71,7 +71,7 @@ public class PieBlock extends Block implements Waterloggable { if (world.isClient) { - if (itemStack.isIn(UTags.CAN_CUT_PIE)) { + if (itemStack.isIn(UTags.Items.CAN_CUT_PIE)) { return ActionResult.SUCCESS; } @@ -84,7 +84,7 @@ public class PieBlock extends Block implements Waterloggable { } } - if (itemStack.isIn(UTags.CAN_CUT_PIE)) { + if (itemStack.isIn(UTags.Items.CAN_CUT_PIE)) { SoundEmitter.playSoundAt(player, USounds.BLOCK_PIE_SLICE, SoundCategory.NEUTRAL, 1, 1); removeSlice(world, pos, state, player); itemStack.damage(1, player, p -> p.sendToolBreakStatus(hand)); diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/PlayerPoser.java b/src/main/java/com/minelittlepony/unicopia/client/render/PlayerPoser.java index ec3b17bb..2402dfab 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/PlayerPoser.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/PlayerPoser.java @@ -52,7 +52,7 @@ public class PlayerPoser { float pitchChange = -0.5F; float yawChange = 0.8F; - if (player.getStackInHand(rightHand).isIn(UTags.POLEARMS) && (!ponyRace.isEquine() || model.rightArm.pitch != 0)) { + if (player.getStackInHand(rightHand).isIn(UTags.Items.POLEARMS) && (!ponyRace.isEquine() || model.rightArm.pitch != 0)) { model.rightArm.pitch += pitchChange; model.rightArm.yaw += yawChange; if (player.handSwingTicks > 0 && rightHand == Hand.MAIN_HAND) { @@ -61,7 +61,7 @@ public class PlayerPoser { } } - if (player.getStackInHand(leftHand).isIn(UTags.POLEARMS) && (!ponyRace.isEquine() || model.leftArm.pitch != 0)) { + if (player.getStackInHand(leftHand).isIn(UTags.Items.POLEARMS) && (!ponyRace.isEquine() || model.leftArm.pitch != 0)) { model.leftArm.pitch += pitchChange; model.leftArm.yaw -= yawChange; if (player.handSwingTicks > 0 && leftHand == Hand.MAIN_HAND) { diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java index e0c2c349..a46d1306 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java @@ -73,27 +73,27 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { private void generateEarthTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { parent.child(UItems.ROCK).criterion("has_rock", hasItems(UItems.ROCK)).build(consumer, "born_on_a_rock_farm").children(p -> { - p.child(UItems.PEBBLES).criterion("killed_entity_with_rock", killWithItems(UTags.FROM_ROCKS)).build(consumer, "sticks_and_stones"); + p.child(UItems.PEBBLES).criterion("killed_entity_with_rock", killWithItems(UTags.DamageTypes.FROM_ROCKS)).build(consumer, "sticks_and_stones"); p.child(UItems.WEIRD_ROCK).hidden().criterion("has_rock", hasItems(UItems.WEIRD_ROCK)).build(consumer, "thats_unusual"); }); parent.child(UItems.OATS).criterion("has_oats", hasItems(UItems.OATS)).build(consumer, "oats_so_easy"); parent.child(Items.HAY_BLOCK).criterion("eat_hay", ConsumeItemCriterion.Conditions.item(Items.HAY_BLOCK)).build(consumer, "what_the_hay"); - parent.child(UItems.COPPER_HORSE_SHOE).criterion("has_horseshoe", hasItems(UTags.HORSE_SHOES)).build(consumer, "blacksmith").children(p -> { + parent.child(UItems.COPPER_HORSE_SHOE).criterion("has_horseshoe", hasItems(UTags.Items.HORSE_SHOES)).build(consumer, "blacksmith").children(p -> { p.child(UItems.IRON_HORSE_SHOE).criterion("has_iron_horseshoe", hasItems(UItems.IRON_HORSE_SHOE)).build(consumer, "change_of_shoes") .child(UItems.GOLDEN_HORSE_SHOE).criterion("has_gold_horseshoe", hasItems(UItems.GOLDEN_HORSE_SHOE)).build(consumer, "fashionably_expensive") .child(UItems.NETHERITE_HORSE_SHOE).criterion("has_netherite_horseshoe", hasItems(UItems.NETHERITE_HORSE_SHOE)).build(consumer, "overkill"); - p.child(UItems.IRON_HORSE_SHOE).hidden().frame(AdvancementFrame.CHALLENGE).criterion("killed_entity_with_horseshoe", killWithItems(UTags.FROM_HORSESHOES)).build(consumer, "dead_ringer"); + p.child(UItems.IRON_HORSE_SHOE).hidden().frame(AdvancementFrame.CHALLENGE).criterion("killed_entity_with_horseshoe", killWithItems(UTags.DamageTypes.FROM_HORSESHOES)).build(consumer, "dead_ringer"); }); parent.child(UItems.PINECONE).frame(AdvancementFrame.CHALLENGE).criterion("eat_pinecone", ConsumeItemCriterion.Conditions.item(UItems.PINECONE)).build(consumer, "eat_pinecone"); - parent.child(UItems.OAK_BASKET).doNotAnnounce().criterion("has_basket", hasItems(UTags.BASKETS)).build(consumer, "basket_case") + parent.child(UItems.OAK_BASKET).doNotAnnounce().criterion("has_basket", hasItems(UTags.Items.BASKETS)).build(consumer, "basket_case") .child(Items.LANTERN).criterion("construct_balloon", CustomEventCriterion.create("construct_balloon")).build(consumer, "aeronaut") .child(UItems.GIANT_BALLOON).announce().frame(AdvancementFrame.CHALLENGE).criterion("ride_balloon", CustomEventCriterion.create("ride_balloon")).build(consumer, "travelling_in_style"); parent.child(UItems.MUFFIN).hidden().criterion("has_muffin", hasItems(UItems.MUFFIN)).build(consumer, "baked_bads"); parent.child(UItems.HORSE_SHOE_FRIES).criterion("has_horse_shoe_fries", hasItems(UItems.HORSE_SHOE_FRIES)).build(consumer, "lucky"); parent.child(UItems.TOAST).criterion("has_toast", hasItems(UItems.TOAST)).build(consumer, "toast") .child(UItems.BURNED_TOAST).hidden().criterion("has_burned_toast", hasItems(UItems.BURNED_TOAST)).build(consumer, "burn_toast"); - parent.child(UItems.GREEN_APPLE).criterion("has_apple", hasItems(UTags.FRESH_APPLES)).build(consumer, "apple_route").children(p -> { + parent.child(UItems.GREEN_APPLE).criterion("has_apple", hasItems(UTags.Items.FRESH_APPLES)).build(consumer, "apple_route").children(p -> { p.child(UItems.SWEET_APPLE).criterion("has_all_apples", hasItems(Items.APPLE, UItems.GREEN_APPLE, UItems.SWEET_APPLE, UItems.SOUR_APPLE, UItems.ROTTEN_APPLE, UItems.ZAP_APPLE, UItems.COOKED_ZAP_APPLE, Items.GOLDEN_APPLE)).build(consumer, "sweet_apple_acres"); p.child(UItems.ZAP_BULB).criterion("has_zap_apple", hasItems(UItems.ZAP_APPLE)).build(consumer, "trick_apple").children(pp -> { pp.child(UItems.ZAP_APPLE).hidden().criterion("eat_trick_apple", CustomEventCriterion.createFlying("eat_trick_apple")).build(consumer, "eat_trick_apple"); @@ -110,7 +110,7 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { parent.child(Items.GLASS_PANE).criterion("break_window", CustomEventCriterion.createFlying("break_window")).rewards(AdvancementRewards.Builder.experience(10)).build(consumer, "rainbow_crash"); parent.child(UItems.PEGASUS_BADGE).criterion("fly_through_the_pain", CustomEventCriterion.createFlying("second_wind")).rewards(AdvancementRewards.Builder.experience(10)).build(consumer, "second_wind"); parent.child(UItems.EMPTY_JAR).criterion("has_empty_jar", hasItems(UItems.EMPTY_JAR)).build(consumer, "jar") - .child(UItems.RAIN_CLOUD_JAR).criterion("has_cloud_jar", hasItems(UTags.CLOUD_JARS)).rewards(AdvancementRewards.Builder.experience(55)).build(consumer, "gotcha"); + .child(UItems.RAIN_CLOUD_JAR).criterion("has_cloud_jar", hasItems(UTags.Items.CLOUD_JARS)).rewards(AdvancementRewards.Builder.experience(55)).build(consumer, "gotcha"); parent.child(UItems.LIGHTNING_JAR).frame(AdvancementFrame.CHALLENGE).criterion("lightning_strike", CustomEventCriterion.createFlying("lightning_strike")).rewards(AdvancementRewards.Builder.experience(30)).build(consumer, "mid_flight_interruption").children(p -> { p.child(UItems.LIGHTNING_JAR).hidden().frame(AdvancementFrame.CHALLENGE).apply(d -> applyLightningBugCriterions(d, RacePredicate.of(Set.of(Race.CHANGELING), Set.of()), 10, 90)).build(consumer, "lightning_bug"); p.child(UItems.LIGHTNING_JAR).hidden().frame(AdvancementFrame.CHALLENGE).apply(d -> applyLightningBugCriterions(d, RacePredicate.of(Set.of(), Set.of(Race.CHANGELING)), 10, 90)).build(consumer, "wonder_bolt"); @@ -255,7 +255,7 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { static CriterionConditions dingCelestia(Set includeTribes, Set excludeTribes) { return new SendViaDragonBreathScrollCriterion.Conditions( LootContextPredicate.EMPTY, - ItemPredicate.Builder.create().tag(UTags.IS_DELIVERED_AGGRESSIVELY).build(), false, + ItemPredicate.Builder.create().tag(UTags.Items.IS_DELIVERED_AGGRESSIVELY).build(), false, Optional.of("princess celestia"), TriState.FALSE, Optional.of("dings_on_celestias_head"), diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java index 72ad8a91..266c73a7 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java @@ -39,7 +39,7 @@ public class UChestAdditionsLootTableProvider extends SimpleFabricLootTableProvi .rolls(UniformLootNumberProvider.create(2, 4)) .with(ItemEntry.builder(UItems.GRYPHON_FEATHER).weight(10).apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 7)))) .with(ItemEntry.builder(UItems.GOLDEN_WING).weight(1).apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 2)))) - .with(TagEntry.expandBuilder(UTags.FRESH_APPLES).weight(1).apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(2, 5)))) + .with(TagEntry.expandBuilder(UTags.Items.FRESH_APPLES).weight(1).apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(2, 5)))) )); exporter.accept(LootTables.VILLAGE_FLETCHER_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(2, 4)) @@ -48,8 +48,8 @@ public class UChestAdditionsLootTableProvider extends SimpleFabricLootTableProvi )); exporter.accept(LootTables.VILLAGE_PLAINS_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(3, 4)) - .with(TagEntry.expandBuilder(UTags.FRESH_APPLES).weight(1)) - .with(TagEntry.expandBuilder(UTags.APPLE_SEEDS).weight(1)) + .with(TagEntry.expandBuilder(UTags.Items.FRESH_APPLES).weight(1)) + .with(TagEntry.expandBuilder(UTags.Items.APPLE_SEEDS).weight(1)) )); exporter.accept(LootTables.ANCIENT_CITY_CHEST, LootTable.builder().pool(LootPool.builder() @@ -59,26 +59,26 @@ public class UChestAdditionsLootTableProvider extends SimpleFabricLootTableProvi exporter.accept(LootTables.BURIED_TREASURE_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 4)) .with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1)) - .with(TagEntry.expandBuilder(UTags.item("food_types/shells")).weight(3)) + .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(3)) )); exporter.accept(LootTables.SHIPWRECK_SUPPLY_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 6)) - .with(TagEntry.expandBuilder(UTags.SHELLS).weight(3)) + .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(3)) )); exporter.accept(LootTables.SHIPWRECK_TREASURE_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 4)) .with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1)) - .with(TagEntry.expandBuilder(UTags.SHELLS).weight(3)) + .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(3)) )); exporter.accept(LootTables.UNDERWATER_RUIN_BIG_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 2)) .with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1)) .with(ItemEntry.builder(UItems.SHELLY).weight(4)) - .with(TagEntry.expandBuilder(UTags.SHELLS).weight(8)) + .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(8)) )); exporter.accept(LootTables.UNDERWATER_RUIN_SMALL_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 4)) - .with(TagEntry.expandBuilder(UTags.SHELLS).weight(1)) + .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(1)) )); exporter.accept(LootTables.DESERT_WELL_ARCHAEOLOGY, LootTable.builder().pool(LootPool.builder() @@ -89,7 +89,7 @@ public class UChestAdditionsLootTableProvider extends SimpleFabricLootTableProvi .with(ItemEntry.builder(UItems.ROCK_STEW).weight(1)) .with(ItemEntry.builder(UItems.PEBBLES).weight(1)) .with(ItemEntry.builder(UItems.SHELLY).weight(1)) - .with(TagEntry.expandBuilder(UTags.SHELLS).weight(1)) + .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(1)) .with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1)) )); exporter.accept(LootTables.TRAIL_RUINS_COMMON_ARCHAEOLOGY, LootTable.builder().pool(LootPool.builder() @@ -106,13 +106,13 @@ public class UChestAdditionsLootTableProvider extends SimpleFabricLootTableProvi )); exporter.accept(LootTables.OCEAN_RUIN_WARM_ARCHAEOLOGY, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 4)) - .with(TagEntry.expandBuilder(UTags.SHELLS).weight(1)) + .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(1)) .with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1)) )); exporter.accept(LootTables.FISHING_GAMEPLAY, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 4)) - .with(TagEntry.expandBuilder(UTags.SHELLS).weight(2)) + .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(2)) )); exporter.accept(LootTables.FISHING_JUNK_GAMEPLAY, LootTable.builder().pool(LootPool.builder() diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/BedSheetPatternRecipeBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/BedSheetPatternRecipeBuilder.java index 0cd69ce6..2e067830 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/BedSheetPatternRecipeBuilder.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/BedSheetPatternRecipeBuilder.java @@ -73,7 +73,7 @@ public class BedSheetPatternRecipeBuilder { private static void offerBedSheetConversionRecipe(Consumer exporter, ItemConvertible output, Stream wools) { var builder = ShapelessRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output) - .input(UTags.WOOL_BED_SHEETS).criterion("has_bed_sheet", RecipeProvider.conditionsFromTag(UTags.WOOL_BED_SHEETS)); + .input(UTags.Items.WOOL_BED_SHEETS).criterion("has_bed_sheet", RecipeProvider.conditionsFromTag(UTags.Items.WOOL_BED_SHEETS)); wools.forEach(builder::input); builder .group("bed_sheet") diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index 3a95e32e..3e27692b 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -80,8 +80,19 @@ public class URecipeProvider extends FabricRecipeProvider { } private void generateVanillaRecipeExtensions(Consumer exporter) { - ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, Items.WRITABLE_BOOK).input(Items.BOOK).input(Items.INK_SAC).input(UTags.MAGIC_FEATHERS).criterion("has_book", conditionsFromItem(Items.BOOK)).offerTo(exporter); - ShapedRecipeJsonBuilder.create(RecipeCategory.COMBAT, Items.ARROW, 4).input('#', UConventionalTags.STICKS).input('X', Items.FLINT).input('Y', UTags.MAGIC_FEATHERS).pattern("X").pattern("#").pattern("Y").criterion("has_feather", conditionsFromTag(UTags.MAGIC_FEATHERS)).criterion("has_flint", conditionsFromItem(Items.FLINT)).offerTo(exporter); + ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, Items.WRITABLE_BOOK) + .input(Items.BOOK).criterion("has_book", conditionsFromItem(Items.BOOK)) + .input(Items.INK_SAC) + .input(UTags.Items.MAGIC_FEATHERS) + .offerTo(exporter); + ShapedRecipeJsonBuilder.create(RecipeCategory.COMBAT, Items.ARROW, 4) + .input('#', UConventionalTags.Items.STICKS) + .input('X', Items.FLINT).criterion("has_flint", conditionsFromItem(Items.FLINT)) + .input('Y', UTags.Items.MAGIC_FEATHERS).criterion("has_feather", conditionsFromTag(UTags.Items.MAGIC_FEATHERS)) + .pattern("X") + .pattern("#") + .pattern("Y") + .offerTo(exporter); } private void offerJarRecipes(Consumer exporter) { @@ -97,7 +108,7 @@ public class URecipeProvider extends FabricRecipeProvider { } private void offerCloudRecipes(Consumer exporter) { - offerShapelessRecipe(exporter, UItems.CLOUD_LUMP, UTags.CLOUD_JARS, "cloud", 4); + offerShapelessRecipe(exporter, UItems.CLOUD_LUMP, UTags.Items.CLOUD_JARS, "cloud", 4); generateFamily(exporter, UBlockFamilies.CLOUD); offer2x3Recipe(exporter, UBlocks.CLOUD_PILLAR, UBlocks.CLOUD, "pillar"); offer2x2CompactingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD, UItems.CLOUD_LUMP); @@ -200,7 +211,7 @@ public class URecipeProvider extends FabricRecipeProvider { // magic staff ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.MAGIC_STAFF) .input('*', UItems.GEMSTONE).criterion("has_gemstone", conditionsFromItem(UItems.GEMSTONE)) - .input('#', UConventionalTags.STICKS).criterion("has_stick", conditionsFromTag(UConventionalTags.STICKS)) + .input('#', UConventionalTags.Items.STICKS).criterion("has_stick", conditionsFromTag(UConventionalTags.Items.STICKS)) .pattern(" *") .pattern(" # ") .pattern("# ") @@ -217,7 +228,7 @@ public class URecipeProvider extends FabricRecipeProvider { // pegasus amulet ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.GOLDEN_FEATHER) .input('*', Items.GOLD_NUGGET).criterion("has_nugget", conditionsFromItem(Items.GOLD_NUGGET)) - .input('#', UTags.MAGIC_FEATHERS).criterion("has_feather", conditionsFromTag(UTags.MAGIC_FEATHERS)) + .input('#', UTags.Items.MAGIC_FEATHERS).criterion("has_feather", conditionsFromTag(UTags.Items.MAGIC_FEATHERS)) .pattern("***") .pattern("*#*") .pattern("***") @@ -232,7 +243,7 @@ public class URecipeProvider extends FabricRecipeProvider { // friendship bracelet ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.FRIENDSHIP_BRACELET) .input('*', Items.STRING) - .input('#', Items.LEATHER).criterion(hasItem(Items.LEATHER), conditionsFromTag(UTags.MAGIC_FEATHERS)) + .input('#', Items.LEATHER).criterion(hasItem(Items.LEATHER), conditionsFromItem(Items.LEATHER)) .pattern("*#*") .pattern("# #") .pattern("*#*") @@ -242,7 +253,7 @@ public class URecipeProvider extends FabricRecipeProvider { // meadowbrook's staff ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.MEADOWBROOKS_STAFF) .input('*', UItems.GEMSTONE).criterion(hasItem(UItems.GEMSTONE), conditionsFromItem(UItems.GEMSTONE)) - .input('/', UConventionalTags.STICKS).criterion(hasItem(Items.STICK), conditionsFromTag(UConventionalTags.STICKS)) + .input('/', UConventionalTags.Items.STICKS).criterion(hasItem(Items.STICK), conditionsFromTag(UConventionalTags.Items.STICKS)) .pattern(" *") .pattern(" / ") .pattern("/ ") @@ -310,7 +321,7 @@ public class URecipeProvider extends FabricRecipeProvider { offerShapelessRecipe(exporter, UItems.SOUR_APPLE_SEEDS, UItems.SOUR_APPLE, "seeds", 3); offerShapelessRecipe(exporter, UItems.GREEN_APPLE_SEEDS, UItems.GREEN_APPLE, "seeds", 3); offerShapelessRecipe(exporter, UItems.GOLDEN_OAK_SEEDS, Items.GOLDEN_APPLE, "seeds", 1); - offerPieRecipe(exporter, UItems.APPLE_PIE, UItems.APPLE_PIE_SLICE, Items.WHEAT, UTags.FRESH_APPLES); + offerPieRecipe(exporter, UItems.APPLE_PIE, UItems.APPLE_PIE_SLICE, Items.WHEAT, UTags.Items.FRESH_APPLES); ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.ROCK_STEW) .input(UItems.ROCK, 3).criterion(hasItem(UItems.ROCK), conditionsFromItem(UItems.ROCK)) @@ -344,20 +355,20 @@ public class URecipeProvider extends FabricRecipeProvider { .pattern("###") .offerTo(exporter, convertBetween(UItems.OATS, Items.WHEAT)); ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.JUICE) - .input(Ingredient.fromTag(UTags.FRESH_APPLES), 6).criterion(hasItem(Items.APPLE), conditionsFromTag(UTags.FRESH_APPLES)) + .input(Ingredient.fromTag(UTags.Items.FRESH_APPLES), 6).criterion(hasItem(Items.APPLE), conditionsFromTag(UTags.Items.FRESH_APPLES)) .input(Items.GLASS_BOTTLE) .group("juice") .offerTo(exporter); appendIngredients(ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.MUFFIN), Items.SUGAR, Items.EGG, Items.POTATO, UItems.JUICE, UItems.WHEAT_WORMS).offerTo(exporter); ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.MUG) .input('*', Items.IRON_NUGGET).criterion(hasItem(Items.IRON_NUGGET), conditionsFromItem(Items.IRON_NUGGET)) - .input('#', UConventionalTags.STICKS).criterion(hasItem(Items.STICK), conditionsFromTag(UConventionalTags.STICKS)) + .input('#', UConventionalTags.Items.STICKS).criterion(hasItem(Items.STICK), conditionsFromTag(UConventionalTags.Items.STICKS)) .pattern("# #") .pattern("* *") .pattern(" # ") .offerTo(exporter); appendIngredients(ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.CIDER), UItems.BURNED_JUICE, UItems.MUG) - .input(Ingredient.fromTag(UTags.FRESH_APPLES)).criterion(hasItem(Items.APPLE), conditionsFromTag(UTags.FRESH_APPLES)) + .input(Ingredient.fromTag(UTags.Items.FRESH_APPLES)).criterion(hasItem(Items.APPLE), conditionsFromTag(UTags.Items.FRESH_APPLES)) .offerTo(exporter); ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.HAY_FRIES) @@ -410,8 +421,8 @@ public class URecipeProvider extends FabricRecipeProvider { .input(UItems.TOAST, 8) .offerTo(exporter); ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.CANDIED_APPLE) - .input(UConventionalTags.STICKS) - .input(UTags.FRESH_APPLES).criterion(hasItem(UItems.ZAP_APPLE_JAM_JAR), conditionsFromItem(UItems.ZAP_APPLE_JAM_JAR)) + .input(UConventionalTags.Items.STICKS) + .input(UTags.Items.FRESH_APPLES).criterion(hasItem(Items.APPLE), conditionsFromTag(UTags.Items.FRESH_APPLES)) .input(Items.SUGAR, 4) .offerTo(exporter); @@ -445,7 +456,7 @@ public class URecipeProvider extends FabricRecipeProvider { .pattern(" C ") .offerTo(exporter); ShapedRecipeJsonBuilder.create(RecipeCategory.COMBAT, UItems.PEARL_NECKLACE) - .input('#', UTags.SHELLS).criterion("has_shell", conditionsFromTag(UTags.SHELLS)) + .input('#', UTags.Items.SHELLS).criterion("has_shell", conditionsFromTag(UTags.Items.SHELLS)) .input('~', Items.STRING) .pattern("# #") .pattern("# #") @@ -492,7 +503,7 @@ public class URecipeProvider extends FabricRecipeProvider { .pattern("#*") .offerTo(exporter, convertBetween(Items.DIRT, UItems.WHEAT_WORMS)); - offerShapelessRecipe(exporter, Items.BONE_MEAL, UTags.SHELLS, "bonemeal", 3); + offerShapelessRecipe(exporter, Items.BONE_MEAL, UTags.Items.SHELLS, "bonemeal", 3); // pegasus feathers for non pegasi ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.PEGASUS_FEATHER) @@ -578,7 +589,7 @@ public class URecipeProvider extends FabricRecipeProvider { public static void offerPolearmRecipe(Consumer exporter, ItemConvertible output, Either> input) { CraftingMaterialHelper .input(ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, output), 'o', input).criterion(CraftingMaterialHelper.hasEither(input), CraftingMaterialHelper.conditionsFromEither(input)) - .input('#', UConventionalTags.STICKS) + .input('#', UConventionalTags.Items.STICKS) .pattern(" o") .pattern(" # ") .pattern("# ") diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java index f4c583a4..6198be9f 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java @@ -44,14 +44,14 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { UBlocks.GOLDEN_OAK_SPROUT }; - getOrCreateTagBuilder(UTags.CATAPULT_IMMUNE).add(Blocks.BEDROCK).forceAddTag(BlockTags.DOORS).forceAddTag(BlockTags.TRAPDOORS); + getOrCreateTagBuilder(UTags.Blocks.CATAPULT_IMMUNE).add(Blocks.BEDROCK).forceAddTag(BlockTags.DOORS).forceAddTag(BlockTags.TRAPDOORS); getOrCreateTagBuilder(UTags.Blocks.BUTTERFLIES_SPAWNABLE_ON).forceAddTag(BlockTags.ANIMALS_SPAWNABLE_ON).forceAddTag(BlockTags.LEAVES).forceAddTag(BlockTags.FLOWERS).forceAddTag(BlockTags.FLOWER_POTS); - getOrCreateTagBuilder(UTags.JARS).add(UBlocks.JAR, UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.ZAP_JAR); + getOrCreateTagBuilder(UTags.Blocks.JARS).add(UBlocks.JAR, UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.ZAP_JAR); getOrCreateTagBuilder(BlockTags.CROPS).add(crops); getOrCreateTagBuilder(BlockTags.BEE_GROWABLES).add(crops); getOrCreateTagBuilder(BlockTags.MAINTAINS_FARMLAND).add(crops); getOrCreateTagBuilder(BlockTags.NEEDS_DIAMOND_TOOL).add(UBlocks.FROSTED_OBSIDIAN); - getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE).add(UBlocks.ROCKS, UBlocks.FROSTED_OBSIDIAN, UBlocks.WEATHER_VANE).forceAddTag(UTags.JARS); + getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE).add(UBlocks.ROCKS, UBlocks.FROSTED_OBSIDIAN, UBlocks.WEATHER_VANE).forceAddTag(UTags.Blocks.JARS); getOrCreateTagBuilder(BlockTags.DRAGON_IMMUNE).add(UBlocks.FROSTED_OBSIDIAN, UBlocks.GOLDEN_OAK_LOG, UBlocks.GOLDEN_OAK_LEAVES); getOrCreateTagBuilder(BlockTags.FIRE).add(UBlocks.SPECTRAL_FIRE); getOrCreateTagBuilder(BlockTags.HOE_MINEABLE).add(UBlocks.HAY_BLOCK).addOptional(Unicopia.id("rice_block")).addOptional(Unicopia.id("straw_block")); @@ -63,31 +63,31 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { addChitinBlocksets(); addFruitTrees(); - getOrCreateTagBuilder(UTags.CRYSTAL_HEART_BASE).add( + getOrCreateTagBuilder(UTags.Blocks.CRYSTAL_HEART_BASE).add( Blocks.DIAMOND_BLOCK, Blocks.QUARTZ_BLOCK, Blocks.QUARTZ_BRICKS, Blocks.QUARTZ_SLAB, Blocks.QUARTZ_STAIRS, Blocks.QUARTZ_PILLAR, Blocks.SMOOTH_QUARTZ, Blocks.SMOOTH_QUARTZ_SLAB, Blocks.SMOOTH_QUARTZ_STAIRS, Blocks.CHISELED_QUARTZ_BLOCK, Blocks.AMETHYST_BLOCK, Blocks.NETHERITE_BLOCK, Blocks.EMERALD_BLOCK ); - getOrCreateTagBuilder(UTags.CRYSTAL_HEART_ORNAMENT).add(Blocks.END_ROD); + getOrCreateTagBuilder(UTags.Blocks.CRYSTAL_HEART_ORNAMENT).add(Blocks.END_ROD); - getOrCreateTagBuilder(UTags.FRAGILE) + getOrCreateTagBuilder(UTags.Blocks.FRAGILE) .forceAddTag(ConventionalBlockTags.GLASS_BLOCKS) .forceAddTag(ConventionalBlockTags.GLASS_PANES) - .forceAddTag(UTags.JARS) + .forceAddTag(UTags.Blocks.JARS) .add(Blocks.VINE, Blocks.LILY_PAD); - getOrCreateTagBuilder(UTags.INTERESTING).add( + getOrCreateTagBuilder(UTags.Blocks.INTERESTING).add( Blocks.SEA_LANTERN, Blocks.ENDER_CHEST, Blocks.END_PORTAL_FRAME, Blocks.JUKEBOX, Blocks.SPAWNER ).forceAddTag(ConventionalBlockTags.ORES); - getOrCreateTagBuilder(UTags.KICKS_UP_DUST).forceAddTag(BlockTags.SAND).add( + getOrCreateTagBuilder(UTags.Blocks.KICKS_UP_DUST).forceAddTag(BlockTags.SAND).add( Blocks.SUSPICIOUS_SAND, Blocks.GRAVEL, Blocks.SUSPICIOUS_GRAVEL ).forceAddTag(TagKey.of(RegistryKeys.BLOCK, new Identifier("c", "concrete_powders"))); - getOrCreateTagBuilder(UTags.UNAFFECTED_BY_GROW_ABILITY).add(Blocks.GRASS_BLOCK); + getOrCreateTagBuilder(UTags.Blocks.UNAFFECTED_BY_GROW_ABILITY).add(Blocks.GRASS_BLOCK); } private void addFruitTrees() { @@ -112,7 +112,7 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { private void addZapWoodset() { getOrCreateTagBuilder(BlockTags.LEAVES).add(UBlocks.ZAP_LEAVES, UBlocks.FLOWERING_ZAP_LEAVES); - getOrCreateTagBuilder(UTags.POLEARM_MINEABLE).add( + getOrCreateTagBuilder(UTags.Blocks.POLEARM_MINEABLE).add( UBlocks.ZAP_LEAVES, UBlocks.FLOWERING_ZAP_LEAVES, UBlocks.ZAP_PLANKS, UBlocks.ZAP_LOG, UBlocks.ZAP_WOOD, UBlocks.STRIPPED_ZAP_LOG, UBlocks.STRIPPED_ZAP_WOOD, diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UDamageTypeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UDamageTypeProvider.java index e4170071..d0b265b1 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UDamageTypeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UDamageTypeProvider.java @@ -19,12 +19,12 @@ public class UDamageTypeProvider extends FabricTagProvider { @Override protected void configure(WrapperLookup lookup) { - getOrCreateTagBuilder(UTags.SPELLBOOK_IMMUNE_TO).add( + getOrCreateTagBuilder(UTags.DamageTypes.SPELLBOOK_IMMUNE_TO).add( UDamageTypes.ZAP_APPLE, UDamageTypes.LOVE_DRAINING, UDamageTypes.LIFE_DRAINING, UDamageTypes.RAINBOOM, UDamageTypes.SUN, UDamageTypes.SUNLIGHT, UDamageTypes.SMASH ).forceAddTag(DamageTypeTags.IS_FALL).forceAddTag(DamageTypeTags.IS_FREEZING).forceAddTag(DamageTypeTags.IS_LIGHTNING).forceAddTag(DamageTypeTags.IS_PROJECTILE); - getOrCreateTagBuilder(UTags.FROM_ROCKS).add(UDamageTypes.ROCK); - getOrCreateTagBuilder(UTags.FROM_HORSESHOES).add(UDamageTypes.HORSESHOE); - getOrCreateTagBuilder(UTags.BREAKS_SUNGLASSES).add(UDamageTypes.BAT_SCREECH, UDamageTypes.RAINBOOM); + getOrCreateTagBuilder(UTags.DamageTypes.FROM_ROCKS).add(UDamageTypes.ROCK); + getOrCreateTagBuilder(UTags.DamageTypes.FROM_HORSESHOES).add(UDamageTypes.HORSESHOE); + getOrCreateTagBuilder(UTags.DamageTypes.BREAKS_SUNGLASSES).add(UDamageTypes.BAT_SCREECH, UDamageTypes.RAINBOOM); } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java index 65c5d92a..30b0c9ca 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.datagen.providers; +package com.minelittlepony.unicopia.datagen.providers.tag; import java.util.Objects; import java.util.concurrent.CompletableFuture; @@ -66,50 +66,50 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { getOrCreateTagBuilder(ItemTags.SIGNS).add(UBlocks.PALM_SIGN.asItem()); getOrCreateTagBuilder(ItemTags.HANGING_SIGNS).add(UBlocks.PALM_HANGING_SIGN.asItem()); - getOrCreateTagBuilder(UTags.HORSE_SHOES).add(ItemFamilies.HORSE_SHOES); - getOrCreateTagBuilder(UTags.POLEARMS).add(ItemFamilies.POLEARMS); + getOrCreateTagBuilder(UTags.Items.HORSE_SHOES).add(ItemFamilies.HORSE_SHOES); + getOrCreateTagBuilder(UTags.Items.POLEARMS).add(ItemFamilies.POLEARMS); - getOrCreateTagBuilder(ItemTags.TOOLS).addTag(UTags.HORSE_SHOES).addTag(UTags.POLEARMS); + getOrCreateTagBuilder(ItemTags.TOOLS).addTag(UTags.Items.HORSE_SHOES).addTag(UTags.Items.POLEARMS); - getOrCreateTagBuilder(UTags.BASKETS).add(ItemFamilies.BASKETS); - getOrCreateTagBuilder(UTags.BADGES).add(Race.REGISTRY.stream() + getOrCreateTagBuilder(UTags.Items.BASKETS).add(ItemFamilies.BASKETS); + getOrCreateTagBuilder(UTags.Items.BADGES).add(Race.REGISTRY.stream() .map(race -> race.getId().withPath(p -> p + "_badge")) .flatMap(id -> Registries.ITEM.getOrEmpty(id).stream()) .toArray(Item[]::new)); - getOrCreateTagBuilder(UTags.WOOL_BED_SHEETS).add(BedsheetsItem.ITEMS.values().stream().filter(sheet -> sheet != UItems.KELP_BED_SHEETS).toArray(Item[]::new)); - getOrCreateTagBuilder(UTags.BED_SHEETS).forceAddTag(UTags.WOOL_BED_SHEETS).add(UItems.KELP_BED_SHEETS); - getOrCreateTagBuilder(UTags.APPLE_SEEDS).add(UItems.GREEN_APPLE_SEEDS, UItems.SWEET_APPLE_SEEDS, UItems.SOUR_APPLE_SEEDS); - getOrCreateTagBuilder(UTags.MAGIC_FEATHERS).add(UItems.PEGASUS_FEATHER, UItems.GRYPHON_FEATHER); - getOrCreateTagBuilder(UTags.FRESH_APPLES).add(Items.APPLE, UItems.GREEN_APPLE, UItems.SWEET_APPLE, UItems.SOUR_APPLE); - getOrCreateTagBuilder(UTags.CLOUD_JARS).add(UItems.RAIN_CLOUD_JAR, UItems.STORM_CLOUD_JAR); - getOrCreateTagBuilder(UTags.PIES).add(UItems.APPLE_PIE, UItems.APPLE_PIE_HOOF); + getOrCreateTagBuilder(UTags.Items.WOOL_BED_SHEETS).add(BedsheetsItem.ITEMS.values().stream().filter(sheet -> sheet != UItems.KELP_BED_SHEETS).toArray(Item[]::new)); + getOrCreateTagBuilder(UTags.Items.BED_SHEETS).forceAddTag(UTags.Items.WOOL_BED_SHEETS).add(UItems.KELP_BED_SHEETS); + getOrCreateTagBuilder(UTags.Items.APPLE_SEEDS).add(UItems.GREEN_APPLE_SEEDS, UItems.SWEET_APPLE_SEEDS, UItems.SOUR_APPLE_SEEDS); + getOrCreateTagBuilder(UTags.Items.MAGIC_FEATHERS).add(UItems.PEGASUS_FEATHER, UItems.GRYPHON_FEATHER); + getOrCreateTagBuilder(UTags.Items.FRESH_APPLES).add(Items.APPLE, UItems.GREEN_APPLE, UItems.SWEET_APPLE, UItems.SOUR_APPLE); + getOrCreateTagBuilder(UTags.Items.CLOUD_JARS).add(UItems.RAIN_CLOUD_JAR, UItems.STORM_CLOUD_JAR); + getOrCreateTagBuilder(UTags.Items.PIES).add(UItems.APPLE_PIE, UItems.APPLE_PIE_HOOF); // technical tags - getOrCreateTagBuilder(ItemTags.VILLAGER_PLANTABLE_SEEDS).addTag(UTags.APPLE_SEEDS); - getOrCreateTagBuilder(UTags.CAN_CUT_PIE).forceAddTag(ConventionalItemTags.SHEARS).addOptionalTag(UConventionalTags.TOOL_KNIVES); - getOrCreateTagBuilder(UTags.COOLS_OFF_KIRINS).add(Items.MELON_SLICE, UItems.JUICE).forceAddTag(ConventionalItemTags.WATER_BUCKETS); - getOrCreateTagBuilder(UTags.FALLS_SLOWLY).add(Items.FEATHER, UItems.CLOUD_LUMP).forceAddTag(UTags.MAGIC_FEATHERS); - getOrCreateTagBuilder(UTags.IS_DELIVERED_AGGRESSIVELY).forceAddTag(ItemTags.ANVIL); - getOrCreateTagBuilder(UTags.SPOOKED_MOB_DROPS).add(Items.BRICK); - getOrCreateTagBuilder(UTags.SHADES).add( + getOrCreateTagBuilder(ItemTags.VILLAGER_PLANTABLE_SEEDS).addTag(UTags.Items.APPLE_SEEDS); + getOrCreateTagBuilder(UTags.Items.CAN_CUT_PIE).forceAddTag(ConventionalItemTags.SHEARS).addOptionalTag(UConventionalTags.Items.TOOL_KNIVES); + getOrCreateTagBuilder(UTags.Items.COOLS_OFF_KIRINS).add(Items.MELON_SLICE, UItems.JUICE).forceAddTag(ConventionalItemTags.WATER_BUCKETS); + getOrCreateTagBuilder(UTags.Items.FALLS_SLOWLY).add(Items.FEATHER, UItems.CLOUD_LUMP).forceAddTag(UTags.Items.MAGIC_FEATHERS); + getOrCreateTagBuilder(UTags.Items.IS_DELIVERED_AGGRESSIVELY).forceAddTag(ItemTags.ANVIL); + getOrCreateTagBuilder(UTags.Items.SPOOKED_MOB_DROPS).add(Items.BRICK); + getOrCreateTagBuilder(UTags.Items.SHADES).add( Items.CARVED_PUMPKIN, Items.SKELETON_SKULL, Items.WITHER_SKELETON_SKULL, Items.PLAYER_HEAD, Items.ZOMBIE_HEAD, Items.CREEPER_HEAD, Items.DRAGON_HEAD, Items.PIGLIN_HEAD, UItems.SUNGLASSES ); - getOrCreateTagBuilder(UTags.FLOATS_ON_CLOUDS) + getOrCreateTagBuilder(UTags.Items.FLOATS_ON_CLOUDS) .forceAddTag(UTags.Items.CLOUD_BEDS) .forceAddTag(UTags.Items.CLOUD_SLABS) .forceAddTag(UTags.Items.CLOUD_STAIRS) .forceAddTag(UTags.Items.CLOUD_BLOCKS) .add(UItems.CLOUD_LUMP); - getOrCreateTagBuilder(UTags.HAS_NO_TRAITS).add( + getOrCreateTagBuilder(UTags.Items.HAS_NO_TRAITS).add( Items.AIR, Items.SPAWNER, Items.STRUCTURE_VOID, Items.STRUCTURE_BLOCK, Items.COMMAND_BLOCK, Items.CHAIN_COMMAND_BLOCK, Items.REPEATING_COMMAND_BLOCK, Items.LIGHT, Items.JIGSAW, Items.BARRIER, Items.BEDROCK, Items.END_PORTAL_FRAME, Items.DEBUG_STICK, Items.COMMAND_BLOCK_MINECART, UItems.PLUNDER_VINE - ).forceAddTag(UTags.BADGES); - getOrCreateTagBuilder(UTags.LOOT_BUG_HIGH_VALUE_DROPS).add( + ).forceAddTag(UTags.Items.BADGES); + getOrCreateTagBuilder(UTags.Items.LOOT_BUG_HIGH_VALUE_DROPS).add( Items.DIAMOND, Items.GOLDEN_APPLE, Items.GOLDEN_CARROT, Items.GOLDEN_HELMET, Items.GOLDEN_BOOTS, Items.GOLDEN_LEGGINGS, Items.GOLDEN_CHESTPLATE, Items.GOLDEN_HORSE_ARMOR, @@ -152,36 +152,38 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { } private void exportConventionalTags() { - getOrCreateTagBuilder(UConventionalTags.ACORNS).add(UItems.ACORN); - getOrCreateTagBuilder(UConventionalTags.APPLES) + copy(UConventionalTags.Blocks.CONCRETES, UConventionalTags.Items.CONCRETES); + copy(UConventionalTags.Blocks.CONCRETE_POWDERS, UConventionalTags.Items.CONCRETE_POWDERS); + getOrCreateTagBuilder(UConventionalTags.Items.ACORNS).add(UItems.ACORN); + getOrCreateTagBuilder(UConventionalTags.Items.APPLES) .add(Items.APPLE, Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE, UItems.ROTTEN_APPLE) - .forceAddTag(UTags.FRESH_APPLES) + .forceAddTag(UTags.Items.FRESH_APPLES) .addOptionalTag(new Identifier("c", "pyrite_apples")) // no idea which mod add pyrite apples ; - getOrCreateTagBuilder(UConventionalTags.BANANAS).add(UItems.BANANA); - getOrCreateTagBuilder(UConventionalTags.COOKED_FISH).add(Items.COOKED_COD, Items.COOKED_SALMON); - getOrCreateTagBuilder(UConventionalTags.STICKS).add(Items.STICK); - getOrCreateTagBuilder(UConventionalTags.PINECONES).add(UItems.PINECONE); - getOrCreateTagBuilder(UConventionalTags.PINEAPPLES).add(UItems.PINEAPPLE); - getOrCreateTagBuilder(UConventionalTags.MANGOES).add(UItems.MANGO); - getOrCreateTagBuilder(UConventionalTags.MUSHROOMS).add(Items.RED_MUSHROOM, Items.BROWN_MUSHROOM); - getOrCreateTagBuilder(UConventionalTags.MUFFINS).add(UItems.MUFFIN); - getOrCreateTagBuilder(UConventionalTags.SEEDS).add(Items.BEETROOT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.TORCHFLOWER_SEEDS, Items.WHEAT_SEEDS) + getOrCreateTagBuilder(UConventionalTags.Items.BANANAS).add(UItems.BANANA); + getOrCreateTagBuilder(UConventionalTags.Items.COOKED_FISH).add(Items.COOKED_COD, Items.COOKED_SALMON); + getOrCreateTagBuilder(UConventionalTags.Items.STICKS).add(Items.STICK); + getOrCreateTagBuilder(UConventionalTags.Items.PINECONES).add(UItems.PINECONE); + getOrCreateTagBuilder(UConventionalTags.Items.PINEAPPLES).add(UItems.PINEAPPLE); + getOrCreateTagBuilder(UConventionalTags.Items.MANGOES).add(UItems.MANGO); + getOrCreateTagBuilder(UConventionalTags.Items.MUSHROOMS).add(Items.RED_MUSHROOM, Items.BROWN_MUSHROOM); + getOrCreateTagBuilder(UConventionalTags.Items.MUFFINS).add(UItems.MUFFIN); + getOrCreateTagBuilder(UConventionalTags.Items.SEEDS).add(Items.BEETROOT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.TORCHFLOWER_SEEDS, Items.WHEAT_SEEDS) .add(UItems.OAT_SEEDS) - .forceAddTag(UTags.APPLE_SEEDS); - getOrCreateTagBuilder(UConventionalTags.OATMEALS).add(UItems.OATMEAL); - getOrCreateTagBuilder(UConventionalTags.GRAIN).add(Items.WHEAT, UItems.OATS); - getOrCreateTagBuilder(UConventionalTags.NUTS).addOptionalTag(UConventionalTags.CROPS_PEANUTS); + .forceAddTag(UTags.Items.APPLE_SEEDS); + getOrCreateTagBuilder(UConventionalTags.Items.OATMEALS).add(UItems.OATMEAL); + getOrCreateTagBuilder(UConventionalTags.Items.GRAIN).add(Items.WHEAT, UItems.OATS); + getOrCreateTagBuilder(UConventionalTags.Items.NUTS).addOptionalTag(UConventionalTags.Items.CROPS_PEANUTS); - getOrCreateTagBuilder(UConventionalTags.FRUITS) - .forceAddTag(UConventionalTags.MANGOES) - .forceAddTag(UConventionalTags.PINEAPPLES) - .forceAddTag(UConventionalTags.APPLES) - .forceAddTag(UConventionalTags.BANANAS); + getOrCreateTagBuilder(UConventionalTags.Items.FRUITS) + .forceAddTag(UConventionalTags.Items.MANGOES) + .forceAddTag(UConventionalTags.Items.PINEAPPLES) + .forceAddTag(UConventionalTags.Items.APPLES) + .forceAddTag(UConventionalTags.Items.BANANAS); } private void exportFarmersDelightItems() { - getOrCreateTagBuilder(UTags.COOLS_OFF_KIRINS) + getOrCreateTagBuilder(UTags.Items.COOLS_OFF_KIRINS) .addOptional(new Identifier("farmersdelight:melon_popsicle")) .addOptional(new Identifier("farmersdelight:melon_juice")); getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, new Identifier("farmersdelight:cabbage_roll_ingredients"))).add(UItems.OATS, UItems.ROCK, UItems.WHEAT_WORMS); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java b/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java index 59d84ddb..27e8ca7f 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java @@ -111,7 +111,7 @@ public class ItemImpl implements Equine { }); } - if (stack.isIn(UTags.FALLS_SLOWLY)) { + if (stack.isIn(UTags.Items.FALLS_SLOWLY)) { if (!entity.isOnGround() && Math.signum(entity.getVelocity().y) != getPhysics().getGravitySignum()) { double ticks = ((Entity)entity).age; double shift = Math.sin(ticks / 9D) / 9D; @@ -160,7 +160,7 @@ public class ItemImpl implements Equine { @Override public boolean collidesWithClouds() { - return entity.getStack().isIn(UTags.FLOATS_ON_CLOUDS) || getSpecies().hasPersistentWeatherMagic(); + return entity.getStack().isIn(UTags.Items.FLOATS_ON_CLOUDS) || getSpecies().hasPersistentWeatherMagic(); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index fecfe073..1696abef 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -310,7 +310,7 @@ public abstract class Living implements Equine, Caste ItemStack payload = stack.payload(); Item item = payload.getItem(); - boolean deliverAggressively = payload.isIn(UTags.IS_DELIVERED_AGGRESSIVELY); + boolean deliverAggressively = payload.isIn(UTags.Items.IS_DELIVERED_AGGRESSIVELY); Vec3d randomPos = deliverAggressively ? targetPos.add(0, 2, 0) : targetPos.add(VecHelper.supply(() -> entity.getRandom().nextTriangular(0.1, 0.5))); @@ -400,7 +400,7 @@ public abstract class Living implements Equine, Caste this.attacker = attacker; } - if (magical.isIn(UTags.BREAKS_SUNGLASSES)) { + if (magical.isIn(UTags.DamageTypes.BREAKS_SUNGLASSES)) { ItemStack glasses = GlassesItem.getForEntity(entity); if (glasses.getItem() == UItems.SUNGLASSES) { ItemStack broken = UItems.BROKEN_SUNGLASSES.getDefaultStack(); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/effect/SunBlindnessStatusEffect.java b/src/main/java/com/minelittlepony/unicopia/entity/effect/SunBlindnessStatusEffect.java index c9f679c6..10e607a9 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/effect/SunBlindnessStatusEffect.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/effect/SunBlindnessStatusEffect.java @@ -72,8 +72,8 @@ public class SunBlindnessStatusEffect extends StatusEffect { return true; } - if (entity.getEquippedStack(EquipmentSlot.HEAD).isIn(UTags.SHADES) - || TrinketsDelegate.getInstance(entity).getEquipped(entity, TrinketsDelegate.FACE).anyMatch(i -> i.isIn(UTags.SHADES)) + if (entity.getEquippedStack(EquipmentSlot.HEAD).isIn(UTags.Items.SHADES) + || TrinketsDelegate.getInstance(entity).getEquipped(entity, TrinketsDelegate.FACE).anyMatch(i -> i.isIn(UTags.Items.SHADES)) || entity.isSubmergedInWater()) { return false; } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/SpellbookEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/SpellbookEntity.java index da18363f..5808aea4 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/SpellbookEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/SpellbookEntity.java @@ -373,7 +373,7 @@ public class SpellbookEntity extends MobEntity implements MagicImmune { @Override public boolean isInvulnerableTo(DamageSource damageSource) { - return super.isInvulnerableTo(damageSource) || damageSource.isIn(UTags.SPELLBOOK_IMMUNE_TO); + return super.isInvulnerableTo(damageSource) || damageSource.isIn(UTags.DamageTypes.SPELLBOOK_IMMUNE_TO); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/UTradeOffers.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/UTradeOffers.java index ff73a2f8..74e38429 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/UTradeOffers.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/UTradeOffers.java @@ -35,7 +35,7 @@ public interface UTradeOffers { factories.add(buyForEmeralds(UItems.GEMSTONE, 3, 1, 20, 1, 0.05F)); }); TradeOfferHelper.registerVillagerOffers(VillagerProfession.FARMER, 2, factories -> { - factories.add(buy(Items.EMERALD, 4, UTags.APPLE_SEEDS, 2, 20, 1, 0.05F)); + factories.add(buy(Items.EMERALD, 4, UTags.Items.APPLE_SEEDS, 2, 20, 1, 0.05F)); factories.add(buy(Items.EMERALD, 8, UItems.MANGO, 1, 15, 1, 0.025F)); }); @@ -47,7 +47,7 @@ public interface UTradeOffers { factories.add(buy(ItemTags.SMALL_FLOWERS, 2, UItems.DAFFODIL_DAISY_SANDWICH, 1, 10, 6, 0.08F)); factories.add(buy(UItems.ZAP_APPLE, 45, UItems.ZAP_APPLE_JAM_JAR, 5, 50, 3, 0.07F)); factories.add(buy(UItems.CIDER, 1, UItems.FRIENDSHIP_BRACELET, 1, 6, 1, 0.05F)); - factories.add(buy(UItems.GEMSTONE, 5, UTags.FRESH_APPLES, 2, 12, 3, 0.05F)); + factories.add(buy(UItems.GEMSTONE, 5, UTags.Items.FRESH_APPLES, 2, 12, 3, 0.05F)); factories.add(buy(Items.EMERALD, 4, UItems.MANGO, 1, 35, 1, 0.025F)); factories.add(new JarredItemTradeOfferFactory()); }); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java index b4db56d0..fc53f9b0 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/PlayerPhysics.java @@ -194,7 +194,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab private FlightType recalculateFlightType() { DimensionType dimension = entity.getWorld().getDimension(); - if ((RegistryUtils.isIn(entity.getWorld(), dimension, RegistryKeys.DIMENSION_TYPE, UTags.HAS_NO_ATMOSPHERE) + if ((RegistryUtils.isIn(entity.getWorld(), dimension, RegistryKeys.DIMENSION_TYPE, UTags.DimensionTypes.HAS_NO_ATMOSPHERE) || Unicopia.getConfig().dimensionsWithoutAtmosphere.get().contains(RegistryUtils.getId(entity.getWorld(), dimension, RegistryKeys.DIMENSION_TYPE).toString())) && !OxygenUtils.API.hasOxygen(entity)) { return FlightType.NONE; @@ -582,7 +582,7 @@ public class PlayerPhysics extends EntityPhysics implements Tickab if (entity.isOnGround() || !force) { BlockState steppingState = pony.asEntity().getSteppingBlockState(); - if (steppingState.isIn(UTags.KICKS_UP_DUST)) { + if (steppingState.isIn(UTags.Blocks.KICKS_UP_DUST)) { pony.addParticle(new BlockStateParticleEffect(UParticles.DUST_CLOUD, steppingState), pony.getOrigin().toCenterPos(), Vec3d.ZERO); } else { Supplier pos = VecHelper.sphere(pony.asWorld().getRandom(), 0.5D); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java index 10efd22d..fad4a95d 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/player/Pony.java @@ -551,7 +551,7 @@ public class Pony extends Living implements Copyable, Update } if (getObservedSpecies() == Race.BAT && !entity.hasPortalCooldown()) { - boolean hasShades = TrinketsDelegate.getInstance(entity).getEquipped(entity, TrinketsDelegate.FACE).anyMatch(s -> s.isIn(UTags.SHADES)); + boolean hasShades = TrinketsDelegate.getInstance(entity).getEquipped(entity, TrinketsDelegate.FACE).anyMatch(s -> s.isIn(UTags.Items.SHADES)); if (!this.hasShades && hasShades && getObservedSpecies() == Race.BAT) { UCriteria.WEAR_SHADES.trigger(entity); } @@ -754,7 +754,7 @@ public class Pony extends Living implements Copyable, Update } if (getObservedSpecies() == Race.KIRIN - && (stack.isIn(UTags.COOLS_OFF_KIRINS) || PotionUtil.getPotion(stack) == Potions.WATER)) { + && (stack.isIn(UTags.Items.COOLS_OFF_KIRINS) || PotionUtil.getPotion(stack) == Potions.WATER)) { getMagicalReserves().getCharge().multiply(0.5F); getSpellSlot().get(SpellType.RAGE, false).ifPresent(RageAbilitySpell::setExtenguishing); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java b/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java index d4f9607c..c334124f 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/CrystalHeartItem.java @@ -188,7 +188,7 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art BlockPos tip = entity.getBlockPos().offset(direction); BlockState tipState = entity.getWorld().getBlockState(tip); - if (!tipState.isIn(UTags.CRYSTAL_HEART_ORNAMENT) || (!tipState.contains(EndRodBlock.FACING)|| tipState.get(EndRodBlock.FACING) != direction.getOpposite())) { + if (!tipState.isIn(UTags.Blocks.CRYSTAL_HEART_ORNAMENT) || (!tipState.contains(EndRodBlock.FACING)|| tipState.get(EndRodBlock.FACING) != direction.getOpposite())) { return false; } @@ -207,6 +207,6 @@ public class CrystalHeartItem extends Item implements FloatingArtefactEntity.Art } private boolean isDiamond(BlockState state) { - return state.isIn(UTags.CRYSTAL_HEART_BASE); + return state.isIn(UTags.Blocks.CRYSTAL_HEART_BASE); } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/PineappleItem.java b/src/main/java/com/minelittlepony/unicopia/item/PineappleItem.java index 7098e7a4..9ff3941f 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/PineappleItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/PineappleItem.java @@ -29,7 +29,7 @@ public class PineappleItem extends Item { }); if (world.random.nextInt(20) == 0) { - RegistryUtils.pickRandom(world, UTags.PINEAPPLE_EFFECTS, e -> !user.hasStatusEffect(e)).ifPresent(effect -> { + RegistryUtils.pickRandom(world, UTags.StatusEffects.PINEAPPLE_EFFECTS, e -> !user.hasStatusEffect(e)).ifPresent(effect -> { user.addStatusEffect(new StatusEffectInstance(effect, 10, 1)); }); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java b/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java index a7f430c4..5dc90908 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java @@ -41,7 +41,7 @@ public class PolearmItem extends SwordItem { @Override public boolean isSuitableFor(BlockState state) { - return state.isIn(UTags.POLEARM_MINEABLE); + return state.isIn(UTags.Blocks.POLEARM_MINEABLE); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index be2973db..30ff595f 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -272,7 +272,7 @@ public interface UItems { FuelRegistry.INSTANCE.add(SPELLBOOK, 9000); FuelRegistry.INSTANCE.add(MEADOWBROOKS_STAFF, 800); FuelRegistry.INSTANCE.add(BURNED_TOAST, 1600); - FuelRegistry.INSTANCE.add(UTags.BASKETS, 1700); + FuelRegistry.INSTANCE.add(UTags.Items.BASKETS, 1700); CompostingChanceRegistry.INSTANCE.add(GREEN_APPLE, 0.65F); CompostingChanceRegistry.INSTANCE.add(SWEET_APPLE, 0.65F); diff --git a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java b/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java index 63cfb026..f8fe1ee3 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ZapAppleItem.java @@ -103,7 +103,7 @@ public class ZapAppleItem extends Item implements ChameleonItem, MultiItem { public List getDefaultStacks() { return Unicopia.SIDE.getPony().map(Pony::asWorld) .stream() - .flatMap(world -> RegistryUtils.valuesForTag(world, UConventionalTags.APPLES)) + .flatMap(world -> RegistryUtils.valuesForTag(world, UConventionalTags.Items.APPLES)) .filter(a -> a != this).map(item -> { ItemStack stack = new ItemStack(this); stack.getOrCreateNbt().putString("appearance", Registries.ITEM.getId(item).toString()); diff --git a/src/main/java/com/minelittlepony/unicopia/item/enchantment/GemFindingEnchantment.java b/src/main/java/com/minelittlepony/unicopia/item/enchantment/GemFindingEnchantment.java index 0010a097..d07383cc 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/enchantment/GemFindingEnchantment.java +++ b/src/main/java/com/minelittlepony/unicopia/item/enchantment/GemFindingEnchantment.java @@ -21,7 +21,7 @@ public class GemFindingEnchantment extends SimpleEnchantment { BlockPos origin = user.getOrigin(); - double volume = BlockPos.findClosest(origin, radius, radius, pos -> user.asWorld().getBlockState(pos).isIn(UTags.INTERESTING)) + double volume = BlockPos.findClosest(origin, radius, radius, pos -> user.asWorld().getBlockState(pos).isIn(UTags.Blocks.INTERESTING)) .map(p -> user.getOriginVector().squaredDistanceTo(p.getX(), p.getY(), p.getZ())) .map(find -> (1 - (Math.sqrt(find) / radius))) .orElse(-1D); diff --git a/src/main/java/com/minelittlepony/unicopia/item/group/ItemGroupRegistry.java b/src/main/java/com/minelittlepony/unicopia/item/group/ItemGroupRegistry.java index 3998f13b..c276d2c6 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/group/ItemGroupRegistry.java +++ b/src/main/java/com/minelittlepony/unicopia/item/group/ItemGroupRegistry.java @@ -4,7 +4,6 @@ import java.util.*; import java.util.function.Supplier; import java.util.stream.Stream; -import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.Unicopia; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; @@ -57,10 +56,9 @@ public interface ItemGroupRegistry { return key; } - static RegistryKey createGroupFromTag(String name, Supplier icon) { - TagKey key = UTags.item("groups/" + name); + static RegistryKey createGroupFromTag(String name, TagKey tag, Supplier icon) { return createDynamic(name, icon, () -> { - return Registries.ITEM.getEntryList(key) + return Registries.ITEM.getEntryList(tag) .stream() .flatMap(named -> named.stream()) .map(entry -> entry.value()); diff --git a/src/main/java/com/minelittlepony/unicopia/item/group/UItemGroups.java b/src/main/java/com/minelittlepony/unicopia/item/group/UItemGroups.java index a1f0efae..a479fa90 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/group/UItemGroups.java +++ b/src/main/java/com/minelittlepony/unicopia/item/group/UItemGroups.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.item.group; import java.util.stream.Stream; +import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.item.ChameleonItem; import com.minelittlepony.unicopia.item.UItems; import net.minecraft.item.*; @@ -12,13 +13,13 @@ public interface UItemGroups { return Stream.concat(Stream.of(Items.APPLE), ItemGroupRegistry.ITEMS.stream() .filter(item -> !(item instanceof ChameleonItem) || ((ChameleonItem)item).isFullyDisguised())); }); - RegistryKey FORAGING_ITEMS = ItemGroupRegistry.createGroupFromTag("foraging", Items.HAY_BLOCK::getDefaultStack); - RegistryKey EARTH_PONY_ITEMS = ItemGroupRegistry.createGroupFromTag("earth_pony", UItems.EARTH_BADGE::getDefaultStack); - RegistryKey UNICORN_ITEMS = ItemGroupRegistry.createGroupFromTag("unicorn", UItems.UNICORN_BADGE::getDefaultStack); - RegistryKey PEGASUS_ITEMS = ItemGroupRegistry.createGroupFromTag("pegasus", UItems.PEGASUS_BADGE::getDefaultStack); - RegistryKey BAT_PONY_ITEMS = ItemGroupRegistry.createGroupFromTag("bat_pony", UItems.BAT_BADGE::getDefaultStack); - RegistryKey SEA_PON_ITEMS = ItemGroupRegistry.createGroupFromTag("sea_pony", UItems.PEARL_NECKLACE::getDefaultStack); - RegistryKey CHANGELING_ITEMS = ItemGroupRegistry.createGroupFromTag("changeling", UItems.CHANGELING_BADGE::getDefaultStack); + RegistryKey FORAGING_ITEMS = ItemGroupRegistry.createGroupFromTag("foraging", UTags.Items.GROUP_FORAGING, Items.HAY_BLOCK::getDefaultStack); + RegistryKey EARTH_PONY_ITEMS = ItemGroupRegistry.createGroupFromTag("earth_pony", UTags.Items.GROUP_EARTH_PONY, UItems.EARTH_BADGE::getDefaultStack); + RegistryKey UNICORN_ITEMS = ItemGroupRegistry.createGroupFromTag("unicorn", UTags.Items.GROUP_UNICORN, UItems.UNICORN_BADGE::getDefaultStack); + RegistryKey PEGASUS_ITEMS = ItemGroupRegistry.createGroupFromTag("pegasus", UTags.Items.GROUP_PEGASUS, UItems.PEGASUS_BADGE::getDefaultStack); + RegistryKey BAT_PONY_ITEMS = ItemGroupRegistry.createGroupFromTag("bat_pony", UTags.Items.GROUP_BAT_PONY, UItems.BAT_BADGE::getDefaultStack); + RegistryKey SEA_PON_ITEMS = ItemGroupRegistry.createGroupFromTag("sea_pony", UTags.Items.GROUP_SEA_PONY, UItems.PEARL_NECKLACE::getDefaultStack); + RegistryKey CHANGELING_ITEMS = ItemGroupRegistry.createGroupFromTag("changeling", UTags.Items.GROUP_CHANGELING, UItems.CHANGELING_BADGE::getDefaultStack); static void bootstrap() { ItemGroupRegistry.bootstrap(); diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/PhysicsBodyProjectileEntity.java b/src/main/java/com/minelittlepony/unicopia/projectile/PhysicsBodyProjectileEntity.java index 531f670e..de74181e 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/PhysicsBodyProjectileEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/PhysicsBodyProjectileEntity.java @@ -145,7 +145,7 @@ public class PhysicsBodyProjectileEntity extends PersistentProjectileEntity impl return; } else { ItemStack stack = asItemStack(); - if (stack.isIn(UTags.HORSE_SHOES)) { + if (stack.isIn(UTags.Items.HORSE_SHOES)) { if (stack.damage(1 + random.nextInt(10), random, null)) { playSound(USounds.Vanilla.ENTITY_ITEM_BREAK, 1, 1); } else { @@ -205,7 +205,7 @@ public class PhysicsBodyProjectileEntity extends PersistentProjectileEntity impl boolean ownerCanModify = !getWorld().isClient && Caster.of(getOwner()).filter(pony -> pony.canModifyAt(hit.getBlockPos())).isPresent(); if (ownerCanModify && getWorld().getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING)) { - if ((!isBouncy() || getWorld().random.nextInt(200) == 0) && state.isIn(UTags.FRAGILE)) { + if ((!isBouncy() || getWorld().random.nextInt(200) == 0) && state.isIn(UTags.Blocks.FRAGILE)) { getWorld().breakBlock(hit.getBlockPos(), true); } } @@ -246,7 +246,7 @@ public class PhysicsBodyProjectileEntity extends PersistentProjectileEntity impl emitGameEvent(GameEvent.STEP); if (!isBouncy()) { - if (stack.isIn(UTags.HORSE_SHOES)) { + if (stack.isIn(UTags.Items.HORSE_SHOES)) { if (stack.damage(1 + random.nextInt(10), random, null)) { playSound(USounds.Vanilla.ENTITY_ITEM_BREAK, 1, 1); discard(); @@ -262,7 +262,7 @@ public class PhysicsBodyProjectileEntity extends PersistentProjectileEntity impl @Override protected SoundEvent getHitSound() { - if (getStack().isIn(UTags.HORSE_SHOES)) { + if (getStack().isIn(UTags.Items.HORSE_SHOES)) { return USounds.Vanilla.ITEM_TRIDENT_HIT_GROUND; } return isBouncy() ? USounds.ITEM_MUFFIN_BOUNCE.value() : USounds.ITEM_ROCK_LAND; From a81336ef88b0692615675a36728795a51250f120 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 31 Mar 2024 16:47:40 +0100 Subject: [PATCH 60/73] Switch support for farmer's delight to farmer's delight refabricated --- build.gradle | 14 +++++++++++--- gradle.properties | 8 ++++---- .../unicopia/server/world/UTreeGen.java | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index 69922b16..58465b32 100644 --- a/build.gradle +++ b/build.gradle @@ -44,13 +44,15 @@ reckon { repositories { mavenLocal() flatDir { dirs 'lib' } - maven { name 'entity-reach-attributes'; url 'https://maven.jamieswhiteshirt.com/libs-release' } + maven { name 'entity-reach-attributes'; url 'https://maven.jamieswhiteshirt.com/libs-release'; content { includeGroup "com.jamieswhiteshirt" } } maven { name 'trinkets'; url 'https://maven.ladysnake.org/releases' } maven { name 'mod-menu'; url 'https://maven.terraformersmc.com/' } maven { name 'minelp-snapshot'; url 'https://repo.minelittlepony-mod.com/maven/snapshot' } maven { name 'minelp-releases'; url 'https://repo.minelittlepony-mod.com/maven/release' } maven { name 'TerraformersMC'; url 'https://maven.terraformersmc.com/' } maven { name 'Nodium'; url 'https://maven.cafeteria.dev/releases/' } + maven { name 'Greenhouse Maven For Farmers delight'; url 'https://maven.greenhouseteam.dev/releases/' } + maven { name 'Porting Lib For Farmers delight'; url = 'https://mvn.devos.one/releases/' } maven { name 'Modrinth'; url 'https://api.modrinth.com/maven' } maven { name 'JitPack'; url 'https://jitpack.io'; content { includeGroup "com.github.Virtuoel" } } } @@ -80,11 +82,13 @@ dependencies { modImplementation "com.terraformersmc.terraform-api:terraform-wood-api-v1:${project.terraformer_api_version}" include "com.terraformersmc.terraform-api:terraform-wood-api-v1:${project.terraformer_api_version}" - + modImplementation "me.luligabi:NoIndium:${project.nodium_version}" include "me.luligabi:NoIndium:${project.nodium_version}" - modCompileOnly "maven.modrinth:farmers-delight-fabric:${project.farmers_delight_version}", { exclude group: "net.fabricmc.fabric-api" } + modImplementation "vectorwing:FarmersDelight-Refabricated:${project.farmers_delight_version}", { + exclude group: "net.fabricmc" + } if (project.use_pehkui == '1') { modCompileOnly "maven.modrinth:pehkui:${project.pehkui_version}", { exclude group: "net.fabricmc.fabric-api" } modCompileOnly "com.github.Virtuoel:KanosConfig:0.4.1", { exclude group: "net.fabricmc.fabric-api" } @@ -103,6 +107,10 @@ dependencies { } } +remapJar { + addNestedDependencies = true +} + processResources { inputs.property "version", project.version.toString() diff --git a/gradle.properties b/gradle.properties index f56cd269..e821a843 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ org.gradle.daemon=false # check these on https://fabricmc.net/develop minecraft_version=1.20.1 yarn_mappings=1.20.1+build.10 - loader_version=0.15.3 + loader_version=0.15.7 fabric_version=0.91.0+1.20.1 # Mod Properties @@ -22,8 +22,8 @@ org.gradle.daemon=false # Dependencies fabwork_version=1.2.0 modmenu_version=7.0.0-beta.2 - minelp_version=4.10.4+1.20.1 - kirin_version=1.15.4+1.20 + minelp_version=4.10.6+1.20.1 + kirin_version=1.15.5-beta.1+1.20.1 reach_attributes_version=2.3.4 trinkets_version=3.7.1 terraformer_api_version=7.0.0-beta.1 @@ -33,7 +33,7 @@ org.gradle.daemon=false use_pehkui=0 use_sodium=1 - farmers_delight_version=1.4.3 + farmers_delight_version=1.20.1-2.0.9 pehkui_version=3.7.8+1.14.4-1.20.1 iris_version=1.6.17+1.20.1 sodium_version=mc1.20.1-0.5.8 diff --git a/src/main/java/com/minelittlepony/unicopia/server/world/UTreeGen.java b/src/main/java/com/minelittlepony/unicopia/server/world/UTreeGen.java index 143db033..77f43a34 100644 --- a/src/main/java/com/minelittlepony/unicopia/server/world/UTreeGen.java +++ b/src/main/java/com/minelittlepony/unicopia/server/world/UTreeGen.java @@ -69,7 +69,7 @@ public interface UTreeGen { .sapling(Unicopia.id("palm_sapling")).sapling((generator, settings) -> { return new SaplingBlock(generator, settings) { @Override - protected boolean canPlantOnTop(BlockState floor, BlockView world, BlockPos pos) { + public boolean canPlantOnTop(BlockState floor, BlockView world, BlockPos pos) { return floor.isIn(BlockTags.SAND); } }; From 7d63797d4dc5fdc7287b9b0e6a49c0f6b1a52024 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 31 Mar 2024 22:34:31 +0100 Subject: [PATCH 61/73] Jars can now hold fluids --- .../unicopia/block/ItemJarBlock.java | 295 +++--------------- .../unicopia/block/jar/EntityJarContents.java | 80 +++++ .../block/jar/FakeFluidJarContents.java | 79 +++++ .../block/jar/FluidOnlyJarContents.java | 55 ++++ .../unicopia/block/jar/ItemsJarContents.java | 208 ++++++++++++ .../unicopia/client/render/RenderUtil.java | 76 +---- .../entity/ItemJarBlockEntityRenderer.java | 99 ++++-- .../client/render/model/CubeModel.java | 77 +++++ .../loot/UBlockLootTableProvider.java | 29 ++ .../unicopia/util/FluidHelper.java | 69 ++++ .../unicopia/util/PsyFluidHelper.java | 51 +++ 11 files changed, 772 insertions(+), 346 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/block/jar/EntityJarContents.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/jar/FakeFluidJarContents.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/jar/FluidOnlyJarContents.java create mode 100644 src/main/java/com/minelittlepony/unicopia/block/jar/ItemsJarContents.java create mode 100644 src/main/java/com/minelittlepony/unicopia/client/render/model/CubeModel.java create mode 100644 src/main/java/com/minelittlepony/unicopia/util/FluidHelper.java create mode 100644 src/main/java/com/minelittlepony/unicopia/util/PsyFluidHelper.java diff --git a/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java index 1c726165..ef84849d 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/ItemJarBlock.java @@ -1,42 +1,34 @@ package com.minelittlepony.unicopia.block; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - import org.jetbrains.annotations.Nullable; -import com.minelittlepony.unicopia.mixin.MixinEntityBucketItem; -import com.minelittlepony.unicopia.util.NbtSerialisable; +import com.minelittlepony.unicopia.block.jar.EntityJarContents; +import com.minelittlepony.unicopia.block.jar.FluidOnlyJarContents; +import com.minelittlepony.unicopia.block.jar.ItemsJarContents; +import com.minelittlepony.unicopia.block.jar.FakeFluidJarContents; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; import net.minecraft.block.InventoryProvider; import net.minecraft.block.entity.BlockEntity; -import net.minecraft.entity.Bucketable; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.SidedInventory; import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; +import net.minecraft.item.ItemUsage; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; import net.minecraft.network.listener.ClientPlayPacketListener; import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket; -import net.minecraft.registry.Registries; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; -import net.minecraft.util.Identifier; import net.minecraft.util.TypedActionResult; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; import net.minecraft.world.World; import net.minecraft.world.WorldAccess; @@ -79,7 +71,7 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven public int getComparatorOutput(BlockState state, World world, BlockPos pos) { return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR) .map(TileData::getItems) - .map(data -> Math.min(16, data.getStacks().size())) + .map(data -> Math.min(16, data.stacks().size())) .orElse(0); } @@ -96,7 +88,7 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven return new TileData(pos, state); } - + @Nullable @Override public SidedInventory getInventory(BlockState state, WorldAccess world, BlockPos pos) { return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(TileData::getItems).orElse(null); @@ -130,6 +122,16 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven return getContents() instanceof EntityJarContents c ? c : null; } + @Nullable + public FluidJarContents getFluid() { + return getContents() instanceof FluidJarContents c ? c : null; + } + + @Nullable + public FakeFluidJarContents getFakeFluid() { + return getContents() instanceof FakeFluidJarContents c ? c : null; + } + @Override public Packet toUpdatePacket() { return BlockEntityUpdateS2CPacket.create(this); @@ -151,11 +153,13 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven @Override public void readNbt(NbtCompound nbt) { if (nbt.contains("items", NbtElement.COMPOUND_TYPE)) { - contents = new ItemsJarContents(this); - contents.fromNBT(nbt.getCompound("items")); + contents = new ItemsJarContents(this, nbt.getCompound("items")); } else if (nbt.contains("entity", NbtElement.COMPOUND_TYPE)) { - contents = new EntityJarContents(this); - contents.fromNBT(nbt.getCompound("entity")); + contents = new EntityJarContents(this, nbt.getCompound("entity")); + } else if (nbt.contains("fluid", NbtElement.COMPOUND_TYPE)) { + contents = new FluidOnlyJarContents(this, nbt.getCompound("fluid")); + } else if (nbt.contains("fakeFluid", NbtElement.COMPOUND_TYPE)) { + contents = new FakeFluidJarContents(this, nbt.getCompound("fakeFluid")); } } @@ -163,249 +167,34 @@ public class ItemJarBlock extends JarBlock implements BlockEntityProvider, Inven protected void writeNbt(NbtCompound nbt) { var items = getItems(); if (items != null) { - nbt.put("items", items.toNBT()); + nbt.put("items", items.toNBT(new NbtCompound())); } else if (getEntity() != null) { - nbt.put("entity", getEntity().toNBT()); + nbt.put("entity", getEntity().toNBT(new NbtCompound())); + } else if (getFluid() != null) { + nbt.put("fluid", getFluid().toNBT(new NbtCompound())); + } else if (getFakeFluid() != null) { + nbt.put("fakeFluid", getFakeFluid().toNBT(new NbtCompound())); } } } - - public interface JarContents extends NbtSerialisable { + public interface JarContents { TypedActionResult interact(PlayerEntity player, Hand hand); void onDestroyed(); + + NbtCompound toNBT(NbtCompound compound); + + default void consumeAndSwap(PlayerEntity player, Hand hand, ItemStack output) { + player.setStackInHand(hand, ItemUsage.exchangeStack(player.getStackInHand(hand), player, output.copy())); + } } - public static class EntityJarContents implements JarContents { - @Nullable - private EntityType entityType; - @Nullable - private Entity renderEntity; + public interface FluidJarContents extends JarContents { + FluidVariant fluid(); - private final TileData tile; - - public EntityJarContents(TileData tile) { - this(tile, null); - } - - public EntityJarContents(TileData tile, EntityType entityType) { - this.tile = tile; - this.entityType = entityType; - } - - @Nullable - public Entity getOrCreateEntity() { - if (entityType == null && tile.getWorld() != null) { - return null; - } - - if (renderEntity == null || renderEntity.getType() != entityType) { - renderEntity = entityType.create(tile.getWorld()); - } - return renderEntity; - } - - @Override - public TypedActionResult interact(PlayerEntity player, Hand hand) { - ItemStack stack = player.getStackInHand(hand); - if (stack.isOf(Items.BUCKET)) { - if (getOrCreateEntity() instanceof Bucketable bucketable) { - if (!player.isCreative()) { - stack.decrement(1); - if (stack.isEmpty()) { - player.setStackInHand(hand, bucketable.getBucketItem()); - } else { - player.giveItemStack(bucketable.getBucketItem()); - } - } - player.playSound(bucketable.getBucketFillSound(), 1, 1); - } - tile.markDirty(); - return TypedActionResult.success(new ItemsJarContents(tile)); - } - return TypedActionResult.pass(this); - } - - @Override - public void onDestroyed() { - tile.getWorld().setBlockState(tile.getPos(), Blocks.WATER.getDefaultState()); - Entity entity = getOrCreateEntity(); - if (entity != null) { - entity.refreshPositionAfterTeleport(tile.getPos().toCenterPos()); - tile.getWorld().spawnEntity(entity); - } - } - - @Override - public void toNBT(NbtCompound compound) { - compound.putString("entity", EntityType.getId(entityType).toString()); - } - - @Override - public void fromNBT(NbtCompound compound) { - entityType = Registries.ENTITY_TYPE.getOrEmpty(Identifier.tryParse(compound.getString("entity"))).orElse(null); - } - - } - - public static class ItemsJarContents implements JarContents, SidedInventory { - private static final int[] SLOTS = IntStream.range(0, 16).toArray(); - - private final TileData tile; - private List stacks = new ArrayList<>(); - - public ItemsJarContents(TileData tile) { - this.tile = tile; - } - - @Override - public TypedActionResult interact(PlayerEntity player, Hand hand) { - ItemStack handStack = player.getStackInHand(hand); - - if (handStack.isEmpty()) { - if (stacks.isEmpty()) { - return TypedActionResult.fail(this); - } - dropStack(tile.getWorld(), tile.getPos(), stacks.remove(0)); - markDirty(); - return TypedActionResult.success(this); - } - - if (stacks.isEmpty()) { - if (handStack.getItem() instanceof MixinEntityBucketItem bucket) { - if (!player.isCreative()) { - handStack.decrement(1); - if (handStack.isEmpty()) { - player.setStackInHand(hand, Items.BUCKET.getDefaultStack()); - } else { - player.giveItemStack(Items.BUCKET.getDefaultStack()); - } - } - - player.playSound(bucket.getEmptyingSound(), 1, 1); - markDirty(); - return TypedActionResult.success(new EntityJarContents(tile, bucket.getEntityType())); - } - } - - if (stacks.size() >= size()) { - return TypedActionResult.fail(this); - } - stacks.add(player.isCreative() ? handStack.copyWithCount(1) : handStack.split(1)); - markDirty(); - - return TypedActionResult.success(this); - } - - @Override - public void onDestroyed() { - stacks.forEach(stack -> { - dropStack(tile.getWorld(), tile.getPos(), stack); - }); - } - - public List getStacks() { - return stacks; - } - - @Override - public int size() { - return 15; - } - - @Override - public boolean isEmpty() { - return stacks.isEmpty(); - } - - @Override - public ItemStack getStack(int slot) { - return slot < 0 || slot >= stacks.size() ? ItemStack.EMPTY : stacks.get(slot); - } - - @Override - public ItemStack removeStack(int slot, int amount) { - if (slot < 0 || slot >= stacks.size()) { - return ItemStack.EMPTY; - } - - try { - ItemStack stack = stacks.get(slot); - ItemStack removed = stack.split(1); - if (stack.isEmpty()) { - stacks.remove(slot); - } - return removed; - } finally { - markDirty(); - } - } - - @Override - public ItemStack removeStack(int slot) { - if (slot < 0 || slot >= stacks.size()) { - return ItemStack.EMPTY; - } - - try { - return stacks.remove(slot); - } finally { - markDirty(); - } - } - - @Override - public void setStack(int slot, ItemStack stack) { - if (slot >= stacks.size()) { - stacks.add(stack); - } else { - stacks.set(slot, stack); - } - markDirty(); - } - - @Override - public boolean canPlayerUse(PlayerEntity player) { - return false; - } - - @Override - public void clear() { - stacks.clear(); - markDirty(); - } - - @Override - public int[] getAvailableSlots(Direction side) { - return SLOTS; - } - - @Override - public boolean canInsert(int slot, ItemStack stack, Direction dir) { - return slot >= 0 && slot < size() && slot >= stacks.size(); - } - - @Override - public boolean canExtract(int slot, ItemStack stack, Direction dir) { - return slot >= 0 && slot < size() && slot < stacks.size(); - } - - @Override - public void toNBT(NbtCompound compound) { - compound.put("items", NbtSerialisable.ITEM_STACK.writeAll(stacks)); - } - - @Override - public void fromNBT(NbtCompound compound) { - stacks = NbtSerialisable.ITEM_STACK.readAll(compound.getList("items", NbtElement.COMPOUND_TYPE)) - .limit(size()) - .collect(Collectors.toList()); - } - - @Override - public void markDirty() { - tile.markDirty(); + default long amount() { + return FluidConstants.BUCKET; } } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/jar/EntityJarContents.java b/src/main/java/com/minelittlepony/unicopia/block/jar/EntityJarContents.java new file mode 100644 index 00000000..967807c1 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/jar/EntityJarContents.java @@ -0,0 +1,80 @@ +package com.minelittlepony.unicopia.block.jar; + +import java.util.function.Supplier; + +import org.jetbrains.annotations.Nullable; + +import com.google.common.base.Suppliers; +import com.minelittlepony.unicopia.block.ItemJarBlock.FluidJarContents; +import com.minelittlepony.unicopia.block.ItemJarBlock.JarContents; +import com.minelittlepony.unicopia.block.ItemJarBlock.TileData; + +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.minecraft.block.Blocks; +import net.minecraft.entity.Bucketable; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.Registries; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.TypedActionResult; + +public record EntityJarContents ( + TileData tile, + @Nullable EntityType entityType, + Supplier<@Nullable Entity> entity +) implements FluidJarContents { + public EntityJarContents(TileData tile, NbtCompound compound) { + this(tile, Registries.ENTITY_TYPE.getOrEmpty(Identifier.tryParse(compound.getString("entity"))).orElse(null)); + } + + public EntityJarContents(TileData tile) { + this(tile, (EntityType)null); + } + + public EntityJarContents(TileData tile, EntityType entityType) { + this(tile, entityType, Suppliers.memoize(() -> { + return entityType == null ? null : entityType.create(tile.getWorld()); + })); + } + + @Override + public TypedActionResult interact(PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + if (stack.isOf(Items.BUCKET)) { + if (entity().get() instanceof Bucketable bucketable) { + consumeAndSwap(player, hand, bucketable.getBucketItem()); + player.playSound(bucketable.getBucketFillSound(), 1, 1); + } + tile.markDirty(); + return TypedActionResult.success(new ItemsJarContents(tile)); + } + return TypedActionResult.pass(this); + } + + @Override + public void onDestroyed() { + tile.getWorld().setBlockState(tile.getPos(), Blocks.WATER.getDefaultState()); + Entity entity = entity().get(); + if (entity != null) { + entity.refreshPositionAfterTeleport(tile.getPos().toCenterPos()); + tile.getWorld().spawnEntity(entity); + } + } + + @Override + public NbtCompound toNBT(NbtCompound compound) { + compound.putString("entity", EntityType.getId(entityType).toString()); + return compound; + } + + @Override + public FluidVariant fluid() { + return FluidVariant.of(Fluids.WATER); + } +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/block/jar/FakeFluidJarContents.java b/src/main/java/com/minelittlepony/unicopia/block/jar/FakeFluidJarContents.java new file mode 100644 index 00000000..e49d648c --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/jar/FakeFluidJarContents.java @@ -0,0 +1,79 @@ +package com.minelittlepony.unicopia.block.jar; + +import java.util.Optional; + +import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.block.ItemJarBlock.JarContents; +import com.minelittlepony.unicopia.block.ItemJarBlock.TileData; +import com.minelittlepony.unicopia.util.FluidHelper; + +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.Fluid; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.Registries; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.TypedActionResult; + +public record FakeFluidJarContents ( + TileData tile, + String fluid, + int color, + Item empty, + Item filled +) implements JarContents { + public FakeFluidJarContents(TileData tile, NbtCompound compound) { + this(tile, compound.getString("fluid"), compound.getInt("color"), + Registries.ITEM.get(new Identifier(compound.getString("empty"))), + Registries.ITEM.get(new Identifier(compound.getString("filled")))); + } + + @Override + public TypedActionResult interact(PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + + tile.markDirty(); + return getRealFluid().map(FluidVariant::of).>map(fluid -> { + long remainder = FluidHelper.deposit(stack, player, hand, fluid, FluidConstants.BUCKET); + fluid.getFluid().getBucketFillSound().ifPresent(sound -> player.playSound(sound, 1, 1)); + if (remainder > 0) { + return TypedActionResult.success(new FluidOnlyJarContents(tile, remainder, fluid)); + } + return TypedActionResult.success(new ItemsJarContents(tile)); + }).orElseGet(() -> { + if (!stack.isOf(empty)) { + return TypedActionResult.pass(this); + } + consumeAndSwap(player, hand, filled.getDefaultStack()); + player.playSound("powder_snow".equalsIgnoreCase(fluid) ? USounds.Vanilla.ITEM_BUCKET_FILL_POWDER_SNOW : USounds.Vanilla.ITEM_BUCKET_FILL, 1, 1); + return TypedActionResult.success(new ItemsJarContents(tile)); + }); + } + + @Override + public void onDestroyed() { + getRealFluid().ifPresent(fluid -> { + tile.getWorld().setBlockState(tile.getPos(), FluidHelper.getFullFluidState(FluidVariant.of(fluid)).getBlockState()); + }); + } + + @Override + public NbtCompound toNBT(NbtCompound compound) { + compound.putString("fluid", fluid); + compound.putInt("color", color); + compound.putString("empty", Registries.ITEM.getId(empty).toString()); + compound.putString("filled", Registries.ITEM.getId(filled).toString()); + return compound; + } + + private Optional getRealFluid() { + return Registries.FLUID.getIds().stream() + .filter(id -> id.getPath().equalsIgnoreCase(fluid)) + .findFirst() + .map(Registries.FLUID::get); + } +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/block/jar/FluidOnlyJarContents.java b/src/main/java/com/minelittlepony/unicopia/block/jar/FluidOnlyJarContents.java new file mode 100644 index 00000000..0cdcab4b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/jar/FluidOnlyJarContents.java @@ -0,0 +1,55 @@ +package com.minelittlepony.unicopia.block.jar; + +import com.minelittlepony.unicopia.block.ItemJarBlock.FluidJarContents; +import com.minelittlepony.unicopia.block.ItemJarBlock.JarContents; +import com.minelittlepony.unicopia.block.ItemJarBlock.TileData; +import com.minelittlepony.unicopia.util.FluidHelper; + +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; + +public record FluidOnlyJarContents ( + TileData tile, + long amount, + FluidVariant fluid +) implements FluidJarContents { + + public FluidOnlyJarContents(TileData tile, NbtCompound compound) { + this(tile, compound.getLong("amount"), FluidVariant.fromNbt(compound.getCompound("fluid"))); + } + + @Override + public TypedActionResult interact(PlayerEntity player, Hand hand) { + ItemStack stack = player.getStackInHand(hand); + if (stack.isOf(Items.BUCKET)) { + long remainder = FluidHelper.deposit(stack, player, hand, fluid, amount); + tile.markDirty(); + fluid.getFluid().getBucketFillSound().ifPresent(sound -> player.playSound(sound, 1, 1)); + if (remainder > 0) { + return TypedActionResult.success(new FluidOnlyJarContents(tile, remainder, fluid)); + } + return TypedActionResult.success(new ItemsJarContents(tile)); + } + return TypedActionResult.pass(this); + } + + @Override + public void onDestroyed() { + if (amount >= FluidConstants.BUCKET) { + tile.getWorld().setBlockState(tile.getPos(), FluidHelper.getFullFluidState(fluid).getBlockState()); + } + } + + @Override + public NbtCompound toNBT(NbtCompound compound) { + compound.put("fluid", fluid.toNbt()); + compound.putLong("amount", amount); + return compound; + } +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/block/jar/ItemsJarContents.java b/src/main/java/com/minelittlepony/unicopia/block/jar/ItemsJarContents.java new file mode 100644 index 00000000..a406c3dd --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/jar/ItemsJarContents.java @@ -0,0 +1,208 @@ +package com.minelittlepony.unicopia.block.jar; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.block.ItemJarBlock.JarContents; +import com.minelittlepony.unicopia.block.ItemJarBlock.TileData; +import com.minelittlepony.unicopia.item.UItems; +import com.minelittlepony.unicopia.mixin.MixinEntityBucketItem; +import com.minelittlepony.unicopia.util.FluidHelper; +import com.minelittlepony.unicopia.util.NbtSerialisable; + +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.minecraft.block.Block; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.SidedInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.util.Hand; +import net.minecraft.util.Pair; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.math.Direction; + +public record ItemsJarContents ( + TileData tile, + List stacks + ) implements JarContents, SidedInventory { + private static final int[] SLOTS = IntStream.range(0, 16).toArray(); + + public ItemsJarContents(TileData tile) { + this(tile, new ArrayList<>()); + } + + public ItemsJarContents(TileData tile, NbtCompound compound) { + this(tile, NbtSerialisable.ITEM_STACK.readAll(compound.getList("items", NbtElement.COMPOUND_TYPE)) + .limit(15) + .collect(Collectors.toList())); + } + + @Override + public TypedActionResult interact(PlayerEntity player, Hand hand) { + ItemStack handStack = player.getStackInHand(hand); + + if (handStack.isEmpty()) { + if (stacks.isEmpty()) { + return TypedActionResult.fail(this); + } + Block.dropStack(tile.getWorld(), tile.getPos(), stacks.remove(0)); + markDirty(); + return TypedActionResult.success(this); + } + + if (stacks.isEmpty()) { + if (handStack.getItem() instanceof MixinEntityBucketItem bucket) { + consumeAndSwap(player, hand, Items.BUCKET.getDefaultStack()); + player.playSound(bucket.getEmptyingSound(), 1, 1); + markDirty(); + return TypedActionResult.success(new EntityJarContents(tile, bucket.getEntityType())); + } + + Pair fluid = FluidHelper.extract(handStack, player, hand).orElse(null); + if (fluid != null) { + fluid.getRight().getFluid().getBucketFillSound().ifPresent(sound -> player.playSound(sound, 1, 1)); + markDirty(); + return TypedActionResult.success(new FluidOnlyJarContents(tile, fluid.getLeft(), fluid.getRight())); + } + + if (handStack.isOf(Items.MILK_BUCKET)) { + consumeAndSwap(player, hand, handStack.getRecipeRemainder()); + player.playSound(USounds.Vanilla.ITEM_BUCKET_EMPTY, 1, 1); + markDirty(); + return TypedActionResult.success(new FakeFluidJarContents(tile, "milk", 0xFFFFFFFF, Items.BUCKET, Items.MILK_BUCKET)); + } + + if (handStack.isOf(Items.POWDER_SNOW_BUCKET)) { + consumeAndSwap(player, hand, Items.BUCKET.getDefaultStack()); + player.playSound(USounds.Vanilla.ITEM_BUCKET_EMPTY_POWDER_SNOW, 1, 1); + markDirty(); + return TypedActionResult.success(new FakeFluidJarContents(tile, "powder_snow", 0xFFFFFFFF, Items.BUCKET, Items.POWDER_SNOW_BUCKET)); + } + + if (handStack.isOf(UItems.LOVE_BUCKET)) { + consumeAndSwap(player, hand, handStack.getRecipeRemainder()); + player.playSound(USounds.Vanilla.ITEM_BUCKET_EMPTY, 1, 1); + markDirty(); + return TypedActionResult.success(new FakeFluidJarContents(tile, "love", 0xFF3030, Items.BUCKET, UItems.LOVE_BUCKET)); + } + + if (handStack.isOf(UItems.JUICE)) { + consumeAndSwap(player, hand, handStack.getRecipeRemainder()); + player.playSound(USounds.Vanilla.ITEM_BUCKET_EMPTY, 1, 1); + markDirty(); + return TypedActionResult.success(new FakeFluidJarContents(tile, "apple_juice", 0x30FF30, Items.GLASS_BOTTLE, UItems.JUICE)); + } + } + + if (stacks.size() >= size()) { + return TypedActionResult.fail(this); + } + stacks.add(player.isCreative() ? handStack.copyWithCount(1) : handStack.split(1)); + markDirty(); + + return TypedActionResult.success(this); + } + + @Override + public void onDestroyed() { + stacks.forEach(stack -> Block.dropStack(tile.getWorld(), tile.getPos(), stack)); + } + + @Override + public int size() { + return 15; + } + + @Override + public boolean isEmpty() { + return stacks.isEmpty(); + } + + @Override + public ItemStack getStack(int slot) { + return slot < 0 || slot >= stacks.size() ? ItemStack.EMPTY : stacks.get(slot); + } + + @Override + public ItemStack removeStack(int slot, int amount) { + if (slot < 0 || slot >= stacks.size()) { + return ItemStack.EMPTY; + } + + try { + ItemStack stack = stacks.get(slot); + ItemStack removed = stack.split(1); + if (stack.isEmpty()) { + stacks.remove(slot); + } + return removed; + } finally { + markDirty(); + } + } + + @Override + public ItemStack removeStack(int slot) { + if (slot < 0 || slot >= stacks.size()) { + return ItemStack.EMPTY; + } + + try { + return stacks.remove(slot); + } finally { + markDirty(); + } + } + + @Override + public void setStack(int slot, ItemStack stack) { + if (slot >= stacks.size()) { + stacks.add(stack); + } else { + stacks.set(slot, stack); + } + markDirty(); + } + + @Override + public boolean canPlayerUse(PlayerEntity player) { + return false; + } + + @Override + public void clear() { + stacks.clear(); + markDirty(); + } + + @Override + public int[] getAvailableSlots(Direction side) { + return SLOTS; + } + + @Override + public boolean canInsert(int slot, ItemStack stack, Direction dir) { + return slot >= 0 && slot < size() && slot >= stacks.size(); + } + + @Override + public boolean canExtract(int slot, ItemStack stack, Direction dir) { + return slot >= 0 && slot < size() && slot < stacks.size(); + } + + @Override + public NbtCompound toNBT(NbtCompound compound) { + compound.put("items", NbtSerialisable.ITEM_STACK.writeAll(stacks)); + return compound; + } + + @Override + public void markDirty() { + tile.markDirty(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java b/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java index c2795b11..9b92256d 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java @@ -5,20 +5,15 @@ import org.joml.Vector3f; import org.joml.Vector4f; import net.minecraft.client.render.BufferBuilder; -import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.Tessellator; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexFormat; import net.minecraft.client.render.VertexFormats; -import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.util.math.ColorHelper; -import net.minecraft.util.math.Direction; public class RenderUtil { public static final Vector4f TEMP_VECTOR = new Vector4f(); - private static final Vector4f TEMP_UV_VECTOR = new Vector4f(); + public static final Vector4f TEMP_UV_VECTOR = new Vector4f(); + public static final Vector3f TEMP_NORMAL_VECTOR = new Vector3f(); public static final Vertex[] UNIT_FACE = new Vertex[] { new Vertex(0, 0, 0, 1, 1), new Vertex(0, 1, 0, 1, 0), @@ -31,72 +26,9 @@ public class RenderUtil { new Vertex(1, 0, 0, 1, 1), new Vertex(0, 0, 0, 0, 1) }; - private static final Vertex[][] CUBE_VERTICES = { - new Vertex[] { // down - new Vertex(0, 0, 0, 0, 0), - new Vertex(1, 0, 0, 1, 0), - new Vertex(1, 0, 1, 1, 1), - new Vertex(0, 0, 1, 0, 1) - }, - new Vertex[] { //up - new Vertex(0, 1, 0, 0, 0), - new Vertex(0, 1, 1, 0, 1), - new Vertex(1, 1, 1, 1, 1), - new Vertex(1, 1, 0, 1, 0) - }, - new Vertex[] { //north - new Vertex(0, 0, 0, 0, 0), - new Vertex(0, 1, 0, 0, 1), - new Vertex(1, 1, 0, 1, 1), - new Vertex(1, 0, 0, 1, 0) - }, - new Vertex[] { //south - new Vertex(0, 0, 1, 0, 0), - new Vertex(1, 0, 1, 1, 0), - new Vertex(1, 1, 1, 1, 1), - new Vertex(0, 1, 1, 0, 1) - }, - new Vertex[] { //west - new Vertex(0, 0, 0, 0, 0), - new Vertex(0, 0, 1, 1, 0), - new Vertex(0, 1, 1, 1, 1), - new Vertex(0, 1, 0, 0, 1) - }, - new Vertex[] { //east - new Vertex(1, 0, 0, 0, 0), - new Vertex(1, 1, 0, 1, 0), - new Vertex(1, 1, 1, 1, 1), - new Vertex(1, 0, 1, 0, 1) - } - }; - public static void renderSpriteCubeFaces(MatrixStack matrices, VertexConsumerProvider provider, Sprite sprite, - float width, float height, float length, - int color, int light, int overlay, - Direction... directions) { - float r = ColorHelper.Abgr.getRed(color), - g = ColorHelper.Abgr.getGreen(color), - b = ColorHelper.Abgr.getBlue(color), - a = ColorHelper.Abgr.getAlpha(color); - float u0 = sprite.getMinU(), uDelta = sprite.getMaxU() - u0; - float v0 = sprite.getMinV(), vDelta = sprite.getMaxV() - v0; - RenderLayer layer = RenderLayer.getEntitySolid(sprite.getAtlasId()); - VertexConsumer buffer = provider.getBuffer(layer); - Matrix4f position = matrices.peek().getPositionMatrix(); - for (Direction direction : directions) { - for (Vertex vertex : CUBE_VERTICES[direction.ordinal()]) { - Vector4f pos = position.transform(TEMP_VECTOR.set(vertex.position(), 1).mul(width, height, length, 1)); - buffer.vertex( - pos.x, pos.y, pos.z, - r, g, b, a, - u0 + vertex.texture().x * uDelta, - v0 + vertex.texture().y * vDelta, - overlay, light, - direction.getOffsetX(), direction.getOffsetY(), direction.getOffsetZ() - ); - } - } - } + + public static void renderFace(MatrixStack matrices, Tessellator te, BufferBuilder buffer, float r, float g, float b, float a, int light) { renderFace(matrices, te, buffer, r, g, b, a, light, 1, 1); diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java index e0b4883c..472a8335 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/entity/ItemJarBlockEntityRenderer.java @@ -1,14 +1,24 @@ package com.minelittlepony.unicopia.client.render.entity; +import java.util.Arrays; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.common.util.Color; import com.minelittlepony.unicopia.block.ItemJarBlock; -import com.minelittlepony.unicopia.block.ItemJarBlock.EntityJarContents; -import com.minelittlepony.unicopia.block.ItemJarBlock.ItemsJarContents; -import com.minelittlepony.unicopia.client.render.RenderUtil; +import com.minelittlepony.unicopia.block.ItemJarBlock.FluidJarContents; +import com.minelittlepony.unicopia.block.jar.ItemsJarContents; +import com.minelittlepony.unicopia.block.jar.FakeFluidJarContents; +import com.minelittlepony.unicopia.block.jar.EntityJarContents; +import com.minelittlepony.unicopia.client.render.model.CubeModel; +import com.minelittlepony.unicopia.util.FluidHelper; import com.minelittlepony.unicopia.util.PosHelper; -import net.minecraft.block.Blocks; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.color.world.BiomeColors; +import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.client.render.block.entity.BlockEntityRendererFactory; @@ -20,8 +30,12 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.command.argument.EntityAnchorArgumentType.EntityAnchor; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.Fluid; +import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RotationAxis; import net.minecraft.util.math.Vec3d; @@ -29,16 +43,13 @@ import net.minecraft.util.math.random.Random; import net.minecraft.world.World; public class ItemJarBlockEntityRenderer implements BlockEntityRenderer { - + private static final Direction[] GLASS_SIDES = Arrays.stream(PosHelper.ALL).filter(i -> i != Direction.UP).toArray(Direction[]::new); private final ItemRenderer itemRenderer; private final EntityRenderDispatcher dispatcher; - private final Sprite waterSprite; - public ItemJarBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) { itemRenderer = ctx.getItemRenderer(); dispatcher = ctx.getEntityRenderDispatcher(); - waterSprite = MinecraftClient.getInstance().getBakedModelManager().getBlockModels().getModel(Blocks.WATER.getDefaultState()).getParticleSprite(); } @Override @@ -53,6 +64,16 @@ public class ItemJarBlockEntityRenderer implements BlockEntityRenderer= 1; + CubeModel.render( matrices, - vertices, - waterSprite, - 0.4F, 0.4F, 0.4F, - BiomeColors.getWaterColor(world, pos), - light, overlay, PosHelper.ALL + vertices.getBuffer(opaque ? RenderLayer.getEntitySolid(topSprite.getAtlasId()) : RenderLayer.getEntityTranslucent(topSprite.getAtlasId())), + topSprite.getMinU(), topSprite.getMinV(), + topSprite.getMaxU(), topSprite.getMaxV(), + 0.28F, 0.01F, 0.28F, + 0.73F, 0.01F + height, 0.73F, + color, + light, overlay, Direction.UP + ); + Sprite sideSprite = sprite[sprite.length - 1]; + CubeModel.render( + matrices, + vertices.getBuffer(opaque ? RenderLayer.getEntitySolid(sideSprite.getAtlasId()) : RenderLayer.getEntityTranslucent(sideSprite.getAtlasId())), + sideSprite.getMinU(), sideSprite.getMinV(), + sideSprite.getMaxU(), sideSprite.getMaxV(), + 0.28F, 0.01F, 0.28F, + 0.73F, 0.01F + height, 0.73F, + color, + light, overlay, GLASS_SIDES ); matrices.pop(); } + + private int getFluidColor(World world, BlockPos pos, FluidState state) { + return getFluidHandler(state.getFluid()).getFluidColor(world, pos, state); + } + + private Sprite[] getFluidSprite(@Nullable World world, BlockPos pos, FluidState state) { + return getFluidHandler(state.getFluid()).getFluidSprites(world, pos, state); + } + + private FluidRenderHandler getFluidHandler(Fluid fluid) { + FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(fluid); + if (handler == null) { + return FluidRenderHandlerRegistry.INSTANCE.get(Fluids.WATER); + } + return handler; + } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/model/CubeModel.java b/src/main/java/com/minelittlepony/unicopia/client/render/model/CubeModel.java new file mode 100644 index 00000000..6aaadb33 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/client/render/model/CubeModel.java @@ -0,0 +1,77 @@ +package com.minelittlepony.unicopia.client.render.model; + +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.joml.Vector2f; +import org.joml.Vector3f; +import org.joml.Vector4f; + +import com.minelittlepony.common.util.Color; +import com.minelittlepony.unicopia.client.render.RenderUtil; +import com.minelittlepony.unicopia.client.render.RenderUtil.Vertex; + +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.Direction; + +public class CubeModel { + private static final Vector2f TEMP_UV_VECTOR = new Vector2f(); + private static final Vertex[][] CUBE_VERTICES = { + new Vertex[] { + new Vertex(0, 0, 0, 0, 0), + new Vertex(1, 0, 0, 1, 0), + new Vertex(1, 0, 1, 1, 1), + new Vertex(0, 0, 1, 0, 1) + }, + new Vertex[] { + new Vertex(0, 1, 0, 0, 0), + new Vertex(0, 1, 1, 0, 1), + new Vertex(1, 1, 1, 1, 1), + new Vertex(1, 1, 0, 1, 0) + }, + new Vertex[] { + new Vertex(0, 0, 0, 0, 0), + new Vertex(0, 1, 0, 0, 1), + new Vertex(1, 1, 0, 1, 1), + new Vertex(1, 0, 0, 1, 0) + }, + new Vertex[] { + new Vertex(0, 0, 1, 0, 0), + new Vertex(1, 0, 1, 1, 0), + new Vertex(1, 1, 1, 1, 1), + new Vertex(0, 1, 1, 0, 1) + }, + new Vertex[] { + new Vertex(0, 0, 0, 0, 0), + new Vertex(0, 0, 1, 1, 0), + new Vertex(0, 1, 1, 1, 1), + new Vertex(0, 1, 0, 0, 1) + }, + new Vertex[] { + new Vertex(1, 0, 0, 0, 0), + new Vertex(1, 1, 0, 1, 0), + new Vertex(1, 1, 1, 1, 1), + new Vertex(1, 0, 1, 0, 1) + } + }; + + public static void render(MatrixStack matrices, VertexConsumer buffer, + float u0, float v0, float u1, float v1, + float x0, float y0, float z0, float x1, float y1, float z1, + int color, int light, int overlay, + Direction... directions) { + float r = Color.r(color), g = Color.g(color), b = Color.b(color); + float du = u1 - u0, dv = v1 - v0; + float dx = x1 - x0, dy = y1 - y0, dz = z1 - z0; + Matrix4f position = matrices.peek().getPositionMatrix(); + Matrix3f normal = matrices.peek().getNormalMatrix(); + for (Direction direction : directions) { + for (Vertex vertex : CUBE_VERTICES[direction.ordinal()]) { + Vector4f pos = position.transform(RenderUtil.TEMP_VECTOR.set(vertex.position(), 1).mul(dx, dy, dz, 1).add(x0, y0, z0, 0)); + Vector2f tex = TEMP_UV_VECTOR.set(vertex.texture().x, vertex.texture().y).mul(du, dv).add(u0, v0); + Vector3f norm = normal.transform(RenderUtil.TEMP_NORMAL_VECTOR.set(direction.getOffsetX(), direction.getOffsetY(), direction.getOffsetZ())); + buffer.vertex(pos.x, pos.y, pos.z, r, g, b, 1, tex.x, tex.y, overlay, light, norm.x, norm.y, norm.z); + } + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java index 77b0d94e..d7ed00b1 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java @@ -1,6 +1,8 @@ package com.minelittlepony.unicopia.datagen.providers.loot; import java.util.List; + +import com.minelittlepony.unicopia.block.PieBlock; import com.minelittlepony.unicopia.block.UBlocks; import com.minelittlepony.unicopia.datagen.providers.UModelProvider; import com.minelittlepony.unicopia.item.UItems; @@ -14,14 +16,21 @@ import net.minecraft.block.Block; import net.minecraft.block.Blocks; import net.minecraft.block.enums.BedPart; import net.minecraft.enchantment.Enchantments; +import net.minecraft.item.Item; import net.minecraft.item.Items; import net.minecraft.loot.LootPool; import net.minecraft.loot.LootTable; +import net.minecraft.loot.condition.BlockStatePropertyLootCondition; +import net.minecraft.loot.condition.LootConditionConsumingBuilder; import net.minecraft.loot.condition.TableBonusLootCondition; import net.minecraft.loot.entry.ItemEntry; import net.minecraft.loot.function.SetCountLootFunction; import net.minecraft.loot.provider.number.ConstantLootNumberProvider; import net.minecraft.loot.provider.number.UniformLootNumberProvider; +import net.minecraft.predicate.StatePredicate; +import net.minecraft.state.property.BooleanProperty; +import net.minecraft.state.property.Property; +import net.minecraft.util.StringIdentifiable; public class UBlockLootTableProvider extends FabricBlockLootTableProvider { @@ -116,6 +125,7 @@ public class UBlockLootTableProvider extends FabricBlockLootTableProvider { addDrop(UBlocks.CLOUD_PILLAR, drops(UBlocks.CLOUD_PILLAR, UBlocks.CLOUD, ConstantLootNumberProvider.create(2))); addDrop(UBlocks.FROSTED_OBSIDIAN, Blocks.OBSIDIAN); + addDrop(UBlocks.APPLE_PIE, pieDrops(UBlocks.APPLE_PIE, UItems.APPLE_PIE, UItems.APPLE_PIE_HOOF)); } private LootTable.Builder fruitLeavesDrops(Block leaves) { @@ -136,4 +146,23 @@ public class UBlockLootTableProvider extends FabricBlockLootTableProvider { ); } + private LootTable.Builder pieDrops(Block block, Item drop, Item stomped) { + return LootTable.builder().pool(LootPool.builder() + .rolls(ConstantLootNumberProvider.create(1)).conditionally(WITH_SILK_TOUCH) + .with(addStateCondition(block, PieBlock.STOMPED, false, applyExplosionDecay(block, ItemEntry.builder(drop)))) + .with(addStateCondition(block, PieBlock.STOMPED, true, applyExplosionDecay(block, ItemEntry.builder(stomped)))) + ); + } + + public static , P extends Comparable

& StringIdentifiable> T addStateCondition(Block block, + Property

property, P value, + LootConditionConsumingBuilder builder) { + return builder.conditionally(BlockStatePropertyLootCondition.builder(block).properties(StatePredicate.Builder.create().exactMatch(property, value))); + } + + public static > T addStateCondition(Block block, + BooleanProperty property, boolean value, + LootConditionConsumingBuilder builder) { + return builder.conditionally(BlockStatePropertyLootCondition.builder(block).properties(StatePredicate.Builder.create().exactMatch(property, value))); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/util/FluidHelper.java b/src/main/java/com/minelittlepony/unicopia/util/FluidHelper.java new file mode 100644 index 00000000..48508815 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/util/FluidHelper.java @@ -0,0 +1,69 @@ +package com.minelittlepony.unicopia.util; + +import java.util.Iterator; +import java.util.Optional; +import java.util.function.Function; + +import net.fabricmc.fabric.api.transfer.v1.context.ContainerItemContext; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidConstants; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidStorage; +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.fabricmc.fabric.api.transfer.v1.storage.Storage; +import net.fabricmc.fabric.api.transfer.v1.storage.StorageView; +import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.fluid.FluidState; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Hand; +import net.minecraft.util.Pair; + +/** + * Here be dragons + */ +public interface FluidHelper { + static FluidState getFullFluidState(FluidVariant variant) { + return PsyFluidHelper.getFullFluidState(variant); + } + + static Optional> extract(ItemStack stack, PlayerEntity player, Hand hand) { + return getAsContainer(stack, ContainerItemContext.forPlayerInteraction(player, hand)) + .filter(c -> !c.isResourceBlank()) + .map(container -> applyTransaction(t -> { + FluidVariant type = container.getResource(); + long amountExtracted = container.extract(type, FluidConstants.BUCKET, t); + if (amountExtracted > 0) { + return new Pair<>(amountExtracted, type); + } + return null; + })); + } + + static long deposit(ItemStack stack, PlayerEntity player, Hand hand, FluidVariant variant, long amount) { + return amount - getAsStorage(stack, ContainerItemContext.forPlayerInteraction(player, hand)) + .map(storage -> applyTransaction(t -> storage.insert(variant, amount, t))) + .orElse(0L); + } + + private static Optional> getAsStorage(ItemStack stack, ContainerItemContext context) { + return Optional.ofNullable(FluidStorage.ITEM.find(stack, context)); + } + + private static Optional> getAsContainer(ItemStack stack, ContainerItemContext context) { + return getAsStorage(stack, context).map(storage -> { + Iterator> iter = storage.iterator(); + return iter.hasNext() ? iter.next() : null; + }); + } + + private static T applyTransaction(Function action) { + try (@SuppressWarnings("deprecation") var transaction = Transaction.isOpen() + ? Transaction.getCurrentUnsafe().openNested() + : Transaction.openOuter()) { + try { + return action.apply(transaction); + } finally { + transaction.commit(); + } + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/util/PsyFluidHelper.java b/src/main/java/com/minelittlepony/unicopia/util/PsyFluidHelper.java new file mode 100644 index 00000000..f83e44df --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/util/PsyFluidHelper.java @@ -0,0 +1,51 @@ +package com.minelittlepony.unicopia.util; + +import java.lang.reflect.Method; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +import com.google.common.base.Suppliers; + +import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant; +import net.minecraft.fluid.FluidState; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.Registries; + +final class PsyFluidHelper { + private static final Supplier>> SIMPLE_FLUID_CLASS = Suppliers.memoize(() -> { + try { + return Optional.ofNullable(Class.forName("ivorius.psychedelicraft.fluid.SimpleFluid")); + } catch (Throwable t) { + return Optional.empty(); + } + }); + private static final Function FALLBACK_METHOD = fluid -> fluid.getFluid().getDefaultState(); + private static final Supplier> GET_FULL_FLUID_STATE = Suppliers.memoize(() -> SIMPLE_FLUID_CLASS.get().>map(type -> { + try { + final Method method = type.getDeclaredMethod("getFluidState", ItemStack.class); + if (method != null) { + return fluid -> { + try { + ItemStack stack = Items.STONE.getDefaultStack(); + NbtCompound fluidTag = stack.getOrCreateSubNbt("fluid"); + fluidTag.putString("id", Registries.FLUID.getId(fluid.getFluid()).toString()); + fluidTag.put("attributes", fluid.getNbt()); + return FluidState.class.cast(method.invoke(type.cast(fluid), stack)); + } catch (Throwable tt) {} + return FALLBACK_METHOD.apply(fluid); + }; + } + } catch (Throwable t) {} + return FALLBACK_METHOD; + }).orElse(FALLBACK_METHOD)); + + static FluidState getFullFluidState(FluidVariant variant) { + return SIMPLE_FLUID_CLASS.get() + .filter(type -> type.isAssignableFrom(variant.getFluid().getClass())) + .map(type -> GET_FULL_FLUID_STATE.get().apply(variant)) + .orElseGet(() -> variant.getFluid().getDefaultState()); + } +} From 77d1d624949c6d2887fad6cefd827bf231a4abbc Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 31 Mar 2024 22:47:15 +0100 Subject: [PATCH 62/73] Fix build --- .../unicopia/block/PineappleCropBlock.java | 2 +- .../unicopia/block/SegmentedCropBlock.java | 2 +- .../loot_tables/blocks/apple_pie.json | 47 ------------------- 3 files changed, 2 insertions(+), 49 deletions(-) delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/apple_pie.json diff --git a/src/main/java/com/minelittlepony/unicopia/block/PineappleCropBlock.java b/src/main/java/com/minelittlepony/unicopia/block/PineappleCropBlock.java index 2530a8d9..431597c5 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/PineappleCropBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/PineappleCropBlock.java @@ -41,7 +41,7 @@ public class PineappleCropBlock extends CropBlock { } @Override - protected boolean canPlantOnTop(BlockState floor, BlockView world, BlockPos pos) { + public boolean canPlantOnTop(BlockState floor, BlockView world, BlockPos pos) { return floor.isOf(this) || super.canPlantOnTop(floor, world, pos); } diff --git a/src/main/java/com/minelittlepony/unicopia/block/SegmentedCropBlock.java b/src/main/java/com/minelittlepony/unicopia/block/SegmentedCropBlock.java index 25f3539c..83decf55 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/SegmentedCropBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/SegmentedCropBlock.java @@ -97,7 +97,7 @@ public class SegmentedCropBlock extends CropBlock implements SegmentedBlock { } @Override - protected boolean canPlantOnTop(BlockState state, BlockView view, BlockPos pos) { + public boolean canPlantOnTop(BlockState state, BlockView view, BlockPos pos) { return (state.getBlock() instanceof SegmentedCropBlock o && o.canSupportBlock(this, state, view, pos)) || super.canPlantOnTop(state, view, pos); } diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/apple_pie.json b/src/main/resources/data/unicopia/loot_tables/blocks/apple_pie.json deleted file mode 100644 index 263cdd20..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/apple_pie.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "type": "minecraft:block", - "functions": [ - { - "function": "minecraft:explosion_decay" - } - ], - "pools": [ - { - "bonus_rolls": 0.0, - "conditions": [ - { - "condition": "minecraft:all_of", - "terms": [ - { - "block": "unicopia:apple_pie", - "condition": "minecraft:block_state_property", - "properties": { - "stomped": true - } - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "enchantments": [ - { - "enchantment": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - ] - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:apple_pie_hoof" - } - ], - "rolls": 1.0 - } - ] -} \ No newline at end of file From 3bc1628fd4c27d40bd225c89826788f44b39092f Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 1 Apr 2024 23:39:21 +0100 Subject: [PATCH 63/73] Datagen loot tables and partially rewrite food --- .../unicopia/UConventionalTags.java | 18 ++ .../com/minelittlepony/unicopia/UTags.java | 5 +- .../unicopia/block/EnchantedFruitBlock.java | 2 +- .../unicopia/block/SegmentedCropBlock.java | 4 + .../unicopia/datagen/Datagen.java | 22 ++ .../providers/UBlockStateModelGenerator.java | 6 +- .../loot/UBlockLootTableProvider.java | 240 +++++++++++++++--- .../UChestAdditionsLootTableProvider.java | 4 + .../loot/UChestLootTableProvider.java | 56 ++++ .../loot/UEntityLootTableProvider.java | 63 +++++ .../providers/tag/UBlockTagProvider.java | 4 + .../providers/tag/UItemTagProvider.java | 61 ++++- .../unicopia/diet/DietProfile.java | 40 ++- .../unicopia/diet/DietsLoader.java | 65 ++--- .../minelittlepony/unicopia/diet/Effect.java | 22 +- .../unicopia/diet/FoodGroupKey.java | 49 ++++ .../unicopia/diet/PonyDiets.java | 18 +- .../resources/assets/unicopia/lang/en_us.json | 12 +- .../resources/data/c/tags/items/concrete.json | 21 -- .../data/c/tags/items/cooked_insects.json | 7 - .../data/c/tags/items/cooked_meats.json | 22 -- .../data/c/tags/items/coral_blocks.json | 10 - .../data/c/tags/items/coral_fans.json | 10 - .../resources/data/c/tags/items/corals.json | 10 - .../data/c/tags/items/glazed_terracotta.json | 21 -- .../resources/data/c/tags/items/love.json | 8 - .../resources/data/c/tags/items/raw_fish.json | 10 - .../data/c/tags/items/raw_insects.json | 9 - .../data/c/tags/items/raw_meats.json | 17 -- .../resources/data/c/tags/items/rocks.json | 6 - .../data/c/tags/items/rotten_meats.json | 6 - .../resources/data/c/tags/items/worms.json | 6 - .../conglomerate_materials_from_ground.json | 4 +- .../items/overworld/edible_cooked_meat.json | 2 - .../items/overworld/edible_raw_meat.json | 2 +- .../baked_goods.json | 0 .../diets/food_groups/bat_ponys_delight.json | 10 + .../{food_effects => food_groups}/candy.json | 0 .../desserts.json | 0 .../fish/cooked.json | 2 +- .../fish/raw.json | 2 +- .../fish/rotten.json | 2 +- .../foraging/blinding.json | 0 .../foraging/dangerous.json | 0 .../foraging/edible.json | 0 .../foraging/edible_filling.json | 0 .../foraging/leafy_greens.json | 0 .../foraging/moderate.json | 0 .../foraging/nauseating.json | 0 .../foraging/prickly.json | 0 .../foraging/radioactive.json | 0 .../foraging/risky.json | 0 .../foraging/severely_nauseating.json | 0 .../foraging/severely_prickly.json | 0 .../foraging/strengthening.json | 0 .../{food_effects => food_groups}/fruit.json | 0 .../insect/cooked.json | 2 +- .../insect/raw.json | 2 +- .../data/unicopia/diets/food_groups/love.json | 21 ++ .../meat/cooked.json | 0 .../meat/raw.json | 0 .../meat/rotten.json | 2 +- .../nuts_and_seeds.json | 0 .../pinecone.json | 0 .../{food_effects => food_groups}/rocks.json | 0 .../food_groups/sea_vegetable/cooked.json | 11 + .../diets/food_groups/sea_vegetable/raw.json | 11 + .../unicopia/diets/food_groups/shells.json | 10 + .../unicopia/diets/food_groups/shelly.json | 10 + .../data/unicopia/diets/races/alicorn.json | 24 +- .../data/unicopia/diets/races/bat.json | 32 +-- .../data/unicopia/diets/races/changeling.json | 36 +-- .../data/unicopia/diets/races/earth.json | 32 +-- .../data/unicopia/diets/races/hippogriff.json | 32 +-- .../data/unicopia/diets/races/human.json | 14 +- .../data/unicopia/diets/races/kirin.json | 38 +-- .../data/unicopia/diets/races/pegasus.json | 24 +- .../data/unicopia/diets/races/seapony.json | 21 +- .../data/unicopia/diets/races/unicorn.json | 20 +- .../unicopia/loot_tables/blocks/bananas.json | 40 --- .../blocks/chiselled_chitin_hull.json | 49 ---- .../loot_tables/blocks/clam_shell.json | 96 ------- .../loot_tables/blocks/cloud_slab.json | 41 --- .../loot_tables/blocks/dense_cloud_slab.json | 41 --- .../loot_tables/blocks/etched_cloud_slab.json | 41 --- .../loot_tables/blocks/gold_root.json | 51 ---- .../loot_tables/blocks/golden_apple.json | 49 ---- .../loot_tables/blocks/hay_block.json | 157 ------------ .../loot_tables/blocks/mysterious_egg.json | 64 ----- .../unicopia/loot_tables/blocks/oats.json | 55 ---- .../loot_tables/blocks/oats_crown.json | 29 --- .../loot_tables/blocks/oats_stem.json | 29 --- .../loot_tables/blocks/pineapple.json | 35 --- .../loot_tables/blocks/plunder_vine.json | 42 --- .../loot_tables/blocks/rice_block.json | 165 ------------ .../unicopia/loot_tables/blocks/rocks.json | 85 ------- .../loot_tables/blocks/scallop_shell.json | 96 ------- .../loot_tables/blocks/slime_pustule.json | 55 ---- .../loot_tables/blocks/soggy_cloud_slab.json | 27 -- .../loot_tables/blocks/straw_block.json | 165 ------------ .../loot_tables/blocks/turret_shell.json | 96 ------- .../chests/changeling_hive_trap.json | 204 --------------- .../loot_tables/entities/butterfly.json | 25 -- .../loot_tables/entities/loot_bug.json | 87 ------- .../loot_tables/entities/storm_cloud.json | 34 --- .../tags/items/food_types/cooked_fish.json | 9 - .../tags/items/food_types/cooked_insect.json | 6 - .../tags/items/food_types/cooked_meat.json | 2 +- .../unicopia/tags/items/food_types/love.json | 2 +- .../tags/items/food_types/raw_fish.json | 10 - .../tags/items/food_types/raw_insect.json | 6 - .../tags/items/food_types/raw_meat.json | 2 +- .../tags/items/food_types/rotten_meat.json | 6 - .../unicopia/tags/items/groups/bat_pony.json | 2 +- .../tags/items/groups/changeling.json | 8 +- .../unicopia/tags/items/groups/pegasus.json | 4 +- .../resources/data/unicopia/traits/love.json | 2 +- 117 files changed, 809 insertions(+), 2328 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestLootTableProvider.java create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UEntityLootTableProvider.java create mode 100644 src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java delete mode 100644 src/main/resources/data/c/tags/items/concrete.json delete mode 100644 src/main/resources/data/c/tags/items/cooked_insects.json delete mode 100644 src/main/resources/data/c/tags/items/cooked_meats.json delete mode 100644 src/main/resources/data/c/tags/items/coral_blocks.json delete mode 100644 src/main/resources/data/c/tags/items/coral_fans.json delete mode 100644 src/main/resources/data/c/tags/items/corals.json delete mode 100644 src/main/resources/data/c/tags/items/glazed_terracotta.json delete mode 100644 src/main/resources/data/c/tags/items/love.json delete mode 100644 src/main/resources/data/c/tags/items/raw_fish.json delete mode 100644 src/main/resources/data/c/tags/items/raw_insects.json delete mode 100644 src/main/resources/data/c/tags/items/raw_meats.json delete mode 100644 src/main/resources/data/c/tags/items/rocks.json delete mode 100644 src/main/resources/data/c/tags/items/rotten_meats.json delete mode 100644 src/main/resources/data/c/tags/items/worms.json rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/baked_goods.json (100%) create mode 100644 src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/candy.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/desserts.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/fish/cooked.json (81%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/fish/raw.json (87%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/fish/rotten.json (87%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/blinding.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/dangerous.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/edible.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/edible_filling.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/leafy_greens.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/moderate.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/nauseating.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/prickly.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/radioactive.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/risky.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/severely_nauseating.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/severely_prickly.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/foraging/strengthening.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/fruit.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/insect/cooked.json (80%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/insect/raw.json (81%) create mode 100644 src/main/resources/data/unicopia/diets/food_groups/love.json rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/meat/cooked.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/meat/raw.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/meat/rotten.json (87%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/nuts_and_seeds.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/pinecone.json (100%) rename src/main/resources/data/unicopia/diets/{food_effects => food_groups}/rocks.json (100%) create mode 100644 src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json create mode 100644 src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json create mode 100644 src/main/resources/data/unicopia/diets/food_groups/shells.json create mode 100644 src/main/resources/data/unicopia/diets/food_groups/shelly.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/bananas.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/chiselled_chitin_hull.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/clam_shell.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/cloud_slab.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/dense_cloud_slab.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/etched_cloud_slab.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/gold_root.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/golden_apple.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/hay_block.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/mysterious_egg.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/oats.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/oats_crown.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/oats_stem.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/pineapple.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/plunder_vine.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/rice_block.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/rocks.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/scallop_shell.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/slime_pustule.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/soggy_cloud_slab.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/straw_block.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/blocks/turret_shell.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/chests/changeling_hive_trap.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/entities/butterfly.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/entities/loot_bug.json delete mode 100644 src/main/resources/data/unicopia/loot_tables/entities/storm_cloud.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/cooked_fish.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/cooked_insect.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/raw_fish.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/raw_insect.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/rotten_meat.json diff --git a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java index bb55a662..a4be14e6 100644 --- a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java @@ -10,6 +10,10 @@ public interface UConventionalTags { interface Blocks { TagKey CONCRETE_POWDERS = block("concrete_powders"); TagKey CONCRETES = block("concretes"); + TagKey GLAZED_TERRACOTTAS = block("glazed_terracottas"); + TagKey CORAL_BLOCKS = block("coral_blocks"); + TagKey CORAL_FANS = block("coral_fans"); + TagKey CORALS = block("corals"); private static TagKey block(String name) { return TagKey.of(RegistryKeys.BLOCK, new Identifier("c", name)); @@ -19,6 +23,10 @@ public interface UConventionalTags { interface Items { TagKey CONCRETE_POWDERS = item("concrete_powders"); TagKey CONCRETES = item("concretes"); + TagKey GLAZED_TERRACOTTAS = item("glazed_terracottas"); + TagKey CORAL_BLOCKS = item("coral_blocks"); + TagKey CORAL_FANS = item("coral_fans"); + TagKey CORALS = item("corals"); TagKey APPLES = item("apples"); TagKey ACORNS = item("acorns"); @@ -35,8 +43,18 @@ public interface UConventionalTags { TagKey OATMEALS = item("oatmeals"); TagKey FRUITS = item("fruits"); + TagKey WORMS = item("worms"); + TagKey ROCKS = item("rocks"); + TagKey RAW_INSECT = item("raw_insect"); + TagKey COOKED_INSECT = item("cooked_insect"); + + TagKey RAW_FISH = item("raw_fish"); TagKey COOKED_FISH = item("cooked_fish"); + TagKey ROTTEN_FISH = item("rotten_fish"); + TagKey RAW_MEAT = item("raw_meat"); + TagKey COOKED_MEAT = item("cooked_meat"); + TagKey ROTTEN_MEAT = item("rotten_meat"); TagKey CROPS_PEANUTS = item("crops/peanuts"); TagKey TOOL_KNIVES = item("tools/knives"); diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index 82bd5417..cb045541 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -34,9 +34,12 @@ public interface UTags { TagKey SPOOKED_MOB_DROPS = item("spooked_mob_drops"); TagKey HAS_NO_TRAITS = item("has_no_traits"); TagKey IS_DELIVERED_AGGRESSIVELY = item("is_delivered_aggressively"); + TagKey CONTAINER_WITH_LOVE = item("container_with_love"); TagKey FLOATS_ON_CLOUDS = item("floats_on_clouds"); TagKey COOLS_OFF_KIRINS = item("cools_off_kirins"); - TagKey LOOT_BUG_HIGH_VALUE_DROPS = item("loot_bug_high_value_drops"); + TagKey LOOT_BUG_COMMON_DROPS = item("loot_bug_common_drops"); + TagKey LOOT_BUG_RARE_DROPS = item("loot_bug_rare_drops"); + TagKey LOOT_BUG_EPIC_DROPS = item("loot_bug_epic_drops"); TagKey SHELLS = item("food_types/shells"); diff --git a/src/main/java/com/minelittlepony/unicopia/block/EnchantedFruitBlock.java b/src/main/java/com/minelittlepony/unicopia/block/EnchantedFruitBlock.java index c6af9166..fc72ef95 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/EnchantedFruitBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/EnchantedFruitBlock.java @@ -8,7 +8,7 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.shape.VoxelShape; public class EnchantedFruitBlock extends FruitBlock { - static final BooleanProperty ENCHANTED = BooleanProperty.of("enchanted"); + public static final BooleanProperty ENCHANTED = BooleanProperty.of("enchanted"); public EnchantedFruitBlock(Settings settings, Direction attachmentFace, Block stem, VoxelShape shape) { super(settings, attachmentFace, stem, shape); diff --git a/src/main/java/com/minelittlepony/unicopia/block/SegmentedCropBlock.java b/src/main/java/com/minelittlepony/unicopia/block/SegmentedCropBlock.java index 83decf55..1f16f7c3 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/SegmentedCropBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/SegmentedCropBlock.java @@ -204,4 +204,8 @@ public class SegmentedCropBlock extends CropBlock implements SegmentedBlock { return state.getBlock() == this || (nextSegmentSupplier != null && nextSegmentSupplier.get().isNext(state)); } + @Nullable + public SegmentedCropBlock getNext() { + return nextSegmentSupplier == null ? null : nextSegmentSupplier.get(); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java index f8d103a6..667d6173 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java @@ -3,12 +3,15 @@ package com.minelittlepony.unicopia.datagen; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.minelittlepony.unicopia.block.EdibleBlock; import com.minelittlepony.unicopia.datagen.providers.SeasonsGrowthRatesProvider; import com.minelittlepony.unicopia.datagen.providers.UAdvancementsProvider; import com.minelittlepony.unicopia.datagen.providers.UModelProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UBlockAdditionsLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UBlockLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UChestAdditionsLootTableProvider; +import com.minelittlepony.unicopia.datagen.providers.loot.UChestLootTableProvider; +import com.minelittlepony.unicopia.datagen.providers.loot.UEntityLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.recipe.URecipeProvider; import com.minelittlepony.unicopia.datagen.providers.tag.UBlockTagProvider; import com.minelittlepony.unicopia.datagen.providers.tag.UDamageTypeProvider; @@ -18,13 +21,30 @@ import com.minelittlepony.unicopia.server.world.UWorldGen; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryBuilder; import net.minecraft.registry.RegistryKeys; +import net.minecraft.util.Identifier; import net.minecraft.world.biome.OverworldBiomeCreator; public class Datagen implements DataGeneratorEntrypoint { public static final Logger LOGGER = LogManager.getLogger(); + public static Block getOrCreateBaleBlock(Identifier id) { + return Registries.BLOCK.getOrEmpty(id).orElseGet(() -> { + return Registry.register(Registries.BLOCK, id, new EdibleBlock(id, id, false)); + }); + } + + public static Item getOrCreateItem(Identifier id) { + return Registries.ITEM.getOrEmpty(id).orElseGet(() -> { + return Registry.register(Registries.ITEM, id, new Item(new Item.Settings())); + }); + } + @Override public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { final var pack = fabricDataGenerator.createPack(); @@ -35,6 +55,8 @@ public class Datagen implements DataGeneratorEntrypoint { pack.addProvider(UModelProvider::new); pack.addProvider(URecipeProvider::new); pack.addProvider(UBlockLootTableProvider::new); + pack.addProvider(UEntityLootTableProvider::new); + pack.addProvider(UChestLootTableProvider::new); pack.addProvider(UBlockAdditionsLootTableProvider::new); pack.addProvider(UChestAdditionsLootTableProvider::new); pack.addProvider(SeasonsGrowthRatesProvider::new); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java index 048c3ad6..d016daae 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java @@ -16,6 +16,7 @@ import com.minelittlepony.unicopia.block.ShellsBlock; import com.minelittlepony.unicopia.block.SlimePustuleBlock; import com.minelittlepony.unicopia.block.UBlocks; import com.minelittlepony.unicopia.block.zap.ZapAppleLeavesBlock; +import com.minelittlepony.unicopia.datagen.Datagen; import com.minelittlepony.unicopia.datagen.UBlockFamilies; import com.minelittlepony.unicopia.server.world.Tree; @@ -41,7 +42,6 @@ import net.minecraft.data.client.When; import net.minecraft.item.Item; import net.minecraft.item.Items; import net.minecraft.registry.Registries; -import net.minecraft.registry.Registry; import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.EnumProperty; import net.minecraft.state.property.Properties; @@ -429,9 +429,7 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator { Identifier side = baseBlockId.withPath(p -> "block/" + p + "_side"); TextureMap textures = new TextureMap().put(TOP, top).put(SIDE, side); - MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(Registries.BLOCK.getOrEmpty(blockId).orElseGet(() -> { - return Registry.register(Registries.BLOCK, blockId, new EdibleBlock(blockId, blockId, false)); - })); + MultipartBlockStateSupplier supplier = MultipartBlockStateSupplier.create(Datagen.getOrCreateBaleBlock(blockId)); Map uploadedModels = new HashMap<>(); for (Direction.Axis axis : Direction.Axis.VALUES) { diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java index d7ed00b1..9c625a1d 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockLootTableProvider.java @@ -2,8 +2,16 @@ package com.minelittlepony.unicopia.datagen.providers.loot; import java.util.List; +import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.block.EdibleBlock; +import com.minelittlepony.unicopia.block.EnchantedFruitBlock; import com.minelittlepony.unicopia.block.PieBlock; +import com.minelittlepony.unicopia.block.PileBlock; +import com.minelittlepony.unicopia.block.SegmentedCropBlock; +import com.minelittlepony.unicopia.block.ShellsBlock; +import com.minelittlepony.unicopia.block.SlimePustuleBlock; import com.minelittlepony.unicopia.block.UBlocks; +import com.minelittlepony.unicopia.datagen.Datagen; import com.minelittlepony.unicopia.datagen.providers.UModelProvider; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.server.world.Tree; @@ -11,29 +19,44 @@ import com.minelittlepony.unicopia.server.world.UTreeGen; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider; +import net.fabricmc.fabric.api.resource.conditions.v1.DefaultResourceConditions; import net.minecraft.block.BedBlock; import net.minecraft.block.Block; import net.minecraft.block.Blocks; +import net.minecraft.block.CarrotsBlock; +import net.minecraft.block.SlabBlock; import net.minecraft.block.enums.BedPart; +import net.minecraft.block.enums.BlockHalf; +import net.minecraft.block.enums.SlabType; import net.minecraft.enchantment.Enchantments; import net.minecraft.item.Item; +import net.minecraft.item.ItemConvertible; import net.minecraft.item.Items; import net.minecraft.loot.LootPool; import net.minecraft.loot.LootTable; import net.minecraft.loot.condition.BlockStatePropertyLootCondition; import net.minecraft.loot.condition.LootConditionConsumingBuilder; +import net.minecraft.loot.condition.RandomChanceLootCondition; import net.minecraft.loot.condition.TableBonusLootCondition; import net.minecraft.loot.entry.ItemEntry; +import net.minecraft.loot.function.ApplyBonusLootFunction; +import net.minecraft.loot.function.ConditionalLootFunction; import net.minecraft.loot.function.SetCountLootFunction; import net.minecraft.loot.provider.number.ConstantLootNumberProvider; +import net.minecraft.loot.provider.number.LootNumberProvider; import net.minecraft.loot.provider.number.UniformLootNumberProvider; import net.minecraft.predicate.StatePredicate; import net.minecraft.state.property.BooleanProperty; +import net.minecraft.state.property.IntProperty; +import net.minecraft.state.property.Properties; import net.minecraft.state.property.Property; +import net.minecraft.util.Identifier; import net.minecraft.util.StringIdentifiable; public class UBlockLootTableProvider extends FabricBlockLootTableProvider { + private static final ConditionalLootFunction.Builder FORTUNE_BONUS = ApplyBonusLootFunction.binomialWithBonusCount(Enchantments.FORTUNE, 0.5714286F, 3); + public UBlockLootTableProvider(FabricDataOutput output) { super(output); } @@ -72,13 +95,22 @@ public class UBlockLootTableProvider extends FabricBlockLootTableProvider { UBlocks.CHISELLED_CHITIN_SLAB, UBlocks.CLOUD_BRICK_SLAB, UBlocks.CLOUD_PLANK_SLAB, UBlocks.PALM_SLAB, UBlocks.ZAP_SLAB, UBlocks.WAXED_ZAP_SLAB ).forEach(slab -> addDrop(slab, this::slabDrops)); + addDrop(UBlocks.CLOUD_SLAB, slab -> decomposingSlabDrops(slab, UItems.CLOUD_LUMP, 2)); + addDrop(UBlocks.SOGGY_CLOUD_SLAB, slab -> decomposingSlabDrops(slab, UItems.CLOUD_LUMP, 2)); + addDrop(UBlocks.DENSE_CLOUD_SLAB, slab -> decomposingSlabDrops(slab, UItems.CLOUD_LUMP, 4)); + addDrop(UBlocks.ETCHED_CLOUD_SLAB, slab -> decomposingSlabDrops(slab, UItems.CLOUD_LUMP, 4)); // fruit UModelProvider.FRUITS.forEach((block, drop) -> { if (block != UBlocks.GOLDEN_APPLE) { - addDrop(block, drop); + addDrop(block, fortuneBonusDrops(drop)); } }); + addDrop(UBlocks.GOLDEN_APPLE, LootTable.builder().pool(LootPool.builder() + .rolls(exactly(1)) + .with(applyStateCondition(UBlocks.GOLDEN_APPLE, EnchantedFruitBlock.ENCHANTED, false, applyExplosionDecay(UBlocks.GOLDEN_APPLE, ItemEntry.builder(Items.GOLDEN_APPLE))).apply(FORTUNE_BONUS)) + .with(applyStateCondition(UBlocks.GOLDEN_APPLE, EnchantedFruitBlock.ENCHANTED, true, applyExplosionDecay(UBlocks.GOLDEN_APPLE, ItemEntry.builder(Items.ENCHANTED_GOLDEN_APPLE))).apply(FORTUNE_BONUS)) + )); List.of(UBlocks.GREEN_APPLE_LEAVES, UBlocks.SOUR_APPLE_LEAVES, UBlocks.SWEET_APPLE_LEAVES, UBlocks.GOLDEN_OAK_LEAVES).forEach(block -> addDrop(block, this::fruitLeavesDrops)); addDrop(UBlocks.MANGO_LEAVES, block -> leavesDrops(block, UTreeGen.MANGO_TREE.sapling().get(), 0.025F, 0.027777778F, 0.03125F, 0.041666668F, 0.1F)); // same chance as jungle addDrop(UBlocks.ZAP_LEAVES, block -> leavesDrops(block, UTreeGen.ZAP_APPLE_TREE.sapling().get(), SAPLING_DROP_CHANCE)); @@ -106,63 +138,197 @@ public class UBlockLootTableProvider extends FabricBlockLootTableProvider { UBlocks.CLOUD_BED, UBlocks.CLOTH_BED ).forEach(bed -> addDrop(bed, b -> dropsWithProperty(b, BedBlock.PART, BedPart.HEAD))); - addDrop(UBlocks.CHITIN_SPIKES, drops(UBlocks.CHITIN_SPIKES, UItems.CARAPACE, ConstantLootNumberProvider.create(6))); - addDrop(UBlocks.CHITIN, drops(UBlocks.CHITIN, UItems.CARAPACE, ConstantLootNumberProvider.create(9))); - addDrop(UBlocks.SURFACE_CHITIN, drops(UBlocks.SURFACE_CHITIN, UItems.CARAPACE, ConstantLootNumberProvider.create(9))); + addDrop(UBlocks.CHITIN_SPIKES, drops(UBlocks.CHITIN_SPIKES, UItems.CARAPACE, exactly(6))); + addDrop(UBlocks.CHITIN, drops(UBlocks.CHITIN, UItems.CARAPACE, exactly(9))); + addDrop(UBlocks.SURFACE_CHITIN, drops(UBlocks.SURFACE_CHITIN, UItems.CARAPACE, exactly(9))); + addDrop(UBlocks.CHISELLED_CHITIN_HULL, hullDrops(UBlocks.CHISELLED_CHITIN_HULL, UBlocks.CHITIN, UBlocks.CHISELLED_CHITIN)); - addDrop(UBlocks.CLOUD, drops(UBlocks.CLOUD, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(4))); - addDrop(UBlocks.CLOUD_STAIRS, drops(UBlocks.CLOUD_STAIRS, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(6))); + addDrop(UBlocks.SLIME_PUSTULE, LootTable.builder() + .pool(applyStateCondition(UBlocks.SLIME_PUSTULE, SlimePustuleBlock.SHAPE, SlimePustuleBlock.Shape.POD, + addSurvivesExplosionCondition(UBlocks.SLIME_PUSTULE, LootPool.builder() + .rolls(exactly(1)) + .with(ItemEntry.builder(UBlocks.SLIME_PUSTULE)).conditionally(WITH_SILK_TOUCH_OR_SHEARS)) + ))); + addDrop(UBlocks.MYSTERIOUS_EGG, LootTable.builder() + .pool(addSurvivesExplosionCondition(UBlocks.MYSTERIOUS_EGG, LootPool.builder() + .rolls(exactly(1)) + .with(ItemEntry.builder(UBlocks.MYSTERIOUS_EGG)) + .apply(PileBlock.COUNT.getValues(), count -> applyStateCondition(UBlocks.MYSTERIOUS_EGG, PileBlock.COUNT, count, SetCountLootFunction.builder(exactly(count))))))); - addDrop(UBlocks.SOGGY_CLOUD, drops(UBlocks.CLOUD, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(4))); - addDrop(UBlocks.SOGGY_CLOUD_STAIRS, drops(UBlocks.CLOUD_STAIRS, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(6))); + addDrop(UBlocks.CLOUD, drops(UBlocks.CLOUD, UItems.CLOUD_LUMP, exactly(4))); + addDrop(UBlocks.CLOUD_STAIRS, drops(UBlocks.CLOUD_STAIRS, UItems.CLOUD_LUMP, exactly(6))); - addDrop(UBlocks.DENSE_CLOUD, drops(UBlocks.DENSE_CLOUD, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(9))); - addDrop(UBlocks.DENSE_CLOUD_STAIRS, drops(UBlocks.DENSE_CLOUD_STAIRS, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(13))); - addDrop(UBlocks.ETCHED_CLOUD, drops(UBlocks.ETCHED_CLOUD, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(9))); - addDrop(UBlocks.ETCHED_CLOUD_STAIRS, drops(UBlocks.ETCHED_CLOUD_STAIRS, UItems.CLOUD_LUMP, ConstantLootNumberProvider.create(13))); + addDrop(UBlocks.SOGGY_CLOUD, drops(UBlocks.CLOUD, UItems.CLOUD_LUMP, exactly(4))); + addDrop(UBlocks.SOGGY_CLOUD_STAIRS, drops(UBlocks.CLOUD_STAIRS, UItems.CLOUD_LUMP, exactly(6))); + + addDrop(UBlocks.DENSE_CLOUD, drops(UBlocks.DENSE_CLOUD, UItems.CLOUD_LUMP, exactly(9))); + addDrop(UBlocks.DENSE_CLOUD_STAIRS, drops(UBlocks.DENSE_CLOUD_STAIRS, UItems.CLOUD_LUMP, exactly(13))); + addDrop(UBlocks.ETCHED_CLOUD, drops(UBlocks.ETCHED_CLOUD, UItems.CLOUD_LUMP, exactly(9))); + addDrop(UBlocks.ETCHED_CLOUD_STAIRS, drops(UBlocks.ETCHED_CLOUD_STAIRS, UItems.CLOUD_LUMP, exactly(13))); // recipe produces: 6 blocks -> 3 pillars means: 6/3 = 2 - addDrop(UBlocks.CLOUD_PILLAR, drops(UBlocks.CLOUD_PILLAR, UBlocks.CLOUD, ConstantLootNumberProvider.create(2))); + addDrop(UBlocks.CLOUD_PILLAR, drops(UBlocks.CLOUD_PILLAR, UBlocks.CLOUD, exactly(2))); addDrop(UBlocks.FROSTED_OBSIDIAN, Blocks.OBSIDIAN); addDrop(UBlocks.APPLE_PIE, pieDrops(UBlocks.APPLE_PIE, UItems.APPLE_PIE, UItems.APPLE_PIE_HOOF)); + + // crops + addTallCropDrops(UBlocks.OATS, UItems.OATS); + addDrop(UBlocks.BANANAS, LootTable.builder() + .pool(addSurvivesExplosionCondition(UBlocks.BANANAS, LootPool.builder() + .rolls(exactly(1)) + .with(item(UItems.BANANA, between(6, 12F)).apply(FORTUNE_BONUS)) + ))); + addDrop(UBlocks.PINEAPPLE, LootTable.builder() + .pool(addSurvivesExplosionCondition(UBlocks.PINEAPPLE, LootPool.builder() + .rolls(exactly(1)) + .with(item(UItems.PINEAPPLE, between(6, 12F)) + .apply(FORTUNE_BONUS) + .conditionally(BlockStatePropertyLootCondition.builder(UBlocks.PINEAPPLE).properties(StatePredicate.Builder.create() + .exactMatch(Properties.BLOCK_HALF, BlockHalf.TOP) + .exactMatch(Properties.AGE_7, Properties.AGE_7_MAX)))) + ))); + addDrop(UBlocks.ROCKS, applyExplosionDecay(UBlocks.ROCKS, LootTable.builder() + .pool(applyStateCondition(UBlocks.ROCKS, Properties.AGE_7, Properties.AGE_7_MAX, LootPool.builder() + .rolls(exactly(1)) + .with(ItemEntry.builder(UItems.WEIRD_ROCK).conditionally(RandomChanceLootCondition.builder(0.25F)).apply(FORTUNE_BONUS)) + .with(ItemEntry.builder(UItems.ROCK).apply(FORTUNE_BONUS)))) + .pool(LootPool.builder() + .rolls(exactly(1)) + .with(ItemEntry.builder(UItems.PEBBLES))) + )); + addDrop(UBlocks.GOLD_ROOT, applyExplosionDecay(UBlocks.GOLD_ROOT, LootTable.builder() + .pool(LootPool.builder().with(ItemEntry.builder(Items.GOLDEN_CARROT))) + .pool(applyStateCondition(UBlocks.GOLD_ROOT, CarrotsBlock.AGE, 7, LootPool.builder()) + .with(ItemEntry.builder(Items.GOLDEN_CARROT).apply(FORTUNE_BONUS))))); + addDrop(UBlocks.PLUNDER_VINE, applyExplosionDecay(UBlocks.PLUNDER_VINE, LootTable.builder() + .pool(LootPool.builder().rolls(exactly(4)) + .with(ItemEntry.builder(Items.STICK)) + .with(ItemEntry.builder(Items.DEAD_BUSH))) + .pool(LootPool.builder().rolls(exactly(1)) + .with(ItemEntry.builder(Items.STICK)) + .with(ItemEntry.builder(Items.DEAD_BUSH)) + .with(ItemEntry.builder(UItems.GRYPHON_FEATHER))) + )); + + // hay + addDrop(UBlocks.HAY_BLOCK, b -> edibleBlockDrops(b, Items.WHEAT)); + + // shells + addDrop(UBlocks.CLAM_SHELL, shellDrops(UBlocks.CLAM_SHELL, UItems.CLAM_SHELL)); + addDrop(UBlocks.SCALLOP_SHELL, shellDrops(UBlocks.SCALLOP_SHELL, UItems.SCALLOP_SHELL)); + addDrop(UBlocks.TURRET_SHELL, shellDrops(UBlocks.TURRET_SHELL, UItems.TURRET_SHELL)); + + var farmersDelightGenerator = withConditions(DefaultResourceConditions.allModsLoaded("farmersdelight")); + farmersDelightGenerator.addDrop(Datagen.getOrCreateBaleBlock(Unicopia.id("rice_block")), b -> edibleBlockDrops(b, Datagen.getOrCreateItem(new Identifier("farmersdelight", "rice_panicle")))); + farmersDelightGenerator.addDrop(Datagen.getOrCreateBaleBlock(Unicopia.id("straw_block")), b -> edibleBlockDrops(b, Datagen.getOrCreateItem(new Identifier("farmersdelight", "straw")))); + } + + private void addTallCropDrops(SegmentedCropBlock baseCrop, ItemConvertible crop) { + addDrop(baseCrop, applyExplosionDecay(baseCrop, LootTable.builder() + .pool(LootPool.builder() + .rolls(exactly(1)) + .with(ItemEntry.builder(baseCrop.getSeedsItem())))) + .pool(applyStateCondition(baseCrop, baseCrop.getAgeProperty(), baseCrop.getMaxAge(), LootPool.builder() + .rolls(exactly(1)) + .with(ItemEntry.builder(baseCrop.getSeedsItem()).apply(FORTUNE_BONUS))))); + + SegmentedCropBlock stage = baseCrop; + while ((stage = stage.getNext()) != null) { + addDrop(stage, applyExplosionDecay(stage, LootTable.builder() + .pool(LootPool.builder() + .rolls(exactly(1)) + .with(applyStateCondition(stage, stage.getAgeProperty(), stage.getMaxAge(), ItemEntry.builder(crop)))))); + } + } + + private LootTable.Builder decomposingSlabDrops(Block slab, ItemConvertible drop, int count) { + return LootTable.builder() + .pool(applyExplosionDecay(slab, LootPool.builder() + .rolls(exactly(1)) + .with(item(drop, exactly(count)) + .apply(applyStateCondition(slab, SlabBlock.TYPE, SlabType.DOUBLE, SetCountLootFunction.builder(exactly(count * 2))))))); } private LootTable.Builder fruitLeavesDrops(Block leaves) { return LootTable.builder() .pool(LootPool.builder() - .rolls(ConstantLootNumberProvider.create(1)) - .with(ItemEntry.builder(leaves).conditionally(WITH_SILK_TOUCH_OR_SHEARS)) - ) - .pool(LootPool.builder() - .rolls(ConstantLootNumberProvider.create(1)) - .conditionally(WITHOUT_SILK_TOUCH_NOR_SHEARS) - .with( - applyExplosionDecay(leaves, ItemEntry.builder(Items.STICK) - .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 2))) - ) - .conditionally(TableBonusLootCondition.builder(Enchantments.FORTUNE, LEAVES_STICK_DROP_CHANCE)) - ) - ); + .rolls(exactly(1)) + .with(ItemEntry.builder(leaves).conditionally(WITH_SILK_TOUCH_OR_SHEARS))) + .pool(applyExplosionDecay(leaves, LootPool.builder() + .rolls(exactly(1)) + .conditionally(WITHOUT_SILK_TOUCH_NOR_SHEARS) + .with(item(Items.STICK, between(1, 2)).conditionally(TableBonusLootCondition.builder(Enchantments.FORTUNE, LEAVES_STICK_DROP_CHANCE))))); + } + + private LootTable.Builder hullDrops(Block hull, ItemConvertible inner, ItemConvertible outer) { + return LootTable.builder() + .pool(addSurvivesExplosionCondition(hull, LootPool.builder() + .rolls(exactly(1)) + .with(item(hull, exactly(2)).conditionally(WITHOUT_SILK_TOUCH)) + .with(item(inner, exactly(2)).conditionally(WITHOUT_SILK_TOUCH)) + .with(item(outer, exactly(2)).conditionally(WITH_SILK_TOUCH)))); + } + + private LootTable.Builder edibleBlockDrops(Block block, ItemConvertible drop) { + LootTable.Builder builder = LootTable.builder(); + for (BooleanProperty segment : EdibleBlock.SEGMENTS) { + builder + .pool(addSurvivesExplosionCondition(block, LootPool.builder() + .rolls(exactly(1)) + .with(applyStateCondition(block, segment, true, ItemEntry.builder(drop))))); + } + return builder; } private LootTable.Builder pieDrops(Block block, Item drop, Item stomped) { - return LootTable.builder().pool(LootPool.builder() - .rolls(ConstantLootNumberProvider.create(1)).conditionally(WITH_SILK_TOUCH) - .with(addStateCondition(block, PieBlock.STOMPED, false, applyExplosionDecay(block, ItemEntry.builder(drop)))) - .with(addStateCondition(block, PieBlock.STOMPED, true, applyExplosionDecay(block, ItemEntry.builder(stomped)))) - ); + return LootTable.builder() + .pool(applyExplosionDecay(block, LootPool.builder() + .rolls(exactly(1)).conditionally(WITH_SILK_TOUCH) + .with(applyStateCondition(block, PieBlock.STOMPED, false, ItemEntry.builder(drop))) + .with(applyStateCondition(block, PieBlock.STOMPED, true, ItemEntry.builder(stomped))))); } - public static , P extends Comparable

& StringIdentifiable> T addStateCondition(Block block, - Property

property, P value, - LootConditionConsumingBuilder builder) { + private LootTable.Builder shellDrops(Block block, Item shell) { + return LootTable.builder() + .pool(applyExplosionDecay(block, LootPool.builder() + .rolls(exactly(1)) + .with(ItemEntry.builder(shell)) + .apply(ShellsBlock.COUNT.getValues(), count -> applyStateCondition(block, ShellsBlock.COUNT, count, SetCountLootFunction.builder(exactly(count)))) + .apply(FORTUNE_BONUS))); + } + + + public LootTable.Builder fortuneBonusDrops(ItemConvertible drop) { + return LootTable.builder().pool(addSurvivesExplosionCondition(drop, LootPool.builder() + .rolls(exactly(1)) + .with(ItemEntry.builder(drop).apply(FORTUNE_BONUS)))); + } + + public static ConstantLootNumberProvider exactly(float n) { + return ConstantLootNumberProvider.create(n); + } + + public static UniformLootNumberProvider between(float from, float to) { + return UniformLootNumberProvider.create(from, to); + } + + public static ItemEntry.Builder item(ItemConvertible item, LootNumberProvider count) { + return ItemEntry.builder(item).apply(SetCountLootFunction.builder(count)); + } + + public static , P extends Comparable

& StringIdentifiable> T applyStateCondition(Block block, + Property

property, P value, LootConditionConsumingBuilder builder) { return builder.conditionally(BlockStatePropertyLootCondition.builder(block).properties(StatePredicate.Builder.create().exactMatch(property, value))); } - public static > T addStateCondition(Block block, - BooleanProperty property, boolean value, - LootConditionConsumingBuilder builder) { + public static > T applyStateCondition(Block block, + BooleanProperty property, boolean value, LootConditionConsumingBuilder builder) { + return builder.conditionally(BlockStatePropertyLootCondition.builder(block).properties(StatePredicate.Builder.create().exactMatch(property, value))); + } + + public static > T applyStateCondition(Block block, + IntProperty property, int value, LootConditionConsumingBuilder builder) { return builder.conditionally(BlockStatePropertyLootCondition.builder(block).properties(StatePredicate.Builder.create().exactMatch(property, value))); } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java index 266c73a7..051875e7 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java @@ -24,6 +24,10 @@ public class UChestAdditionsLootTableProvider extends SimpleFabricLootTableProvi super(dataOutput, LootContextTypes.CHEST); } + @Override + public String getName() { + return super.getName() + " Additions"; + } @Override public void accept(BiConsumer exporter) { diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestLootTableProvider.java new file mode 100644 index 00000000..0ea207e9 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestLootTableProvider.java @@ -0,0 +1,56 @@ +package com.minelittlepony.unicopia.datagen.providers.loot; + +import java.util.function.BiConsumer; + +import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.entity.effect.UPotions; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.SimpleFabricLootTableProvider; +import net.minecraft.item.Items; +import net.minecraft.loot.LootPool; +import net.minecraft.loot.LootTable; +import net.minecraft.loot.LootTable.Builder; +import net.minecraft.loot.context.LootContextTypes; +import net.minecraft.loot.entry.ItemEntry; +import net.minecraft.loot.function.SetCountLootFunction; +import net.minecraft.loot.function.SetPotionLootFunction; +import net.minecraft.loot.provider.number.ConstantLootNumberProvider; +import net.minecraft.loot.provider.number.UniformLootNumberProvider; +import net.minecraft.potion.Potion; +import net.minecraft.util.Identifier; + +public class UChestLootTableProvider extends SimpleFabricLootTableProvider { + public UChestLootTableProvider(FabricDataOutput output) { + super(output, LootContextTypes.CHEST); + } + + @Override + public void accept(BiConsumer exporter) { + exporter.accept(Unicopia.id("chests/changeling_hive_trap"), LootTable.builder() + .pool(LootPool.builder() + .rolls(ConstantLootNumberProvider.create(6)) + + .with(createTippedArrowEntry(UPotions.MORPH_EARTH_PONY.shortEffect(), 3)) + .with(createTippedArrowEntry(UPotions.MORPH_UNICORN.shortEffect(), 1)) + .with(createTippedArrowEntry(UPotions.MORPH_PEGASUS.shortEffect(), 1)) + .with(createTippedArrowEntry(UPotions.MORPH_BAT.shortEffect(), 1)) + .with(createTippedArrowEntry(UPotions.MORPH_KIRIN.shortEffect(), 1)) + .with(createTippedArrowEntry(UPotions.MORPH_HIPPOGRIFF.shortEffect(), 1)) + + .with(createTippedArrowEntry(UPotions.MORPH_EARTH_PONY.longEffect(), 5)) + .with(createTippedArrowEntry(UPotions.MORPH_UNICORN.longEffect(), 2)) + .with(createTippedArrowEntry(UPotions.MORPH_PEGASUS.longEffect(), 2)) + .with(createTippedArrowEntry(UPotions.MORPH_BAT.longEffect(), 2)) + .with(createTippedArrowEntry(UPotions.MORPH_KIRIN.longEffect(), 2)) + .with(createTippedArrowEntry(UPotions.MORPH_HIPPOGRIFF.longEffect(), 2)) + )); + } + + private static ItemEntry.Builder createTippedArrowEntry(Potion potion, int weight) { + return ItemEntry.builder(Items.TIPPED_ARROW) + .weight(weight) + .apply(SetPotionLootFunction.builder(potion)) + .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(3, 9))); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UEntityLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UEntityLootTableProvider.java new file mode 100644 index 00000000..bdcc6942 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UEntityLootTableProvider.java @@ -0,0 +1,63 @@ +package com.minelittlepony.unicopia.datagen.providers.loot; + +import java.util.function.BiConsumer; + +import com.minelittlepony.unicopia.UTags; +import com.minelittlepony.unicopia.entity.mob.UEntities; +import com.minelittlepony.unicopia.item.UItems; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.SimpleFabricLootTableProvider; +import net.minecraft.entity.EntityType; +import net.minecraft.loot.LootPool; +import net.minecraft.loot.LootTable; +import net.minecraft.loot.LootTable.Builder; +import net.minecraft.loot.condition.RandomChanceLootCondition; +import net.minecraft.loot.context.LootContextTypes; +import net.minecraft.loot.entry.ItemEntry; +import net.minecraft.loot.entry.TagEntry; +import net.minecraft.loot.function.LootingEnchantLootFunction; +import net.minecraft.loot.function.SetCountLootFunction; +import net.minecraft.loot.provider.number.ConstantLootNumberProvider; +import net.minecraft.loot.provider.number.UniformLootNumberProvider; +import net.minecraft.util.Identifier; + +public class UEntityLootTableProvider extends SimpleFabricLootTableProvider { + public UEntityLootTableProvider(FabricDataOutput output) { + super(output, LootContextTypes.ENTITY); + } + + @Override + public void accept(BiConsumer exporter) { + generate((type, builder) -> exporter.accept(EntityType.getId(type).withPrefixedPath("entities/"), builder)); + } + + protected void generate(BiConsumer, Builder> exporter) { + exporter.accept(UEntities.BUTTERFLY, LootTable.builder() + .pool(LootPool.builder() + .rolls(ConstantLootNumberProvider.create(1)) + .with(ItemEntry.builder(UItems.BUTTERFLY) + .apply(LootingEnchantLootFunction.builder(UniformLootNumberProvider.create(0, 1)))))); + exporter.accept(UEntities.STORM_CLOUD, LootTable.builder() + .pool(LootPool.builder() + .rolls(ConstantLootNumberProvider.create(1)) + .with(ItemEntry.builder(UItems.CLOUD_LUMP) + .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(6, 12))) + .apply(LootingEnchantLootFunction.builder(UniformLootNumberProvider.create(0, 1)))))); + exporter.accept(UEntities.LOOT_BUG, LootTable.builder() + .pool(LootPool.builder() + .rolls(ConstantLootNumberProvider.create(1)) + .with(TagEntry.builder(UTags.Items.LOOT_BUG_COMMON_DROPS) + .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(6, 12))) + .apply(LootingEnchantLootFunction.builder(UniformLootNumberProvider.create(0, 3)))) + .with(TagEntry.builder(UTags.Items.LOOT_BUG_RARE_DROPS) + .conditionally(RandomChanceLootCondition.builder(0.25F)) + .apply(SetCountLootFunction.builder(UniformLootNumberProvider.create(1, 3))) + .apply(LootingEnchantLootFunction.builder(UniformLootNumberProvider.create(0, 6)))) + .with(TagEntry.builder(UTags.Items.LOOT_BUG_EPIC_DROPS) + .conditionally(RandomChanceLootCondition.builder(0.1F)) + .apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(1))) + .apply(LootingEnchantLootFunction.builder(UniformLootNumberProvider.create(0, 2)))) + )); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java index 6198be9f..a576582d 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UBlockTagProvider.java @@ -214,5 +214,9 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider { private void populateConventionalTags() { getOrCreateTagBuilder(UConventionalTags.Blocks.CONCRETES).add(Arrays.stream(DyeColor.values()).map(i -> Registries.BLOCK.get(new Identifier(i.getName() + "_concrete"))).toArray(Block[]::new)); getOrCreateTagBuilder(UConventionalTags.Blocks.CONCRETE_POWDERS).add(Arrays.stream(DyeColor.values()).map(i -> Registries.BLOCK.get(new Identifier(i.getName() + "_concrete_powder"))).toArray(Block[]::new)); + getOrCreateTagBuilder(UConventionalTags.Blocks.GLAZED_TERRACOTTAS).add(Arrays.stream(DyeColor.values()).map(i -> Registries.BLOCK.get(new Identifier(i.getName() + "_glazed_terracotta"))).toArray(Block[]::new)); + getOrCreateTagBuilder(UConventionalTags.Blocks.CORAL_BLOCKS).add(Blocks.TUBE_CORAL_BLOCK, Blocks.BRAIN_CORAL_BLOCK, Blocks.BUBBLE_CORAL_BLOCK, Blocks.FIRE_CORAL_BLOCK, Blocks.HORN_CORAL_BLOCK); + getOrCreateTagBuilder(UConventionalTags.Blocks.CORAL_FANS).add(Blocks.TUBE_CORAL_FAN, Blocks.BRAIN_CORAL_FAN, Blocks.BUBBLE_CORAL_FAN, Blocks.FIRE_CORAL_FAN, Blocks.HORN_CORAL_FAN); + getOrCreateTagBuilder(UConventionalTags.Blocks.CORALS).add(Blocks.TUBE_CORAL, Blocks.BRAIN_CORAL, Blocks.BUBBLE_CORAL, Blocks.FIRE_CORAL, Blocks.HORN_CORAL); } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java index 30b0c9ca..f54b7751 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java @@ -102,6 +102,7 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { .forceAddTag(UTags.Items.CLOUD_STAIRS) .forceAddTag(UTags.Items.CLOUD_BLOCKS) .add(UItems.CLOUD_LUMP); + getOrCreateTagBuilder(UTags.Items.CONTAINER_WITH_LOVE).add(UItems.LOVE_BOTTLE, UItems.LOVE_BUCKET, UItems.LOVE_MUG); getOrCreateTagBuilder(UTags.Items.HAS_NO_TRAITS).add( Items.AIR, Items.SPAWNER, Items.STRUCTURE_VOID, Items.STRUCTURE_BLOCK, Items.COMMAND_BLOCK, Items.CHAIN_COMMAND_BLOCK, Items.REPEATING_COMMAND_BLOCK, @@ -109,16 +110,23 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { Items.DEBUG_STICK, Items.COMMAND_BLOCK_MINECART, UItems.PLUNDER_VINE ).forceAddTag(UTags.Items.BADGES); - getOrCreateTagBuilder(UTags.Items.LOOT_BUG_HIGH_VALUE_DROPS).add( + getOrCreateTagBuilder(UTags.Items.LOOT_BUG_COMMON_DROPS).forceAddTag(ConventionalItemTags.NUGGETS); + getOrCreateTagBuilder(UTags.Items.LOOT_BUG_RARE_DROPS).add( Items.DIAMOND, Items.GOLDEN_APPLE, Items.GOLDEN_CARROT, Items.GOLDEN_HELMET, Items.GOLDEN_BOOTS, Items.GOLDEN_LEGGINGS, Items.GOLDEN_CHESTPLATE, Items.GOLDEN_HORSE_ARMOR, Items.GOLDEN_PICKAXE, Items.GOLDEN_SHOVEL, Items.GOLDEN_AXE, Items.GOLDEN_SWORD, Items.GOLDEN_HOE, UItems.GOLDEN_HORSE_SHOE, UItems.GOLDEN_POLEARM, UItems.GOLDEN_FEATHER, UItems.GOLDEN_WING, UItems.GOLDEN_OAK_SEEDS - ).forceAddTag(ConventionalItemTags.NUGGETS) - .forceAddTag(ConventionalItemTags.GOLD_INGOTS).forceAddTag(ConventionalItemTags.RAW_GOLD_ORES).forceAddTag(ConventionalItemTags.RAW_GOLD_BLOCKS) + ).forceAddTag(ConventionalItemTags.GOLD_INGOTS).forceAddTag(ConventionalItemTags.RAW_GOLD_ORES).forceAddTag(ConventionalItemTags.RAW_GOLD_BLOCKS) .addOptionalTag(new Identifier("farmersdelight:golden_knife")); + getOrCreateTagBuilder(UTags.Items.LOOT_BUG_EPIC_DROPS).add( + Items.DIAMOND_BLOCK, + Items.DIAMOND_HELMET, Items.DIAMOND_BOOTS, Items.DIAMOND_LEGGINGS, Items.DIAMOND_CHESTPLATE, + Items.DIAMOND_HORSE_ARMOR, + Items.DIAMOND_PICKAXE, Items.DIAMOND_SHOVEL, Items.DIAMOND_AXE, Items.DIAMOND_SWORD, Items.DIAMOND_HOE, + UItems.DIAMOND_POLEARM + ).forceAddTag(UTags.Items.BADGES).forceAddTag(ConventionalItemTags.GOLD_INGOTS); exportFarmersDelightItems(); } @@ -154,6 +162,10 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { private void exportConventionalTags() { copy(UConventionalTags.Blocks.CONCRETES, UConventionalTags.Items.CONCRETES); copy(UConventionalTags.Blocks.CONCRETE_POWDERS, UConventionalTags.Items.CONCRETE_POWDERS); + copy(UConventionalTags.Blocks.GLAZED_TERRACOTTAS, UConventionalTags.Items.GLAZED_TERRACOTTAS); + copy(UConventionalTags.Blocks.CORAL_BLOCKS, UConventionalTags.Items.CORAL_BLOCKS); + copy(UConventionalTags.Blocks.CORAL_FANS, UConventionalTags.Items.CORAL_FANS); + copy(UConventionalTags.Blocks.CORALS, UConventionalTags.Items.CORALS); getOrCreateTagBuilder(UConventionalTags.Items.ACORNS).add(UItems.ACORN); getOrCreateTagBuilder(UConventionalTags.Items.APPLES) .add(Items.APPLE, Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE, UItems.ROTTEN_APPLE) @@ -161,8 +173,34 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { .addOptionalTag(new Identifier("c", "pyrite_apples")) // no idea which mod add pyrite apples ; getOrCreateTagBuilder(UConventionalTags.Items.BANANAS).add(UItems.BANANA); + getOrCreateTagBuilder(UConventionalTags.Items.RAW_FISH).add(Items.COD, Items.SALMON, Items.PUFFERFISH, Items.TROPICAL_FISH).addOptionalTag(new Identifier("c", "mollusks")); getOrCreateTagBuilder(UConventionalTags.Items.COOKED_FISH).add(Items.COOKED_COD, Items.COOKED_SALMON); + getOrCreateTagBuilder(UConventionalTags.Items.COOKED_MEAT) + .add(Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.COOKED_MUTTON, Items.COOKED_RABBIT, Items.COOKED_CHICKEN, Items.RABBIT_STEW) + .addOptionalTag(new Identifier("c", "cooked_bacon")) + .addOptionalTag(new Identifier("c", "cooked_beef")) + .addOptionalTag(new Identifier("c", "cooked_chicken")) + .addOptionalTag(new Identifier("c", "cooked_mutton")) + .addOptionalTag(new Identifier("c", "cooked_pork")) + .addOptionalTag(new Identifier("c", "fried_chickens")) + .addOptionalTag(new Identifier("c", "hamburgers")) + .addOptionalTag(new Identifier("c", "pork_and_beans")) + .addOptionalTag(new Identifier("c", "pork_jerkies")) + .addOptionalTag(new Identifier("c", "protien")); + getOrCreateTagBuilder(UConventionalTags.Items.RAW_MEAT) + .add(Items.PORKCHOP, Items.BEEF, Items.MUTTON, Items.RABBIT, Items.CHICKEN) + .addOptionalTag(new Identifier("c", "raw_bacon")) + .addOptionalTag(new Identifier("c", "raw_beef")) + .addOptionalTag(new Identifier("c", "raw_chicken")) + .addOptionalTag(new Identifier("c", "raw_mutton")) + .addOptionalTag(new Identifier("c", "raw_pork")) + .addOptionalTag(new Identifier("c", "lemon_chickens")); + getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_MEAT).add(Items.ROTTEN_FLESH); + getOrCreateTagBuilder(UConventionalTags.Items.COOKED_INSECT).add(Items.FERMENTED_SPIDER_EYE); + getOrCreateTagBuilder(UConventionalTags.Items.RAW_INSECT).add(Items.SPIDER_EYE, UItems.BUTTERFLY, UItems.WHEAT_WORMS, UBlocks.WORM_BLOCK.asItem()); + getOrCreateTagBuilder(UConventionalTags.Items.WORMS).add(UItems.WHEAT_WORMS); getOrCreateTagBuilder(UConventionalTags.Items.STICKS).add(Items.STICK); + getOrCreateTagBuilder(UConventionalTags.Items.ROCKS).add(UItems.ROCK); getOrCreateTagBuilder(UConventionalTags.Items.PINECONES).add(UItems.PINECONE); getOrCreateTagBuilder(UConventionalTags.Items.PINEAPPLES).add(UItems.PINEAPPLE); getOrCreateTagBuilder(UConventionalTags.Items.MANGOES).add(UItems.MANGO); @@ -184,9 +222,18 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { private void exportFarmersDelightItems() { getOrCreateTagBuilder(UTags.Items.COOLS_OFF_KIRINS) - .addOptional(new Identifier("farmersdelight:melon_popsicle")) - .addOptional(new Identifier("farmersdelight:melon_juice")); - getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, new Identifier("farmersdelight:cabbage_roll_ingredients"))).add(UItems.OATS, UItems.ROCK, UItems.WHEAT_WORMS); - getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, new Identifier("farmersdelight:comfort_foods"))).add(UItems.OATMEAL, UItems.ROCK_STEW, UItems.MUFFIN); + .addOptional(new Identifier("farmersdelight", "melon_popsicle")) + .addOptional(new Identifier("farmersdelight", "melon_juice")); + getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, new Identifier("farmersdelight", "cabbage_roll_ingredients"))).add(UItems.OATS, UItems.ROCK, UItems.WHEAT_WORMS); + getOrCreateTagBuilder(TagKey.of(RegistryKeys.ITEM, new Identifier("farmersdelight", "comfort_foods"))).add(UItems.OATMEAL, UItems.ROCK_STEW, UItems.MUFFIN); + getOrCreateTagBuilder(UConventionalTags.Items.RAW_FISH) + .addOptional(new Identifier("farmersdelight", "cod_roll")) + .addOptional(new Identifier("farmersdelight", "salmon_roll")) + .addOptional(new Identifier("farmersdelight", "cod_slice")) + .addOptional(new Identifier("farmersdelight", "salmon_slice")); + getOrCreateTagBuilder(UConventionalTags.Items.COOKED_FISH) + .addOptional(new Identifier("farmersdelight", "fish_stew")) + .addOptional(new Identifier("farmersdelight", "baked_cod_stew")) + .addOptional(new Identifier("farmersdelight", "grilled_salmon")); } } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java b/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java index a71c8499..4638ed04 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java @@ -5,11 +5,11 @@ import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; import org.jetbrains.annotations.Nullable; - import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.ItemDuck; import com.mojang.datafixers.util.Pair; @@ -19,13 +19,11 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.client.item.TooltipContext; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.FoodComponent; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.tag.TagKey; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; import net.minecraft.util.UseAction; public record DietProfile( @@ -40,12 +38,34 @@ public record DietProfile( Codec.FLOAT.fieldOf("default_multiplier").forGetter(DietProfile::defaultMultiplier), Codec.FLOAT.fieldOf("foraging_multiplier").forGetter(DietProfile::foragingMultiplier), Codec.list(Multiplier.CODEC).fieldOf("multipliers").forGetter(DietProfile::multipliers), - Codec.list(Effect.CODEC).fieldOf("effects").forGetter(DietProfile::effects), + Codec.list(Effect.PROFILE_CODEC).fieldOf("effects").forGetter(DietProfile::effects), Effect.CODEC.optionalFieldOf("default_effect").forGetter(DietProfile::defaultEffect) ).apply(instance, DietProfile::new)); public DietProfile(PacketByteBuf buffer) { - this(buffer.readFloat(), buffer.readFloat(), buffer.readList(Multiplier::new), buffer.readList(Effect::new), buffer.readOptional(Effect::new)); + this(buffer.readFloat(), buffer.readFloat(), + buffer.readList(Multiplier::new), + buffer.readList(b -> new Effect(b, FoodGroupKey.LOOKUP)), + buffer.readOptional(b -> new Effect(b, FoodGroupKey.LOOKUP)) + ); + } + + public void validate(Consumer issues, Predicate foodGroupExists) { + multipliers.stream().flatMap(i -> i.tags().stream()).forEach(key -> { + if (!foodGroupExists.test(key.id())) { + issues.accept("Multiplier referenced unknown food group: " + key.id()); + } + }); + effects.stream().flatMap(i -> i.tags().stream()).forEach(key -> { + if (!foodGroupExists.test(key.id())) { + issues.accept("Override defined for unknown food group: " + key.id()); + } + }); + defaultEffect.stream().flatMap(i -> i.tags().stream()).forEach(key -> { + if (!foodGroupExists.test(key.id())) { + issues.accept("Default override defined for unknown food group: " + key.id()); + } + }); } public void toBuffer(PacketByteBuf buffer) { @@ -145,11 +165,11 @@ public record DietProfile( } public record Multiplier( - Set> tags, + Set tags, float hunger, float saturation ) implements Predicate { - public static final Codec>> TAGS_CODEC = Codec.list(TagKey.unprefixedCodec(RegistryKeys.ITEM)).xmap( + public static final Codec> TAGS_CODEC = FoodGroupKey.CODEC.listOf().xmap( l -> l.stream().distinct().collect(Collectors.toSet()), set -> new ArrayList<>(set) ); @@ -160,12 +180,12 @@ public record DietProfile( ).apply(instance, Multiplier::new)); public Multiplier(PacketByteBuf buffer) { - this(buffer.readCollection(HashSet::new, p -> TagKey.of(RegistryKeys.ITEM, p.readIdentifier())), buffer.readFloat(), buffer.readFloat()); + this(buffer.readCollection(HashSet::new, p -> FoodGroupKey.LOOKUP.apply(p.readIdentifier())), buffer.readFloat(), buffer.readFloat()); } @Override public boolean test(ItemStack stack) { - return tags.stream().anyMatch(tag -> stack.isIn(tag)); + return tags.stream().anyMatch(tag -> tag.contains(stack)); } public void toBuffer(PacketByteBuf buffer) { diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java b/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java index 963efb77..f517c7a2 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java @@ -1,12 +1,9 @@ package com.minelittlepony.unicopia.diet; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; - import org.slf4j.Logger; import com.google.gson.JsonElement; @@ -36,9 +33,24 @@ public class DietsLoader implements IdentifiableResourceReloadListener { Profiler prepareProfiler, Profiler applyProfiler, Executor prepareExecutor, Executor applyExecutor) { - var dietsLoadTask = loadData(manager, prepareExecutor, "diets/races").thenApplyAsync(data -> { + CompletableFuture> foodGroupsFuture = CompletableFuture.supplyAsync(() -> { + Map foodGroups = new HashMap<>(); + for (var group : loadData(manager, prepareExecutor, "diets/food_groups").entrySet()) { + try { + Effect.CODEC.parse(JsonOps.INSTANCE, group.getValue()) + .resultOrPartial(error -> LOGGER.error("Could not load food group {}: {}", group.getKey(), error)) + .ifPresent(value -> { + foodGroups.put(group.getKey(), value); + }); + } catch (Throwable t) { + LOGGER.error("Could not load food effects {}", group.getKey(), t); + } + } + return foodGroups; + }, prepareExecutor); + CompletableFuture> profilesFuture = CompletableFuture.supplyAsync(() -> { Map profiles = new HashMap<>(); - for (var entry : data.entrySet()) { + for (var entry : loadData(manager, prepareExecutor, "diets/races").entrySet()) { Identifier id = entry.getKey(); try { Race.REGISTRY.getOrEmpty(id).ifPresentOrElse(race -> { @@ -53,33 +65,26 @@ public class DietsLoader implements IdentifiableResourceReloadListener { return profiles; }, prepareExecutor); - var effectsLoadTask = loadData(manager, prepareExecutor, "diets/food_effects").thenApplyAsync(data -> data.entrySet().stream() - .map(entry -> { - try { - return Effect.CODEC.parse(JsonOps.INSTANCE, entry.getValue()) - .resultOrPartial(error -> LOGGER.error("Could not load food effect {}: {}", entry.getKey(), error)); - } catch (Throwable t) { - LOGGER.error("Could not load food effects {}", entry.getKey(), t); - } - return Optional.empty(); - }) - .filter(Optional::isPresent) - .map(Optional::get) - .toList(), prepareExecutor); - - return CompletableFuture.allOf(dietsLoadTask, effectsLoadTask).thenCompose(sync::whenPrepared).thenRunAsync(() -> { - PonyDiets.load(new PonyDiets( - dietsLoadTask.getNow(Map.of()), - effectsLoadTask.getNow(List.of()) - )); + return CompletableFuture.allOf(foodGroupsFuture, profilesFuture).thenCompose(sync::whenPrepared).thenAcceptAsync(v -> { + var profiles = profilesFuture.getNow(Map.of()); + var foodGroups = foodGroupsFuture.getNow(Map.of()); + profiles.entrySet().removeIf(entry -> { + StringBuilder issueList = new StringBuilder(); + entry.getValue().validate(issue -> { + issueList.append(System.lineSeparator()).append(issue); + }, foodGroups::containsKey); + if (!issueList.isEmpty()) { + LOGGER.error("Could not load diet profile {}. Caused by {}", entry.getKey(), issueList.toString()); + } + return issueList.isEmpty(); + }); + PonyDiets.load(new PonyDiets(profiles, foodGroups)); }, applyExecutor); } - private static CompletableFuture> loadData(ResourceManager manager, Executor prepareExecutor, String path) { - return CompletableFuture.supplyAsync(() -> { - Map results = new HashMap<>(); - JsonDataLoader.load(manager, path, Resources.GSON, results); - return results; - }); + private static Map loadData(ResourceManager manager, Executor prepareExecutor, String path) { + Map results = new HashMap<>(); + JsonDataLoader.load(manager, path, Resources.GSON, results); + return results; } } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/Effect.java b/src/main/java/com/minelittlepony/unicopia/diet/Effect.java index 9b7ba05d..b8ce1338 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/Effect.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/Effect.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.diet; import java.util.List; import java.util.Optional; +import java.util.function.Function; import java.util.function.Predicate; import com.minelittlepony.unicopia.entity.player.Pony; @@ -10,30 +11,33 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.client.item.TooltipContext; import net.minecraft.item.FoodComponent; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.tag.TagKey; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; import net.minecraft.util.UseAction; import net.minecraft.util.Util; public record Effect( - List> tags, + List tags, Optional foodComponent, Ailment ailment ) implements Predicate { public static final Effect EMPTY = new Effect(List.of(), Optional.empty(), Ailment.EMPTY); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - TagKey.unprefixedCodec(RegistryKeys.ITEM).listOf().fieldOf("tags").forGetter(Effect::tags), + FoodGroupKey.TAG_CODEC.listOf().fieldOf("tags").forGetter(Effect::tags), + FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(Effect::foodComponent), + Ailment.CODEC.fieldOf("ailment").forGetter(Effect::ailment) + ).apply(instance, Effect::new)); + public static final Codec PROFILE_CODEC = RecordCodecBuilder.create(instance -> instance.group( + FoodGroupKey.CODEC.listOf().fieldOf("tags").forGetter(Effect::tags), FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(Effect::foodComponent), Ailment.CODEC.fieldOf("ailment").forGetter(Effect::ailment) ).apply(instance, Effect::new)); - public Effect(PacketByteBuf buffer) { - this(buffer.readList(b -> TagKey.of(RegistryKeys.ITEM, b.readIdentifier())), buffer.readOptional(FoodAttributes::read), new Ailment(buffer)); + public Effect(PacketByteBuf buffer, Function lookup) { + this(buffer.readList(b -> lookup.apply(b.readIdentifier())), buffer.readOptional(FoodAttributes::read), new Ailment(buffer)); } public void afflict(Pony pony, ItemStack stack) { @@ -43,7 +47,7 @@ public record Effect( public void appendTooltip(ItemStack stack, List tooltip, TooltipContext context) { int size = tooltip.size(); tags.forEach(tag -> { - if (stack.isIn(tag)) { + if (tag.contains(stack)) { tooltip.add(Text.literal(" ").append(Text.translatable(Util.createTranslationKey("tag", tag.id()))).formatted(Formatting.GRAY)); } }); @@ -71,6 +75,6 @@ public record Effect( @Override public boolean test(ItemStack stack) { - return tags.stream().anyMatch(stack::isIn); + return tags.stream().anyMatch(tag -> tag.contains(stack)); } } \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java new file mode 100644 index 00000000..efa49837 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java @@ -0,0 +1,49 @@ +package com.minelittlepony.unicopia.diet; + +import java.util.function.Function; + +import com.mojang.serialization.Codec; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; + +public interface FoodGroupKey { + Function LOOKUP = Util.memoize(id -> { + return new FoodGroupKey() { + @Override + public Identifier id() { + return id; + } + + @Override + public boolean contains(ItemStack stack) { + var group = PonyDiets.getEffect(id); + return group != null && group.test(stack); + } + }; + }); + Function, FoodGroupKey> TAG_LOOKUP = Util.memoize(tag -> { + return new FoodGroupKey() { + @Override + public Identifier id() { + return tag.id(); + } + + @Override + public boolean contains(ItemStack stack) { + return stack.isIn(tag); + } + }; + }); + Function TAG_ID_LOOKUP = id -> TAG_LOOKUP.apply(TagKey.of(RegistryKeys.ITEM, id)); + Codec CODEC = Identifier.CODEC.xmap(LOOKUP, FoodGroupKey::id); + Codec TAG_CODEC = TagKey.unprefixedCodec(RegistryKeys.ITEM).xmap(TAG_LOOKUP, k -> TagKey.of(RegistryKeys.ITEM, k.id())); + + Identifier id(); + + boolean contains(ItemStack stack); +} diff --git a/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java b/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java index 3566bf06..e233871d 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java @@ -18,35 +18,41 @@ import net.minecraft.network.PacketByteBuf; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; import net.minecraft.util.TypedActionResult; import net.minecraft.world.World; public class PonyDiets implements DietView { private final Map diets; - private final List effects; + private final Map effects; - private static PonyDiets INSTANCE = new PonyDiets(Map.of(), List.of()); + private static PonyDiets INSTANCE = new PonyDiets(Map.of(), Map.of()); public static PonyDiets getInstance() { return INSTANCE; } + @Nullable + static Effect getEffect(Identifier id) { + return INSTANCE.effects.get(id); + } + public static void load(PonyDiets diets) { INSTANCE = diets; } - PonyDiets(Map diets, List effects) { + PonyDiets(Map diets, Map effects) { this.diets = diets; this.effects = effects; } public PonyDiets(PacketByteBuf buffer) { - this(buffer.readMap(b -> b.readRegistryValue(Race.REGISTRY), DietProfile::new), buffer.readList(Effect::new)); + this(buffer.readMap(b -> b.readRegistryValue(Race.REGISTRY), DietProfile::new), buffer.readMap(PacketByteBuf::readIdentifier, b -> new Effect(b, FoodGroupKey.TAG_ID_LOOKUP))); } public void toBuffer(PacketByteBuf buffer) { buffer.writeMap(diets, (b, r) -> b.writeRegistryValue(Race.REGISTRY, r), (b, e) -> e.toBuffer(b)); - buffer.writeCollection(effects, (b, e) -> e.toBuffer(b)); + buffer.writeMap(effects, PacketByteBuf::writeIdentifier, (b, e) -> e.toBuffer(b)); } private DietProfile getDiet(Pony pony) { @@ -54,7 +60,7 @@ public class PonyDiets implements DietView { } Effect getEffects(ItemStack stack) { - return effects.stream().filter(effect -> effect.test(stack)).findFirst().orElse(Effect.EMPTY); + return effects.values().stream().filter(effect -> effect.test(stack)).findFirst().orElse(Effect.EMPTY); } private Effect getEffects(ItemStack stack, Pony pony) { diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 54133a8a..6f5978b0 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -622,17 +622,17 @@ "tag.unicopia.food_types.rotten_meat": "Rotting Meat", "tag.unicopia.food_types.raw_meat": "Fresh Meat", "tag.unicopia.food_types.cooked_meat": "Prepared Meat", - "tag.unicopia.food_types.raw_fish": "Fresh Fish", - "tag.unicopia.food_types.cooked_fish": "Prepared Fish", - "tag.unicopia.food_types.raw_insect": "Bugs & Insects", + "tag.c.raw_fish": "Fresh Fish", + "tag.c.cooked_fish": "Prepared Fish", + "tag.c.raw_insect": "Bugs & Insects", "tag.unicopia.food_types.cooked_insect": "Cooked Bugs & Insects", "tag.unicopia.food_types.nuts_and_seeds": "Nuts & Seeds", - "tag.unicopia.food_types.love": "Love", + "tag.unicopia.container_with_love": "Love", "tag.unicopia.food_types.rocks": "Rocks", "tag.unicopia.food_types.pinecone": "Nuts & Seeds", "tag.unicopia.food_types.bat_ponys_delight": "Bat Pony Treats", - "tag.unicopia.food_types.cooked_sea_vegitables": "Prepared Fish Food", - "tag.unicopia.food_types.raw_sea_vegitables": "Fresh Fish Food", + "tag.unicopia.food_types.cooked_sea_vegitable": "Prepared Fish Food", + "tag.unicopia.food_types.raw_sea_vegitable": "Fresh Fish Food", "tag.unicopia.food_types.shells": "Sea Shells", "tag.unicopia.food_types.shelly": "Sea Shells", "tag.unicopia.food_types.candy": "Candy", diff --git a/src/main/resources/data/c/tags/items/concrete.json b/src/main/resources/data/c/tags/items/concrete.json deleted file mode 100644 index c09d67ba..00000000 --- a/src/main/resources/data/c/tags/items/concrete.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:white_concrete", - "minecraft:orange_concrete", - "minecraft:magenta_concrete", - "minecraft:light_blue_concrete", - "minecraft:yellow_concrete", - "minecraft:lime_concrete", - "minecraft:pink_concrete", - "minecraft:gray_concrete", - "minecraft:light_gray_concrete", - "minecraft:cyan_concrete", - "minecraft:purple_concrete", - "minecraft:blue_concrete", - "minecraft:brown_concrete", - "minecraft:green_concrete", - "minecraft:red_concrete", - "minecraft:black_concrete" - ] -} diff --git a/src/main/resources/data/c/tags/items/cooked_insects.json b/src/main/resources/data/c/tags/items/cooked_insects.json deleted file mode 100644 index 1a241c36..00000000 --- a/src/main/resources/data/c/tags/items/cooked_insects.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:fermented_spider_eye", - { "id": "#c:cooked_insect", "required": false } - ] -} diff --git a/src/main/resources/data/c/tags/items/cooked_meats.json b/src/main/resources/data/c/tags/items/cooked_meats.json deleted file mode 100644 index 52b592bc..00000000 --- a/src/main/resources/data/c/tags/items/cooked_meats.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:cooked_porkchop", - "minecraft:cooked_beef", - "minecraft:cooked_mutton", - "minecraft:cooked_rabbit", - "minecraft:rabbit_stew", - "minecraft:cooked_chicken", - { "id": "#c:cooked_meat", "required": false }, - { "id": "#c:cooked_bacon", "required": false }, - { "id": "#c:cooked_beef", "required": false }, - { "id": "#c:cooked_chicken", "required": false }, - { "id": "#c:cooked_mutton", "required": false }, - { "id": "#c:cooked_pork", "required": false }, - { "id": "#c:fried_chickens", "required": false }, - { "id": "#c:hamburgers", "required": false }, - { "id": "#c:pork_and_beans", "required": false }, - { "id": "#c:pork_jerkies", "required": false }, - { "id": "#c:protein", "required": false } - ] -} diff --git a/src/main/resources/data/c/tags/items/coral_blocks.json b/src/main/resources/data/c/tags/items/coral_blocks.json deleted file mode 100644 index e907eedc..00000000 --- a/src/main/resources/data/c/tags/items/coral_blocks.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:tube_coral_block", - "minecraft:brain_coral_block", - "minecraft:bubble_coral_block", - "minecraft:fire_coral_block", - "minecraft:horn_coral_block" - ] -} diff --git a/src/main/resources/data/c/tags/items/coral_fans.json b/src/main/resources/data/c/tags/items/coral_fans.json deleted file mode 100644 index 531d24c9..00000000 --- a/src/main/resources/data/c/tags/items/coral_fans.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:tube_coral_fan", - "minecraft:brain_coral_fan", - "minecraft:bubble_coral_fan", - "minecraft:fire_coral_fan", - "minecraft:horn_coral_fan" - ] -} diff --git a/src/main/resources/data/c/tags/items/corals.json b/src/main/resources/data/c/tags/items/corals.json deleted file mode 100644 index cec1b08e..00000000 --- a/src/main/resources/data/c/tags/items/corals.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:tube_coral", - "minecraft:brain_coral", - "minecraft:bubble_coral", - "minecraft:fire_coral", - "minecraft:horn_coral" - ] -} diff --git a/src/main/resources/data/c/tags/items/glazed_terracotta.json b/src/main/resources/data/c/tags/items/glazed_terracotta.json deleted file mode 100644 index 02b98848..00000000 --- a/src/main/resources/data/c/tags/items/glazed_terracotta.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:white_glazed_terracotta", - "minecraft:orange_glazed_terracotta", - "minecraft:magenta_glazed_terracotta", - "minecraft:light_blue_glazed_terracotta", - "minecraft:yellow_glazed_terracotta", - "minecraft:lime_glazed_terracotta", - "minecraft:pink_glazed_terracotta", - "minecraft:gray_glazed_terracotta", - "minecraft:light_gray_glazed_terracotta", - "minecraft:cyan_glazed_terracotta", - "minecraft:purple_glazed_terracotta", - "minecraft:blue_glazed_terracotta", - "minecraft:brown_glazed_terracotta", - "minecraft:green_glazed_terracotta", - "minecraft:red_glazed_terracotta", - "minecraft:black_glazed_terracotta" - ] -} diff --git a/src/main/resources/data/c/tags/items/love.json b/src/main/resources/data/c/tags/items/love.json deleted file mode 100644 index 213d70aa..00000000 --- a/src/main/resources/data/c/tags/items/love.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:love_bottle", - "unicopia:love_bucket", - "unicopia:love_mug" - ] -} diff --git a/src/main/resources/data/c/tags/items/raw_fish.json b/src/main/resources/data/c/tags/items/raw_fish.json deleted file mode 100644 index 902fad0f..00000000 --- a/src/main/resources/data/c/tags/items/raw_fish.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:pufferfish", - "minecraft:cod", - "minecraft:salmon", - "minecraft:tropical_fish", - { "id": "#c:mollusks", "required": false } - ] -} diff --git a/src/main/resources/data/c/tags/items/raw_insects.json b/src/main/resources/data/c/tags/items/raw_insects.json deleted file mode 100644 index ad219e8b..00000000 --- a/src/main/resources/data/c/tags/items/raw_insects.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:spider_eye", - "unicopia:butterfly", - "unicopia:wheat_worms", - "unicopia:worm_block" - ] -} diff --git a/src/main/resources/data/c/tags/items/raw_meats.json b/src/main/resources/data/c/tags/items/raw_meats.json deleted file mode 100644 index 5333f1f8..00000000 --- a/src/main/resources/data/c/tags/items/raw_meats.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:porkchop", - "minecraft:beef", - "minecraft:mutton", - "minecraft:rabbit", - "minecraft:chicken", - { "id": "#c:raw_meat", "required": false }, - { "id": "#c:lemon_chickens", "required": false }, - { "id": "#c:raw_bacon", "required": false }, - { "id": "#c:raw_beef", "required": false }, - { "id": "#c:raw_chicken", "required": false }, - { "id": "#c:raw_mutton", "required": false }, - { "id": "#c:raw_pork", "required": false } - ] -} diff --git a/src/main/resources/data/c/tags/items/rocks.json b/src/main/resources/data/c/tags/items/rocks.json deleted file mode 100644 index 9ab866dd..00000000 --- a/src/main/resources/data/c/tags/items/rocks.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:rock" - ] -} diff --git a/src/main/resources/data/c/tags/items/rotten_meats.json b/src/main/resources/data/c/tags/items/rotten_meats.json deleted file mode 100644 index 3f3bc662..00000000 --- a/src/main/resources/data/c/tags/items/rotten_meats.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:rotten_flesh" - ] -} diff --git a/src/main/resources/data/c/tags/items/worms.json b/src/main/resources/data/c/tags/items/worms.json deleted file mode 100644 index 9c8b8692..00000000 --- a/src/main/resources/data/c/tags/items/worms.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:wheat_worms" - ] -} diff --git a/src/main/resources/data/minecraft/traits/blocks/overworld/conglomerate_materials_from_ground.json b/src/main/resources/data/minecraft/traits/blocks/overworld/conglomerate_materials_from_ground.json index a19e4901..200f8b3f 100644 --- a/src/main/resources/data/minecraft/traits/blocks/overworld/conglomerate_materials_from_ground.json +++ b/src/main/resources/data/minecraft/traits/blocks/overworld/conglomerate_materials_from_ground.json @@ -3,7 +3,7 @@ "traits": "earth:1 order:1 knowledge:4", "items": [ "#minecraft:terracotta", - "#c:concrete", - "#c:glazed_terracotta" + "#c:concretes", + "#c:glazed_terracottas" ] } \ No newline at end of file diff --git a/src/main/resources/data/minecraft/traits/items/overworld/edible_cooked_meat.json b/src/main/resources/data/minecraft/traits/items/overworld/edible_cooked_meat.json index e65442d1..8dd2afb5 100644 --- a/src/main/resources/data/minecraft/traits/items/overworld/edible_cooked_meat.json +++ b/src/main/resources/data/minecraft/traits/items/overworld/edible_cooked_meat.json @@ -2,8 +2,6 @@ "replace": false, "traits": "famine:-0.5 life:-1 knowledge:2", "items": [ - "#c:cooked_meats", - "#c:cooked_fish", "minecraft:fermented_spider_eye", "#unicopia:food_types/cooked_fish", "#unicopia:food_types/cooked_meat" diff --git a/src/main/resources/data/minecraft/traits/items/overworld/edible_raw_meat.json b/src/main/resources/data/minecraft/traits/items/overworld/edible_raw_meat.json index 07371361..19d29187 100644 --- a/src/main/resources/data/minecraft/traits/items/overworld/edible_raw_meat.json +++ b/src/main/resources/data/minecraft/traits/items/overworld/edible_raw_meat.json @@ -2,6 +2,6 @@ "replace": false, "traits": "blood:1 famine:-2", "items": [ - "#c:raw_meats" + "#c:raw_meat" ] } \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_effects/baked_goods.json b/src/main/resources/data/unicopia/diets/food_groups/baked_goods.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/baked_goods.json rename to src/main/resources/data/unicopia/diets/food_groups/baked_goods.json diff --git a/src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json b/src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json new file mode 100644 index 00000000..0fd1f3a0 --- /dev/null +++ b/src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json @@ -0,0 +1,10 @@ +{ + "tags": [ "unicopia:food_types/bat_ponys_delight" ], + "food_component": { + "hunger": 1, + "saturation": 0.1 + }, + "ailment": { + "effects": [] + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_effects/candy.json b/src/main/resources/data/unicopia/diets/food_groups/candy.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/candy.json rename to src/main/resources/data/unicopia/diets/food_groups/candy.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/desserts.json b/src/main/resources/data/unicopia/diets/food_groups/desserts.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/desserts.json rename to src/main/resources/data/unicopia/diets/food_groups/desserts.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/fish/cooked.json b/src/main/resources/data/unicopia/diets/food_groups/fish/cooked.json similarity index 81% rename from src/main/resources/data/unicopia/diets/food_effects/fish/cooked.json rename to src/main/resources/data/unicopia/diets/food_groups/fish/cooked.json index 423e578f..cddeb511 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/fish/cooked.json +++ b/src/main/resources/data/unicopia/diets/food_groups/fish/cooked.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/cooked_fish" ], + "tags": [ "c:cooked_fish" ], "food_component": { "hunger": 1, "saturation": 0.1 diff --git a/src/main/resources/data/unicopia/diets/food_effects/fish/raw.json b/src/main/resources/data/unicopia/diets/food_groups/fish/raw.json similarity index 87% rename from src/main/resources/data/unicopia/diets/food_effects/fish/raw.json rename to src/main/resources/data/unicopia/diets/food_groups/fish/raw.json index 40368a26..d33785d3 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/fish/raw.json +++ b/src/main/resources/data/unicopia/diets/food_groups/fish/raw.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/raw_fish" ], + "tags": [ "c:raw_fish" ], "food_component": { "hunger": 1, "saturation": 0.1 diff --git a/src/main/resources/data/unicopia/diets/food_effects/fish/rotten.json b/src/main/resources/data/unicopia/diets/food_groups/fish/rotten.json similarity index 87% rename from src/main/resources/data/unicopia/diets/food_effects/fish/rotten.json rename to src/main/resources/data/unicopia/diets/food_groups/fish/rotten.json index 4259828b..fc362289 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/fish/rotten.json +++ b/src/main/resources/data/unicopia/diets/food_groups/fish/rotten.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/rotten_fish" ], + "tags": [ "c:rotten_fish" ], "food_component": { "hunger": 1, "saturation": 0.1 diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/blinding.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/blinding.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/blinding.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/blinding.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/dangerous.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/dangerous.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/dangerous.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/dangerous.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/edible.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/edible.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/edible.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/edible.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/edible_filling.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/edible_filling.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/edible_filling.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/edible_filling.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/leafy_greens.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/leafy_greens.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/leafy_greens.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/leafy_greens.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/moderate.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/moderate.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/moderate.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/moderate.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/nauseating.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/nauseating.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/nauseating.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/nauseating.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/prickly.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/prickly.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/prickly.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/prickly.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/radioactive.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/radioactive.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/radioactive.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/radioactive.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/risky.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/risky.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/risky.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/risky.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/severely_nauseating.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/severely_nauseating.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/severely_nauseating.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/severely_nauseating.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/severely_prickly.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/severely_prickly.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/severely_prickly.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/severely_prickly.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/foraging/strengthening.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/strengthening.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/foraging/strengthening.json rename to src/main/resources/data/unicopia/diets/food_groups/foraging/strengthening.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/fruit.json b/src/main/resources/data/unicopia/diets/food_groups/fruit.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/fruit.json rename to src/main/resources/data/unicopia/diets/food_groups/fruit.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/insect/cooked.json b/src/main/resources/data/unicopia/diets/food_groups/insect/cooked.json similarity index 80% rename from src/main/resources/data/unicopia/diets/food_effects/insect/cooked.json rename to src/main/resources/data/unicopia/diets/food_groups/insect/cooked.json index 9dbdc566..7d35ae55 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/insect/cooked.json +++ b/src/main/resources/data/unicopia/diets/food_groups/insect/cooked.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/cooked_insect" ], + "tags": [ "c:cooked_insect" ], "food_component": { "hunger": 1, "saturation": 0.1 diff --git a/src/main/resources/data/unicopia/diets/food_effects/insect/raw.json b/src/main/resources/data/unicopia/diets/food_groups/insect/raw.json similarity index 81% rename from src/main/resources/data/unicopia/diets/food_effects/insect/raw.json rename to src/main/resources/data/unicopia/diets/food_groups/insect/raw.json index 01a176d0..37686f06 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/insect/raw.json +++ b/src/main/resources/data/unicopia/diets/food_groups/insect/raw.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/raw_insect" ], + "tags": [ "c:raw_insect" ], "food_component": { "hunger": 6, "saturation": 0.3 diff --git a/src/main/resources/data/unicopia/diets/food_groups/love.json b/src/main/resources/data/unicopia/diets/food_groups/love.json new file mode 100644 index 00000000..29837e42 --- /dev/null +++ b/src/main/resources/data/unicopia/diets/food_groups/love.json @@ -0,0 +1,21 @@ +{ + "tags": [ "unicopia:container_with_love" ], + "food_component": { + "hunger": 2, + "saturation": 0.4 + }, + "ailment": { + "effects": [ + { + "effect": "unicopia:food_poisoning", + "seconds": 50, + "amplifier": 2 + }, + { + "name": "unicopia.affliction.love_sickness", + "type": "unicopia:lose_hunger", + "multiplier": 0.5 + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_effects/meat/cooked.json b/src/main/resources/data/unicopia/diets/food_groups/meat/cooked.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/meat/cooked.json rename to src/main/resources/data/unicopia/diets/food_groups/meat/cooked.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/meat/raw.json b/src/main/resources/data/unicopia/diets/food_groups/meat/raw.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/meat/raw.json rename to src/main/resources/data/unicopia/diets/food_groups/meat/raw.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/meat/rotten.json b/src/main/resources/data/unicopia/diets/food_groups/meat/rotten.json similarity index 87% rename from src/main/resources/data/unicopia/diets/food_effects/meat/rotten.json rename to src/main/resources/data/unicopia/diets/food_groups/meat/rotten.json index 72faee0e..1af89970 100644 --- a/src/main/resources/data/unicopia/diets/food_effects/meat/rotten.json +++ b/src/main/resources/data/unicopia/diets/food_groups/meat/rotten.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/rotten_meat" ], + "tags": [ "c:rotten_meat" ], "food_component": { "hunger": 1, "saturation": 1 diff --git a/src/main/resources/data/unicopia/diets/food_effects/nuts_and_seeds.json b/src/main/resources/data/unicopia/diets/food_groups/nuts_and_seeds.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/nuts_and_seeds.json rename to src/main/resources/data/unicopia/diets/food_groups/nuts_and_seeds.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/pinecone.json b/src/main/resources/data/unicopia/diets/food_groups/pinecone.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/pinecone.json rename to src/main/resources/data/unicopia/diets/food_groups/pinecone.json diff --git a/src/main/resources/data/unicopia/diets/food_effects/rocks.json b/src/main/resources/data/unicopia/diets/food_groups/rocks.json similarity index 100% rename from src/main/resources/data/unicopia/diets/food_effects/rocks.json rename to src/main/resources/data/unicopia/diets/food_groups/rocks.json diff --git a/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json b/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json new file mode 100644 index 00000000..194273c0 --- /dev/null +++ b/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json @@ -0,0 +1,11 @@ +{ + "tags": [ "unicopia:food_types/cooked_sea_vegitable" ], + "food_component": { + "hunger": 0, + "saturation": 0 + }, + "ailment": { + "effects": [ + ] + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json b/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json new file mode 100644 index 00000000..9fdb8ebf --- /dev/null +++ b/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json @@ -0,0 +1,11 @@ +{ + "tags": [ "unicopia:food_types/raw_sea_vegitable" ], + "food_component": { + "hunger": 0, + "saturation": 0 + }, + "ailment": { + "effects": [ + ] + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/shells.json b/src/main/resources/data/unicopia/diets/food_groups/shells.json new file mode 100644 index 00000000..e4760a96 --- /dev/null +++ b/src/main/resources/data/unicopia/diets/food_groups/shells.json @@ -0,0 +1,10 @@ +{ + "tags": [ "unicopia:food_types/shells", "unicopia:food_types/shelly" ], + "food_component": { + "hunger": 0, + "saturation": 0 + }, + "ailment": { + "effects": [] + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/shelly.json b/src/main/resources/data/unicopia/diets/food_groups/shelly.json new file mode 100644 index 00000000..e4760a96 --- /dev/null +++ b/src/main/resources/data/unicopia/diets/food_groups/shelly.json @@ -0,0 +1,10 @@ +{ + "tags": [ "unicopia:food_types/shells", "unicopia:food_types/shelly" ], + "food_component": { + "hunger": 0, + "saturation": 0 + }, + "ailment": { + "effects": [] + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/races/alicorn.json b/src/main/resources/data/unicopia/diets/races/alicorn.json index caf175c1..8801183e 100644 --- a/src/main/resources/data/unicopia/diets/races/alicorn.json +++ b/src/main/resources/data/unicopia/diets/races/alicorn.json @@ -3,49 +3,49 @@ "foraging_multiplier": 0.9, "multipliers": [ { - "tags": [ "unicopia:food_types/cooked_fish" ], + "tags": [ "unicopia:fish/cooked" ], "hunger": 1.5, "saturation": 1.5 }, { - "tags": [ "unicopia:food_types/raw_fish" ], + "tags": [ "unicopia:fish/raw" ], "hunger": 0.5, "saturation": 0.6 }, { "tags": [ - "unicopia:food_types/baked_goods" + "unicopia:baked_goods" ], "hunger": 1, "saturation": 1 }, { "tags": [ - "unicopia:food_types/cooked_insect", - "unicopia:food_types/cooked_meat" + "unicopia:insect/cooked", + "unicopia:meat/cooked" ], "hunger": 0.1, "saturation": 0.1 }, { "tags": [ - "unicopia:food_types/love", - "unicopia:food_types/raw_insect", - "unicopia:food_types/raw_meat", - "unicopia:food_types/rotten_meat" + "unicopia:love", + "unicopia:insect/raw", + "unicopia:meat/raw", + "unicopia:meat/rotten" ], "hunger": 0, "saturation": 0 }, { - "tags": [ "unicopia:food_types/pinecone" ], + "tags": [ "unicopia:pinecone" ], "hunger": 0.9, "saturation": 0.9 } ], "effects": [ { - "tags": [ "unicopia:food_types/cooked_fish" ], + "tags": [ "unicopia:fish/cooked" ], "food_component": { "hunger": 2, "saturation": 1 @@ -55,7 +55,7 @@ } }, { - "tags": [ "unicopia:food_types/raw_fish" ], + "tags": [ "unicopia:fish/raw" ], "ailment": { "effects": [ ] } diff --git a/src/main/resources/data/unicopia/diets/races/bat.json b/src/main/resources/data/unicopia/diets/races/bat.json index 283a8788..b5c17d1b 100644 --- a/src/main/resources/data/unicopia/diets/races/bat.json +++ b/src/main/resources/data/unicopia/diets/races/bat.json @@ -3,54 +3,54 @@ "foraging_multiplier": 0.9, "multipliers": [ { - "tags": [ "unicopia:food_types/cooked_fish" ], + "tags": [ "unicopia:fish/cooked" ], "hunger": 0.75, "saturation": 0.75 }, { - "tags": [ "unicopia:food_types/raw_fish" ], + "tags": [ "unicopia:fish/raw" ], "hunger": 0.5, "saturation": 0.6 }, { - "tags": [ "unicopia:food_types/cooked_insect" ], + "tags": [ "unicopia:insect/cooked" ], "hunger": 1.75, "saturation": 1.75 }, { - "tags": [ "unicopia:food_types/cooked_meat" ], + "tags": [ "unicopia:meat/cooked" ], "hunger": 1.15, "saturation": 1.15 }, { - "tags": [ "unicopia:food_types/raw_insect" ], + "tags": [ "unicopia:insect/raw" ], "hunger": 1, "saturation": 1 }, { - "tags": [ "unicopia:food_types/raw_meat" ], + "tags": [ "unicopia:meat/raw" ], "hunger": 0.25, "saturation": 0.25 }, { - "tags": [ "unicopia:food_types/rotten_meat" ], + "tags": [ "unicopia:meat/rotten" ], "hunger": 0.2, "saturation": 0.2 }, { - "tags": [ "unicopia:food_types/love" ], + "tags": [ "unicopia:love" ], "hunger": 0, "saturation": 0 }, { - "tags": [ "unicopia:food_types/pinecone" ], + "tags": [ "unicopia:pinecone" ], "hunger": 0.9, "saturation": 0.9 } ], "effects": [ { - "tags": [ "unicopia:food_types/rotten_fish" ], + "tags": [ "unicopia:fish/rotten" ], "ailment": { "effects": [ { @@ -64,15 +64,15 @@ }, { "tags": [ - "unicopia:food_types/cooked_insect", - "unicopia:food_types/cooked_meat" + "unicopia:insect/cooked", + "unicopia:meat/cooked" ], "ailment": { "effects": [ ] } }, { - "tags": [ "unicopia:food_types/raw_insect" ], + "tags": [ "unicopia:insect/raw" ], "ailment": { "effects": [ { @@ -85,8 +85,8 @@ }, { "tags": [ - "unicopia:food_types/raw_meat", - "unicopia:food_types/rotten_meat" + "unicopia:meat/raw", + "unicopia:meat/rotten" ], "ailment": { "effects": [ @@ -100,7 +100,7 @@ } }, { - "tags": [ "unicopia:food_types/bat_ponys_delight" ], + "tags": [ "unicopia:bat_ponys_delight" ], "ailment": { "effects": [ { diff --git a/src/main/resources/data/unicopia/diets/races/changeling.json b/src/main/resources/data/unicopia/diets/races/changeling.json index c20c7753..e0c79004 100644 --- a/src/main/resources/data/unicopia/diets/races/changeling.json +++ b/src/main/resources/data/unicopia/diets/races/changeling.json @@ -3,39 +3,39 @@ "foraging_multiplier": 0.1, "multipliers": [ { - "tags": [ "unicopia:food_types/cooked_insect" ], + "tags": [ "unicopia:insect/cooked" ], "hunger": 2.0, "saturation": 1.3 }, { - "tags": [ "unicopia:food_types/cooked_meat" ], + "tags": [ "unicopia:meat/cooked" ], "hunger": 1.9, "saturation": 1.2 }, { - "tags": [ "unicopia:food_types/raw_insect" ], + "tags": [ "unicopia:insect/raw" ], "hunger": 1, "saturation": 1 }, { - "tags": [ "unicopia:food_types/raw_meat" ], + "tags": [ "unicopia:meat/raw" ], "hunger": 1.25, "saturation": 1.25 }, { - "tags": [ "unicopia:food_types/rotten_meat" ], + "tags": [ "unicopia:meat/rotten" ], "hunger": 0.6, "saturation": 0.6 }, { "tags": [ - "unicopia:food_types/baked_goods" + "unicopia:baked_goods" ], "hunger": 0.5, "saturation": 0.9 }, { - "tags": [ "unicopia:food_types/love" ], + "tags": [ "unicopia:love" ], "hunger": 5, "saturation": 3 } @@ -60,7 +60,7 @@ }, "effects": [ { - "tags": [ "unicopia:food_types/love" ], + "tags": [ "unicopia:love" ], "food_component": { "hunger": 2, "saturation": 1 @@ -76,7 +76,7 @@ }, { "tags": [ - "unicopia:food_types/raw_insect" + "unicopia:insect/raw" ], "food_component": { "hunger": 3, @@ -88,8 +88,8 @@ }, { "tags": [ - "unicopia:food_types/cooked_fish", - "unicopia:food_types/raw_fish" + "unicopia:fish/cooked", + "unicopia:fish/raw" ], "ailment": { "effects": [ @@ -108,11 +108,11 @@ }, { "tags": [ - "unicopia:food_types/rotten_fish", - "unicopia:food_types/cooked_insect", - "unicopia:food_types/cooked_meat", - "unicopia:food_types/raw_meat", - "unicopia:food_types/rotten_meat" + "unicopia:fish/rotten", + "unicopia:insect/cooked", + "unicopia:meat/cooked", + "unicopia:meat/raw", + "unicopia:meat/rotten" ], "food_component": { "hunger": 6, @@ -129,8 +129,8 @@ }, { "tags": [ - "unicopia:food_types/forage_edible", - "unicopia:food_types/forage_edible_filling" + "unicopia:foraging/edible", + "unicopia:foraging/edible_filling" ], "food_component": { "hunger": 18, diff --git a/src/main/resources/data/unicopia/diets/races/earth.json b/src/main/resources/data/unicopia/diets/races/earth.json index e06a0fd5..75cd8f16 100644 --- a/src/main/resources/data/unicopia/diets/races/earth.json +++ b/src/main/resources/data/unicopia/diets/races/earth.json @@ -4,46 +4,46 @@ "multipliers": [ { "tags": [ - "unicopia:food_types/candy", - "unicopia:food_types/desserts", - "unicopia:food_types/rocks" + "unicopia:candy", + "unicopia:desserts", + "unicopia:rocks" ], "hunger": 2.5, "saturation": 1.7 }, { "tags": [ - "unicopia:food_types/baked_goods" + "unicopia:baked_goods" ], "hunger": 1.2, "saturation": 2 }, { - "tags": [ "unicopia:food_types/cooked_fish" ], + "tags": [ "unicopia:fish/cooked" ], "hunger": 0.2, "saturation": 0.2 }, { "tags": [ - "unicopia:food_types/cooked_insect", - "unicopia:food_types/cooked_meat" + "unicopia:insect/cooked", + "unicopia:meat/cooked" ], "hunger": 0.1, "saturation": 0.1 }, { "tags": [ - "unicopia:food_types/love", - "unicopia:food_types/raw_fish", - "unicopia:food_types/raw_insect", - "unicopia:food_types/raw_meat", - "unicopia:food_types/rotten_meat" + "unicopia:love", + "unicopia:fish/raw", + "unicopia:insect/raw", + "unicopia:meat/raw", + "unicopia:meat/rotten" ], "hunger": 0, "saturation": 0 }, { - "tags": [ "unicopia:food_types/pinecone" ], + "tags": [ "unicopia:pinecone" ], "hunger": 1, "saturation": 1 } @@ -51,8 +51,8 @@ "effects": [ { "tags": [ - "unicopia:food_types/candy", - "unicopia:food_types/rocks" + "unicopia:candy", + "unicopia:rocks" ], "food_component": { "hunger": 5, @@ -65,7 +65,7 @@ }, { "tags": [ - "unicopia:food_types/desserts" + "unicopia:desserts" ], "food_component": { "hunger": 12, diff --git a/src/main/resources/data/unicopia/diets/races/hippogriff.json b/src/main/resources/data/unicopia/diets/races/hippogriff.json index c91d791e..22c21e1f 100644 --- a/src/main/resources/data/unicopia/diets/races/hippogriff.json +++ b/src/main/resources/data/unicopia/diets/races/hippogriff.json @@ -4,57 +4,57 @@ "multipliers": [ { "tags": [ - "unicopia:food_types/cooked_meat", - "unicopia:food_types/cooked_fish" + "unicopia:meat/cooked", + "unicopia:fish/cooked" ], "hunger": 1.6, "saturation": 1.6 }, { "tags": [ - "unicopia:food_types/nuts_and_seeds" + "unicopia:nuts_and_seeds" ], "hunger": 1.4, "saturation": 1.4 }, { "tags": [ - "unicopia:food_types/baked_goods" + "unicopia:baked_goods" ], "hunger": 1, "saturation": 1 }, { "tags": [ - "unicopia:food_types/raw_meat", - "unicopia:food_types/raw_fish" + "unicopia:meat/raw", + "unicopia:fish/raw" ], "hunger": 0.6, "saturation": 0.6 }, { - "tags": [ "unicopia:food_types/rotten_meat" ], + "tags": [ "unicopia:meat/rotten" ], "hunger": 0.3, "saturation": 0.3 }, { "tags": [ - "unicopia:food_types/love", - "unicopia:food_types/raw_insect", - "unicopia:food_types/cooked_insect" + "unicopia:love", + "unicopia:insect/raw", + "unicopia:insect/cooked" ], "hunger": 0, "saturation": 0 }, { - "tags": [ "unicopia:food_types/pinecone" ], + "tags": [ "unicopia:pinecone" ], "hunger": 1, "saturation": 1 } ], "effects": [ { - "tags": [ "unicopia:food_types/cooked_fish" ], + "tags": [ "unicopia:fish/cooked" ], "food_component": { "hunger": 2, "saturation": 1 @@ -64,15 +64,15 @@ } }, { - "tags": [ "unicopia:food_types/raw_fish" ], + "tags": [ "unicopia:fish/raw" ], "ailment": { "effects": [ ] } }, { "tags": [ - "unicopia:food_types/forage_prickly", - "unicopia:food_types/forage_severely_prickly" + "unicopia:foraging/prickly", + "unicopia:foraging/severely_prickly" ], "food_component": { "hunger": 2, @@ -83,7 +83,7 @@ } }, { - "tags": [ "unicopia:food_types/pinecone" ], + "tags": [ "unicopia:pinecone" ], "ailment": { "effects": [ { diff --git a/src/main/resources/data/unicopia/diets/races/human.json b/src/main/resources/data/unicopia/diets/races/human.json index ddf024b3..67db4d5b 100644 --- a/src/main/resources/data/unicopia/diets/races/human.json +++ b/src/main/resources/data/unicopia/diets/races/human.json @@ -5,13 +5,13 @@ "effects": [ { "tags": [ - "unicopia:food_types/cooked_fish", - "unicopia:food_types/raw_fish", - "unicopia:food_types/rotten_fish", - "unicopia:food_types/cooked_meat", - "unicopia:food_types/raw_meat", - "unicopia:food_types/rotten_meat", - "unicopia:food_types/pinecone" + "unicopia:fish/cooked", + "unicopia:fish/raw", + "unicopia:fish/rotten", + "unicopia:meat/cooked", + "unicopia:meat/raw", + "unicopia:meat/rotten", + "unicopia:pinecone" ], "ailment": { "effects": [ ] diff --git a/src/main/resources/data/unicopia/diets/races/kirin.json b/src/main/resources/data/unicopia/diets/races/kirin.json index 42b41a67..5a9a5919 100644 --- a/src/main/resources/data/unicopia/diets/races/kirin.json +++ b/src/main/resources/data/unicopia/diets/races/kirin.json @@ -3,42 +3,42 @@ "foraging_multiplier": 0.9, "multipliers": [ { - "tags": [ "unicopia:food_types/cooked_meat" ], + "tags": [ "unicopia:meat/cooked" ], "hunger": 1.5, "saturation": 1.5 }, { - "tags": [ "unicopia:food_types/raw_meat" ], + "tags": [ "unicopia:meat/raw" ], "hunger": 0.5, "saturation": 0.6 }, { "tags": [ - "unicopia:food_types/baked_goods" + "unicopia:baked_goods" ], "hunger": 1, "saturation": 1 }, { "tags": [ - "unicopia:food_types/cooked_insect", - "unicopia:food_types/cooked_fish" + "unicopia:insect/cooked", + "unicopia:fish/cooked" ], "hunger": 0.1, "saturation": 0.1 }, { "tags": [ - "unicopia:food_types/love", - "unicopia:food_types/raw_insect", - "unicopia:food_types/raw_fish", - "unicopia:food_types/rotten_meat" + "unicopia:love", + "unicopia:insect/raw", + "unicopia:fish/raw", + "unicopia:meat/rotten" ], "hunger": 0, "saturation": 0 }, { - "tags": [ "unicopia:food_types/pinecone" ], + "tags": [ "unicopia:pinecone" ], "hunger": 0.9, "saturation": 0.9 } @@ -46,15 +46,15 @@ "effects": [ { "tags": [ - "unicopia:food_types/rotten_fish", - "unicopia:food_types/cooked_insect", - "unicopia:food_types/cooked_meat", - "unicopia:food_types/raw_meat", - "unicopia:food_types/rotten_meat", - "unicopia:food_types/forage_blinding", - "unicopia:food_types/forage_prickly", - "unicopia:food_types/forage_severely_prickly", - "unicopia:food_types/forage_strengthening" + "unicopia:fish/rotten", + "unicopia:insect/cooked", + "unicopia:meat/cooked", + "unicopia:meat/raw", + "unicopia:meat/rotten", + "unicopia:foraging/blinding", + "unicopia:foraging/prickly", + "unicopia:foraging/severely_prickly", + "unicopia:foraging/strengthening" ], "food_component": { "hunger": 2, diff --git a/src/main/resources/data/unicopia/diets/races/pegasus.json b/src/main/resources/data/unicopia/diets/races/pegasus.json index d1208202..7cbd683a 100644 --- a/src/main/resources/data/unicopia/diets/races/pegasus.json +++ b/src/main/resources/data/unicopia/diets/races/pegasus.json @@ -3,55 +3,55 @@ "foraging_multiplier": 1, "multipliers": [ { - "tags": [ "unicopia:food_types/cooked_fish" ], + "tags": [ "unicopia:fish/cooked" ], "hunger": 1.5, "saturation": 1.5 }, { - "tags": [ "unicopia:food_types/raw_fish" ], + "tags": [ "unicopia:fish/raw" ], "hunger": 0.5, "saturation": 0.6 }, { "tags": [ - "unicopia:food_types/baked_goods" + "unicopia:baked_goods" ], "hunger": 1, "saturation": 1 }, { "tags": [ - "unicopia:food_types/cooked_insect", - "unicopia:food_types/cooked_meat" + "unicopia:insect/cooked", + "unicopia:meat/cooked" ], "hunger": 0.1, "saturation": 0.1 }, { "tags": [ - "unicopia:food_types/love", - "unicopia:food_types/raw_insect", - "unicopia:food_types/raw_meat", - "unicopia:food_types/rotten_meat" + "unicopia:love", + "unicopia:insect/raw", + "unicopia:meat/raw", + "unicopia:meat/rotten" ], "hunger": 0, "saturation": 0 }, { - "tags": [ "unicopia:food_types/pinecone" ], + "tags": [ "unicopia:pinecone" ], "hunger": 0.9, "saturation": 0.9 } ], "effects": [ { - "tags": [ "unicopia:food_types/cooked_fish" ], + "tags": [ "unicopia:fish/cooked" ], "ailment": { "effects": [ ] } }, { - "tags": [ "unicopia:food_types/raw_fish" ], + "tags": [ "unicopia:fish/raw" ], "ailment": { "effects": [ { diff --git a/src/main/resources/data/unicopia/diets/races/seapony.json b/src/main/resources/data/unicopia/diets/races/seapony.json index 6558338a..c67aa9f7 100644 --- a/src/main/resources/data/unicopia/diets/races/seapony.json +++ b/src/main/resources/data/unicopia/diets/races/seapony.json @@ -3,14 +3,13 @@ "foraging_multiplier": 0.7, "multipliers": [ { - "tags": [ "unicopia:food_types/raw_sea_vegitable" ], + "tags": [ "unicopia:sea_vegetable/raw" ], "hunger": 1, "saturation": 1 }, { "tags": [ - "unicopia:food_types/shells", - "unicopia:food_types/shelly" + "unicopia:shells", "unicopia:shelly" ], "hunger": 1, "saturation": 1 @@ -27,21 +26,21 @@ }, "effects": [ { - "tags": [ "unicopia:food_types/cooked_fish" ], + "tags": [ "unicopia:fish/cooked" ], "ailment": { "effects": [ ] } }, { - "tags": [ "unicopia:food_types/raw_fish" ], + "tags": [ "unicopia:fish/raw" ], "ailment": { "effects": [ ] } }, { "tags": [ - "unicopia:food_types/forage_edible", - "unicopia:food_types/forage_edible_filling" + "unicopia:foraging/edible", + "unicopia:foraging/edible_filling" ], "food_component": { "hunger": 18, @@ -58,7 +57,7 @@ } }, { - "tags": [ "unicopia:food_types/raw_sea_vegitable" ], + "tags": [ "unicopia:sea_vegetable/raw" ], "food_component": { "hunger": 2, "saturation": 1 @@ -68,7 +67,7 @@ } }, { - "tags": [ "unicopia:food_types/cooked_sea_vegitable" ], + "tags": [ "unicopia:sea_vegetable/cooked" ], "food_component": { "hunger": 6, "saturation": 2 @@ -78,7 +77,7 @@ } }, { - "tags": [ "unicopia:food_types/shells" ], + "tags": [ "unicopia:shells" ], "food_component": { "hunger": 3, "saturation": 5 @@ -88,7 +87,7 @@ } }, { - "tags": [ "unicopia:food_types/shelly" ], + "tags": [ "unicopia:shelly" ], "food_component": { "hunger": 6, "saturation": 7 diff --git a/src/main/resources/data/unicopia/diets/races/unicorn.json b/src/main/resources/data/unicopia/diets/races/unicorn.json index be679a08..3213c82b 100644 --- a/src/main/resources/data/unicopia/diets/races/unicorn.json +++ b/src/main/resources/data/unicopia/diets/races/unicorn.json @@ -4,33 +4,33 @@ "multipliers": [ { "tags": [ - "unicopia:food_types/cooked_insect", - "unicopia:food_types/cooked_meat", - "unicopia:food_types/cooked_fish" + "unicopia:insect/cooked", + "unicopia:meat/cooked", + "unicopia:fish/cooked" ], "hunger": 0.1, "saturation": 0.1 }, { "tags": [ - "unicopia:food_types/baked_goods" + "unicopia:baked_goods" ], "hunger": 1, "saturation": 1 }, { "tags": [ - "unicopia:food_types/love", - "unicopia:food_types/raw_insect", - "unicopia:food_types/raw_meat", - "unicopia:food_types/raw_fish", - "unicopia:food_types/rotten_meat" + "unicopia:love", + "unicopia:insect/raw", + "unicopia:meat/raw", + "unicopia:fish/raw", + "unicopia:meat/rotten" ], "hunger": 0, "saturation": 0 }, { - "tags": [ "unicopia:food_types/pinecone" ], + "tags": [ "unicopia:pinecone" ], "hunger": 0.9, "saturation": 0.9 } diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/bananas.json b/src/main/resources/data/unicopia/loot_tables/blocks/bananas.json deleted file mode 100644 index 7e5ce591..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/bananas.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "functions": [ - { - "add": false, - "count": { - "type": "minecraft:uniform", - "max": 12.0, - "min": 6.0 - }, - "function": "minecraft:set_count" - }, - { - "enchantment": "minecraft:fortune", - "formula": "minecraft:binomial_with_bonus_count", - "function": "minecraft:apply_bonus", - "parameters": { - "extra": 3, - "probability": 0.5714286 - } - } - ], - "name": "unicopia:banana" - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/chiselled_chitin_hull.json b/src/main/resources/data/unicopia/loot_tables/blocks/chiselled_chitin_hull.json deleted file mode 100644 index 5af0f74d..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/chiselled_chitin_hull.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:chitin", - "functions": [ - { - "add": false, - "count": 2, - "function": "minecraft:set_count" - } - ] - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - }, - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:chiselled_chitin", - "functions": [ - { - "add": false, - "count": 2, - "function": "minecraft:set_count" - } - ] - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/clam_shell.json b/src/main/resources/data/unicopia/loot_tables/blocks/clam_shell.json deleted file mode 100644 index f21c580e..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/clam_shell.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:clam_shell", - "conditions": [ - { - "block": "unicopia:clam_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "1" - } - } - ], - "functions": [ - { - "add": false, - "count": 1, - "function": "minecraft:set_count" - } - ] - }, - { - "type": "minecraft:item", - "name": "unicopia:clam_shell", - "conditions": [ - { - "block": "unicopia:clam_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "2" - } - } - ], - "functions": [ - { - "add": false, - "count": 2, - "function": "minecraft:set_count" - } - ] - }, - { - "type": "minecraft:item", - "name": "unicopia:clam_shell", - "conditions": [ - { - "block": "unicopia:clam_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "3" - } - } - ], - "functions": [ - { - "add": false, - "count": 3, - "function": "minecraft:set_count" - } - ] - }, - { - "type": "minecraft:item", - "name": "unicopia:clam_shell", - "conditions": [ - { - "block": "unicopia:clam_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "4" - } - } - ], - "functions": [ - { - "add": false, - "count": 4, - "function": "minecraft:set_count" - } - ] - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/cloud_slab.json b/src/main/resources/data/unicopia/loot_tables/blocks/cloud_slab.json deleted file mode 100644 index 6926e7fe..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/cloud_slab.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:cloud_lump", - "functions": [ - { - "add": false, - "count": 2, - "function": "minecraft:set_count" - }, - { - "add": false, - "count": 4, - "function": "minecraft:set_count", - "conditions": [ - { - "block": "unicopia:cloud_slab", - "condition": "minecraft:block_state_property", - "properties": { - "type": "double" - } - } - ] - } - ] - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/dense_cloud_slab.json b/src/main/resources/data/unicopia/loot_tables/blocks/dense_cloud_slab.json deleted file mode 100644 index e9d1f0e2..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/dense_cloud_slab.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:cloud_lump", - "functions": [ - { - "add": false, - "count": 4, - "function": "minecraft:set_count" - }, - { - "add": false, - "count": 8, - "function": "minecraft:set_count", - "conditions": [ - { - "block": "unicopia:dense_cloud_slab", - "condition": "minecraft:block_state_property", - "properties": { - "type": "double" - } - } - ] - } - ] - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/etched_cloud_slab.json b/src/main/resources/data/unicopia/loot_tables/blocks/etched_cloud_slab.json deleted file mode 100644 index 4465e094..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/etched_cloud_slab.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:cloud_lump", - "functions": [ - { - "add": false, - "count": 4, - "function": "minecraft:set_count" - }, - { - "add": false, - "count": 8, - "function": "minecraft:set_count", - "conditions": [ - { - "block": "unicopia:etched_cloud_slab", - "condition": "minecraft:block_state_property", - "properties": { - "type": "double" - } - } - ] - } - ] - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/gold_root.json b/src/main/resources/data/unicopia/loot_tables/blocks/gold_root.json deleted file mode 100644 index 6bfe9e77..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/gold_root.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "type": "minecraft:block", - "functions": [ - { - "function": "minecraft:explosion_decay" - } - ], - "pools": [ - { - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:golden_carrot" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:gold_root", - "condition": "minecraft:block_state_property", - "properties": { - "age": "7" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "functions": [ - { - "enchantment": "minecraft:fortune", - "formula": "minecraft:binomial_with_bonus_count", - "function": "minecraft:apply_bonus", - "parameters": { - "extra": 3, - "probability": 0.5714286 - } - } - ], - "name": "minecraft:golden_carrot" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/carrots" -} diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/golden_apple.json b/src/main/resources/data/unicopia/loot_tables/blocks/golden_apple.json deleted file mode 100644 index 7bd87a25..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/golden_apple.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:golden_apple" - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "block": "unicopia:golden_apple", - "condition": "minecraft:block_state_property", - "properties": { - "enchanted": "false" - } - } - ] - }, - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:enchanted_golden_apple" - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "block": "unicopia:golden_apple", - "condition": "minecraft:block_state_property", - "properties": { - "enchanted": "true" - } - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/hay_block.json b/src/main/resources/data/unicopia/loot_tables/blocks/hay_block.json deleted file mode 100644 index 1101857f..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/hay_block.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:hay_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_north_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:wheat" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:hay_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_north_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:wheat" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:hay_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_south_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:wheat" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:hay_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_south_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:wheat" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:hay_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_north_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:wheat" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:hay_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_north_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:wheat" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:hay_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_south_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:wheat" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:hay_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_south_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:wheat" - } - ], - "rolls": 1.0 - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/mysterious_egg.json b/src/main/resources/data/unicopia/loot_tables/blocks/mysterious_egg.json deleted file mode 100644 index 915f5152..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/mysterious_egg.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:mysterious_egg", - "functions": [ - { - "add": false, - "count": 1, - "function": "minecraft:set_count", - "conditions": [ - { - "block": "unicopia:mysterious_egg", - "condition": "minecraft:block_state_property", - "properties": { - "count": "1" - } - } - ] - }, - { - "add": false, - "count": 2, - "function": "minecraft:set_count", - "conditions": [ - { - "block": "unicopia:mysterious_egg", - "condition": "minecraft:block_state_property", - "properties": { - "count": "2" - } - } - ] - }, - { - "add": false, - "count": 3, - "function": "minecraft:set_count", - "conditions": [ - { - "block": "unicopia:mysterious_egg", - "condition": "minecraft:block_state_property", - "properties": { - "count": "3" - } - } - ] - } - ] - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/oats.json b/src/main/resources/data/unicopia/loot_tables/blocks/oats.json deleted file mode 100644 index 17b0d17a..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/oats.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "type": "minecraft:block", - "functions": [ - { - "function": "minecraft:explosion_decay" - } - ], - "pools": [ - { - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "name": "unicopia:oat_seeds" - } - ] - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:oats", - "condition": "minecraft:block_state_property", - "properties": { - "age": "11" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "functions": [ - { - "enchantment": "minecraft:fortune", - "formula": "minecraft:binomial_with_bonus_count", - "function": "minecraft:apply_bonus", - "parameters": { - "extra": 3, - "probability": 0.5714286 - } - } - ], - "name": "unicopia:oat_seeds" - } - ], - "rolls": 1.0 - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/oats_crown.json b/src/main/resources/data/unicopia/loot_tables/blocks/oats_crown.json deleted file mode 100644 index fe5807ed..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/oats_crown.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "type": "minecraft:block", - "functions": [ - { - "function": "minecraft:explosion_decay" - } - ], - "pools": [ - { - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "block": "unicopia:oats_crown", - "condition": "minecraft:block_state_property", - "properties": { - "age": "1" - } - } - ], - "name": "unicopia:oats" - } - ], - "rolls": 1.0 - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/oats_stem.json b/src/main/resources/data/unicopia/loot_tables/blocks/oats_stem.json deleted file mode 100644 index 72ea00c4..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/oats_stem.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "type": "minecraft:block", - "functions": [ - { - "function": "minecraft:explosion_decay" - } - ], - "pools": [ - { - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "block": "unicopia:oats_stem", - "condition": "minecraft:block_state_property", - "properties": { - "age": "6" - } - } - ], - "name": "unicopia:oats" - } - ], - "rolls": 1.0 - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/pineapple.json b/src/main/resources/data/unicopia/loot_tables/blocks/pineapple.json deleted file mode 100644 index aced6181..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/pineapple.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:block_state_property", - "block": "unicopia:pineapple", - "properties": { - "age": "7", - "half": "top" - } - } - ], - "name": "unicopia:pineapple" - } - ] - } - ] - } - ], - "functions": [ - { - "function": "minecraft:explosion_decay" - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/plunder_vine.json b/src/main/resources/data/unicopia/loot_tables/blocks/plunder_vine.json deleted file mode 100644 index 857d1f4c..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/plunder_vine.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "type": "minecraft:block", - "functions": [ - { - "function": "minecraft:explosion_decay" - } - ], - "pools": [ - { - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:stick" - }, - { - "type": "minecraft:item", - "name": "minecraft:dead_bush" - } - ], - "rolls": 4.0 - }, - { - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:stick" - }, - { - "type": "minecraft:item", - "name": "minecraft:dead_bush" - }, - { - "type": "minecraft:item", - "name": "unicopia:gryphon_feather" - } - ], - "rolls": 1.0 - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/rice_block.json b/src/main/resources/data/unicopia/loot_tables/blocks/rice_block.json deleted file mode 100644 index e79c51d7..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/rice_block.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "type": "minecraft:block", - "fabric:load_conditions": [ - { - "condition": "fabric:all_mods_loaded", - "values": [ - "farmersdelight" - ] - } - ], - "pools": [ - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:rice_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_north_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:rice_panicle" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:rice_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_north_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:rice_panicle" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:rice_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_south_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:rice_panicle" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:rice_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_south_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:rice_panicle" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:rice_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_north_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:rice_panicle" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:rice_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_north_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:rice_panicle" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:rice_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_south_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:rice_panicle" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:rice_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_south_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:rice_panicle" - } - ], - "rolls": 1.0 - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/rocks.json b/src/main/resources/data/unicopia/loot_tables/blocks/rocks.json deleted file mode 100644 index 83eda199..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/rocks.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:block_state_property", - "block": "unicopia:rocks", - "properties": { - "age": "7" - } - }, - { - "condition": "minecraft:random_chance", - "chance": 0.25 - } - ], - "name": "unicopia:weird_rock" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:block_state_property", - "block": "unicopia:rocks", - "properties": { - "age": "7" - } - } - ], - "name": "unicopia:rock" - }, - { - "type": "minecraft:item", - "name": "unicopia:pebbles" - } - ] - } - ] - }, - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "functions": [ - { - "function": "minecraft:apply_bonus", - "enchantment": "minecraft:fortune", - "formula": "minecraft:binomial_with_bonus_count", - "parameters": { - "extra": 3, - "probability": 0.5714286 - } - } - ], - "name": "unicopia:pebbles" - } - ], - "conditions": [ - { - "condition": "minecraft:block_state_property", - "block": "unicopia:rocks", - "properties": { - "age": "7" - } - } - ] - } - ], - "functions": [ - { - "function": "minecraft:explosion_decay" - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/scallop_shell.json b/src/main/resources/data/unicopia/loot_tables/blocks/scallop_shell.json deleted file mode 100644 index c1e002b1..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/scallop_shell.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:scallop_shell", - "conditions": [ - { - "block": "unicopia:scallop_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "1" - } - } - ], - "functions": [ - { - "add": false, - "count": 1, - "function": "minecraft:set_count" - } - ] - }, - { - "type": "minecraft:item", - "name": "unicopia:scallop_shell", - "conditions": [ - { - "block": "unicopia:scallop_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "2" - } - } - ], - "functions": [ - { - "add": false, - "count": 2, - "function": "minecraft:set_count" - } - ] - }, - { - "type": "minecraft:item", - "name": "unicopia:scallop_shell", - "conditions": [ - { - "block": "unicopia:scallop_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "3" - } - } - ], - "functions": [ - { - "add": false, - "count": 3, - "function": "minecraft:set_count" - } - ] - }, - { - "type": "minecraft:item", - "name": "unicopia:scallop_shell", - "conditions": [ - { - "block": "unicopia:scallop_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "4" - } - } - ], - "functions": [ - { - "add": false, - "count": 4, - "function": "minecraft:set_count" - } - ] - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/slime_pustule.json b/src/main/resources/data/unicopia/loot_tables/blocks/slime_pustule.json deleted file mode 100644 index 3945bf2f..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/slime_pustule.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:slime_pustule" - } - ], - "conditions": [ - { - "condition": "minecraft:all_of", - "terms": [ - { - "block": "unicopia:slime_pustule", - "condition": "minecraft:block_state_property", - "properties": { - "shape": "pod" - } - }, - { - "condition": "minecraft:any_of", - "terms": [ - { - "condition": "minecraft:match_tool", - "predicate": { - "items": [ - "minecraft:shears" - ] - } - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "enchantments": [ - { - "enchantment": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - ] - } - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/soggy_cloud_slab.json b/src/main/resources/data/unicopia/loot_tables/blocks/soggy_cloud_slab.json deleted file mode 100644 index b805f097..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/soggy_cloud_slab.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:cloud", - "functions": [ - { - "add": false, - "count": 3, - "function": "minecraft:set_count" - } - ] - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/straw_block.json b/src/main/resources/data/unicopia/loot_tables/blocks/straw_block.json deleted file mode 100644 index ca46ba50..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/straw_block.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "type": "minecraft:block", - "fabric:load_conditions": [ - { - "condition": "fabric:all_mods_loaded", - "values": [ - "farmersdelight" - ] - } - ], - "pools": [ - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:straw_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_north_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:straw" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:straw_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_north_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:straw" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:straw_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_south_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:straw" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:straw_block", - "condition": "minecraft:block_state_property", - "properties": { - "top_south_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:straw" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:straw_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_north_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:straw" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:straw_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_north_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:straw" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:straw_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_south_east": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:straw" - } - ], - "rolls": 1.0 - }, - { - "bonus_rolls": 0.0, - "conditions": [ - { - "block": "unicopia:straw_block", - "condition": "minecraft:block_state_property", - "properties": { - "bottom_south_west": "true" - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "farmersdelight:straw" - } - ], - "rolls": 1.0 - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/blocks/turret_shell.json b/src/main/resources/data/unicopia/loot_tables/blocks/turret_shell.json deleted file mode 100644 index b300a2d4..00000000 --- a/src/main/resources/data/unicopia/loot_tables/blocks/turret_shell.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "rolls": 1.0, - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "unicopia:turret_shell", - "conditions": [ - { - "block": "unicopia:turret_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "1" - } - } - ], - "functions": [ - { - "add": false, - "count": 1, - "function": "minecraft:set_count" - } - ] - }, - { - "type": "minecraft:item", - "name": "unicopia:turret_shell", - "conditions": [ - { - "block": "unicopia:turret_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "2" - } - } - ], - "functions": [ - { - "add": false, - "count": 2, - "function": "minecraft:set_count" - } - ] - }, - { - "type": "minecraft:item", - "name": "unicopia:turret_shell", - "conditions": [ - { - "block": "unicopia:turret_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "3" - } - } - ], - "functions": [ - { - "add": false, - "count": 3, - "function": "minecraft:set_count" - } - ] - }, - { - "type": "minecraft:item", - "name": "unicopia:turret_shell", - "conditions": [ - { - "block": "unicopia:turret_shell", - "condition": "minecraft:block_state_property", - "properties": { - "count": "4" - } - } - ], - "functions": [ - { - "add": false, - "count": 4, - "function": "minecraft:set_count" - } - ] - } - ], - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/chests/changeling_hive_trap.json b/src/main/resources/data/unicopia/loot_tables/chests/changeling_hive_trap.json deleted file mode 100644 index 2dac1a86..00000000 --- a/src/main/resources/data/unicopia/loot_tables/chests/changeling_hive_trap.json +++ /dev/null @@ -1,204 +0,0 @@ -{ - "type": "minecraft:chest", - "pools": [ - { - "bonus_rolls": 0.0, - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:short_morph_earth" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 3 - }, - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:short_morph_unicorn" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 1 - }, - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:short_morph_pegasus" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 1 - }, - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:short_morph_bat" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 1 - }, - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:short_morph_kirin" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 1 - }, - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:short_morph_hippogriff" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 1 - }, - - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:long_morph_earth" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 5 - }, - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:long_morph_unicorn" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 2 - }, - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:long_morph_pegasus" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 2 - }, - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:long_morph_bat" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 2 - }, - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:long_morph_kirin" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 2 - }, - { - "type": "minecraft:item", - "name": "minecraft:tipped_arrow", - "functions": [ - { "function": "minecraft:set_potion", "id": "unicopia:long_morph_hippogriff" }, - { - "function": "minecraft:set_count", - "count": { - "min": 3.0, - "max": 9.0, - "type": "minecraft:uniform" - } - } - ], - "weight": 2 - } - ], - "rolls": 6.0 - } - ] -} diff --git a/src/main/resources/data/unicopia/loot_tables/entities/butterfly.json b/src/main/resources/data/unicopia/loot_tables/entities/butterfly.json deleted file mode 100644 index 9992d4bd..00000000 --- a/src/main/resources/data/unicopia/loot_tables/entities/butterfly.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "type": "minecraft:entity", - "pools": [ - { - "rolls": 1, - "bonus_rolls": 0, - "entries": [ - { - "type": "minecraft:item", - "functions": [ - { - "function": "minecraft:looting_enchant", - "count": { - "type": "minecraft:uniform", - "min": 0.0, - "max": 1.0 - } - } - ], - "name": "unicopia:butterfly" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/entities/loot_bug.json b/src/main/resources/data/unicopia/loot_tables/entities/loot_bug.json deleted file mode 100644 index 7e8ec0ae..00000000 --- a/src/main/resources/data/unicopia/loot_tables/entities/loot_bug.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "type": "minecraft:entity", - "pools": [ - { - "rolls": 11, - "bonus_rolls": 0, - "entries": [ - { - "type": "minecraft:item", - "functions": [ - { - "add": false, - "count": { - "type": "minecraft:uniform", - "max": 12.0, - "min": 6.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:looting_enchant", - "count": { - "type": "minecraft:uniform", - "min": 0.0, - "max": 3.0 - } - } - ], - "name": "minecraft:gold_nugget" - }, - { - "type": "minecraft:item", - "functions": [ - { - "add": false, - "count": { - "type": "minecraft:uniform", - "max": 12.0, - "min": 6.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:looting_enchant", - "count": { - "type": "minecraft:uniform", - "min": 0.0, - "max": 3.0 - } - } - ], - "name": "minecraft:iron_nugget" - } - ] - }, - { - "rolls": 1, - "bonus_rolls": 0, - "entries": [ - { - "type": "minecraft:tag", - "functions": [ - { - "add": false, - "count": { - "type": "minecraft:uniform", - "max": 3.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:looting_enchant", - "count": { - "type": "minecraft:uniform", - "min": 0.0, - "max": 6.0 - } - } - ], - "name": "unicopia:loot_bug_high_value_drops", - "expand": true - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/loot_tables/entities/storm_cloud.json b/src/main/resources/data/unicopia/loot_tables/entities/storm_cloud.json deleted file mode 100644 index 8d599d1a..00000000 --- a/src/main/resources/data/unicopia/loot_tables/entities/storm_cloud.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "type": "minecraft:entity", - "pools": [ - { - "rolls": 1, - "bonus_rolls": 0, - "entries": [ - { - "type": "minecraft:item", - "functions": [ - { - "add": false, - "count": { - "type": "minecraft:uniform", - "max": 12.0, - "min": 6.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:looting_enchant", - "count": { - "type": "minecraft:uniform", - "min": 0.0, - "max": 1.0 - } - } - ], - "name": "unicopia:cloud_lump" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/tags/items/food_types/cooked_fish.json b/src/main/resources/data/unicopia/tags/items/food_types/cooked_fish.json deleted file mode 100644 index 216c3f5d..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/cooked_fish.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "replace": false, - "values": [ - "#c:cooked_fish", - { "id": "farmersdelight:fish_stew", "required": false }, - { "id": "farmersdelight:baked_cod_stew", "required": false }, - { "id": "farmersdelight:grilled_salmon", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/cooked_insect.json b/src/main/resources/data/unicopia/tags/items/food_types/cooked_insect.json deleted file mode 100644 index 8e23aa37..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/cooked_insect.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "#c:cooked_insects" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/cooked_meat.json b/src/main/resources/data/unicopia/tags/items/food_types/cooked_meat.json index 9860573f..f3e131a6 100644 --- a/src/main/resources/data/unicopia/tags/items/food_types/cooked_meat.json +++ b/src/main/resources/data/unicopia/tags/items/food_types/cooked_meat.json @@ -1,7 +1,7 @@ { "replace": false, "values": [ - "#c:cooked_meats", + "#c:cooked_meat", { "id": "farmersdelight:chicken_soup", "required": false }, { "id": "farmersdelight:bacon_and_eggs", "required": false }, { "id": "farmersdelight:pasta_with_meatballs", "required": false }, diff --git a/src/main/resources/data/unicopia/tags/items/food_types/love.json b/src/main/resources/data/unicopia/tags/items/food_types/love.json index 72d0be9d..d9127025 100644 --- a/src/main/resources/data/unicopia/tags/items/food_types/love.json +++ b/src/main/resources/data/unicopia/tags/items/food_types/love.json @@ -1,6 +1,6 @@ { "replace": false, "values": [ - "#c:love" + "#unicopia:container_with_love" ] } diff --git a/src/main/resources/data/unicopia/tags/items/food_types/raw_fish.json b/src/main/resources/data/unicopia/tags/items/food_types/raw_fish.json deleted file mode 100644 index 1fb0b027..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/raw_fish.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "replace": false, - "values": [ - "#c:raw_fish", - { "id": "farmersdelight:cod_roll", "required": false }, - { "id": "farmersdelight:salmon_roll", "required": false }, - { "id": "farmersdelight:salmon_slice", "required": false }, - { "id": "farmersdelight:cod_slice", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/raw_insect.json b/src/main/resources/data/unicopia/tags/items/food_types/raw_insect.json deleted file mode 100644 index 24b2cff4..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/raw_insect.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "#c:raw_insects" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/raw_meat.json b/src/main/resources/data/unicopia/tags/items/food_types/raw_meat.json index dcf23921..e48e50ee 100644 --- a/src/main/resources/data/unicopia/tags/items/food_types/raw_meat.json +++ b/src/main/resources/data/unicopia/tags/items/food_types/raw_meat.json @@ -1,7 +1,7 @@ { "replace": false, "values": [ - "#c:raw_meats", + "#c:raw_meat", { "id": "farmersdelight:ham", "required": false } ] } diff --git a/src/main/resources/data/unicopia/tags/items/food_types/rotten_meat.json b/src/main/resources/data/unicopia/tags/items/food_types/rotten_meat.json deleted file mode 100644 index 4dee31d1..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/rotten_meat.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "#c:rotten_meats" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/groups/bat_pony.json b/src/main/resources/data/unicopia/tags/items/groups/bat_pony.json index 8c547253..d8ace57f 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/bat_pony.json +++ b/src/main/resources/data/unicopia/tags/items/groups/bat_pony.json @@ -1,7 +1,7 @@ { "replace": false, "values": [ - "#unicopia:food_types/raw_insect", + "#c:raw_insect", "#unicopia:polearms", "unicopia:mango_leaves", "unicopia:mango_sapling", diff --git a/src/main/resources/data/unicopia/tags/items/groups/changeling.json b/src/main/resources/data/unicopia/tags/items/groups/changeling.json index 3cc31831..8c094993 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/changeling.json +++ b/src/main/resources/data/unicopia/tags/items/groups/changeling.json @@ -12,10 +12,10 @@ "unicopia:mysterious_egg", "unicopia:hive", "unicopia:dark_oak_stable_door", - "#unicopia:food_types/cooked_meat", + "#c:cooked_meat", "#unicopia:food_types/raw_meat", - "#unicopia:food_types/raw_insect", - "#unicopia:food_types/rotten_meat", - "#unicopia:food_types/love" + "#c:raw_insect", + "#c:rotten_meat", + "#unicopia:container_with_love" ] } diff --git a/src/main/resources/data/unicopia/tags/items/groups/pegasus.json b/src/main/resources/data/unicopia/tags/items/groups/pegasus.json index b76a934d..59b825f5 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/pegasus.json +++ b/src/main/resources/data/unicopia/tags/items/groups/pegasus.json @@ -24,8 +24,8 @@ "unicopia:cloud_door", "unicopia:cloud_bed", "#unicopia:bed_sheets", - "#unicopia:food_types/raw_fish", - "#unicopia:food_types/cooked_fish", + "#c:raw_fish", + "#c:cooked_fish", "unicopia:rain_cloud_jar", "unicopia:storm_cloud_jar", "unicopia:lightning_jar", diff --git a/src/main/resources/data/unicopia/traits/love.json b/src/main/resources/data/unicopia/traits/love.json index 534e5a40..af8df4e3 100644 --- a/src/main/resources/data/unicopia/traits/love.json +++ b/src/main/resources/data/unicopia/traits/love.json @@ -2,7 +2,7 @@ "replace": false, "traits": "happiness:10 kindness:10", "items": [ - "#c:love", + "#unicopia:container_with_love", "#unicopia:clouds" ] } \ No newline at end of file From a87257de83076da07a612dbc334a8fb93c6c2061 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 2 Apr 2024 08:30:42 +0100 Subject: [PATCH 64/73] Use the id of the food group as the name rather than the tag --- .../unicopia/diet/DietProfile.java | 14 ++-- .../unicopia/diet/DietsLoader.java | 4 +- .../minelittlepony/unicopia/diet/Effect.java | 63 +++++----------- .../unicopia/diet/FoodGroup.java | 48 +++++++++++++ .../unicopia/diet/FoodGroupEffects.java | 42 +++++++++++ .../unicopia/diet/PonyDiets.java | 12 +++- .../resources/assets/unicopia/lang/en_us.json | 71 +++++++++---------- 7 files changed, 160 insertions(+), 94 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/diet/FoodGroup.java create mode 100644 src/main/java/com/minelittlepony/unicopia/diet/FoodGroupEffects.java diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java b/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java index 4638ed04..18ceaefb 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java @@ -30,23 +30,23 @@ public record DietProfile( float defaultMultiplier, float foragingMultiplier, List multipliers, - List effects, - Optional defaultEffect + List effects, + Optional defaultEffect ) { public static final DietProfile EMPTY = new DietProfile(1, 1, List.of(), List.of(), Optional.empty()); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codec.FLOAT.fieldOf("default_multiplier").forGetter(DietProfile::defaultMultiplier), Codec.FLOAT.fieldOf("foraging_multiplier").forGetter(DietProfile::foragingMultiplier), Codec.list(Multiplier.CODEC).fieldOf("multipliers").forGetter(DietProfile::multipliers), - Codec.list(Effect.PROFILE_CODEC).fieldOf("effects").forGetter(DietProfile::effects), - Effect.CODEC.optionalFieldOf("default_effect").forGetter(DietProfile::defaultEffect) + Codec.list(FoodGroupEffects.CODEC).fieldOf("effects").forGetter(DietProfile::effects), + FoodGroupEffects.CODEC.optionalFieldOf("default_effect").forGetter(DietProfile::defaultEffect) ).apply(instance, DietProfile::new)); public DietProfile(PacketByteBuf buffer) { this(buffer.readFloat(), buffer.readFloat(), buffer.readList(Multiplier::new), - buffer.readList(b -> new Effect(b, FoodGroupKey.LOOKUP)), - buffer.readOptional(b -> new Effect(b, FoodGroupKey.LOOKUP)) + buffer.readList(b -> new FoodGroupEffects(b, FoodGroupKey.LOOKUP)), + buffer.readOptional(b -> new FoodGroupEffects(b, FoodGroupKey.LOOKUP)) ); } @@ -81,7 +81,7 @@ public record DietProfile( } public Optional findEffect(ItemStack stack) { - return effects.stream().filter(m -> m.test(stack)).findFirst().or(this::defaultEffect); + return effects.stream().filter(m -> m.test(stack)).findFirst().or(this::defaultEffect).map(Effect.class::cast); } static boolean isForaged(ItemStack stack) { diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java b/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java index f517c7a2..7da493ea 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java @@ -37,10 +37,10 @@ public class DietsLoader implements IdentifiableResourceReloadListener { Map foodGroups = new HashMap<>(); for (var group : loadData(manager, prepareExecutor, "diets/food_groups").entrySet()) { try { - Effect.CODEC.parse(JsonOps.INSTANCE, group.getValue()) + FoodGroup.CODEC.parse(JsonOps.INSTANCE, group.getValue()) .resultOrPartial(error -> LOGGER.error("Could not load food group {}: {}", group.getKey(), error)) .ifPresent(value -> { - foodGroups.put(group.getKey(), value); + foodGroups.put(group.getKey(), new FoodGroup(group.getKey(), value)); }); } catch (Throwable t) { LOGGER.error("Could not load food effects {}", group.getKey(), t); diff --git a/src/main/java/com/minelittlepony/unicopia/diet/Effect.java b/src/main/java/com/minelittlepony/unicopia/diet/Effect.java index b8ce1338..af9ad3d9 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/Effect.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/Effect.java @@ -2,60 +2,31 @@ package com.minelittlepony.unicopia.diet; import java.util.List; import java.util.Optional; -import java.util.function.Function; import java.util.function.Predicate; -import com.minelittlepony.unicopia.entity.player.Pony; -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; - import net.minecraft.client.item.TooltipContext; import net.minecraft.item.FoodComponent; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; import net.minecraft.text.Text; import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; import net.minecraft.util.UseAction; -import net.minecraft.util.Util; -public record Effect( - List tags, - Optional foodComponent, - Ailment ailment -) implements Predicate { - public static final Effect EMPTY = new Effect(List.of(), Optional.empty(), Ailment.EMPTY); - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - FoodGroupKey.TAG_CODEC.listOf().fieldOf("tags").forGetter(Effect::tags), - FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(Effect::foodComponent), - Ailment.CODEC.fieldOf("ailment").forGetter(Effect::ailment) - ).apply(instance, Effect::new)); - public static final Codec PROFILE_CODEC = RecordCodecBuilder.create(instance -> instance.group( - FoodGroupKey.CODEC.listOf().fieldOf("tags").forGetter(Effect::tags), - FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(Effect::foodComponent), - Ailment.CODEC.fieldOf("ailment").forGetter(Effect::ailment) - ).apply(instance, Effect::new)); +public interface Effect extends Predicate { + Effect EMPTY = new FoodGroupEffects(List.of(), Optional.empty(), Ailment.EMPTY); - public Effect(PacketByteBuf buffer, Function lookup) { - this(buffer.readList(b -> lookup.apply(b.readIdentifier())), buffer.readOptional(FoodAttributes::read), new Ailment(buffer)); - } + List tags(); - public void afflict(Pony pony, ItemStack stack) { - ailment().effects().afflict(pony.asEntity(), stack); - } + Optional foodComponent(); - public void appendTooltip(ItemStack stack, List tooltip, TooltipContext context) { - int size = tooltip.size(); - tags.forEach(tag -> { - if (tag.contains(stack)) { - tooltip.add(Text.literal(" ").append(Text.translatable(Util.createTranslationKey("tag", tag.id()))).formatted(Formatting.GRAY)); - } - }); - if (tooltip.size() == size) { + Ailment ailment(); + + default void appendTooltip(ItemStack stack, List tooltip, TooltipContext context) { + if (!test(stack)) { if (stack.isFood()) { - tooltip.add(Text.literal(" ").append(Text.translatable("tag.unicopia.food_types.misc")).formatted(Formatting.GRAY)); + tooltip.add(Text.literal(" ").append(Text.translatable("food_group.unicopia.misc")).formatted(Formatting.GRAY)); } else if (stack.getUseAction() == UseAction.DRINK) { - tooltip.add(Text.literal(" ").append(Text.translatable("tag.unicopia.food_types.drinks")).formatted(Formatting.GRAY)); + tooltip.add(Text.literal(" ").append(Text.translatable("food_group.unicopia.drinks")).formatted(Formatting.GRAY)); } } @@ -67,14 +38,14 @@ public record Effect( } } - public void toBuffer(PacketByteBuf buffer) { - buffer.writeCollection(tags, (b, t) -> b.writeIdentifier(t.id())); - buffer.writeOptional(foodComponent, FoodAttributes::write); - ailment.toBuffer(buffer); + default void toBuffer(PacketByteBuf buffer) { + buffer.writeCollection(tags(), (b, t) -> b.writeIdentifier(t.id())); + buffer.writeOptional(foodComponent(), FoodAttributes::write); + ailment().toBuffer(buffer); } @Override - public boolean test(ItemStack stack) { - return tags.stream().anyMatch(tag -> tag.contains(stack)); + default boolean test(ItemStack stack) { + return tags().stream().anyMatch(tag -> tag.contains(stack)); } -} \ No newline at end of file +} diff --git a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroup.java b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroup.java new file mode 100644 index 00000000..9c6279b5 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroup.java @@ -0,0 +1,48 @@ +package com.minelittlepony.unicopia.diet; + +import java.util.List; +import java.util.Optional; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.client.item.TooltipContext; +import net.minecraft.item.FoodComponent; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; + +public record FoodGroup( + Identifier id, + List tags, + Optional foodComponent, + Ailment ailment) implements Effect { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + FoodGroupKey.TAG_CODEC.listOf().fieldOf("tags").forGetter(FoodGroupEffects::tags), + FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(FoodGroupEffects::foodComponent), + Ailment.CODEC.fieldOf("ailment").forGetter(FoodGroupEffects::ailment) + ).apply(instance, FoodGroupEffects::new)); + + public FoodGroup(Identifier id, Effect effect) { + this(id, effect.tags(), effect.foodComponent(), effect.ailment()); + } + + public FoodGroup(PacketByteBuf buffer) { + this(buffer.readIdentifier(), new FoodGroupEffects(buffer, FoodGroupKey.TAG_ID_LOOKUP)); + } + + @Override + public void appendTooltip(ItemStack stack, List tooltip, TooltipContext context) { + tooltip.add(Text.literal(" ").append(Text.translatable(Util.createTranslationKey("food_group", id()))).formatted(Formatting.GRAY)); + Effect.super.appendTooltip(stack, tooltip, context); + } + + @Override + public void toBuffer(PacketByteBuf buffer) { + buffer.writeIdentifier(id()); + Effect.super.toBuffer(buffer); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupEffects.java b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupEffects.java new file mode 100644 index 00000000..e92f2995 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupEffects.java @@ -0,0 +1,42 @@ +package com.minelittlepony.unicopia.diet; + +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import net.minecraft.client.item.TooltipContext; +import net.minecraft.item.FoodComponent; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; + +public record FoodGroupEffects( + List tags, + Optional foodComponent, + Ailment ailment +) implements Effect { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + FoodGroupKey.CODEC.listOf().fieldOf("tags").forGetter(FoodGroupEffects::tags), + FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(FoodGroupEffects::foodComponent), + Ailment.CODEC.fieldOf("ailment").forGetter(FoodGroupEffects::ailment) + ).apply(instance, FoodGroupEffects::new)); + + public FoodGroupEffects(PacketByteBuf buffer, Function lookup) { + this(buffer.readList(b -> lookup.apply(b.readIdentifier())), buffer.readOptional(FoodAttributes::read), new Ailment(buffer)); + } + + @Override + public void appendTooltip(ItemStack stack, List tooltip, TooltipContext context) { + tags.forEach(tag -> { + if (tag.contains(stack)) { + tooltip.add(Text.literal(" ").append(Text.translatable(Util.createTranslationKey("tag", tag.id()))).formatted(Formatting.GRAY)); + } + }); + Effect.super.appendTooltip(stack, tooltip, context); + } +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java b/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java index e233871d..54990fee 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/PonyDiets.java @@ -1,8 +1,11 @@ package com.minelittlepony.unicopia.diet; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; import org.jetbrains.annotations.Nullable; @@ -47,12 +50,15 @@ public class PonyDiets implements DietView { } public PonyDiets(PacketByteBuf buffer) { - this(buffer.readMap(b -> b.readRegistryValue(Race.REGISTRY), DietProfile::new), buffer.readMap(PacketByteBuf::readIdentifier, b -> new Effect(b, FoodGroupKey.TAG_ID_LOOKUP))); + this( + buffer.readMap(b -> b.readRegistryValue(Race.REGISTRY), DietProfile::new), + buffer.readCollection(ArrayList::new, FoodGroup::new).stream().collect(Collectors.toMap(FoodGroup::id, Function.identity())) + ); } public void toBuffer(PacketByteBuf buffer) { buffer.writeMap(diets, (b, r) -> b.writeRegistryValue(Race.REGISTRY, r), (b, e) -> e.toBuffer(b)); - buffer.writeMap(effects, PacketByteBuf::writeIdentifier, (b, e) -> e.toBuffer(b)); + buffer.writeCollection(effects.values(), (b, e) -> e.toBuffer(b)); } private DietProfile getDiet(Pony pony) { @@ -77,7 +83,7 @@ public class PonyDiets implements DietView { @Override public void finishUsing(ItemStack stack, World world, LivingEntity entity) { if (initEdibility(stack, entity)) { - Pony.of(entity).ifPresent(pony -> getEffects(stack, pony).afflict(pony, stack)); + Pony.of(entity).ifPresent(pony -> getEffects(stack, pony).ailment().effects().afflict(pony.asEntity(), stack)); } } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 6f5978b0..8552f3f2 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -619,42 +619,41 @@ "unicopia.diet.hunger": "Hunger Ratio: %s%%", "unicopia.diet.saturation": "Saturation Ratio: %s%%", - "tag.unicopia.food_types.rotten_meat": "Rotting Meat", - "tag.unicopia.food_types.raw_meat": "Fresh Meat", - "tag.unicopia.food_types.cooked_meat": "Prepared Meat", - "tag.c.raw_fish": "Fresh Fish", - "tag.c.cooked_fish": "Prepared Fish", - "tag.c.raw_insect": "Bugs & Insects", - "tag.unicopia.food_types.cooked_insect": "Cooked Bugs & Insects", - "tag.unicopia.food_types.nuts_and_seeds": "Nuts & Seeds", - "tag.unicopia.container_with_love": "Love", - "tag.unicopia.food_types.rocks": "Rocks", - "tag.unicopia.food_types.pinecone": "Nuts & Seeds", - "tag.unicopia.food_types.bat_ponys_delight": "Bat Pony Treats", - "tag.unicopia.food_types.cooked_sea_vegitable": "Prepared Fish Food", - "tag.unicopia.food_types.raw_sea_vegitable": "Fresh Fish Food", - "tag.unicopia.food_types.shells": "Sea Shells", - "tag.unicopia.food_types.shelly": "Sea Shells", - "tag.unicopia.food_types.candy": "Candy", - "tag.unicopia.food_types.desserts": "Desserts", - "tag.unicopia.food_types.fruit": "Fruit", - "tag.unicopia.food_types.baked_goods": "Baked Goods", - "tag.unicopia.food_types.misc": "Misc", - "tag.unicopia.food_types.fruits_and_vegetables": "Fruits & Vegetables", - "tag.unicopia.food_types.drinks": "Drinks", - "tag.minecraft.leaves": "Leaves", - - "tag.unicopia.food_types.forage_edible_filling": "Bulky Plant Matter", - "tag.unicopia.food_types.forage_edible": "Plant Matter", - "tag.unicopia.food_types.forage_nauseating": "Nauseating", - "tag.unicopia.food_types.forage_prickly": "Prickly", - "tag.unicopia.food_types.forage_risky": "Unsafe", - "tag.unicopia.food_types.forage_strengthening": "Strength Enhancing", - "tag.unicopia.food_types.forage_severely_prickly": "Very Prickly", - "tag.unicopia.food_types.forage_severely_nauseating": "Sickening", - "tag.unicopia.food_types.forage_radioactive": "Glowy", - "tag.unicopia.food_types.forage_dangerous": "Dangerous", - "tag.unicopia.food_types.forage_blinding": "Toxic", + "food_group.unicopia.meat.rotten": "Rotting Meat", + "food_group.unicopia.meat.raw": "Fresh Meat", + "food_group.unicopia.meat.cooked": "Prepared Meat", + "food_group.unicopia.fish.raw": "Fresh Fish", + "food_group.unicopia.fish.cooked": "Prepared Fish", + "food_group.unicopia.insect.raw": "Bugs & Insects", + "food_group.unicopia.fish.cooked": "Cooked Bugs & Insects", + "food_group.unicopia.nuts_and_seeds": "Nuts & Seeds", + "food_group.unicopia.love": "Love", + "food_group.unicopia.rocks": "Rocks", + "food_group.unicopia.pinecone": "Nuts & Seeds", + "food_group.unicopia.bat_ponys_delight": "Bat Pony Treats", + "food_group.unicopia.sea_vegitable.cooked": "Prepared Fish Food", + "food_group.unicopia.sea_vegitable.raw": "Fresh Fish Food", + "food_group.unicopia.shells": "Sea Shells", + "food_group.unicopia.shelly": "Sea Shells", + "food_group.unicopia.candy": "Candy", + "food_group.unicopia.desserts": "Desserts", + "food_group.unicopia.fruit": "Fruit", + "food_group.unicopia.baked_goods": "Baked Goods", + "food_group.unicopia.misc": "Misc", + "food_group.unicopia.fruits_and_vegetables": "Fruits & Vegetables", + "food_group.unicopia.drinks": "Drinks", + "food_group.unicopia.foraging.edible_filling": "Bulky Plant Matter", + "food_group.unicopia.foraging.edible": "Plant Matter", + "food_group.unicopia.foraging.nauseating": "Nauseating", + "food_group.unicopia.foraging.prickly": "Prickly", + "food_group.unicopia.foraging.risky": "Unsafe", + "food_group.unicopia.foraging.strengthening": "Strength Enhancing", + "food_group.unicopia.foraging.severely_prickly": "Very Prickly", + "food_group.unicopia.foraging.severely_nauseating": "Sickening", + "food_group.unicopia.foraging.radioactive": "Glowy", + "food_group.unicopia.foraging.dangerous": "Dangerous", + "food_group.unicopia.foraging.blinding": "Toxic", + "food_group.unicopia.foraging.leafy_greens": "Leafy Greens", "toxicity.safe.name": "Safe", "toxicity.mild.name": "Mildly Toxic", From 4f613ebb910604abb0e997dd9cf0115d0b6a34ab Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 2 Apr 2024 11:27:38 +0100 Subject: [PATCH 65/73] Adjust food categorizations and move some more tags to datagen --- .../unicopia/UConventionalTags.java | 3 + .../com/minelittlepony/unicopia/UTags.java | 5 +- .../providers/tag/UItemTagProvider.java | 66 ++++++++++++++++++- .../unicopia/diet/FoodGroupKey.java | 11 ++++ .../diets/food_groups/baked_goods.json | 2 +- .../diets/food_groups/bat_ponys_delight.json | 2 +- .../unicopia/diets/food_groups/candy.json | 2 +- .../unicopia/diets/food_groups/desserts.json | 2 +- .../unicopia/diets/food_groups/fruit.json | 2 +- .../diets/food_groups/meat/cooked.json | 2 +- .../unicopia/diets/food_groups/meat/raw.json | 2 +- .../diets/food_groups/nuts_and_seeds.json | 2 +- .../unicopia/diets/food_groups/pinecone.json | 2 +- .../unicopia/diets/food_groups/rocks.json | 2 +- .../food_groups/sea_vegetable/cooked.json | 2 +- .../diets/food_groups/sea_vegetable/raw.json | 2 +- .../unicopia/diets/food_groups/shells.json | 2 +- .../unicopia/diets/food_groups/shelly.json | 2 +- .../tags/items/food_types/baked_goods.json | 32 --------- .../items/food_types/bat_ponys_delight.json | 8 --- .../unicopia/tags/items/food_types/candy.json | 10 --- .../tags/items/food_types/cooked_meat.json | 24 ------- .../food_types/cooked_sea_vegitable.json | 3 +- .../tags/items/food_types/desserts.json | 12 ---- .../unicopia/tags/items/food_types/fruit.json | 19 ------ .../unicopia/tags/items/food_types/love.json | 6 -- .../tags/items/food_types/nuts_and_seeds.json | 11 ---- .../tags/items/food_types/pinecone.json | 6 -- .../tags/items/food_types/raw_meat.json | 7 -- .../items/food_types/raw_sea_vegitable.json | 3 - .../unicopia/tags/items/food_types/rocks.json | 6 -- .../tags/items/food_types/shells.json | 11 ---- .../tags/items/food_types/shelly.json | 6 -- .../tags/items/groups/changeling.json | 2 +- .../tags/items/groups/earth_pony.json | 2 + .../unicopia/tags/items/groups/sea_pony.json | 5 +- 36 files changed, 101 insertions(+), 185 deletions(-) delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/bat_ponys_delight.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/candy.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/cooked_meat.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/desserts.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/fruit.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/love.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/nuts_and_seeds.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/pinecone.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/raw_meat.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/rocks.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/shells.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/shelly.json diff --git a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java index a4be14e6..0b1942ce 100644 --- a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java @@ -41,6 +41,7 @@ public interface UConventionalTags { TagKey MUFFINS = item("muffins"); TagKey MANGOES = item("mangoes"); TagKey OATMEALS = item("oatmeals"); + TagKey COOKIES = item("cookies"); TagKey FRUITS = item("fruits"); TagKey WORMS = item("worms"); @@ -55,6 +56,8 @@ public interface UConventionalTags { TagKey RAW_MEAT = item("raw_meat"); TagKey COOKED_MEAT = item("cooked_meat"); TagKey ROTTEN_MEAT = item("rotten_meat"); + TagKey DESSERTS = item("desserts"); + TagKey CANDY = item("candy"); TagKey CROPS_PEANUTS = item("crops/peanuts"); TagKey TOOL_KNIVES = item("tools/knives"); diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index cb045541..24fd3a3f 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -41,7 +41,10 @@ public interface UTags { TagKey LOOT_BUG_RARE_DROPS = item("loot_bug_rare_drops"); TagKey LOOT_BUG_EPIC_DROPS = item("loot_bug_epic_drops"); - TagKey SHELLS = item("food_types/shells"); + TagKey SHELLS = item("shells"); + TagKey SPECIAL_SHELLS = item("special_shells"); + TagKey ROCK_STEWS = item("rock_stews"); + TagKey BAKED_GOODS = item("baked_goods"); TagKey POLEARMS = item("polearms"); TagKey HORSE_SHOES = item("horse_shoes"); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java index f54b7751..7187116a 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java @@ -127,6 +127,9 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { Items.DIAMOND_PICKAXE, Items.DIAMOND_SHOVEL, Items.DIAMOND_AXE, Items.DIAMOND_SWORD, Items.DIAMOND_HOE, UItems.DIAMOND_POLEARM ).forceAddTag(UTags.Items.BADGES).forceAddTag(ConventionalItemTags.GOLD_INGOTS); + getOrCreateTagBuilder(UTags.Items.SHELLS).add(Items.NAUTILUS_SHELL, UItems.CLAM_SHELL, UItems.SCALLOP_SHELL, UItems.TURRET_SHELL); + getOrCreateTagBuilder(UTags.Items.SPECIAL_SHELLS).add(UItems.SHELLY); + getOrCreateTagBuilder(UTags.Items.ROCK_STEWS).add(UItems.ROCK_STEW); exportFarmersDelightItems(); } @@ -209,15 +212,31 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { getOrCreateTagBuilder(UConventionalTags.Items.SEEDS).add(Items.BEETROOT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.TORCHFLOWER_SEEDS, Items.WHEAT_SEEDS) .add(UItems.OAT_SEEDS) .forceAddTag(UTags.Items.APPLE_SEEDS); + getOrCreateTagBuilder(UConventionalTags.Items.COOKIES).add(Items.COOKIE, UItems.OATMEAL_COOKIE, UItems.CHOCOLATE_OATMEAL_COOKIE, UItems.PINECONE_COOKIE); getOrCreateTagBuilder(UConventionalTags.Items.OATMEALS).add(UItems.OATMEAL); getOrCreateTagBuilder(UConventionalTags.Items.GRAIN).add(Items.WHEAT, UItems.OATS); - getOrCreateTagBuilder(UConventionalTags.Items.NUTS).addOptionalTag(UConventionalTags.Items.CROPS_PEANUTS); - + getOrCreateTagBuilder(UConventionalTags.Items.NUTS).add(UItems.BOWL_OF_NUTS) + .addOptionalTag(UConventionalTags.Items.CROPS_PEANUTS) + .forceAddTag(UConventionalTags.Items.ACORNS) + .addOptional(new Identifier("garnished", "nuts")) + .addOptional(new Identifier("garnished", "nut_mix")) + .addOptional(new Identifier("garnished", "neverable_delecacies")); getOrCreateTagBuilder(UConventionalTags.Items.FRUITS) + .add(Items.MELON_SLICE, Items.SWEET_BERRIES, Items.GLOW_BERRIES, Items.CHORUS_FRUIT) + .add(UItems.JUICE, UItems.ZAP_APPLE, UItems.ZAP_BULB) .forceAddTag(UConventionalTags.Items.MANGOES) .forceAddTag(UConventionalTags.Items.PINEAPPLES) .forceAddTag(UConventionalTags.Items.APPLES) - .forceAddTag(UConventionalTags.Items.BANANAS); + .forceAddTag(UConventionalTags.Items.BANANAS) + .addOptionalTag(new Identifier("garnished", "berries")); + getOrCreateTagBuilder(UConventionalTags.Items.DESSERTS).add(Items.CAKE, UItems.APPLE_PIE_SLICE).forceAddTag(UTags.Items.PIES); + getOrCreateTagBuilder(UConventionalTags.Items.CANDY).add(Items.SUGAR, UItems.ROCK_CANDY, UItems.CANDIED_APPLE); + getOrCreateTagBuilder(UTags.Items.BAKED_GOODS).add( + Items.BREAD, Items.COOKIE, Items.PUMPKIN_PIE, + UItems.MUFFIN, UItems.SCONE, UItems.COOKED_ZAP_APPLE, UItems.TOAST, UItems.BURNED_TOAST, UItems.JAM_TOAST, UItems.IMPORTED_OATS, + UItems.HAY_FRIES, UItems.CRISPY_HAY_FRIES, UItems.HORSE_SHOE_FRIES) + .forceAddTag(UConventionalTags.Items.OATMEALS) + .forceAddTag(UConventionalTags.Items.COOKIES); } private void exportFarmersDelightItems() { @@ -235,5 +254,46 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { .addOptional(new Identifier("farmersdelight", "fish_stew")) .addOptional(new Identifier("farmersdelight", "baked_cod_stew")) .addOptional(new Identifier("farmersdelight", "grilled_salmon")); + getOrCreateTagBuilder(UConventionalTags.Items.RAW_MEAT) + .addOptional(new Identifier("farmersdelight", "ham")); + getOrCreateTagBuilder(UConventionalTags.Items.COOKED_MEAT) + .addOptional(new Identifier("farmersdelight", "chicken_soup")) + .addOptional(new Identifier("farmersdelight", "bacon_and_eggs")) + .addOptional(new Identifier("farmersdelight", "pasta_with_meatballs")) + .addOptional(new Identifier("farmersdelight", "beef_stew")) + .addOptional(new Identifier("farmersdelight", "bone_broth")) + .addOptional(new Identifier("farmersdelight", "mutton_wrap")) + .addOptional(new Identifier("farmersdelight", "bacon_sandwich")) + .addOptional(new Identifier("farmersdelight", "hamburger")) + .addOptional(new Identifier("farmersdelight", "chicken_sandwich")) + .addOptional(new Identifier("farmersdelight", "barbecue_stick")) + .addOptional(new Identifier("farmersdelight", "smoked_ham")) + .addOptional(new Identifier("farmersdelight", "honey_glazed_ham")) + .addOptional(new Identifier("farmersdelight", "honey_glazed_ham_block")) + .addOptional(new Identifier("farmersdelight", "roast_chicken")) + .addOptional(new Identifier("farmersdelight", "roast_chicken_block")) + .addOptional(new Identifier("farmersdelight", "steak_and_potatoes")) + .addOptional(new Identifier("farmersdelight", "roasted_mutton_chops")) + .addOptional(new Identifier("farmersdelight", "pasta_with_mutton_chop")); + getOrCreateTagBuilder(UConventionalTags.Items.FRUITS) + .addOptional(new Identifier("farmersdelight", "pumpkin_slice")) + .addOptional(new Identifier("farmersdelight", "tomato")) + .addOptional(new Identifier("farmersdelight", "melon_juice")) + .addOptional(new Identifier("farmersdelight", "fruit_salad")); + getOrCreateTagBuilder(UConventionalTags.Items.DESSERTS) + .addOptional(new Identifier("farmersdelight", "sweet_berry_cheesecake")) + .addOptional(new Identifier("farmersdelight", "sweet_berry_cheesecake_slice")) + .addOptional(new Identifier("farmersdelight", "chocolate_pie_slice")) + .addOptional(new Identifier("farmersdelight", "cake_slice")) + .addOptional(new Identifier("farmersdelight", "apple_pie_slice")) + .addOptional(new Identifier("farmersdelight", "glow_berry_custard")); + getOrCreateTagBuilder(UConventionalTags.Items.COOKIES) + .addOptional(new Identifier("farmersdelight", "sweet_berry_cookie")) + .addOptional(new Identifier("farmersdelight", "honey_cookie")); + getOrCreateTagBuilder(UTags.Items.BAKED_GOODS) + .addOptional(new Identifier("farmersdelight", "wheat_dough")) + .addOptional(new Identifier("farmersdelight", "raw_pasta")) + .addOptional(new Identifier("farmersdelight", "pie_crust")) + .addOptional(new Identifier("farmersdelight", "egg_sandwich")); } } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java index efa49837..ac59d145 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java @@ -2,10 +2,13 @@ package com.minelittlepony.unicopia.diet; import java.util.function.Function; +import com.minelittlepony.unicopia.Debug; +import com.minelittlepony.unicopia.Unicopia; import com.mojang.serialization.Codec; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.tag.TagKey; import net.minecraft.util.Identifier; @@ -28,6 +31,7 @@ public interface FoodGroupKey { }); Function, FoodGroupKey> TAG_LOOKUP = Util.memoize(tag -> { return new FoodGroupKey() { + private boolean check; @Override public Identifier id() { return tag.id(); @@ -35,6 +39,13 @@ public interface FoodGroupKey { @Override public boolean contains(ItemStack stack) { + if (Debug.CHECK_GAME_VALUES && !check) { + check = true; + if (Registries.ITEM.getEntryList(tag).isEmpty()) { + Unicopia.LOGGER.info("Tag is empty: " + tag.id()); + } + } + return stack.isIn(tag); } }; diff --git a/src/main/resources/data/unicopia/diets/food_groups/baked_goods.json b/src/main/resources/data/unicopia/diets/food_groups/baked_goods.json index 31306e54..12d8e949 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/baked_goods.json +++ b/src/main/resources/data/unicopia/diets/food_groups/baked_goods.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/baked_goods" ], + "tags": [ "unicopia:baked_goods" ], "food_component": { "hunger": 1, "saturation": 1 diff --git a/src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json b/src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json index 0fd1f3a0..73e2acf8 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json +++ b/src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/bat_ponys_delight" ], + "tags": [ "c:mangoes" ], "food_component": { "hunger": 1, "saturation": 0.1 diff --git a/src/main/resources/data/unicopia/diets/food_groups/candy.json b/src/main/resources/data/unicopia/diets/food_groups/candy.json index a7d7d64b..e5df4d14 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/candy.json +++ b/src/main/resources/data/unicopia/diets/food_groups/candy.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/candy" ], + "tags": [ "c:candy" ], "food_component": { "hunger": 1, "saturation": 1 diff --git a/src/main/resources/data/unicopia/diets/food_groups/desserts.json b/src/main/resources/data/unicopia/diets/food_groups/desserts.json index 63913e02..4892ee6b 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/desserts.json +++ b/src/main/resources/data/unicopia/diets/food_groups/desserts.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/desserts" ], + "tags": [ "c:desserts" ], "food_component": { "hunger": 1, "saturation": 1 diff --git a/src/main/resources/data/unicopia/diets/food_groups/fruit.json b/src/main/resources/data/unicopia/diets/food_groups/fruit.json index 20793232..c8710f92 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/fruit.json +++ b/src/main/resources/data/unicopia/diets/food_groups/fruit.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/fruit" ], + "tags": [ "c:fruits" ], "food_component": { "hunger": 1, "saturation": 1 diff --git a/src/main/resources/data/unicopia/diets/food_groups/meat/cooked.json b/src/main/resources/data/unicopia/diets/food_groups/meat/cooked.json index 80b1e542..49207c8b 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/meat/cooked.json +++ b/src/main/resources/data/unicopia/diets/food_groups/meat/cooked.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/cooked_meat" ], + "tags": [ "c:cooked_meat" ], "food_component": { "hunger": 12, "saturation": 1.2 diff --git a/src/main/resources/data/unicopia/diets/food_groups/meat/raw.json b/src/main/resources/data/unicopia/diets/food_groups/meat/raw.json index f2c547d9..18879268 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/meat/raw.json +++ b/src/main/resources/data/unicopia/diets/food_groups/meat/raw.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/raw_meat" ], + "tags": [ "c:raw_meat" ], "food_component": { "hunger": 1, "saturation": 1 diff --git a/src/main/resources/data/unicopia/diets/food_groups/nuts_and_seeds.json b/src/main/resources/data/unicopia/diets/food_groups/nuts_and_seeds.json index 30f205a2..eee07b2d 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/nuts_and_seeds.json +++ b/src/main/resources/data/unicopia/diets/food_groups/nuts_and_seeds.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/nuts_and_seeds" ], + "tags": [ "c:grain", "c:nuts", "c:seeds" ], "food_component": { "hunger": 2, "saturation": 2.5 diff --git a/src/main/resources/data/unicopia/diets/food_groups/pinecone.json b/src/main/resources/data/unicopia/diets/food_groups/pinecone.json index 75f92718..735bff30 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/pinecone.json +++ b/src/main/resources/data/unicopia/diets/food_groups/pinecone.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/pinecone" ], + "tags": [ "c:pinecones" ], "food_component": { "hunger": 1, "saturation": 0.1 diff --git a/src/main/resources/data/unicopia/diets/food_groups/rocks.json b/src/main/resources/data/unicopia/diets/food_groups/rocks.json index ebe7b986..ead61325 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/rocks.json +++ b/src/main/resources/data/unicopia/diets/food_groups/rocks.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/rocks" ], + "tags": [ "c:rocks", "unicopia:rock_stews" ], "food_component": { "hunger": 1, "saturation": 0.1 diff --git a/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json b/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json index 194273c0..06d46526 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json +++ b/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/cooked_sea_vegitable" ], + "tags": [ "unicopia:food_types/cooked_sea_vegitable", "c:coral_blocks" ], "food_component": { "hunger": 0, "saturation": 0 diff --git a/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json b/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json index 9fdb8ebf..94bea223 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json +++ b/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/raw_sea_vegitable" ], + "tags": [ "unicopia:food_types/raw_sea_vegitable", "c:corals", "c:coral_fans" ], "food_component": { "hunger": 0, "saturation": 0 diff --git a/src/main/resources/data/unicopia/diets/food_groups/shells.json b/src/main/resources/data/unicopia/diets/food_groups/shells.json index e4760a96..f154f859 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/shells.json +++ b/src/main/resources/data/unicopia/diets/food_groups/shells.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/shells", "unicopia:food_types/shelly" ], + "tags": [ "unicopia:shells" ], "food_component": { "hunger": 0, "saturation": 0 diff --git a/src/main/resources/data/unicopia/diets/food_groups/shelly.json b/src/main/resources/data/unicopia/diets/food_groups/shelly.json index e4760a96..791711a0 100644 --- a/src/main/resources/data/unicopia/diets/food_groups/shelly.json +++ b/src/main/resources/data/unicopia/diets/food_groups/shelly.json @@ -1,5 +1,5 @@ { - "tags": [ "unicopia:food_types/shells", "unicopia:food_types/shelly" ], + "tags": [ "unicopia:special_shells" ], "food_component": { "hunger": 0, "saturation": 0 diff --git a/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json b/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json deleted file mode 100644 index e9ac11e8..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/baked_goods.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:bread", - "minecraft:cookie", - "unicopia:muffin", - "unicopia:scone", - "#c:grain", - "unicopia:cooked_zap_apple", - "minecraft:pumpkin_pie", - "#unicopia:pies", - "unicopia:apple_pie_slice", - "unicopia:toast", - "unicopia:burned_toast", - "unicopia:jam_toast", - "unicopia:imported_oats", - "unicopia:oatmeal", - "unicopia:hay_fries", - "unicopia:crispy_hay_fries", - "unicopia:horse_shoe_fries", - "unicopia:oatmeal_cookie", - "unicopia:chocolate_oatmeal_cookie", - "unicopia:pinecone_cookie", - "unicopia:bowl_of_nuts", - { "id": "farmersdelight:wheat_dough", "required": false }, - { "id": "farmersdelight:raw_pasta", "required": false }, - { "id": "farmersdelight:pie_crust", "required": false }, - { "id": "farmersdelight:sweet_berry_cookie", "required": false }, - { "id": "farmersdelight:honey_cookie", "required": false }, - { "id": "farmersdelight:egg_sandwich", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/bat_ponys_delight.json b/src/main/resources/data/unicopia/tags/items/food_types/bat_ponys_delight.json deleted file mode 100644 index 8309c0f0..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/bat_ponys_delight.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:mango", - { "id": "#c:mango", "required": false }, - { "id": "#c:mangoes", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/candy.json b/src/main/resources/data/unicopia/tags/items/food_types/candy.json deleted file mode 100644 index 8a152f67..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/candy.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:rock_candy", - "unicopia:candied_apple", - "minecraft:sugar", - { "id": "bakersdelight:sweet_berry_cheesecake_slice", "required": false }, - { "id": "bakersdelight:cake_slice", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/cooked_meat.json b/src/main/resources/data/unicopia/tags/items/food_types/cooked_meat.json deleted file mode 100644 index f3e131a6..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/cooked_meat.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "replace": false, - "values": [ - "#c:cooked_meat", - { "id": "farmersdelight:chicken_soup", "required": false }, - { "id": "farmersdelight:bacon_and_eggs", "required": false }, - { "id": "farmersdelight:pasta_with_meatballs", "required": false }, - { "id": "farmersdelight:beef_stew", "required": false }, - { "id": "farmersdelight:bone_broth", "required": false }, - { "id": "farmersdelight:mutton_wrap", "required": false }, - { "id": "farmersdelight:bacon_sandwich", "required": false }, - { "id": "farmersdelight:hamburger", "required": false }, - { "id": "farmersdelight:chicken_sandwich", "required": false }, - { "id": "farmersdelight:barbecue_stick", "required": false }, - { "id": "farmersdelight:smoked_ham", "required": false }, - { "id": "farmersdelight:honey_glazed_ham", "required": false }, - { "id": "farmersdelight:honey_glazed_ham_block", "required": false }, - { "id": "farmersdelight:roast_chicken", "required": false }, - { "id": "farmersdelight:roast_chicken_block", "required": false }, - { "id": "farmersdelight:steak_and_potatoes", "required": false }, - { "id": "farmersdelight:roasted_mutton_chops", "required": false }, - { "id": "farmersdelight:pasta_with_mutton_chop", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/cooked_sea_vegitable.json b/src/main/resources/data/unicopia/tags/items/food_types/cooked_sea_vegitable.json index 30ffdfce..bde823d2 100644 --- a/src/main/resources/data/unicopia/tags/items/food_types/cooked_sea_vegitable.json +++ b/src/main/resources/data/unicopia/tags/items/food_types/cooked_sea_vegitable.json @@ -2,7 +2,6 @@ "replace": false, "values": [ "minecraft:dried_kelp_block", - "minecraft:glow_lichen", - "#c:coral_blocks" + "minecraft:glow_lichen" ] } diff --git a/src/main/resources/data/unicopia/tags/items/food_types/desserts.json b/src/main/resources/data/unicopia/tags/items/food_types/desserts.json deleted file mode 100644 index c88f3f26..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/desserts.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:cake", - { "id": "farmersdelight:sweet_berry_cheesecake", "required": false }, - { "id": "farmersdelight:sweet_berry_cheesecake_slice", "required": false }, - { "id": "farmersdelight:chocolate_pie_slice", "required": false }, - { "id": "farmersdelight:cake_slice", "required": false }, - { "id": "farmersdelight:apple_pie_slice", "required": false }, - { "id": "farmersdelight:glow_berry_custard", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/fruit.json b/src/main/resources/data/unicopia/tags/items/food_types/fruit.json deleted file mode 100644 index 39c40cdc..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/fruit.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "replace": false, - "values": [ - "#c:fruits", - "unicopia:zap_apple", - "unicopia:zap_bulb", - "unicopia:rotten_apple", - "minecraft:melon_slice", - "minecraft:sweet_berries", - "minecraft:glow_berries", - "minecraft:chorus_fruit", - "unicopia:juice", - { "id": "farmersdelight:pumpkin_slice", "required": false }, - { "id": "farmersdelight:tomato", "required": false }, - { "id": "farmersdelight:melon_juice", "required": false }, - { "id": "farmersdelight:fruit_salad", "required": false }, - { "id": "#garnished:berries", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/love.json b/src/main/resources/data/unicopia/tags/items/food_types/love.json deleted file mode 100644 index d9127025..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/love.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "#unicopia:container_with_love" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/nuts_and_seeds.json b/src/main/resources/data/unicopia/tags/items/food_types/nuts_and_seeds.json deleted file mode 100644 index 937e7578..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/nuts_and_seeds.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "replace": false, - "values": [ - "#c:seeds", - "#c:acorns", - "#c:nuts", - { "id": "#garnished:nuts", "required": false }, - { "id": "#garnished:nut_mix", "required": false }, - { "id": "#garnished:neverable_delecacies", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/pinecone.json b/src/main/resources/data/unicopia/tags/items/food_types/pinecone.json deleted file mode 100644 index 9ad60d14..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/pinecone.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "#c:pinecones" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/raw_meat.json b/src/main/resources/data/unicopia/tags/items/food_types/raw_meat.json deleted file mode 100644 index e48e50ee..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/raw_meat.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "replace": false, - "values": [ - "#c:raw_meat", - { "id": "farmersdelight:ham", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/raw_sea_vegitable.json b/src/main/resources/data/unicopia/tags/items/food_types/raw_sea_vegitable.json index c570e4a4..cc815d78 100644 --- a/src/main/resources/data/unicopia/tags/items/food_types/raw_sea_vegitable.json +++ b/src/main/resources/data/unicopia/tags/items/food_types/raw_sea_vegitable.json @@ -5,9 +5,6 @@ "minecraft:dried_kelp", "minecraft:seagrass", "minecraft:sea_pickle", - "#c:corals", - "#c:coral_fans", - { "id": "farmersdelight:melon_popsicle", "required": false }, { "id": "farmersdelight:kelp_roll", "required": false }, { "id": "farmersdelight:kelp_roll_slice", "required": false } ] diff --git a/src/main/resources/data/unicopia/tags/items/food_types/rocks.json b/src/main/resources/data/unicopia/tags/items/food_types/rocks.json deleted file mode 100644 index 229f317a..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/rocks.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:rock_stew" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/shells.json b/src/main/resources/data/unicopia/tags/items/food_types/shells.json deleted file mode 100644 index d62b7052..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/shells.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:nautilus_shell", - "unicopia:clam_shell", - "unicopia:scallop_shell", - "unicopia:turret_shell", - "minecraft:seagrass", - "minecraft:sea_pickle" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/shelly.json b/src/main/resources/data/unicopia/tags/items/food_types/shelly.json deleted file mode 100644 index f8790589..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/shelly.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "unicopia:shelly" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/groups/changeling.json b/src/main/resources/data/unicopia/tags/items/groups/changeling.json index 8c094993..f25692d7 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/changeling.json +++ b/src/main/resources/data/unicopia/tags/items/groups/changeling.json @@ -13,7 +13,7 @@ "unicopia:hive", "unicopia:dark_oak_stable_door", "#c:cooked_meat", - "#unicopia:food_types/raw_meat", + "#c:raw_meat", "#c:raw_insect", "#c:rotten_meat", "#unicopia:container_with_love" diff --git a/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json b/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json index 51b9f951..c75fb733 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json +++ b/src/main/resources/data/unicopia/tags/items/groups/earth_pony.json @@ -52,6 +52,7 @@ "unicopia:imported_oats", "unicopia:oatmeal", "unicopia:oatmeal_cookie", + "unicopia:chocolate_oatmeal_cookie", "unicopia:daffodil_daisy_sandwich", "unicopia:hay_burger", "unicopia:hay_fries", @@ -61,6 +62,7 @@ "unicopia:baited_fishing_rod", "unicopia:worm_block", "unicopia:muffin", + "unicopia:scone", "unicopia:acorn", "unicopia:pinecone", "unicopia:pinecone_cookie", diff --git a/src/main/resources/data/unicopia/tags/items/groups/sea_pony.json b/src/main/resources/data/unicopia/tags/items/groups/sea_pony.json index a9259060..5d2c981b 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/sea_pony.json +++ b/src/main/resources/data/unicopia/tags/items/groups/sea_pony.json @@ -2,9 +2,8 @@ "replace": false, "values": [ "unicopia:pearl_necklace", - "minecraft:nautilus_shell", - "#unicopia:food_types/shells", - "#unicopia:food_types/shelly", + "#unicopia:shells", + "#unicopia:special_shells", "#unicopia:food_types/raw_sea_vegitable", "#unicopia:food_types/cooked_sea_vegitable" ] From 734e75f8c878495141c38cc2706dc3029032f883 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 2 Apr 2024 16:25:28 +0100 Subject: [PATCH 66/73] Add proper item models and textures for the slime pustule and mysterious egg --- .../providers/UBlockStateModelGenerator.java | 4 ++-- .../unicopia/models/item/mysterious_egg.json | 16 ---------------- .../unicopia/textures/item/mysterious_egg.png | Bin 0 -> 6922 bytes .../unicopia/textures/item/slime_pustule.png | Bin 0 -> 6682 bytes 4 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 src/main/resources/assets/unicopia/models/item/mysterious_egg.json create mode 100644 src/main/resources/assets/unicopia/textures/item/mysterious_egg.png create mode 100644 src/main/resources/assets/unicopia/textures/item/slime_pustule.png diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java index d016daae..40fe766c 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UBlockStateModelGenerator.java @@ -113,7 +113,7 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator { registerHiveBlock(UBlocks.HIVE); registerRotated(UBlocks.CHITIN_SPIKES, BlockModels.SPIKES); registerHull(UBlocks.CHISELLED_CHITIN_HULL, UBlocks.CHITIN, UBlocks.CHISELLED_CHITIN); - registerParentedItemModel(UBlocks.SLIME_PUSTULE, ModelIds.getBlockSubModelId(UBlocks.SLIME_PUSTULE, "_pod")); + registerItemModel(UBlocks.SLIME_PUSTULE.asItem()); blockStateCollector.accept(VariantsBlockStateSupplier.create(UBlocks.SLIME_PUSTULE) .coordinate(BlockStateVariantMap.create(SlimePustuleBlock.SHAPE) .register(state -> BlockStateVariant.create().put(MODEL, ModelIds.getBlockSubModelId(UBlocks.SLIME_PUSTULE, "_" + state.asString()))))); @@ -176,7 +176,7 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator { registerWithStages(UBlocks.FROSTED_OBSIDIAN, Properties.AGE_3, BlockModels.CUBE_ALL, 0, 1, 2, 3); registerWithStagesBuiltinModels(UBlocks.ROCKS, Properties.AGE_7, 0, 1, 2, 3, 4, 5, 6, 7); registerWithStagesBuiltinModels(UBlocks.MYSTERIOUS_EGG, PileBlock.COUNT, 1, 2, 3); - excludeFromSimpleItemModelGeneration(UBlocks.MYSTERIOUS_EGG); + registerItemModel(UBlocks.MYSTERIOUS_EGG.asItem()); FireModels.registerSoulFire(this, UBlocks.SPECTRAL_FIRE, Blocks.SOUL_FIRE); blockStateCollector.accept(createSingletonBlockState(UBlocks.JAR, BlockModels.TEMPLATE_JAR)); diff --git a/src/main/resources/assets/unicopia/models/item/mysterious_egg.json b/src/main/resources/assets/unicopia/models/item/mysterious_egg.json deleted file mode 100644 index 7c9548c9..00000000 --- a/src/main/resources/assets/unicopia/models/item/mysterious_egg.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "parent": "unicopia:block/mysterious_egg_stage1", - "gui_light": "side", - "display": { - "gui": { - "rotation": [ 30, 225, 0 ], - "translation": [ 0, 0, 0], - "scale":[ 0.625, 0.625, 0.625 ] - }, - "fixed": { - "rotation": [ 0, 0, 0 ], - "translation": [ 0, 0, 0], - "scale":[ 0.5, 0.5, 0.5 ] - } - } -} diff --git a/src/main/resources/assets/unicopia/textures/item/mysterious_egg.png b/src/main/resources/assets/unicopia/textures/item/mysterious_egg.png new file mode 100644 index 0000000000000000000000000000000000000000..bc1d9a42e705931098bcdc4d2c6f427fe60a6d93 GIT binary patch literal 6922 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

RHGv5syn>$b9llh<{bGpWUbA%#dTE7K`^>2PZ z_1d1M8>jU3tBE-ShTVSa-Ttc&HJvTlxqJVo70ei=U=vfUZ3KD7h={GcJzQ|ps+ G=lu)2_dk{Z literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/slime_pustule.png b/src/main/resources/assets/unicopia/textures/item/slime_pustule.png new file mode 100644 index 0000000000000000000000000000000000000000..e3111b434f00de6bf4716182c864187e29c52490 GIT binary patch literal 6682 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 Date: Thu, 4 Apr 2024 20:22:10 +0100 Subject: [PATCH 67/73] Datagen food groups+ - add more variety in the foraging groups - rebalance the probability of negative effects/food poisoning when eating the foraged things - add groups for rotten insect - moved fermented spider eye to the rotten insect category - removed unused foraging_moderate category - fixed incorrect tag reference breaking sapling eating --- .../unicopia/UConventionalTags.java | 1 + .../com/minelittlepony/unicopia/UTags.java | 16 ++- .../unicopia/datagen/DataCollector.java | 4 + .../unicopia/datagen/Datagen.java | 4 +- .../providers/DietProfileGenerator.java | 12 ++ .../datagen/providers/DietsProvider.java | 83 ++++++++++++ .../providers/FoodGroupsGenerator.java | 123 ++++++++++++++++++ .../providers/SeasonsGrowthRatesProvider.java | 6 +- .../providers/tag/UItemTagProvider.java | 47 ++++++- .../unicopia/diet/FoodGroup.java | 22 +++- .../unicopia/diet/FoodGroupEffects.java | 44 +++++++ .../unicopia/diet/FoodGroupKey.java | 20 +++ .../unicopia/diet/affliction/Affliction.java | 2 +- .../diet/affliction/CompoundAffliction.java | 2 +- .../diet/affliction/HealingAffliction.java | 2 +- .../unicopia/diet/affliction/Range.java | 6 +- .../affliction/StatusEffectAffliction.java | 52 ++++---- .../unicopia/item/UFoodComponents.java | 6 - .../data/c/tags/items/foraging/edibles.json | 13 -- .../tags/items/foraging/edibles_filling.json | 8 -- .../data/c/tags/items/foraging/risky.json | 8 -- .../diets/food_groups/baked_goods.json | 11 -- .../diets/food_groups/bat_ponys_delight.json | 10 -- .../unicopia/diets/food_groups/candy.json | 11 -- .../unicopia/diets/food_groups/desserts.json | 11 -- .../diets/food_groups/fish/cooked.json | 16 --- .../unicopia/diets/food_groups/fish/raw.json | 22 ---- .../diets/food_groups/fish/rotten.json | 23 ---- .../diets/food_groups/foraging/blinding.json | 21 --- .../diets/food_groups/foraging/dangerous.json | 17 --- .../diets/food_groups/foraging/edible.json | 10 -- .../food_groups/foraging/edible_filling.json | 10 -- .../food_groups/foraging/leafy_greens.json | 10 -- .../diets/food_groups/foraging/moderate.json | 17 --- .../food_groups/foraging/nauseating.json | 22 ---- .../diets/food_groups/foraging/prickly.json | 17 --- .../food_groups/foraging/radioactive.json | 22 ---- .../diets/food_groups/foraging/risky.json | 17 --- .../foraging/severely_nauseating.json | 21 --- .../foraging/severely_prickly.json | 21 --- .../food_groups/foraging/strengthening.json | 22 ---- .../unicopia/diets/food_groups/fruit.json | 11 -- .../diets/food_groups/insect/cooked.json | 16 --- .../diets/food_groups/insect/raw.json | 16 --- .../data/unicopia/diets/food_groups/love.json | 21 --- .../diets/food_groups/meat/cooked.json | 16 --- .../unicopia/diets/food_groups/meat/raw.json | 23 ---- .../diets/food_groups/meat/rotten.json | 23 ---- .../diets/food_groups/nuts_and_seeds.json | 11 -- .../unicopia/diets/food_groups/pinecone.json | 15 --- .../unicopia/diets/food_groups/rocks.json | 10 -- .../food_groups/sea_vegetable/cooked.json | 11 -- .../diets/food_groups/sea_vegetable/raw.json | 11 -- .../unicopia/diets/food_groups/shells.json | 10 -- .../unicopia/diets/food_groups/shelly.json | 10 -- .../food_types/cooked_sea_vegitable.json | 7 - .../items/food_types/forage_blinding.json | 6 - .../items/food_types/forage_dangerous.json | 7 - .../tags/items/food_types/forage_edible.json | 19 --- .../food_types/forage_edible_filling.json | 7 - .../items/food_types/forage_nauseating.json | 8 -- .../tags/items/food_types/forage_prickly.json | 7 - .../items/food_types/forage_radioactive.json | 7 - .../tags/items/food_types/forage_risky.json | 9 -- .../forage_severely_nauseating.json | 6 - .../food_types/forage_severely_prickly.json | 6 - .../food_types/forage_strengthening.json | 6 - .../items/food_types/raw_sea_vegitable.json | 11 -- 68 files changed, 400 insertions(+), 722 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/DietProfileGenerator.java create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/DietsProvider.java create mode 100644 src/main/java/com/minelittlepony/unicopia/datagen/providers/FoodGroupsGenerator.java delete mode 100644 src/main/resources/data/c/tags/items/foraging/edibles.json delete mode 100644 src/main/resources/data/c/tags/items/foraging/edibles_filling.json delete mode 100644 src/main/resources/data/c/tags/items/foraging/risky.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/baked_goods.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/candy.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/desserts.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/fish/cooked.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/fish/raw.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/fish/rotten.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/blinding.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/dangerous.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/edible.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/edible_filling.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/leafy_greens.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/moderate.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/nauseating.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/prickly.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/radioactive.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/risky.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/severely_nauseating.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/severely_prickly.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/foraging/strengthening.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/fruit.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/insect/cooked.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/insect/raw.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/love.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/meat/cooked.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/meat/raw.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/meat/rotten.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/nuts_and_seeds.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/pinecone.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/rocks.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/shells.json delete mode 100644 src/main/resources/data/unicopia/diets/food_groups/shelly.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/cooked_sea_vegitable.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_blinding.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_dangerous.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_edible.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_edible_filling.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_nauseating.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_prickly.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_radioactive.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_risky.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_severely_nauseating.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_severely_prickly.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/forage_strengthening.json delete mode 100644 src/main/resources/data/unicopia/tags/items/food_types/raw_sea_vegitable.json diff --git a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java index 0b1942ce..6b54e607 100644 --- a/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UConventionalTags.java @@ -49,6 +49,7 @@ public interface UConventionalTags { TagKey RAW_INSECT = item("raw_insect"); TagKey COOKED_INSECT = item("cooked_insect"); + TagKey ROTTEN_INSECT = item("rotten_insect"); TagKey RAW_FISH = item("raw_fish"); TagKey COOKED_FISH = item("cooked_fish"); diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index 24fd3a3f..83e9cb37 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -30,7 +30,6 @@ public interface UTags { TagKey MAGIC_FEATHERS = item("magic_feathers"); TagKey SHADES = item("shades"); - TagKey CHANGELING_EDIBLE = item("food_types/changeling_edible"); TagKey SPOOKED_MOB_DROPS = item("spooked_mob_drops"); TagKey HAS_NO_TRAITS = item("has_no_traits"); TagKey IS_DELIVERED_AGGRESSIVELY = item("is_delivered_aggressively"); @@ -46,6 +45,9 @@ public interface UTags { TagKey ROCK_STEWS = item("rock_stews"); TagKey BAKED_GOODS = item("baked_goods"); + TagKey HIGH_QUALITY_SEA_VEGETABLES = item("food_types/high_quality_sea_vegetables"); + TagKey LOW_QUALITY_SEA_VEGETABLES = item("food_types/low_quality_sea_vegetables"); + TagKey POLEARMS = item("polearms"); TagKey HORSE_SHOES = item("horse_shoes"); TagKey APPLE_SEEDS = item("apple_seeds"); @@ -64,6 +66,18 @@ public interface UTags { TagKey GROUP_SEA_PONY = item("groups/sea_pony"); TagKey GROUP_CHANGELING = item("groups/changeling"); + TagKey FORAGE_BLINDING = item("forage/blinding"); + TagKey FORAGE_DANGEROUS = item("forage/dangerous"); + TagKey FORAGE_FILLING = item("forage/filling"); + TagKey FORAGE_SAFE = item("forage/safe"); + TagKey FORAGE_NAUSEATING = item("forage/nauseating"); + TagKey FORAGE_PRICKLY = item("forage/prickly"); + TagKey FORAGE_GLOWING = item("forage/glowing"); + TagKey FORAGE_RISKY = item("forage/risky"); + TagKey FORAGE_STRENGHENING = item("forage/strenghtening"); + TagKey FORAGE_SEVERE_NAUSEATING = item("forage/severe/nauseating"); + TagKey FORAGE_SEVERE_PRICKLY = item("forage/severe/prickly"); + private static TagKey item(String name) { return TagKey.of(RegistryKeys.ITEM, Unicopia.id(name)); } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/DataCollector.java b/src/main/java/com/minelittlepony/unicopia/datagen/DataCollector.java index 46b27642..2dabd5cd 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/DataCollector.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/DataCollector.java @@ -22,6 +22,10 @@ public class DataCollector { this.resolver = resolver; } + public boolean isDefined(Identifier id) { + return values.containsKey(id); + } + public BiConsumer> prime() { values.clear(); return (Identifier id, Supplier value) -> diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java index 667d6173..517a21e4 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.minelittlepony.unicopia.block.EdibleBlock; +import com.minelittlepony.unicopia.datagen.providers.DietsProvider; import com.minelittlepony.unicopia.datagen.providers.SeasonsGrowthRatesProvider; import com.minelittlepony.unicopia.datagen.providers.UAdvancementsProvider; import com.minelittlepony.unicopia.datagen.providers.UModelProvider; @@ -49,7 +50,8 @@ public class Datagen implements DataGeneratorEntrypoint { public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { final var pack = fabricDataGenerator.createPack(); final var blockTags = pack.addProvider(UBlockTagProvider::new); - pack.addProvider((output, registries) -> new UItemTagProvider(output, registries, blockTags)); + final var itemTags = pack.addProvider((output, registries) -> new UItemTagProvider(output, registries, blockTags)); + pack.addProvider((output, registries) -> new DietsProvider(output, itemTags)); pack.addProvider(UDamageTypeProvider::new); pack.addProvider(UModelProvider::new); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/DietProfileGenerator.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/DietProfileGenerator.java new file mode 100644 index 00000000..6afe54f9 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/DietProfileGenerator.java @@ -0,0 +1,12 @@ +package com.minelittlepony.unicopia.datagen.providers; + +import java.util.function.BiConsumer; +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.diet.DietProfile; + +public class DietProfileGenerator { + + public void generate(BiConsumer exporter) { + + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/DietsProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/DietsProvider.java new file mode 100644 index 00000000..5b14e3dd --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/DietsProvider.java @@ -0,0 +1,83 @@ +package com.minelittlepony.unicopia.datagen.providers; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +import com.google.gson.JsonObject; +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.datagen.DataCollector; +import com.minelittlepony.unicopia.diet.DietProfile; +import com.minelittlepony.unicopia.diet.FoodGroup; +import com.mojang.serialization.JsonOps; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.minecraft.data.DataOutput; +import net.minecraft.data.DataProvider; +import net.minecraft.data.DataWriter; +import net.minecraft.data.server.tag.TagProvider; +import net.minecraft.data.server.tag.TagProvider.TagLookup; +import net.minecraft.item.Item; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; + +public class DietsProvider implements DataProvider { + private final DataCollector dietsCollector; + private final DataCollector categoriesCollector; + + private final CompletableFuture> itemTagLookup; + + public DietsProvider(FabricDataOutput output, TagProvider tagProvider) { + this.dietsCollector = new DataCollector(output.getResolver(DataOutput.OutputType.DATA_PACK, "diet/races")); + this.categoriesCollector = new DataCollector(output.getResolver(DataOutput.OutputType.DATA_PACK, "diet/food_groups")); + itemTagLookup = tagProvider.getTagLookupFuture(); + } + + @Override + public String getName() { + return "Diets"; + } + + @Override + public CompletableFuture run(DataWriter writer) { + return itemTagLookup.thenCompose(tagLookup -> { + var diets = categoriesCollector.prime(); + Map> keyToGroupId = new HashMap<>(); + new FoodGroupsGenerator().generate((id, builder) -> { + var attributes = builder.build(); + attributes.tags().forEach(key -> { + if (!tagLookup.contains(TagKey.of(RegistryKeys.ITEM, key.id()))) { + throw new IllegalArgumentException("Food group " + id + " references unknown item tag " + key.id()); + } + keyToGroupId.computeIfAbsent(key.id(), i -> new HashSet<>()).add(id); + }); + diets.accept(id, () -> FoodGroup.CODEC.encode(attributes, JsonOps.INSTANCE, new JsonObject()).result().get()); + }); + var profiles = dietsCollector.prime(); + new DietProfileGenerator().generate((race, profile) -> { + Identifier id = Race.REGISTRY.getId(race); + StringBuilder issues = new StringBuilder(); + profile.validate(issue -> { + issues.append(System.lineSeparator()).append(issue); + }, categoriesCollector::isDefined); + if (!issues.isEmpty()) { + throw new IllegalArgumentException("Diet profile " + id + " failed validation: " + issues.toString()); + } + profiles.accept(id, () -> DietProfile.CODEC.encode(profile, JsonOps.INSTANCE, new JsonObject()).result().get()); + }); + keyToGroupId.forEach((tag, groups) -> { + if (groups.size() > 1) { + throw new IllegalArgumentException("Multiple groups referenced the same tag " + tag + " held by " + + groups.stream().map(Identifier::toString).collect(Collectors.joining()) + ); + } + }); + + return CompletableFuture.allOf(categoriesCollector.upload(writer), dietsCollector.upload(writer)); + }); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/FoodGroupsGenerator.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/FoodGroupsGenerator.java new file mode 100644 index 00000000..c1e4bf75 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/FoodGroupsGenerator.java @@ -0,0 +1,123 @@ +package com.minelittlepony.unicopia.datagen.providers; + +import java.util.List; +import java.util.function.BiConsumer; +import com.minelittlepony.unicopia.UConventionalTags; +import com.minelittlepony.unicopia.UTags; +import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.diet.FoodGroupEffects; +import com.minelittlepony.unicopia.diet.affliction.Affliction; +import com.minelittlepony.unicopia.diet.affliction.CompoundAffliction; +import com.minelittlepony.unicopia.diet.affliction.HealingAffliction; +import com.minelittlepony.unicopia.diet.affliction.LoseHungerAffliction; +import com.minelittlepony.unicopia.diet.affliction.Range; +import com.minelittlepony.unicopia.diet.affliction.StatusEffectAffliction; +import com.minelittlepony.unicopia.entity.effect.UEffects; +import com.minelittlepony.unicopia.item.UFoodComponents; + +import net.minecraft.entity.effect.StatusEffects; +import net.minecraft.item.FoodComponent; +import net.minecraft.item.FoodComponents; +import net.minecraft.item.Item; +import net.minecraft.registry.tag.ItemTags; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; + +public class FoodGroupsGenerator { + public void generate(BiConsumer exporter) { + exporter.accept(Unicopia.id("baked_goods"), new FoodGroupEffects.Builder().tag(UTags.Items.BAKED_GOODS).food(FoodComponents.BREAD)); + exporter.accept(Unicopia.id("bat_ponys_delight"), new FoodGroupEffects.Builder().tag(UConventionalTags.Items.MANGOES).food(UFoodComponents.MANGO)); + exporter.accept(Unicopia.id("candy"), new FoodGroupEffects.Builder().tag(UConventionalTags.Items.CANDY).food(UFoodComponents.CANDY)); + exporter.accept(Unicopia.id("desserts"), new FoodGroupEffects.Builder().tag(UConventionalTags.Items.DESSERTS).food(FoodComponents.COOKIE)); + exporter.accept(Unicopia.id("fruit"), new FoodGroupEffects.Builder().tag(UConventionalTags.Items.FRUITS).food(UFoodComponents.BANANA)); + exporter.accept(Unicopia.id("rocks"), new FoodGroupEffects.Builder().tag(UConventionalTags.Items.ROCKS).tag(UTags.Items.ROCK_STEWS).food(FoodComponents.MUSHROOM_STEW)); + exporter.accept(Unicopia.id("shells"), new FoodGroupEffects.Builder().tag(UTags.Items.SHELLS).food(UFoodComponents.SHELL)); + exporter.accept(Unicopia.id("special_shells"), new FoodGroupEffects.Builder().tag(UTags.Items.SPECIAL_SHELLS).food(UFoodComponents.SHELLY)); + exporter.accept(Unicopia.id("love"), new FoodGroupEffects.Builder().tag(UTags.Items.CONTAINER_WITH_LOVE).food(UFoodComponents.LOVE_MUG).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(50), Range.of(2), 0), + new LoseHungerAffliction(0.5F) + )))); + exporter.accept(Unicopia.id("nuts_and_seeds"), new FoodGroupEffects.Builder() + .tag(UConventionalTags.Items.GRAIN).tag(UConventionalTags.Items.NUTS).tag(UConventionalTags.Items.SEEDS) + .food(UFoodComponents.BANANA) + ); + exporter.accept(Unicopia.id("pinecone"), new FoodGroupEffects.Builder().tag(UConventionalTags.Items.PINECONES).food(UFoodComponents.PINECONE).ailment(new CompoundAffliction(List.of( + new HealingAffliction(1) + )))); + + provideMeatCategory("fish", + UConventionalTags.Items.COOKED_FISH, UConventionalTags.Items.RAW_FISH, UConventionalTags.Items.ROTTEN_FISH, + FoodComponents.COOKED_COD, FoodComponents.COD, FoodComponents.ROTTEN_FLESH, exporter); + provideMeatCategory("meat", + UConventionalTags.Items.COOKED_MEAT, UConventionalTags.Items.RAW_MEAT, UConventionalTags.Items.ROTTEN_MEAT, + FoodComponents.COOKED_BEEF, FoodComponents.BEEF, FoodComponents.ROTTEN_FLESH, exporter); + provideMeatCategory("insect", + UConventionalTags.Items.COOKED_INSECT, UConventionalTags.Items.RAW_INSECT, UConventionalTags.Items.ROTTEN_INSECT, + FoodComponents.COOKED_BEEF, FoodComponents.BEEF, FoodComponents.ROTTEN_FLESH, exporter); + provideVegetableCategory("sea_vegetable", + UTags.Items.HIGH_QUALITY_SEA_VEGETABLES, UTags.Items.LOW_QUALITY_SEA_VEGETABLES, + FoodComponents.COOKED_BEEF, FoodComponents.BEEF, exporter); + + exporter.accept(Unicopia.id("foraging/blinding"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_BLINDING).food(4, 0.2F).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(StatusEffects.BLINDNESS, Range.of(30), Range.of(0), 50), + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 12) + )))); + exporter.accept(Unicopia.id("foraging/dangerous"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_DANGEROUS).food(3, 0.3F).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(250), Range.of(2), 4) + )))); + exporter.accept(Unicopia.id("foraging/edible_filling"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_FILLING).food(17, 0.6F)); + exporter.accept(Unicopia.id("foraging/edible"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_SAFE).food(2, 1)); + exporter.accept(Unicopia.id("foraging/leafy_greens"), new FoodGroupEffects.Builder().tag(ItemTags.LEAVES).food(1, 1.4F)); + exporter.accept(Unicopia.id("foraging/nauseating"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_NAUSEATING).food(5, 0.5F).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(StatusEffects.WEAKNESS, Range.of(200), Range.of(1), 30), + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(200), Range.of(2), 0) + )))); + exporter.accept(Unicopia.id("foraging/prickly"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_PRICKLY).food(0, 1.5F).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(StatusEffects.INSTANT_DAMAGE, Range.of(1), Range.of(0), 30) + )))); + exporter.accept(Unicopia.id("foraging/glowing"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_GLOWING).food(1, 1.6F).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(StatusEffects.GLOWING, Range.of(30), Range.of(0), 30), + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 0) + )))); + exporter.accept(Unicopia.id("foraging/risky"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_RISKY).food(9, 1.1F).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 80) + )))); + exporter.accept(Unicopia.id("foraging/severely_nauseating"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_SEVERE_NAUSEATING).food(3, 0.9F).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(StatusEffects.WEAKNESS, Range.of(200), Range.of(1), 0), + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 80) + )))); + exporter.accept(Unicopia.id("foraging/severely_prickly"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_SEVERE_PRICKLY).food(2, 0.9F).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(StatusEffects.INSTANT_DAMAGE, Range.of(1), Range.of(0), 0), + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 80) + )))); + exporter.accept(Unicopia.id("foraging/strengthening"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_STRENGHENING).food(4, 0.2F).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(StatusEffects.STRENGTH, Range.of(1300), Range.of(0), 0), + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 70) + )))); + } + + private void provideMeatCategory(String name, + TagKey cookedTag, TagKey rawTag, TagKey rottenTag, + FoodComponent cooked, FoodComponent raw, FoodComponent rotten, + BiConsumer exporter) { + exporter.accept(Unicopia.id(name + "/cooked"), new FoodGroupEffects.Builder().tag(cookedTag).food(cooked).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 25) + )))); + exporter.accept(Unicopia.id(name + "/raw"), new FoodGroupEffects.Builder().tag(rawTag).food(raw).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(StatusEffects.POISON, Range.of(45), Range.of(2), 80), + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 65) + )))); + exporter.accept(Unicopia.id(name + "/rotten"), new FoodGroupEffects.Builder().tag(rottenTag).food(rotten).ailment(new CompoundAffliction(List.of( + new StatusEffectAffliction(StatusEffects.POISON, Range.of(45), Range.of(2), 80), + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 95) + )))); + } + + private void provideVegetableCategory(String name, + TagKey cookedTag, TagKey rawTag, + FoodComponent cooked, FoodComponent raw, + BiConsumer exporter) { + exporter.accept(Unicopia.id(name + "/cooked"), new FoodGroupEffects.Builder().tag(cookedTag).food(cooked)); + exporter.accept(Unicopia.id(name + "/raw"), new FoodGroupEffects.Builder().tag(rawTag).food(raw)); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/SeasonsGrowthRatesProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/SeasonsGrowthRatesProvider.java index 186c0685..d802bbc7 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/SeasonsGrowthRatesProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/SeasonsGrowthRatesProvider.java @@ -12,17 +12,16 @@ import com.minelittlepony.unicopia.server.world.UTreeGen; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.minecraft.block.Block; import net.minecraft.data.DataOutput; -import net.minecraft.data.DataOutput.PathResolver; import net.minecraft.registry.Registries; import net.minecraft.data.DataProvider; import net.minecraft.data.DataWriter; public class SeasonsGrowthRatesProvider implements DataProvider { - private final PathResolver pathResolver; + private final DataCollector collectedData; public SeasonsGrowthRatesProvider(FabricDataOutput output) { - this.pathResolver = output.getResolver(DataOutput.OutputType.DATA_PACK, "seasons/crop"); + this.collectedData = new DataCollector(output.getResolver(DataOutput.OutputType.DATA_PACK, "seasons/crop")); } @Override @@ -32,7 +31,6 @@ public class SeasonsGrowthRatesProvider implements DataProvider { @Override public CompletableFuture run(DataWriter writer) { - DataCollector collectedData = new DataCollector(pathResolver); var exporter = collectedData.prime(); generate((block, crop) -> { exporter.accept(Registries.BLOCK.getId(block), crop::toJson); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java index 7187116a..bc248a61 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java @@ -130,7 +130,14 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { getOrCreateTagBuilder(UTags.Items.SHELLS).add(Items.NAUTILUS_SHELL, UItems.CLAM_SHELL, UItems.SCALLOP_SHELL, UItems.TURRET_SHELL); getOrCreateTagBuilder(UTags.Items.SPECIAL_SHELLS).add(UItems.SHELLY); getOrCreateTagBuilder(UTags.Items.ROCK_STEWS).add(UItems.ROCK_STEW); + getOrCreateTagBuilder(UTags.Items.HIGH_QUALITY_SEA_VEGETABLES) + .add(Items.DRIED_KELP_BLOCK, Items.GLOW_LICHEN) + .forceAddTag(UConventionalTags.Items.CORAL_BLOCKS); + getOrCreateTagBuilder(UTags.Items.LOW_QUALITY_SEA_VEGETABLES) + .add(Items.KELP, Items.DRIED_KELP, Items.SEAGRASS, Items.SEA_PICKLE) + .forceAddTag(UConventionalTags.Items.CORALS).forceAddTag(UConventionalTags.Items.CORAL_FANS); + exportForagingTags(); exportFarmersDelightItems(); } @@ -162,6 +169,23 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { copy(UTags.Blocks.CHITIN_BLOCKS, UTags.Items.CHITIN_BLOCKS); } + private void exportForagingTags() { + getOrCreateTagBuilder(UTags.Items.FORAGE_BLINDING).add(Items.OXEYE_DAISY); + getOrCreateTagBuilder(UTags.Items.FORAGE_DANGEROUS).add(Items.POPPY, Items.LILY_OF_THE_VALLEY); + getOrCreateTagBuilder(UTags.Items.FORAGE_FILLING).add(Items.HAY_BLOCK); + getOrCreateTagBuilder(UTags.Items.FORAGE_SAFE).add(Items.BLUE_ORCHID, Items.RED_TULIP, Items.ORANGE_TULIP, + Items.PINK_TULIP, Items.CORNFLOWER, Items.PEONY, Items.SUNFLOWER, Items.DANDELION, Items.LILAC, Items.TALL_GRASS, + Items.DEAD_BUSH, Items.PINK_PETALS + ).forceAddTag(UConventionalTags.Items.MUSHROOMS).forceAddTag(ItemTags.SAPLINGS); + getOrCreateTagBuilder(UTags.Items.FORAGE_NAUSEATING).add(Items.GRASS, UItems.CIDER); + getOrCreateTagBuilder(UTags.Items.FORAGE_PRICKLY).add(Items.ROSE_BUSH).forceAddTag(ItemTags.SAPLINGS); + getOrCreateTagBuilder(UTags.Items.FORAGE_GLOWING).add(Items.AZURE_BLUET, Items.TORCHFLOWER); + getOrCreateTagBuilder(UTags.Items.FORAGE_RISKY).add(Items.ALLIUM, Items.WHITE_TULIP, UItems.BURNED_JUICE); + getOrCreateTagBuilder(UTags.Items.FORAGE_STRENGHENING).add(Items.FERN); + getOrCreateTagBuilder(UTags.Items.FORAGE_SEVERE_NAUSEATING).add(Items.PITCHER_PLANT); + getOrCreateTagBuilder(UTags.Items.FORAGE_SEVERE_PRICKLY).add(Items.LARGE_FERN); + } + private void exportConventionalTags() { copy(UConventionalTags.Blocks.CONCRETES, UConventionalTags.Items.CONCRETES); copy(UConventionalTags.Blocks.CONCRETE_POWDERS, UConventionalTags.Items.CONCRETE_POWDERS); @@ -199,7 +223,9 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { .addOptionalTag(new Identifier("c", "raw_pork")) .addOptionalTag(new Identifier("c", "lemon_chickens")); getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_MEAT).add(Items.ROTTEN_FLESH); - getOrCreateTagBuilder(UConventionalTags.Items.COOKED_INSECT).add(Items.FERMENTED_SPIDER_EYE); + getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_FISH);//.add(Items.ROTTEN_FLESH); TODO: + getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_INSECT).add(Items.FERMENTED_SPIDER_EYE); + getOrCreateTagBuilder(UConventionalTags.Items.COOKED_INSECT);//.add(Items.FERMENTED_SPIDER_EYE); getOrCreateTagBuilder(UConventionalTags.Items.RAW_INSECT).add(Items.SPIDER_EYE, UItems.BUTTERFLY, UItems.WHEAT_WORMS, UBlocks.WORM_BLOCK.asItem()); getOrCreateTagBuilder(UConventionalTags.Items.WORMS).add(UItems.WHEAT_WORMS); getOrCreateTagBuilder(UConventionalTags.Items.STICKS).add(Items.STICK); @@ -295,5 +321,24 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { .addOptional(new Identifier("farmersdelight", "raw_pasta")) .addOptional(new Identifier("farmersdelight", "pie_crust")) .addOptional(new Identifier("farmersdelight", "egg_sandwich")); + getOrCreateTagBuilder(UTags.Items.HIGH_QUALITY_SEA_VEGETABLES) + .addOptional(new Identifier("farmersdelight", "kelp_roll")); + getOrCreateTagBuilder(UTags.Items.LOW_QUALITY_SEA_VEGETABLES) + .addOptional(new Identifier("farmersdelight", "kelp_roll_slice")); + getOrCreateTagBuilder(UTags.Items.FORAGE_FILLING) + .addOptional(new Identifier("farmersdelight", "horse_feed")) + .addOptional(new Identifier("farmersdelight", "rice_bale")) + .addOptional(new Identifier("farmersdelight", "straw_bale")); + getOrCreateTagBuilder(UTags.Items.FORAGE_SAFE) + .addOptional(new Identifier("farmersdelight", "sandy_shrub")) + .addOptional(new Identifier("farmersdelight", "wild_cabbages")) + .addOptional(new Identifier("farmersdelight", "wild_onions")) + .addOptional(new Identifier("farmersdelight", "wild_carrots")) + .addOptional(new Identifier("farmersdelight", "wild_beetroots")) + .addOptional(new Identifier("farmersdelight", "wild_rice")); + getOrCreateTagBuilder(UTags.Items.FORAGE_RISKY) + .addOptional(new Identifier("farmersdelight", "wild_tomatoes")) + .addOptional(new Identifier("farmersdelight", "wild_potatoes")) + .addOptionalTag(new Identifier("c", "meads")); } } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroup.java b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroup.java index 9c6279b5..173b1fef 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroup.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroup.java @@ -17,23 +17,31 @@ import net.minecraft.util.Util; public record FoodGroup( Identifier id, - List tags, - Optional foodComponent, - Ailment ailment) implements Effect { + FoodGroupEffects attributes) implements Effect { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( FoodGroupKey.TAG_CODEC.listOf().fieldOf("tags").forGetter(FoodGroupEffects::tags), FoodAttributes.CODEC.optionalFieldOf("food_component").forGetter(FoodGroupEffects::foodComponent), Ailment.CODEC.fieldOf("ailment").forGetter(FoodGroupEffects::ailment) ).apply(instance, FoodGroupEffects::new)); - public FoodGroup(Identifier id, Effect effect) { - this(id, effect.tags(), effect.foodComponent(), effect.ailment()); - } - public FoodGroup(PacketByteBuf buffer) { this(buffer.readIdentifier(), new FoodGroupEffects(buffer, FoodGroupKey.TAG_ID_LOOKUP)); } + @Override + public List tags() { + return attributes.tags(); + } + + @Override + public Optional foodComponent() { + return attributes.foodComponent(); + } + + @Override + public Ailment ailment() { + return attributes.ailment(); + } @Override public void appendTooltip(ItemStack stack, List tooltip, TooltipContext context) { tooltip.add(Text.literal(" ").append(Text.translatable(Util.createTranslationKey("food_group", id()))).formatted(Formatting.GRAY)); diff --git a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupEffects.java b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupEffects.java index e92f2995..ad207ed1 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupEffects.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupEffects.java @@ -1,15 +1,22 @@ package com.minelittlepony.unicopia.diet; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.function.Function; + +import com.minelittlepony.unicopia.diet.affliction.Affliction; +import com.minelittlepony.unicopia.item.UFoodComponents; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.client.item.TooltipContext; import net.minecraft.item.FoodComponent; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.TagKey; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; @@ -39,4 +46,41 @@ public record FoodGroupEffects( }); Effect.super.appendTooltip(stack, tooltip, context); } + + public static final class Builder { + private final List tags = new ArrayList<>(); + private Optional foodComponent = Optional.empty(); + private Ailment ailment = new Ailment(Affliction.EMPTY); + + public Builder tag(Identifier tag) { + return tag(TagKey.of(RegistryKeys.ITEM, tag)); + } + + public Builder tag(TagKey tag) { + tags.add(FoodGroupKey.TAG_LOOKUP.apply(tag)); + return this; + } + + public Builder ailment(Affliction affliction) { + ailment = new Ailment(affliction); + return this; + } + + public Builder food(int hunger, float saturation) { + return food(UFoodComponents.builder(hunger, saturation)); + } + + public Builder food(FoodComponent.Builder food) { + return food(food.build()); + } + + public Builder food(FoodComponent food) { + foodComponent = Optional.of(food); + return this; + } + + public FoodGroupEffects build() { + return new FoodGroupEffects(tags, foodComponent, ailment); + } + } } \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java index ac59d145..567c4a36 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/FoodGroupKey.java @@ -27,6 +27,16 @@ public interface FoodGroupKey { var group = PonyDiets.getEffect(id); return group != null && group.test(stack); } + + @Override + public boolean equals(Object o) { + return o == this && (o instanceof FoodGroupKey k && k.id().equals(id())); + } + + @Override + public int hashCode() { + return id().hashCode(); + } }; }); Function, FoodGroupKey> TAG_LOOKUP = Util.memoize(tag -> { @@ -48,6 +58,16 @@ public interface FoodGroupKey { return stack.isIn(tag); } + + @Override + public boolean equals(Object o) { + return o == this && (o instanceof FoodGroupKey k && k.id().equals(id())); + } + + @Override + public int hashCode() { + return id().hashCode(); + } }; }); Function TAG_ID_LOOKUP = id -> TAG_LOOKUP.apply(TagKey.of(RegistryKeys.ITEM, id)); diff --git a/src/main/java/com/minelittlepony/unicopia/diet/affliction/Affliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/Affliction.java index 013d3f51..ff228b31 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/affliction/Affliction.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/Affliction.java @@ -37,7 +37,7 @@ public interface Affliction { affliction -> ((CompoundAffliction)affliction).afflictions )).xmap( either -> either.left().or(either::right).get(), - affliction -> affliction instanceof CompoundAffliction ? Either.left(affliction) : Either.right(affliction) + affliction -> affliction instanceof CompoundAffliction ? Either.right(affliction) : Either.left(affliction) ); void afflict(PlayerEntity player, ItemStack stack); diff --git a/src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java index d41cf4ad..0d561985 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java @@ -7,7 +7,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; import net.minecraft.text.Text; -class CompoundAffliction implements Affliction { +public class CompoundAffliction implements Affliction { public final List afflictions; private final Text name; diff --git a/src/main/java/com/minelittlepony/unicopia/diet/affliction/HealingAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/HealingAffliction.java index 71590879..8e6bc53d 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/affliction/HealingAffliction.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/HealingAffliction.java @@ -8,7 +8,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; import net.minecraft.text.Text; -record HealingAffliction(float health) implements Affliction { +public record HealingAffliction(float health) implements Affliction { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codec.FLOAT.fieldOf("health").forGetter(HealingAffliction::health) ).apply(instance, HealingAffliction::new)); diff --git a/src/main/java/com/minelittlepony/unicopia/diet/affliction/Range.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/Range.java index ed84ad97..78c3abe1 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/affliction/Range.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/Range.java @@ -7,7 +7,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.network.PacketByteBuf; import net.minecraft.util.dynamic.Codecs; -record Range(int min, int max) { +public record Range(int min, int max) { public static final Codec CODEC = Codecs.xor( Codec.INT.xmap(value -> Range.of(value, -1), range -> range.min()), RecordCodecBuilder.create(instance -> instance.group( @@ -20,6 +20,10 @@ record Range(int min, int max) { return new Range(min, max); } + public static Range of(int exact) { + return of(exact, exact); + } + public static Range of(PacketByteBuf buffer) { return of(buffer.readInt(), buffer.readInt()); } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/affliction/StatusEffectAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/StatusEffectAffliction.java index d0c0b91c..9bc7adff 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/affliction/StatusEffectAffliction.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/StatusEffectAffliction.java @@ -4,6 +4,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.entity.attribute.EntityAttributes; +import net.minecraft.entity.effect.StatusEffect; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; @@ -11,25 +12,24 @@ import net.minecraft.network.PacketByteBuf; import net.minecraft.registry.Registries; import net.minecraft.text.MutableText; import net.minecraft.text.Text; -import net.minecraft.util.Identifier; import net.minecraft.util.StringHelper; import net.minecraft.util.math.MathHelper; -record StatusEffectAffliction(Identifier effect, Range seconds, Range amplifier, int chance) implements Affliction { +public record StatusEffectAffliction(StatusEffect effect, Range seconds, Range amplifier, int chance) implements Affliction { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("effect").forGetter(StatusEffectAffliction::effect), + Registries.STATUS_EFFECT.getCodec().fieldOf("effect").forGetter(StatusEffectAffliction::effect), Range.CODEC.fieldOf("seconds").forGetter(StatusEffectAffliction::seconds), Range.CODEC.optionalFieldOf("amplifier", Range.of(0, -1)).forGetter(StatusEffectAffliction::amplifier), Codec.INT.optionalFieldOf("chance", 0).forGetter(StatusEffectAffliction::chance) ).apply(instance, StatusEffectAffliction::new)); public StatusEffectAffliction(PacketByteBuf buffer) { - this(buffer.readIdentifier(), Range.of(buffer), Range.of(buffer), buffer.readInt()); + this(Registries.STATUS_EFFECT.get(buffer.readIdentifier()), Range.of(buffer), Range.of(buffer), buffer.readInt()); } @Override public void toBuffer(PacketByteBuf buffer) { - buffer.writeIdentifier(effect); + buffer.writeIdentifier(Registries.STATUS_EFFECT.getId(effect)); seconds.toBuffer(buffer); amplifier.toBuffer(buffer); buffer.writeInt(chance); @@ -45,35 +45,31 @@ record StatusEffectAffliction(Identifier effect, Range seconds, Range amplifier, if (chance > 0 && player.getWorld().random.nextInt(chance) > 0) { return; } - Registries.STATUS_EFFECT.getOrEmpty(effect).ifPresent(effect -> { - float health = player.getHealth(); - StatusEffectInstance current = player.getStatusEffect(effect); - player.addStatusEffect(new StatusEffectInstance(effect, - seconds.getClamped(current == null ? 0 : current.getDuration(), 20), - amplifier.getClamped(current == null ? 0 : current.getAmplifier(), 1) - )); - // keep original health - if (effect.getAttributeModifiers().containsKey(EntityAttributes.GENERIC_MAX_HEALTH)) { - player.setHealth(MathHelper.clamp(health, 0, player.getMaxHealth())); - } - }); + float health = player.getHealth(); + StatusEffectInstance current = player.getStatusEffect(effect); + player.addStatusEffect(new StatusEffectInstance(effect, + seconds.getClamped(current == null ? 0 : current.getDuration(), 20), + amplifier.getClamped(current == null ? 0 : current.getAmplifier(), 1) + )); + // keep original health + if (effect.getAttributeModifiers().containsKey(EntityAttributes.GENERIC_MAX_HEALTH)) { + player.setHealth(MathHelper.clamp(health, 0, player.getMaxHealth())); + } } @Override public Text getName() { - return Registries.STATUS_EFFECT.getOrEmpty(effect).map(effect -> { - MutableText text = effect.getName().copy(); + MutableText text = effect.getName().copy(); - if (amplifier.min() > 0) { - text = Text.translatable("potion.withAmplifier", text, Text.translatable("potion.potency." + (amplifier.min()))); - } + if (amplifier.min() > 0) { + text = Text.translatable("potion.withAmplifier", text, Text.translatable("potion.potency." + (amplifier.min()))); + } - text = Text.translatable("potion.withDuration", text, StringHelper.formatTicks(seconds.min() * 20)); + text = Text.translatable("potion.withDuration", text, StringHelper.formatTicks(seconds.min() * 20)); - if (chance > 0) { - text = Text.translatable("potion.withChance", chance, text); - } - return (Text)text; - }).orElse(EMPTY.getName()); + if (chance > 0) { + text = Text.translatable("potion.withChance", chance, text); + } + return text; } } \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java b/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java index ee093b08..8217a4c1 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java @@ -30,10 +30,6 @@ public interface UFoodComponents { FoodComponent CHOCOLATE_OATMEAL_COOKIE = builder(3, 0.4F).build(); FoodComponent SCONE = builder(2, 0.2F).build(); - @Deprecated - FoodComponent RANDOM_FOLIAGE = builder(2, 1).build(); - @Deprecated - FoodComponent RANDOM_FOLIAGE_FILLING = builder(18, 1).build(); FoodComponent WORMS = builder(1, 1.5F).alwaysEdible().meat().build(); FoodComponent INSECTS = builder(1, 0).alwaysEdible().build(); @@ -62,9 +58,7 @@ public interface UFoodComponents { FoodComponent POISON_JOKE = builder(0, 0F).alwaysEdible().snack().build(); - @Deprecated FoodComponent SHELL = builder(3, 5).build(); - @Deprecated FoodComponent SHELLY = builder(6, 7).build(); static FoodComponent.Builder builder(int hunger, float saturation) { diff --git a/src/main/resources/data/c/tags/items/foraging/edibles.json b/src/main/resources/data/c/tags/items/foraging/edibles.json deleted file mode 100644 index a0432ed7..00000000 --- a/src/main/resources/data/c/tags/items/foraging/edibles.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "replace": false, - "values": [ - { "id": "#c:mushrooms", "required": false }, - { "id": "#c:saplings", "required": false }, - { "id": "farmersdelight:sandy_shrub", "required": false }, - { "id": "farmersdelight:wild_cabbages", "required": false }, - { "id": "farmersdelight:wild_onions", "required": false }, - { "id": "farmersdelight:wild_carrots", "required": false }, - { "id": "farmersdelight:wild_beetroots", "required": false }, - { "id": "farmersdelight:wild_rice", "required": false } - ] -} diff --git a/src/main/resources/data/c/tags/items/foraging/edibles_filling.json b/src/main/resources/data/c/tags/items/foraging/edibles_filling.json deleted file mode 100644 index bc799386..00000000 --- a/src/main/resources/data/c/tags/items/foraging/edibles_filling.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "replace": false, - "values": [ - { "id": "farmersdelight:horse_feed", "required": false }, - { "id": "farmersdelight:rice_bale", "required": false }, - { "id": "farmersdelight:straw_bale", "required": false } - ] -} diff --git a/src/main/resources/data/c/tags/items/foraging/risky.json b/src/main/resources/data/c/tags/items/foraging/risky.json deleted file mode 100644 index aa54573a..00000000 --- a/src/main/resources/data/c/tags/items/foraging/risky.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "replace": false, - "values": [ - { "id": "#c:meads", "required": false }, - { "id": "farmersdelight:wild_tomatoes", "required": false }, - { "id": "farmersdelight:wild_potatoes", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/diets/food_groups/baked_goods.json b/src/main/resources/data/unicopia/diets/food_groups/baked_goods.json deleted file mode 100644 index 12d8e949..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/baked_goods.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "tags": [ "unicopia:baked_goods" ], - "food_component": { - "hunger": 1, - "saturation": 1 - }, - "ailment": { - "effects": [ - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json b/src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json deleted file mode 100644 index 73e2acf8..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/bat_ponys_delight.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "tags": [ "c:mangoes" ], - "food_component": { - "hunger": 1, - "saturation": 0.1 - }, - "ailment": { - "effects": [] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/candy.json b/src/main/resources/data/unicopia/diets/food_groups/candy.json deleted file mode 100644 index e5df4d14..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/candy.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "tags": [ "c:candy" ], - "food_component": { - "hunger": 1, - "saturation": 1 - }, - "ailment": { - "effects": [ - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/desserts.json b/src/main/resources/data/unicopia/diets/food_groups/desserts.json deleted file mode 100644 index 4892ee6b..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/desserts.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "tags": [ "c:desserts" ], - "food_component": { - "hunger": 1, - "saturation": 1 - }, - "ailment": { - "effects": [ - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/fish/cooked.json b/src/main/resources/data/unicopia/diets/food_groups/fish/cooked.json deleted file mode 100644 index cddeb511..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/fish/cooked.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "tags": [ "c:cooked_fish" ], - "food_component": { - "hunger": 1, - "saturation": 0.1 - }, - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/fish/raw.json b/src/main/resources/data/unicopia/diets/food_groups/fish/raw.json deleted file mode 100644 index d33785d3..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/fish/raw.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "tags": [ "c:raw_fish" ], - "food_component": { - "hunger": 1, - "saturation": 0.1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:poison", - "seconds": 45, - "amplifier": 2, - "chance": 80 - }, - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/fish/rotten.json b/src/main/resources/data/unicopia/diets/food_groups/fish/rotten.json deleted file mode 100644 index fc362289..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/fish/rotten.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "tags": [ "c:rotten_fish" ], - "food_component": { - "hunger": 1, - "saturation": 0.1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:poison", - "seconds": 45, - "amplifier": 2, - "chance": 80 - }, - { - "effect": "unicopia:food_poisoning", - "seconds": 400, - "amplifier": 3, - "chance": 5 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/blinding.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/blinding.json deleted file mode 100644 index ca392e74..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/blinding.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_blinding" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:blindness", - "seconds": 30, - "amplifier": 0 - }, - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/dangerous.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/dangerous.json deleted file mode 100644 index 372abede..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/dangerous.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_dangerous" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 250, - "amplifier": 2, - "chance": 4 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/edible.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/edible.json deleted file mode 100644 index 33887410..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/edible.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_edible" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/edible_filling.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/edible_filling.json deleted file mode 100644 index b6721b3f..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/edible_filling.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_edible_filling" ], - "food_component": { - "hunger": 18, - "saturation": 9 - }, - "ailment": { - "effects": [] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/leafy_greens.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/leafy_greens.json deleted file mode 100644 index 0c81ee64..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/leafy_greens.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "tags": [ "minecraft:leaves" ], - "food_component": { - "hunger": 2, - "saturation": 1.5 - }, - "ailment": { - "effects": [] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/moderate.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/moderate.json deleted file mode 100644 index 4d7a238a..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/moderate.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_moderate" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2, - "chance": 40 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/nauseating.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/nauseating.json deleted file mode 100644 index e79628a0..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/nauseating.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_nauseating" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:weakness", - "seconds": 200, - "amplifier": 1, - "chance": 30 - }, - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/prickly.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/prickly.json deleted file mode 100644 index d3c61180..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/prickly.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_prickly" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:instant_damage", - "seconds": 1, - "amplifier": 0, - "chance": 30 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/radioactive.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/radioactive.json deleted file mode 100644 index 7a023788..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/radioactive.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_radioactive" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:glowing", - "seconds": 15, - "amplifier": 0, - "chance": 30 - }, - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/risky.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/risky.json deleted file mode 100644 index 9ee5d1dc..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/risky.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_risky" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2, - "chance": 80 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/severely_nauseating.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/severely_nauseating.json deleted file mode 100644 index 7f4ef36e..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/severely_nauseating.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_severely_nauseating" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:weakness", - "seconds": 200, - "amplifier": 1 - }, - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/severely_prickly.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/severely_prickly.json deleted file mode 100644 index 3b5a1cd6..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/severely_prickly.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_severely_prickly" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:instant_damage", - "seconds": 1, - "amplifier": 0 - }, - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/foraging/strengthening.json b/src/main/resources/data/unicopia/diets/food_groups/foraging/strengthening.json deleted file mode 100644 index 11477833..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/foraging/strengthening.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "tags": [ "unicopia:food_types/forage_strengthening" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:strength", - "seconds": 30, - "amplifier": 0 - }, - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2, - "chance": 10 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/fruit.json b/src/main/resources/data/unicopia/diets/food_groups/fruit.json deleted file mode 100644 index c8710f92..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/fruit.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "tags": [ "c:fruits" ], - "food_component": { - "hunger": 1, - "saturation": 1 - }, - "ailment": { - "effects": [ - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/insect/cooked.json b/src/main/resources/data/unicopia/diets/food_groups/insect/cooked.json deleted file mode 100644 index 7d35ae55..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/insect/cooked.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "tags": [ "c:cooked_insect" ], - "food_component": { - "hunger": 1, - "saturation": 0.1 - }, - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/insect/raw.json b/src/main/resources/data/unicopia/diets/food_groups/insect/raw.json deleted file mode 100644 index 37686f06..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/insect/raw.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "tags": [ "c:raw_insect" ], - "food_component": { - "hunger": 6, - "saturation": 0.3 - }, - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/love.json b/src/main/resources/data/unicopia/diets/food_groups/love.json deleted file mode 100644 index 29837e42..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/love.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "tags": [ "unicopia:container_with_love" ], - "food_component": { - "hunger": 2, - "saturation": 0.4 - }, - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 50, - "amplifier": 2 - }, - { - "name": "unicopia.affliction.love_sickness", - "type": "unicopia:lose_hunger", - "multiplier": 0.5 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/meat/cooked.json b/src/main/resources/data/unicopia/diets/food_groups/meat/cooked.json deleted file mode 100644 index 49207c8b..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/meat/cooked.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "tags": [ "c:cooked_meat" ], - "food_component": { - "hunger": 12, - "saturation": 1.2 - }, - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/meat/raw.json b/src/main/resources/data/unicopia/diets/food_groups/meat/raw.json deleted file mode 100644 index 18879268..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/meat/raw.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "tags": [ "c:raw_meat" ], - "food_component": { - "hunger": 1, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:poison", - "seconds": 45, - "amplifier": 2, - "chance": 80 - }, - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2, - "chance": 5 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/meat/rotten.json b/src/main/resources/data/unicopia/diets/food_groups/meat/rotten.json deleted file mode 100644 index 1af89970..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/meat/rotten.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "tags": [ "c:rotten_meat" ], - "food_component": { - "hunger": 1, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "effect": "minecraft:poison", - "seconds": 45, - "amplifier": 2, - "chance": 80 - }, - { - "effect": "unicopia:food_poisoning", - "seconds": 400, - "amplifier": 3, - "chance": 5 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/nuts_and_seeds.json b/src/main/resources/data/unicopia/diets/food_groups/nuts_and_seeds.json deleted file mode 100644 index eee07b2d..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/nuts_and_seeds.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "tags": [ "c:grain", "c:nuts", "c:seeds" ], - "food_component": { - "hunger": 2, - "saturation": 2.5 - }, - "ailment": { - "effects": [ - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/pinecone.json b/src/main/resources/data/unicopia/diets/food_groups/pinecone.json deleted file mode 100644 index 735bff30..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/pinecone.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "tags": [ "c:pinecones" ], - "food_component": { - "hunger": 1, - "saturation": 0.1 - }, - "ailment": { - "effects": [ - { - "type": "unicopia:healing", - "health": 1 - } - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/rocks.json b/src/main/resources/data/unicopia/diets/food_groups/rocks.json deleted file mode 100644 index ead61325..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/rocks.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "tags": [ "c:rocks", "unicopia:rock_stews" ], - "food_component": { - "hunger": 1, - "saturation": 0.1 - }, - "ailment": { - "effects": [] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json b/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json deleted file mode 100644 index 06d46526..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/cooked.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "tags": [ "unicopia:food_types/cooked_sea_vegitable", "c:coral_blocks" ], - "food_component": { - "hunger": 0, - "saturation": 0 - }, - "ailment": { - "effects": [ - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json b/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json deleted file mode 100644 index 94bea223..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/sea_vegetable/raw.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "tags": [ "unicopia:food_types/raw_sea_vegitable", "c:corals", "c:coral_fans" ], - "food_component": { - "hunger": 0, - "saturation": 0 - }, - "ailment": { - "effects": [ - ] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/shells.json b/src/main/resources/data/unicopia/diets/food_groups/shells.json deleted file mode 100644 index f154f859..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/shells.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "tags": [ "unicopia:shells" ], - "food_component": { - "hunger": 0, - "saturation": 0 - }, - "ailment": { - "effects": [] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/diets/food_groups/shelly.json b/src/main/resources/data/unicopia/diets/food_groups/shelly.json deleted file mode 100644 index 791711a0..00000000 --- a/src/main/resources/data/unicopia/diets/food_groups/shelly.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "tags": [ "unicopia:special_shells" ], - "food_component": { - "hunger": 0, - "saturation": 0 - }, - "ailment": { - "effects": [] - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/tags/items/food_types/cooked_sea_vegitable.json b/src/main/resources/data/unicopia/tags/items/food_types/cooked_sea_vegitable.json deleted file mode 100644 index bde823d2..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/cooked_sea_vegitable.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:dried_kelp_block", - "minecraft:glow_lichen" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_blinding.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_blinding.json deleted file mode 100644 index 2734f9e9..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_blinding.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:oxeye_daisy" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_dangerous.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_dangerous.json deleted file mode 100644 index 40636af9..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_dangerous.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:poppy", - "minecraft:lily_of_the_valley" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_edible.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_edible.json deleted file mode 100644 index ee20b95a..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_edible.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:blue_orchid", - "minecraft:red_tulip", - "minecraft:orange_tulip", - "minecraft:pink_tulip", - "minecraft:cornflower", - "minecraft:peony", - "minecraft:sunflower", - "minecraft:dandelion", - "minecraft:lilac", - "minecraft:tall_grass", - "minecraft:wheat", - "minecraft:dead_bush", - "minecraft:pink_petals", - "#c:foraging/edibles" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_edible_filling.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_edible_filling.json deleted file mode 100644 index c3245df5..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_edible_filling.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:hay_block", - "#c:foraging/edibles_filling" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_nauseating.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_nauseating.json deleted file mode 100644 index 9b5ae248..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_nauseating.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:grass", - "unicopia:cider", - { "id": "farmersdelight:rotten_tomato", "required": false } - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_prickly.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_prickly.json deleted file mode 100644 index 3fbb59d5..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_prickly.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:rose_bush", - "#minecraft:saplings" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_radioactive.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_radioactive.json deleted file mode 100644 index f274ebe5..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_radioactive.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:azure_bluet", - "minecraft:torchflower" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_risky.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_risky.json deleted file mode 100644 index 533231e1..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_risky.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:allium", - "minecraft:white_tulip", - "unicopia:burned_juice", - "#c:foraging/risky" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_severely_nauseating.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_severely_nauseating.json deleted file mode 100644 index ae67591c..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_severely_nauseating.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:pitcher_plant" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_severely_prickly.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_severely_prickly.json deleted file mode 100644 index 4ff8aebc..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_severely_prickly.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:large_fern" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/forage_strengthening.json b/src/main/resources/data/unicopia/tags/items/food_types/forage_strengthening.json deleted file mode 100644 index 97038fab..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/forage_strengthening.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:fern" - ] -} diff --git a/src/main/resources/data/unicopia/tags/items/food_types/raw_sea_vegitable.json b/src/main/resources/data/unicopia/tags/items/food_types/raw_sea_vegitable.json deleted file mode 100644 index cc815d78..00000000 --- a/src/main/resources/data/unicopia/tags/items/food_types/raw_sea_vegitable.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "replace": false, - "values": [ - "minecraft:kelp", - "minecraft:dried_kelp", - "minecraft:seagrass", - "minecraft:sea_pickle", - { "id": "farmersdelight:kelp_roll", "required": false }, - { "id": "farmersdelight:kelp_roll_slice", "required": false } - ] -} From eeded18c36d1a65ef96da6d717704282d7037db7 Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 5 Apr 2024 14:06:29 +0100 Subject: [PATCH 68/73] Move pony diets to datagen. Summary of diets: Unicorns: - have a general even preference of foods - Improved benefits from cooking their food before eating it - Can still eat raw and rotten but at a reduced yield Earth Ponies: - Are vegans - They get the most from foraging - Pastries are their passion - If they must eat meat, they have to cook it and not let it spoil. - They have a sweet tooth and prefer candy, desserts, and rocks - Candy and rocks gives them a massive saturation boost. Maybe too much? Pegasus - prefer fish over other food sources - Cannot eat love, or raw/rotten meat - Can eat raw and rotten fish but still prefers if they are cooked - Can safely eat fresh and cooked fish with no ill effects - Is less affected when eating rotten fish Bat Ponies: - prefer cooked foods over raw, and meat/insects over fish - Doesn't like baked goods but really likes meats, fish, and insects - Gets food poisoning from eating rotten and raw meat - Can eat cooked meat and insects without negative effects - Becomes hyper when eating mangoes Kirins: - Much like Earth Ponies, Kirins must cook their meat before they eat it - Cannot eat love, or raw/rotten meats and fish - Can eat cooked meat and insect without negative effects - Can eat blinding, prickly, strengthening, and glowing foraged foods without negative effects Changelings: - like meat and fish but really prefer feasting on ponies' love directly from the tap - Doesn't like baked goods but really likes meats, fish, and insects - Can eat fish, meat, insects, and love without negative effects - Gets sick when eating foraged plants and vegetables Hippogriffs: - like fish, nuts, and seeds - Can eat fish and prickly foods without negative effect - Gains more health from pinecones Seaponies: - can eat seaweed, kelp, shells, and other undersea foods - Can eat fish without negative effect - Gains more health from pinecones --- .../providers/DietProfileGenerator.java | 263 ++++++++++++++++++ .../providers/FoodGroupsGenerator.java | 52 ++-- .../unicopia/diet/DietProfile.java | 25 ++ .../ClearLoveSicknessAffliction.java | 3 +- .../diet/affliction/CompoundAffliction.java | 4 + .../data/unicopia/diets/races/alicorn.json | 64 ----- .../data/unicopia/diets/races/bat.json | 130 --------- .../data/unicopia/diets/races/changeling.json | 159 ----------- .../data/unicopia/diets/races/earth.json | 81 ------ .../data/unicopia/diets/races/hippogriff.json | 97 ------- .../data/unicopia/diets/races/human.json | 21 -- .../data/unicopia/diets/races/kirin.json | 68 ----- .../data/unicopia/diets/races/pegasus.json | 66 ----- .../data/unicopia/diets/races/seapony.json | 100 ------- .../data/unicopia/diets/races/unicorn.json | 39 --- 15 files changed, 316 insertions(+), 856 deletions(-) delete mode 100644 src/main/resources/data/unicopia/diets/races/alicorn.json delete mode 100644 src/main/resources/data/unicopia/diets/races/bat.json delete mode 100644 src/main/resources/data/unicopia/diets/races/changeling.json delete mode 100644 src/main/resources/data/unicopia/diets/races/earth.json delete mode 100644 src/main/resources/data/unicopia/diets/races/hippogriff.json delete mode 100644 src/main/resources/data/unicopia/diets/races/human.json delete mode 100644 src/main/resources/data/unicopia/diets/races/kirin.json delete mode 100644 src/main/resources/data/unicopia/diets/races/pegasus.json delete mode 100644 src/main/resources/data/unicopia/diets/races/seapony.json delete mode 100644 src/main/resources/data/unicopia/diets/races/unicorn.json diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/DietProfileGenerator.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/DietProfileGenerator.java index 6afe54f9..4034021f 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/DietProfileGenerator.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/DietProfileGenerator.java @@ -1,12 +1,275 @@ package com.minelittlepony.unicopia.datagen.providers; +import java.util.List; +import java.util.Optional; import java.util.function.BiConsumer; import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.diet.DietProfile; +import com.minelittlepony.unicopia.diet.DietProfile.Multiplier; +import com.minelittlepony.unicopia.diet.FoodGroupEffects; +import com.minelittlepony.unicopia.diet.affliction.ClearLoveSicknessAffliction; +import com.minelittlepony.unicopia.diet.affliction.CompoundAffliction; +import com.minelittlepony.unicopia.diet.affliction.HealingAffliction; +import com.minelittlepony.unicopia.diet.affliction.LoseHungerAffliction; +import com.minelittlepony.unicopia.diet.affliction.Range; +import com.minelittlepony.unicopia.diet.affliction.StatusEffectAffliction; +import com.minelittlepony.unicopia.entity.effect.UEffects; +import com.minelittlepony.unicopia.item.UFoodComponents; + +import net.minecraft.entity.effect.StatusEffects; +import net.minecraft.item.FoodComponents; public class DietProfileGenerator { public void generate(BiConsumer exporter) { + // Pinecones are for everypony + var pineconeMultiplier = new Multiplier.Builder().tag(Unicopia.id("pinecone")).hunger(0.9F).saturation(0.9F).build(); + var bakedGoodPreference = new Multiplier.Builder().tag(Unicopia.id("baked_goods")).build(); + var bakedGoodExtremePreference = new Multiplier.Builder().tag(Unicopia.id("baked_goods")).hunger(1.2F).saturation(2).build(); + var bakedGoodNonPreference = new Multiplier.Builder().tag(Unicopia.id("baked_goods")).hunger(0.4F).saturation(0.2F).build(); + var properMeatStandards = new Multiplier.Builder().tag(Unicopia.id("love")) + .tag(Unicopia.id("meat/raw")).tag(Unicopia.id("insect/raw")).tag(Unicopia.id("fish/raw")) + .tag(Unicopia.id("meat/rotten")).tag(Unicopia.id("insect/rotten")).tag(Unicopia.id("fish/rotten")) + .hunger(0).saturation(0).build(); + var avianMeatStandards = new Multiplier.Builder().tag(Unicopia.id("love")) + .tag(Unicopia.id("meat/raw")).tag(Unicopia.id("insect/raw")) + .tag(Unicopia.id("meat/rotten")).tag(Unicopia.id("insect/rotten")) + .hunger(0).saturation(0).build(); + var loveSicknessEffects = CompoundAffliction.of( + new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 95), + new StatusEffectAffliction(StatusEffects.WEAKNESS, Range.of(200), Range.of(1), 0), + new LoseHungerAffliction(0.5F)); + var seaFoodExclusions = new Multiplier.Builder() + .tag(Unicopia.id("sea_vegetable/raw")).tag(Unicopia.id("sea_vegetable/cooked")) + .tag(Unicopia.id("shells")).tag(Unicopia.id("special_shells")) + .hunger(0).saturation(0).build(); + exporter.accept(Race.HUMAN, new DietProfile(1, 0, List.of(), List.of( + new FoodGroupEffects.Builder() + .tag(Unicopia.id("fish/cooked")).tag(Unicopia.id("fish/raw")).tag(Unicopia.id("fish/rotten")) + .tag(Unicopia.id("meat/cooked")).tag(Unicopia.id("meat/raw")).tag(Unicopia.id("meat/rotten")) + .tag(Unicopia.id("sea_vegetable/cooked")).tag(Unicopia.id("sea_vegetable/raw")) + .tag(Unicopia.id("pinecone")) + .build() + ), Optional.empty())); + // Alicorns are a mashup of unicorn, pegasus, and earth pony eating habits + exporter.accept(Race.ALICORN, new DietProfile(0.9F, 1, List.of( + // Pastries are their passion + bakedGoodExtremePreference, pineconeMultiplier, avianMeatStandards, seaFoodExclusions, + // They have a more of a sweet tooth than earth ponies + new Multiplier.Builder().tag(Unicopia.id("desserts")).hunger(2.5F).saturation(1.7F).build(), + new Multiplier.Builder().tag(Unicopia.id("candy")).tag(Unicopia.id("rocks")).hunger(1.5F).saturation(1.3F).build(), + + // Cannot eat love, or raw/rotten meats and fish + // Can eat raw and rotten fish but still prefers if they are cooked + new Multiplier.Builder().tag(Unicopia.id("fish/cooked")).hunger(1.5F).saturation(1.5F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/cooked")).hunger(0.25F).saturation(0.16F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/cooked")).hunger(0.1F).saturation(0.7F).build(), + + new Multiplier.Builder().tag(Unicopia.id("fish/raw")).hunger(0.5F).saturation(0.8F).build(), + new Multiplier.Builder().tag(Unicopia.id("fish/rotten")).hunger(0.25F).saturation(0.5F).build() + ), List.of( + // Can safely eat fresh and cooked fish with no ill effects + new FoodGroupEffects.Builder().tag(Unicopia.id("fish/cooked")).tag(Unicopia.id("fish/raw")).build(), + // Is less affected when eating rotten fish + new FoodGroupEffects.Builder().tag(Unicopia.id("fish/rotten")).ailment(new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(50), Range.of(2), 95)).build() + ), Optional.empty())); + // Unicorns have a general even preference of foods + exporter.accept(Race.UNICORN, new DietProfile(1.1F, 1, List.of( + bakedGoodPreference, pineconeMultiplier, seaFoodExclusions, + new Multiplier.Builder().tag(Unicopia.id("love")).hunger(0).saturation(0).build(), + + // Improved benefits from cooking their food + new Multiplier.Builder().tag(Unicopia.id("fish/cooked")).hunger(0.3F).saturation(0.2F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/cooked")).hunger(0.4F).saturation(0.4F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/cooked")).hunger(0.1F).saturation(0.1F).build(), + + new Multiplier.Builder().tag(Unicopia.id("fish/raw")).hunger(0.25F).saturation(0.1F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/raw")).hunger(0.3F).saturation(0.1F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/raw")).hunger(0.15F).saturation(0.1F).build(), + + // Can still eat raw and rotten but at a reduced yield + new Multiplier.Builder().tag(Unicopia.id("fish/rotten")).hunger(0.1F).saturation(0.1F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/rotten")).hunger(0.1F).saturation(0.1F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/rotten")).hunger(0).saturation(0.1F).build() + ), List.of(), Optional.empty())); + // Bats prefer cooked foods over raw, and meat/insects over fish + exporter.accept(Race.BAT, new DietProfile(0.7F, 0.9F, List.of( + pineconeMultiplier, seaFoodExclusions, + // Doesn't like baked goods but really likes meats, fish, and insects + bakedGoodNonPreference, + + new Multiplier.Builder().tag(Unicopia.id("fish/cooked")).hunger(0.75F).saturation(0.75F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/cooked")).hunger(1.15F).saturation(1.16F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/cooked")).hunger(1.75F).saturation(1.74F).build(), + + new Multiplier.Builder().tag(Unicopia.id("fish/raw")).hunger(0.5F).saturation(0.6F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/raw")).hunger(0.25F).saturation(0.25F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/raw")).hunger(1).saturation(1).build(), + + new Multiplier.Builder().tag(Unicopia.id("fish/rotten")).hunger(0.24F).saturation(0.25F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/rotten")).hunger(0.2F).saturation(0.2F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/rotten")).hunger(0.9F).saturation(0.9F).build() + ), List.of( + // Gets food poisoning from eating rotten and raw meat + new FoodGroupEffects.Builder().tag(Unicopia.id("fish/rotten")).tag(Unicopia.id("meat/raw")).tag(Unicopia.id("meat/rotten")).ailment(new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 5)).build(), + new FoodGroupEffects.Builder().tag(Unicopia.id("insect/rotten")).ailment(new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(50), Range.of(1), 15)).build(), + // Can eat cooked meat and insects without negative effects + new FoodGroupEffects.Builder().tag(Unicopia.id("insect/cooked")).tag(Unicopia.id("meat/cooked")).build(), + // Becomes hyper when eating mangoes + new FoodGroupEffects.Builder().tag(Unicopia.id("bat_ponys_delight")).ailment(CompoundAffliction.of( + new StatusEffectAffliction(StatusEffects.HEALTH_BOOST, Range.of(30, 60), Range.of(2, 6), 0), + new StatusEffectAffliction(StatusEffects.JUMP_BOOST, Range.of(30, 60), Range.of(1, 6), 0), + new StatusEffectAffliction(StatusEffects.REGENERATION, Range.of(3, 30), Range.of(3, 6), 0) + )).build() + ), Optional.empty())); + // Much like Earth Ponies, Kirins must cook their meat before they eat it + exporter.accept(Race.KIRIN, new DietProfile(0.6F, 0.9F, List.of( + // Cannot eat love, or raw/rotten meats and fish + bakedGoodPreference, properMeatStandards, pineconeMultiplier, seaFoodExclusions, + + new Multiplier.Builder().tag(Unicopia.id("fish/cooked")).hunger(0.75F).saturation(0.35F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/cooked")).hunger(1.5F).saturation(1.6F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/cooked")).hunger(0.25F).saturation(0.74F).build() + ), List.of( + // can eat these without negative effects + new FoodGroupEffects.Builder().tag(Unicopia.id("insect/cooked")).tag(Unicopia.id("meat/cooked")).food(FoodComponents.COOKED_BEEF).build(), + new FoodGroupEffects.Builder().tag(Unicopia.id("foraging/blinding")).food(4, 0.2F).build(), + new FoodGroupEffects.Builder().tag(Unicopia.id("foraging/prickly")).food(0, 1.5F).build(), + new FoodGroupEffects.Builder().tag(Unicopia.id("foraging/severely_prickly")).food(2, 0.9F).build(), + new FoodGroupEffects.Builder().tag(Unicopia.id("foraging/strengthening")).food(4, 0.2F).ailment(new StatusEffectAffliction(StatusEffects.STRENGTH, Range.of(1300), Range.of(0), 0)).build(), + new FoodGroupEffects.Builder().tag(Unicopia.id("foraging/glowing")).food(1, 1.6F).ailment(new StatusEffectAffliction(StatusEffects.GLOWING, Range.of(30), Range.of(0), 30)).build() + ), Optional.empty())); + // Earth Ponies are vegans. They get the most from foraging + exporter.accept(Race.EARTH, new DietProfile(0.7F, 1.2F, List.of( + // Pastries are their passion + // If they must eat meat, they have to cook it and not let it spoil. + bakedGoodExtremePreference, pineconeMultiplier, properMeatStandards, seaFoodExclusions, + // They have a sweet tooth + new Multiplier.Builder().tag(Unicopia.id("candy")).tag(Unicopia.id("desserts")).tag(Unicopia.id("rocks")).hunger(2.5F).saturation(1.7F).build(), + new Multiplier.Builder().tag(Unicopia.id("fish/cooked")).hunger(0.2F).saturation(0.3F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/cooked")).hunger(0.1F).saturation(0.1F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/cooked")).hunger(0.1F).saturation(0.1F).build() + ), List.of( + // Candy and rocks gives them a massive saturation boost. Maybe too much? + new FoodGroupEffects.Builder().tag(Unicopia.id("candy")).tag(Unicopia.id("rocks")).food(UFoodComponents.builder(5, 12).alwaysEdible()).build(), + new FoodGroupEffects.Builder().tag(Unicopia.id("desserts")).food(UFoodComponents.builder(12, 32).snack().alwaysEdible()).build() + ), Optional.empty())); + // Pegasi prefer fish over other food sources + exporter.accept(Race.PEGASUS, new DietProfile(0.9F, 1, List.of( + bakedGoodPreference, pineconeMultiplier, avianMeatStandards, seaFoodExclusions, + // Cannot eat love, or raw/rotten meat + // Can eat raw and rotten fish but still prefers if they are cooked + new Multiplier.Builder().tag(Unicopia.id("fish/cooked")).hunger(1.5F).saturation(1.5F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/cooked")).hunger(0.25F).saturation(0.16F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/cooked")).hunger(0.1F).saturation(0.7F).build(), + + new Multiplier.Builder().tag(Unicopia.id("fish/raw")).hunger(0.5F).saturation(0.8F).build(), + new Multiplier.Builder().tag(Unicopia.id("fish/rotten")).hunger(0.25F).saturation(0.5F).build() + ), List.of( + // Can safely eat fresh and cooked fish with no ill effects + new FoodGroupEffects.Builder().tag(Unicopia.id("fish/cooked")).tag(Unicopia.id("fish/raw")).build(), + // Is less affected when eating rotten fish + new FoodGroupEffects.Builder().tag(Unicopia.id("fish/rotten")).ailment(new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(50), Range.of(2), 95)).build() + ), Optional.empty())); + // Changelings like meat and fish but really prefer feasting on ponies' love directly from the tap + exporter.accept(Race.CHANGELING, new DietProfile(0.15F, 0.1F, List.of( + // Doesn't like baked goods but really likes meats, fish, and insects + bakedGoodNonPreference, pineconeMultiplier, seaFoodExclusions, + + new Multiplier.Builder().tag(Unicopia.id("fish/cooked")).hunger(0.5F).saturation(1.2F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/cooked")).hunger(0.9F).saturation(1.2F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/cooked")).hunger(1.2F).saturation(1.3F).build(), + + new Multiplier.Builder().tag(Unicopia.id("fish/raw")).hunger(0.15F).saturation(0.25F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/raw")).hunger(1.25F).saturation(1.25F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/raw")).hunger(1).saturation(1).build(), + + new Multiplier.Builder().tag(Unicopia.id("fish/rotten")).hunger(0.24F).saturation(0.25F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/rotten")).hunger(0.2F).saturation(0.2F).build(), + new Multiplier.Builder().tag(Unicopia.id("insect/rotten")).hunger(0.9F).saturation(0.9F).build(), + + new Multiplier.Builder().tag(Unicopia.id("love")).hunger(1).saturation(1.5F).build() + ), List.of( + // Can eat fish, meat, insects, and love without negative effects + new FoodGroupEffects.Builder() + .tag(Unicopia.id("fish/cooked")).tag(Unicopia.id("meat/cooked")).tag(Unicopia.id("insect/cooked")) + .tag(Unicopia.id("fish/rotten")).tag(Unicopia.id("meat/rotten")).tag(Unicopia.id("insect/rotten")) + .tag(Unicopia.id("fish/raw")).tag(Unicopia.id("meat/raw")).tag(Unicopia.id("insect/raw")) + .tag(Unicopia.id("baked_goods")).tag(Unicopia.id("pinecone")) + .tag(Unicopia.id("love")).ailment(ClearLoveSicknessAffliction.INSTANCE).build(), + + new FoodGroupEffects.Builder() + .tag(Unicopia.id("foraging/blinding")).tag(Unicopia.id("foraging/dangerous")).tag(Unicopia.id("foraging/edible_filling")) + .tag(Unicopia.id("foraging/edible")).tag(Unicopia.id("foraging/leafy_greens")).tag(Unicopia.id("foraging/nauseating")) + .tag(Unicopia.id("foraging/prickly")).tag(Unicopia.id("foraging/glowing")).tag(Unicopia.id("foraging/risky")) + .tag(Unicopia.id("foraging/severely_nauseating")).tag(Unicopia.id("foraging/severely_prickly")) + .tag(Unicopia.id("foraging/strengthening")) + .ailment(loveSicknessEffects) + .build() + ), Optional.empty())); + // Hippogriffs like fish, nuts, and seeds + exporter.accept(Race.HIPPOGRIFF, new DietProfile(0.5F, 0.8F, List.of( + bakedGoodPreference, pineconeMultiplier, seaFoodExclusions, + + new Multiplier.Builder().tag(Unicopia.id("love")) + .tag(Unicopia.id("insect/cooked")).tag(Unicopia.id("insect/raw")).tag(Unicopia.id("insect/rotten")) + .hunger(0).saturation(0).build(), + + new Multiplier.Builder().tag(Unicopia.id("fish/cooked")).hunger(1.5F).saturation(1.2F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/cooked")).hunger(1.9F).saturation(1.2F).build(), + + new Multiplier.Builder().tag(Unicopia.id("fish/raw")).hunger(0.85F).saturation(0.95F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/raw")).hunger(0.75F).saturation(0.75F).build(), + + new Multiplier.Builder().tag(Unicopia.id("fish/rotten")).hunger(0.24F).saturation(0.25F).build(), + new Multiplier.Builder().tag(Unicopia.id("meat/rotten")).hunger(0.3F).saturation(0.5F).build(), + + new Multiplier.Builder().tag(Unicopia.id("nuts_and_seeds")).hunger(1.4F).saturation(1.4F).build() + ), List.of( + // Can eat fish and prickly foods without negative effect + new FoodGroupEffects.Builder() + .tag(Unicopia.id("fish/cooked")).tag(Unicopia.id("fish/raw")).tag(Unicopia.id("fish/rotten")) + .tag(Unicopia.id("foraging/prickly")).tag(Unicopia.id("foraging/severely_prickly")) + .build(), + // Gains more health from pinecones + new FoodGroupEffects.Builder().tag(Unicopia.id("pinecone")).ailment(new HealingAffliction(3)).build() + ), Optional.empty())); + // Seaponies can eat seaweed, kelp, shells, and other undersea foods + exporter.accept(Race.SEAPONY, new DietProfile(0.5F, 0.8F, List.of( + new Multiplier.Builder().tag(Unicopia.id("fish/cooked")).hunger(1.5F).saturation(1.2F).build(), + new Multiplier.Builder().tag(Unicopia.id("fish/raw")).hunger(0.85F).saturation(0.95F).build(), + new Multiplier.Builder().tag(Unicopia.id("fish/rotten")).hunger(0.24F).saturation(0.25F).build(), + new Multiplier.Builder() + .tag(Unicopia.id("sea_vegetable/raw")) + .tag(Unicopia.id("sea_vegetable/cooked")) + .tag(Unicopia.id("shells")).tag(Unicopia.id("special_shells")) + .hunger(1).saturation(1).build() + ), List.of( + // Can eat fish without negative effect + new FoodGroupEffects.Builder() + .tag(Unicopia.id("fish/cooked")).tag(Unicopia.id("fish/raw")).tag(Unicopia.id("fish/rotten")) + .build(), + // Gains more health from pinecones + new FoodGroupEffects.Builder().tag(Unicopia.id("pinecone")).ailment(new HealingAffliction(3)).build() + ), Optional.empty())); } } + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/FoodGroupsGenerator.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/FoodGroupsGenerator.java index c1e4bf75..3959da20 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/FoodGroupsGenerator.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/FoodGroupsGenerator.java @@ -41,9 +41,7 @@ public class FoodGroupsGenerator { .tag(UConventionalTags.Items.GRAIN).tag(UConventionalTags.Items.NUTS).tag(UConventionalTags.Items.SEEDS) .food(UFoodComponents.BANANA) ); - exporter.accept(Unicopia.id("pinecone"), new FoodGroupEffects.Builder().tag(UConventionalTags.Items.PINECONES).food(UFoodComponents.PINECONE).ailment(new CompoundAffliction(List.of( - new HealingAffliction(1) - )))); + exporter.accept(Unicopia.id("pinecone"), new FoodGroupEffects.Builder().tag(UConventionalTags.Items.PINECONES).food(UFoodComponents.PINECONE).ailment(new HealingAffliction(1))); provideMeatCategory("fish", UConventionalTags.Items.COOKED_FISH, UConventionalTags.Items.RAW_FISH, UConventionalTags.Items.ROTTEN_FISH, @@ -58,59 +56,53 @@ public class FoodGroupsGenerator { UTags.Items.HIGH_QUALITY_SEA_VEGETABLES, UTags.Items.LOW_QUALITY_SEA_VEGETABLES, FoodComponents.COOKED_BEEF, FoodComponents.BEEF, exporter); - exporter.accept(Unicopia.id("foraging/blinding"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_BLINDING).food(4, 0.2F).ailment(new CompoundAffliction(List.of( + exporter.accept(Unicopia.id("foraging/blinding"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_BLINDING).food(4, 0.2F).ailment(CompoundAffliction.of( new StatusEffectAffliction(StatusEffects.BLINDNESS, Range.of(30), Range.of(0), 50), new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 12) - )))); - exporter.accept(Unicopia.id("foraging/dangerous"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_DANGEROUS).food(3, 0.3F).ailment(new CompoundAffliction(List.of( - new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(250), Range.of(2), 4) - )))); + ))); + exporter.accept(Unicopia.id("foraging/dangerous"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_DANGEROUS).food(3, 0.3F).ailment(new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(250), Range.of(2), 4))); exporter.accept(Unicopia.id("foraging/edible_filling"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_FILLING).food(17, 0.6F)); exporter.accept(Unicopia.id("foraging/edible"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_SAFE).food(2, 1)); exporter.accept(Unicopia.id("foraging/leafy_greens"), new FoodGroupEffects.Builder().tag(ItemTags.LEAVES).food(1, 1.4F)); - exporter.accept(Unicopia.id("foraging/nauseating"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_NAUSEATING).food(5, 0.5F).ailment(new CompoundAffliction(List.of( + exporter.accept(Unicopia.id("foraging/nauseating"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_NAUSEATING).food(5, 0.5F).ailment(CompoundAffliction.of( new StatusEffectAffliction(StatusEffects.WEAKNESS, Range.of(200), Range.of(1), 30), new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(200), Range.of(2), 0) - )))); - exporter.accept(Unicopia.id("foraging/prickly"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_PRICKLY).food(0, 1.5F).ailment(new CompoundAffliction(List.of( + ))); + exporter.accept(Unicopia.id("foraging/prickly"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_PRICKLY).food(0, 1.5F).ailment(CompoundAffliction.of( new StatusEffectAffliction(StatusEffects.INSTANT_DAMAGE, Range.of(1), Range.of(0), 30) - )))); - exporter.accept(Unicopia.id("foraging/glowing"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_GLOWING).food(1, 1.6F).ailment(new CompoundAffliction(List.of( + ))); + exporter.accept(Unicopia.id("foraging/glowing"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_GLOWING).food(1, 1.6F).ailment(CompoundAffliction.of( new StatusEffectAffliction(StatusEffects.GLOWING, Range.of(30), Range.of(0), 30), new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 0) - )))); - exporter.accept(Unicopia.id("foraging/risky"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_RISKY).food(9, 1.1F).ailment(new CompoundAffliction(List.of( - new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 80) - )))); - exporter.accept(Unicopia.id("foraging/severely_nauseating"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_SEVERE_NAUSEATING).food(3, 0.9F).ailment(new CompoundAffliction(List.of( + ))); + exporter.accept(Unicopia.id("foraging/risky"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_RISKY).food(9, 1.1F).ailment(new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 80))); + exporter.accept(Unicopia.id("foraging/severely_nauseating"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_SEVERE_NAUSEATING).food(3, 0.9F).ailment(CompoundAffliction.of( new StatusEffectAffliction(StatusEffects.WEAKNESS, Range.of(200), Range.of(1), 0), new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 80) - )))); - exporter.accept(Unicopia.id("foraging/severely_prickly"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_SEVERE_PRICKLY).food(2, 0.9F).ailment(new CompoundAffliction(List.of( + ))); + exporter.accept(Unicopia.id("foraging/severely_prickly"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_SEVERE_PRICKLY).food(2, 0.9F).ailment(CompoundAffliction.of( new StatusEffectAffliction(StatusEffects.INSTANT_DAMAGE, Range.of(1), Range.of(0), 0), new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 80) - )))); - exporter.accept(Unicopia.id("foraging/strengthening"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_STRENGHENING).food(4, 0.2F).ailment(new CompoundAffliction(List.of( + ))); + exporter.accept(Unicopia.id("foraging/strengthening"), new FoodGroupEffects.Builder().tag(UTags.Items.FORAGE_STRENGHENING).food(4, 0.2F).ailment(CompoundAffliction.of( new StatusEffectAffliction(StatusEffects.STRENGTH, Range.of(1300), Range.of(0), 0), new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 70) - )))); + ))); } private void provideMeatCategory(String name, TagKey cookedTag, TagKey rawTag, TagKey rottenTag, FoodComponent cooked, FoodComponent raw, FoodComponent rotten, BiConsumer exporter) { - exporter.accept(Unicopia.id(name + "/cooked"), new FoodGroupEffects.Builder().tag(cookedTag).food(cooked).ailment(new CompoundAffliction(List.of( - new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 25) - )))); - exporter.accept(Unicopia.id(name + "/raw"), new FoodGroupEffects.Builder().tag(rawTag).food(raw).ailment(new CompoundAffliction(List.of( + exporter.accept(Unicopia.id(name + "/cooked"), new FoodGroupEffects.Builder().tag(cookedTag).food(cooked).ailment(new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 25))); + exporter.accept(Unicopia.id(name + "/raw"), new FoodGroupEffects.Builder().tag(rawTag).food(raw).ailment(CompoundAffliction.of( new StatusEffectAffliction(StatusEffects.POISON, Range.of(45), Range.of(2), 80), new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 65) - )))); - exporter.accept(Unicopia.id(name + "/rotten"), new FoodGroupEffects.Builder().tag(rottenTag).food(rotten).ailment(new CompoundAffliction(List.of( + ))); + exporter.accept(Unicopia.id(name + "/rotten"), new FoodGroupEffects.Builder().tag(rottenTag).food(rotten).ailment(CompoundAffliction.of( new StatusEffectAffliction(StatusEffects.POISON, Range.of(45), Range.of(2), 80), new StatusEffectAffliction(UEffects.FOOD_POISONING, Range.of(100), Range.of(2), 95) - )))); + ))); } private void provideVegetableCategory(String name, diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java b/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java index 18ceaefb..b10a8143 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietProfile.java @@ -193,5 +193,30 @@ public record DietProfile( buffer.writeFloat(hunger); buffer.writeFloat(saturation); } + + public static final class Builder { + private Set tags = new HashSet<>(); + private float hunger = 1; + private float saturation = 1; + + public Builder tag(Identifier tag) { + tags.add(FoodGroupKey.LOOKUP.apply(tag)); + return this; + } + + public Builder hunger(float hunger) { + this.hunger = hunger; + return this; + } + + public Builder saturation(float saturation) { + this.saturation = saturation; + return this; + } + + public Multiplier build() { + return new Multiplier(tags, hunger, saturation); + } + } } } diff --git a/src/main/java/com/minelittlepony/unicopia/diet/affliction/ClearLoveSicknessAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/ClearLoveSicknessAffliction.java index 79343432..ab8786a4 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/affliction/ClearLoveSicknessAffliction.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/ClearLoveSicknessAffliction.java @@ -7,7 +7,7 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; -final class ClearLoveSicknessAffliction implements Affliction { +public final class ClearLoveSicknessAffliction implements Affliction { public static final ClearLoveSicknessAffliction INSTANCE = new ClearLoveSicknessAffliction(); public static final Codec CODEC = Codec.unit(INSTANCE); @@ -21,6 +21,7 @@ final class ClearLoveSicknessAffliction implements Affliction { player.heal(stack.isFood() ? stack.getItem().getFoodComponent().getHunger() : 1); player.removeStatusEffect(StatusEffects.NAUSEA); player.removeStatusEffect(UEffects.FOOD_POISONING); + player.removeStatusEffect(StatusEffects.WEAKNESS); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java b/src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java index 0d561985..ff77dcbd 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/affliction/CompoundAffliction.java @@ -18,6 +18,10 @@ public class CompoundAffliction implements Affliction { }); } + public static CompoundAffliction of(Affliction...afflictions) { + return new CompoundAffliction(List.of(afflictions)); + } + public CompoundAffliction(PacketByteBuf buffer) { this(buffer.readList(Affliction::read)); } diff --git a/src/main/resources/data/unicopia/diets/races/alicorn.json b/src/main/resources/data/unicopia/diets/races/alicorn.json deleted file mode 100644 index 8801183e..00000000 --- a/src/main/resources/data/unicopia/diets/races/alicorn.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "default_multiplier": 1.4, - "foraging_multiplier": 0.9, - "multipliers": [ - { - "tags": [ "unicopia:fish/cooked" ], - "hunger": 1.5, - "saturation": 1.5 - }, - { - "tags": [ "unicopia:fish/raw" ], - "hunger": 0.5, - "saturation": 0.6 - }, - { - "tags": [ - "unicopia:baked_goods" - ], - "hunger": 1, - "saturation": 1 - }, - { - "tags": [ - "unicopia:insect/cooked", - "unicopia:meat/cooked" - ], - "hunger": 0.1, - "saturation": 0.1 - }, - { - "tags": [ - "unicopia:love", - "unicopia:insect/raw", - "unicopia:meat/raw", - "unicopia:meat/rotten" - ], - "hunger": 0, - "saturation": 0 - }, - { - "tags": [ "unicopia:pinecone" ], - "hunger": 0.9, - "saturation": 0.9 - } - ], - "effects": [ - { - "tags": [ "unicopia:fish/cooked" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ "unicopia:fish/raw" ], - "ailment": { - "effects": [ ] - } - } - ] -} diff --git a/src/main/resources/data/unicopia/diets/races/bat.json b/src/main/resources/data/unicopia/diets/races/bat.json deleted file mode 100644 index b5c17d1b..00000000 --- a/src/main/resources/data/unicopia/diets/races/bat.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "default_multiplier": 0.6, - "foraging_multiplier": 0.9, - "multipliers": [ - { - "tags": [ "unicopia:fish/cooked" ], - "hunger": 0.75, - "saturation": 0.75 - }, - { - "tags": [ "unicopia:fish/raw" ], - "hunger": 0.5, - "saturation": 0.6 - }, - { - "tags": [ "unicopia:insect/cooked" ], - "hunger": 1.75, - "saturation": 1.75 - }, - { - "tags": [ "unicopia:meat/cooked" ], - "hunger": 1.15, - "saturation": 1.15 - }, - { - "tags": [ "unicopia:insect/raw" ], - "hunger": 1, - "saturation": 1 - }, - { - "tags": [ "unicopia:meat/raw" ], - "hunger": 0.25, - "saturation": 0.25 - }, - { - "tags": [ "unicopia:meat/rotten" ], - "hunger": 0.2, - "saturation": 0.2 - }, - { - "tags": [ "unicopia:love" ], - "hunger": 0, - "saturation": 0 - }, - { - "tags": [ "unicopia:pinecone" ], - "hunger": 0.9, - "saturation": 0.9 - } - ], - "effects": [ - { - "tags": [ "unicopia:fish/rotten" ], - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2, - "chance": 5 - } - ] - } - }, - { - "tags": [ - "unicopia:insect/cooked", - "unicopia:meat/cooked" - ], - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ "unicopia:insect/raw" ], - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 50, - "amplifier": 1 - } - ] - } - }, - { - "tags": [ - "unicopia:meat/raw", - "unicopia:meat/rotten" - ], - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2, - "chance": 5 - } - ] - } - }, - { - "tags": [ "unicopia:bat_ponys_delight" ], - "ailment": { - "effects": [ - { - "effect": "minecraft:health_boost", - "seconds": { "min": 30, "max": 60 }, - "amplifier": { "min": 2, "max": 6 } - }, - { - "effect": "minecraft:jump_boost", - "seconds": { "min": 30, "max": 60 }, - "amplifier": { "min": 1, "max": 6 } - }, - { - "effect": "minecraft:health_boost", - "seconds": 30, - "amplifier": { "min": 1, "max": 6 } - }, - { - "effect": "minecraft:regeneration", - "seconds": { "min": 3, "max": 30 }, - "amplifier": { "min": 3, "max": 6 } - } - ] - } - } - ] -} diff --git a/src/main/resources/data/unicopia/diets/races/changeling.json b/src/main/resources/data/unicopia/diets/races/changeling.json deleted file mode 100644 index e0c79004..00000000 --- a/src/main/resources/data/unicopia/diets/races/changeling.json +++ /dev/null @@ -1,159 +0,0 @@ -{ - "default_multiplier": 0.15, - "foraging_multiplier": 0.1, - "multipliers": [ - { - "tags": [ "unicopia:insect/cooked" ], - "hunger": 2.0, - "saturation": 1.3 - }, - { - "tags": [ "unicopia:meat/cooked" ], - "hunger": 1.9, - "saturation": 1.2 - }, - { - "tags": [ "unicopia:insect/raw" ], - "hunger": 1, - "saturation": 1 - }, - { - "tags": [ "unicopia:meat/raw" ], - "hunger": 1.25, - "saturation": 1.25 - }, - { - "tags": [ "unicopia:meat/rotten" ], - "hunger": 0.6, - "saturation": 0.6 - }, - { - "tags": [ - "unicopia:baked_goods" - ], - "hunger": 0.5, - "saturation": 0.9 - }, - { - "tags": [ "unicopia:love" ], - "hunger": 5, - "saturation": 3 - } - ], - "default_effects": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - }, - { - "effect": "minecraft:weakness", - "seconds": 200, - "amplifier": 1 - }, - { - "type": "unicopia:lose_hunger", - "multiplier": 0.5 - } - ] - }, - "effects": [ - { - "tags": [ "unicopia:love" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ - { - "name": "Love Consumption", - "type": "unicopia:cure_love_sickness" - } - ] - } - }, - { - "tags": [ - "unicopia:insect/raw" - ], - "food_component": { - "hunger": 3, - "saturation": 2 - }, - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ - "unicopia:fish/cooked", - "unicopia:fish/raw" - ], - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 50, - "amplifier": 2 - }, - { - "name": "unicopia.affliction.love_sickness", - "type": "unicopia:lose_hunger", - "multiplier": 0.5 - } - ] - } - }, - { - "tags": [ - "unicopia:fish/rotten", - "unicopia:insect/cooked", - "unicopia:meat/cooked", - "unicopia:meat/raw", - "unicopia:meat/rotten" - ], - "food_component": { - "hunger": 6, - "saturation": 9 - }, - "ailment": { - "effects": [ - { - "name": "Love Consumption", - "type": "unicopia:cure_love_sickness" - } - ] - } - }, - { - "tags": [ - "unicopia:foraging/edible", - "unicopia:foraging/edible_filling" - ], - "food_component": { - "hunger": 18, - "saturation": 9 - }, - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 10, - "amplifier": 2 - }, - { - "effect": "minecraft:weakness", - "seconds": 2, - "amplifier": 1 - }, - { - "type": "unicopia:lose_hunger", - "multiplier": 0.5 - } - ] - } - } - ] -} diff --git a/src/main/resources/data/unicopia/diets/races/earth.json b/src/main/resources/data/unicopia/diets/races/earth.json deleted file mode 100644 index 75cd8f16..00000000 --- a/src/main/resources/data/unicopia/diets/races/earth.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "default_multiplier": 0.7, - "foraging_multiplier": 1, - "multipliers": [ - { - "tags": [ - "unicopia:candy", - "unicopia:desserts", - "unicopia:rocks" - ], - "hunger": 2.5, - "saturation": 1.7 - }, - { - "tags": [ - "unicopia:baked_goods" - ], - "hunger": 1.2, - "saturation": 2 - }, - { - "tags": [ "unicopia:fish/cooked" ], - "hunger": 0.2, - "saturation": 0.2 - }, - { - "tags": [ - "unicopia:insect/cooked", - "unicopia:meat/cooked" - ], - "hunger": 0.1, - "saturation": 0.1 - }, - { - "tags": [ - "unicopia:love", - "unicopia:fish/raw", - "unicopia:insect/raw", - "unicopia:meat/raw", - "unicopia:meat/rotten" - ], - "hunger": 0, - "saturation": 0 - }, - { - "tags": [ "unicopia:pinecone" ], - "hunger": 1, - "saturation": 1 - } - ], - "effects": [ - { - "tags": [ - "unicopia:candy", - "unicopia:rocks" - ], - "food_component": { - "hunger": 5, - "saturation": 12, - "fastFood": true - }, - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ - "unicopia:desserts" - ], - "food_component": { - "hunger": 12, - "saturation": 32, - "eatenQuickly": true, - "fastFood": true - }, - "ailment": { - "effects": [ ] - } - } - ] -} diff --git a/src/main/resources/data/unicopia/diets/races/hippogriff.json b/src/main/resources/data/unicopia/diets/races/hippogriff.json deleted file mode 100644 index 22c21e1f..00000000 --- a/src/main/resources/data/unicopia/diets/races/hippogriff.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "default_multiplier": 0.5, - "foraging_multiplier": 0.8, - "multipliers": [ - { - "tags": [ - "unicopia:meat/cooked", - "unicopia:fish/cooked" - ], - "hunger": 1.6, - "saturation": 1.6 - }, - { - "tags": [ - "unicopia:nuts_and_seeds" - ], - "hunger": 1.4, - "saturation": 1.4 - }, - { - "tags": [ - "unicopia:baked_goods" - ], - "hunger": 1, - "saturation": 1 - }, - { - "tags": [ - "unicopia:meat/raw", - "unicopia:fish/raw" - ], - "hunger": 0.6, - "saturation": 0.6 - }, - { - "tags": [ "unicopia:meat/rotten" ], - "hunger": 0.3, - "saturation": 0.3 - }, - { - "tags": [ - "unicopia:love", - "unicopia:insect/raw", - "unicopia:insect/cooked" - ], - "hunger": 0, - "saturation": 0 - }, - { - "tags": [ "unicopia:pinecone" ], - "hunger": 1, - "saturation": 1 - } - ], - "effects": [ - { - "tags": [ "unicopia:fish/cooked" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ "unicopia:fish/raw" ], - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ - "unicopia:foraging/prickly", - "unicopia:foraging/severely_prickly" - ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ "unicopia:pinecone" ], - "ailment": { - "effects": [ - { - "type": "unicopia:healing", - "health": 3 - } - ] - } - } - ] -} diff --git a/src/main/resources/data/unicopia/diets/races/human.json b/src/main/resources/data/unicopia/diets/races/human.json deleted file mode 100644 index 67db4d5b..00000000 --- a/src/main/resources/data/unicopia/diets/races/human.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "default_multiplier": 1, - "foraging_multiplier": 0, - "multipliers": [ ], - "effects": [ - { - "tags": [ - "unicopia:fish/cooked", - "unicopia:fish/raw", - "unicopia:fish/rotten", - "unicopia:meat/cooked", - "unicopia:meat/raw", - "unicopia:meat/rotten", - "unicopia:pinecone" - ], - "ailment": { - "effects": [ ] - } - } - ] -} diff --git a/src/main/resources/data/unicopia/diets/races/kirin.json b/src/main/resources/data/unicopia/diets/races/kirin.json deleted file mode 100644 index 5a9a5919..00000000 --- a/src/main/resources/data/unicopia/diets/races/kirin.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "default_multiplier": 0.25, - "foraging_multiplier": 0.9, - "multipliers": [ - { - "tags": [ "unicopia:meat/cooked" ], - "hunger": 1.5, - "saturation": 1.5 - }, - { - "tags": [ "unicopia:meat/raw" ], - "hunger": 0.5, - "saturation": 0.6 - }, - { - "tags": [ - "unicopia:baked_goods" - ], - "hunger": 1, - "saturation": 1 - }, - { - "tags": [ - "unicopia:insect/cooked", - "unicopia:fish/cooked" - ], - "hunger": 0.1, - "saturation": 0.1 - }, - { - "tags": [ - "unicopia:love", - "unicopia:insect/raw", - "unicopia:fish/raw", - "unicopia:meat/rotten" - ], - "hunger": 0, - "saturation": 0 - }, - { - "tags": [ "unicopia:pinecone" ], - "hunger": 0.9, - "saturation": 0.9 - } - ], - "effects": [ - { - "tags": [ - "unicopia:fish/rotten", - "unicopia:insect/cooked", - "unicopia:meat/cooked", - "unicopia:meat/raw", - "unicopia:meat/rotten", - "unicopia:foraging/blinding", - "unicopia:foraging/prickly", - "unicopia:foraging/severely_prickly", - "unicopia:foraging/strengthening" - ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ ] - } - } - ] -} diff --git a/src/main/resources/data/unicopia/diets/races/pegasus.json b/src/main/resources/data/unicopia/diets/races/pegasus.json deleted file mode 100644 index 7cbd683a..00000000 --- a/src/main/resources/data/unicopia/diets/races/pegasus.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "default_multiplier": 0.9, - "foraging_multiplier": 1, - "multipliers": [ - { - "tags": [ "unicopia:fish/cooked" ], - "hunger": 1.5, - "saturation": 1.5 - }, - { - "tags": [ "unicopia:fish/raw" ], - "hunger": 0.5, - "saturation": 0.6 - }, - { - "tags": [ - "unicopia:baked_goods" - ], - "hunger": 1, - "saturation": 1 - }, - { - "tags": [ - "unicopia:insect/cooked", - "unicopia:meat/cooked" - ], - "hunger": 0.1, - "saturation": 0.1 - }, - { - "tags": [ - "unicopia:love", - "unicopia:insect/raw", - "unicopia:meat/raw", - "unicopia:meat/rotten" - ], - "hunger": 0, - "saturation": 0 - }, - { - "tags": [ "unicopia:pinecone" ], - "hunger": 0.9, - "saturation": 0.9 - } - ], - "effects": [ - { - "tags": [ "unicopia:fish/cooked" ], - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ "unicopia:fish/raw" ], - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 50, - "amplifier": 2 - } - ] - } - } - ] -} diff --git a/src/main/resources/data/unicopia/diets/races/seapony.json b/src/main/resources/data/unicopia/diets/races/seapony.json deleted file mode 100644 index c67aa9f7..00000000 --- a/src/main/resources/data/unicopia/diets/races/seapony.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "default_multiplier": 0.4, - "foraging_multiplier": 0.7, - "multipliers": [ - { - "tags": [ "unicopia:sea_vegetable/raw" ], - "hunger": 1, - "saturation": 1 - }, - { - "tags": [ - "unicopia:shells", "unicopia:shelly" - ], - "hunger": 1, - "saturation": 1 - } - ], - "default_effects": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - }, - "effects": [ - { - "tags": [ "unicopia:fish/cooked" ], - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ "unicopia:fish/raw" ], - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ - "unicopia:foraging/edible", - "unicopia:foraging/edible_filling" - ], - "food_component": { - "hunger": 18, - "saturation": 9 - }, - "ailment": { - "effects": [ - { - "effect": "unicopia:food_poisoning", - "seconds": 100, - "amplifier": 2 - } - ] - } - }, - { - "tags": [ "unicopia:sea_vegetable/raw" ], - "food_component": { - "hunger": 2, - "saturation": 1 - }, - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ "unicopia:sea_vegetable/cooked" ], - "food_component": { - "hunger": 6, - "saturation": 2 - }, - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ "unicopia:shells" ], - "food_component": { - "hunger": 3, - "saturation": 5 - }, - "ailment": { - "effects": [ ] - } - }, - { - "tags": [ "unicopia:shelly" ], - "food_component": { - "hunger": 6, - "saturation": 7 - }, - "ailment": { - "effects": [ ] - } - } - ] -} diff --git a/src/main/resources/data/unicopia/diets/races/unicorn.json b/src/main/resources/data/unicopia/diets/races/unicorn.json deleted file mode 100644 index 3213c82b..00000000 --- a/src/main/resources/data/unicopia/diets/races/unicorn.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "default_multiplier": 1.2, - "foraging_multiplier": 1, - "multipliers": [ - { - "tags": [ - "unicopia:insect/cooked", - "unicopia:meat/cooked", - "unicopia:fish/cooked" - ], - "hunger": 0.1, - "saturation": 0.1 - }, - { - "tags": [ - "unicopia:baked_goods" - ], - "hunger": 1, - "saturation": 1 - }, - { - "tags": [ - "unicopia:love", - "unicopia:insect/raw", - "unicopia:meat/raw", - "unicopia:fish/raw", - "unicopia:meat/rotten" - ], - "hunger": 0, - "saturation": 0 - }, - { - "tags": [ "unicopia:pinecone" ], - "hunger": 0.9, - "saturation": 0.9 - } - ], - "effects": [] -} From 56e91629b1114255c39de9752787c19598b04c39 Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 5 Apr 2024 15:07:07 +0100 Subject: [PATCH 69/73] Fix some tag references and fix diets not loading --- .../unicopia/diet/DietsLoader.java | 4 ++-- .../unicopia/tags/items/groups/foraging.json | 22 +++++++++---------- .../unicopia/tags/items/groups/sea_pony.json | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java b/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java index 7da493ea..0c4eb7f5 100644 --- a/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java +++ b/src/main/java/com/minelittlepony/unicopia/diet/DietsLoader.java @@ -35,7 +35,7 @@ public class DietsLoader implements IdentifiableResourceReloadListener { CompletableFuture> foodGroupsFuture = CompletableFuture.supplyAsync(() -> { Map foodGroups = new HashMap<>(); - for (var group : loadData(manager, prepareExecutor, "diets/food_groups").entrySet()) { + for (var group : loadData(manager, prepareExecutor, "diet/food_groups").entrySet()) { try { FoodGroup.CODEC.parse(JsonOps.INSTANCE, group.getValue()) .resultOrPartial(error -> LOGGER.error("Could not load food group {}: {}", group.getKey(), error)) @@ -50,7 +50,7 @@ public class DietsLoader implements IdentifiableResourceReloadListener { }, prepareExecutor); CompletableFuture> profilesFuture = CompletableFuture.supplyAsync(() -> { Map profiles = new HashMap<>(); - for (var entry : loadData(manager, prepareExecutor, "diets/races").entrySet()) { + for (var entry : loadData(manager, prepareExecutor, "diet/races").entrySet()) { Identifier id = entry.getKey(); try { Race.REGISTRY.getOrEmpty(id).ifPresentOrElse(race -> { diff --git a/src/main/resources/data/unicopia/tags/items/groups/foraging.json b/src/main/resources/data/unicopia/tags/items/groups/foraging.json index f50de618..92eb5eee 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/foraging.json +++ b/src/main/resources/data/unicopia/tags/items/groups/foraging.json @@ -1,16 +1,16 @@ { "replace": false, "values": [ - "#unicopia:food_types/forage_dangerous", - "#unicopia:food_types/forage_edible_filling", - "#unicopia:food_types/forage_edible", - "#unicopia:food_types/forage_nauseating", - "#unicopia:food_types/forage_blinding", - "#unicopia:food_types/forage_prickly", - "#unicopia:food_types/forage_radioactive", - "#unicopia:food_types/forage_risky", - "#unicopia:food_types/forage_severely_nauseating", - "#unicopia:food_types/forage_severely_prickly", - "#unicopia:food_types/forage_strengthening" + "#unicopia:forage/dangerous", + "#unicopia:forage/filling", + "#unicopia:forage/safe", + "#unicopia:forage/nauseating", + "#unicopia:forage/blinding", + "#unicopia:forage/prickly", + "#unicopia:forage/glowing", + "#unicopia:forage/risky", + "#unicopia:forage/severe/nauseating", + "#unicopia:forage/severe/prickly", + "#unicopia:forage/strenghtening" ] } diff --git a/src/main/resources/data/unicopia/tags/items/groups/sea_pony.json b/src/main/resources/data/unicopia/tags/items/groups/sea_pony.json index 5d2c981b..9aeefc68 100644 --- a/src/main/resources/data/unicopia/tags/items/groups/sea_pony.json +++ b/src/main/resources/data/unicopia/tags/items/groups/sea_pony.json @@ -4,7 +4,7 @@ "unicopia:pearl_necklace", "#unicopia:shells", "#unicopia:special_shells", - "#unicopia:food_types/raw_sea_vegitable", - "#unicopia:food_types/cooked_sea_vegitable" + "#unicopia:food_types/low_quality_sea_vegetables", + "#unicopia:food_types/high_quality_sea_vegetables" ] } From d6e1a6c3b896ddf11a25e08ae912231947c4fa4b Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 5 Apr 2024 15:07:21 +0100 Subject: [PATCH 70/73] Fixed slime pustule not triggering a redstone update above it --- .../com/minelittlepony/unicopia/block/SlimePustuleBlock.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/minelittlepony/unicopia/block/SlimePustuleBlock.java b/src/main/java/com/minelittlepony/unicopia/block/SlimePustuleBlock.java index 4d7d58e8..72b1a814 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/SlimePustuleBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/SlimePustuleBlock.java @@ -199,7 +199,7 @@ public class SlimePustuleBlock extends Block { public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) { super.onStateReplaced(state, world, pos, newState, moved); if (state.isOf(this) && newState.isOf(this) && state.get(POWERED) != newState.get(POWERED)) { - world.updateNeighbor(pos.up(), this, pos); + world.updateNeighborsAlways(pos.up(), this); } } From 926b8088cf23190d011c5bdd8cbb2d753c06fa19 Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 5 Apr 2024 15:15:14 +0100 Subject: [PATCH 71/73] Fix some food group names --- src/main/resources/assets/unicopia/lang/en_us.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 8552f3f2..5033eda6 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -622,19 +622,21 @@ "food_group.unicopia.meat.rotten": "Rotting Meat", "food_group.unicopia.meat.raw": "Fresh Meat", "food_group.unicopia.meat.cooked": "Prepared Meat", + "food_group.unicopia.fish.rotten": "Rotten Fish", "food_group.unicopia.fish.raw": "Fresh Fish", "food_group.unicopia.fish.cooked": "Prepared Fish", + "food_group.unicopia.insect.rotten": "Rotted Bugs & Insects", "food_group.unicopia.insect.raw": "Bugs & Insects", - "food_group.unicopia.fish.cooked": "Cooked Bugs & Insects", + "food_group.unicopia.insect.cooked": "Cooked Bugs & Insects", "food_group.unicopia.nuts_and_seeds": "Nuts & Seeds", "food_group.unicopia.love": "Love", "food_group.unicopia.rocks": "Rocks", "food_group.unicopia.pinecone": "Nuts & Seeds", "food_group.unicopia.bat_ponys_delight": "Bat Pony Treats", - "food_group.unicopia.sea_vegitable.cooked": "Prepared Fish Food", - "food_group.unicopia.sea_vegitable.raw": "Fresh Fish Food", + "food_group.unicopia.sea_vegetable.cooked": "Prepared Shells & Coral", + "food_group.unicopia.sea_vegetable.raw": "Shells & Coral", "food_group.unicopia.shells": "Sea Shells", - "food_group.unicopia.shelly": "Sea Shells", + "food_group.unicopia.special_shells": "Companions", "food_group.unicopia.candy": "Candy", "food_group.unicopia.desserts": "Desserts", "food_group.unicopia.fruit": "Fruit", From 8c8364700478947f53670e9fafb57273892334e3 Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 5 Apr 2024 17:10:39 +0100 Subject: [PATCH 72/73] Add cooked and rotten variants of all the fish --- .../providers/UAdvancementsProvider.java | 1 + .../datagen/providers/UModelProvider.java | 14 ++++++++--- .../UBlockAdditionsLootTableProvider.java | 22 +++++++++++++++++ .../UChestAdditionsLootTableProvider.java | 9 +++++++ .../providers/recipe/URecipeProvider.java | 4 +++ .../providers/tag/UItemTagProvider.java | 7 +++++- ...DrinkableItem.java => ConsumableItem.java} | 10 +++++--- .../unicopia/item/UFoodComponents.java | 1 + .../minelittlepony/unicopia/item/UItems.java | 23 +++++++++++++----- .../resources/assets/unicopia/lang/en_us.json | 10 ++++++++ .../textures/item/cooked_pufferfish.png | Bin 0 -> 6980 bytes .../textures/item/cooked_tropical_fish.png | Bin 0 -> 6795 bytes .../unicopia/textures/item/fried_axolotl.png | Bin 0 -> 6561 bytes .../unicopia/textures/item/fried_egg.png | Bin 0 -> 6662 bytes .../textures/item/green_fried_egg.png | Bin 0 -> 6709 bytes .../unicopia/textures/item/rotten_cod.png | Bin 0 -> 7008 bytes .../textures/item/rotten_pufferfish.png | Bin 0 -> 6927 bytes .../unicopia/textures/item/rotten_salmon.png | Bin 0 -> 6986 bytes .../textures/item/rotten_tropical_fish.png | Bin 0 -> 6649 bytes .../tags/items/groups/changeling.json | 1 + .../unicopia/tags/items/groups/pegasus.json | 1 + 21 files changed, 89 insertions(+), 14 deletions(-) rename src/main/java/com/minelittlepony/unicopia/item/{DrinkableItem.java => ConsumableItem.java} (84%) create mode 100644 src/main/resources/assets/unicopia/textures/item/cooked_pufferfish.png create mode 100644 src/main/resources/assets/unicopia/textures/item/cooked_tropical_fish.png create mode 100644 src/main/resources/assets/unicopia/textures/item/fried_axolotl.png create mode 100644 src/main/resources/assets/unicopia/textures/item/fried_egg.png create mode 100644 src/main/resources/assets/unicopia/textures/item/green_fried_egg.png create mode 100644 src/main/resources/assets/unicopia/textures/item/rotten_cod.png create mode 100644 src/main/resources/assets/unicopia/textures/item/rotten_pufferfish.png create mode 100644 src/main/resources/assets/unicopia/textures/item/rotten_salmon.png create mode 100644 src/main/resources/assets/unicopia/textures/item/rotten_tropical_fish.png diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java index a46d1306..a540572c 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java @@ -77,6 +77,7 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { p.child(UItems.WEIRD_ROCK).hidden().criterion("has_rock", hasItems(UItems.WEIRD_ROCK)).build(consumer, "thats_unusual"); }); + parent.child(UItems.FRIED_AXOLOTL).criterion("eaten_axolotl", ConsumeItemCriterion.Conditions.item(UItems.FRIED_AXOLOTL)).build(consumer, "tastes_like_chicken"); parent.child(UItems.OATS).criterion("has_oats", hasItems(UItems.OATS)).build(consumer, "oats_so_easy"); parent.child(Items.HAY_BLOCK).criterion("eat_hay", ConsumeItemCriterion.Conditions.item(Items.HAY_BLOCK)).build(consumer, "what_the_hay"); parent.child(UItems.COPPER_HORSE_SHOE).criterion("has_horseshoe", hasItems(UTags.Items.HORSE_SHOES)).build(consumer, "blacksmith").children(p -> { diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java index 8dd5d9c5..cc317eb5 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UModelProvider.java @@ -59,12 +59,14 @@ public class UModelProvider extends FabricModelProvider { ItemModels.register(itemModelGenerator, UItems.ACORN, UItems.APPLE_PIE_HOOF, UItems.APPLE_PIE_SLICE, UItems.APPLE_PIE, UItems.BANANA, UItems.BOTCHED_GEM, UItems.BOWL_OF_NUTS, UItems.BROKEN_SUNGLASSES, UItems.BURNED_JUICE, UItems.BURNED_TOAST, - UItems.CARAPACE, UItems.CLAM_SHELL, UItems.COOKED_ZAP_APPLE, UItems.CHOCOLATE_OATMEAL_COOKIE, UItems.CLOUD_LUMP, UItems.CRISPY_HAY_FRIES, UItems.CRYSTAL_HEART, UItems.CRYSTAL_SHARD, + UItems.CARAPACE, UItems.CLAM_SHELL, UItems.COOKED_ZAP_APPLE, UItems.CHOCOLATE_OATMEAL_COOKIE, + UItems.CLOUD_LUMP, UItems.CRISPY_HAY_FRIES, UItems.CRYSTAL_HEART, UItems.CRYSTAL_SHARD, + UItems.COOKED_TROPICAL_FISH, UItems.COOKED_PUFFERFISH, UItems.FRIED_AXOLOTL, UItems.DAFFODIL_DAISY_SANDWICH, UItems.DRAGON_BREATH_SCROLL, UItems.EMPTY_JAR, UItems.FRIENDSHIP_BRACELET, UItems.GIANT_BALLOON, UItems.GOLDEN_FEATHER, UItems.GOLDEN_OAK_SEEDS, UItems.GOLDEN_WING, UItems.GREEN_APPLE_SEEDS, UItems.GREEN_APPLE, UItems.GROGARS_BELL, - UItems.GRYPHON_FEATHER, + UItems.GRYPHON_FEATHER, UItems.GREEN_FRIED_EGG, UItems.HAY_BURGER, UItems.HAY_FRIES, UItems.HORSE_SHOE_FRIES, UItems.IMPORTED_OATS, UItems.JAM_TOAST, UItems.JUICE, @@ -72,7 +74,8 @@ public class UModelProvider extends FabricModelProvider { UItems.MANGO, UItems.MUFFIN, UItems.OATMEAL, UItems.OATMEAL_COOKIE, UItems.SCONE, UItems.PEBBLES, UItems.PEGASUS_FEATHER, UItems.PINECONE, UItems.PINECONE_COOKIE, UItems.PINEAPPLE_CROWN, - UItems.RAIN_CLOUD_JAR, UItems.ROCK_STEW, UItems.ROCK, UItems.ROTTEN_APPLE, + UItems.RAIN_CLOUD_JAR, UItems.ROCK_STEW, UItems.ROCK, + UItems.ROTTEN_APPLE, UItems.ROTTEN_COD, UItems.ROTTEN_TROPICAL_FISH, UItems.ROTTEN_SALMON, UItems.ROTTEN_PUFFERFISH, UItems.SALT_CUBE, UItems.SCALLOP_SHELL, UItems.SHELLY, UItems.SOUR_APPLE_SEEDS, UItems.SOUR_APPLE, UItems.SPELLBOOK, UItems.STORM_CLOUD_JAR, UItems.SWEET_APPLE_SEEDS, UItems.SWEET_APPLE, UItems.TOAST, UItems.TOM, UItems.TURRET_SHELL, @@ -106,7 +109,10 @@ public class UModelProvider extends FabricModelProvider { .put(TextureKey.LAYER1, ModelIds.getItemSubModelId(UItems.MAGIC_STAFF, "_magic")), itemModelGenerator.writer); // polearms - List.of(UItems.DIAMOND_POLEARM, UItems.GOLDEN_POLEARM, UItems.NETHERITE_POLEARM, UItems.STONE_POLEARM, UItems.WOODEN_POLEARM, UItems.IRON_POLEARM).forEach(item -> ItemModels.registerPolearm(itemModelGenerator, item)); + List.of( + UItems.DIAMOND_POLEARM, UItems.GOLDEN_POLEARM, UItems.NETHERITE_POLEARM, + UItems.STONE_POLEARM, UItems.WOODEN_POLEARM, UItems.IRON_POLEARM + ).forEach(item -> ItemModels.registerPolearm(itemModelGenerator, item)); // sheets ItemModels.register(itemModelGenerator, BedsheetsItem.ITEMS.values().stream().toArray(Item[]::new)); // badges diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockAdditionsLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockAdditionsLootTableProvider.java index 4663bd66..cf6ed6d5 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockAdditionsLootTableProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UBlockAdditionsLootTableProvider.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.datagen.providers.loot; import java.util.function.Function; +import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.enchantment.UEnchantments; @@ -14,20 +15,24 @@ import net.minecraft.enchantment.Enchantments; import net.minecraft.item.ItemConvertible; import net.minecraft.loot.LootPool; import net.minecraft.loot.LootTable; +import net.minecraft.loot.condition.LocationCheckLootCondition; import net.minecraft.loot.condition.LootCondition; import net.minecraft.loot.condition.MatchToolLootCondition; import net.minecraft.loot.condition.RandomChanceLootCondition; import net.minecraft.loot.condition.TableBonusLootCondition; import net.minecraft.loot.entry.ItemEntry; import net.minecraft.loot.entry.LootPoolEntry; +import net.minecraft.loot.entry.TagEntry; import net.minecraft.loot.function.ApplyBonusLootFunction; import net.minecraft.loot.function.SetCountLootFunction; import net.minecraft.loot.provider.number.ConstantLootNumberProvider; import net.minecraft.loot.provider.number.UniformLootNumberProvider; import net.minecraft.predicate.NumberRange; +import net.minecraft.predicate.entity.LocationPredicate; import net.minecraft.predicate.item.EnchantmentPredicate; import net.minecraft.predicate.item.ItemPredicate; import net.minecraft.util.Identifier; +import net.minecraft.world.biome.BiomeKeys; public class UBlockAdditionsLootTableProvider extends FabricBlockLootTableProvider { public static final LootCondition.Builder WITH_GEM_FINDER = MatchToolLootCondition.builder(ItemPredicate.Builder.create().enchantment(new EnchantmentPredicate(UEnchantments.GEM_FINDER, NumberRange.IntRange.atLeast(1)))); @@ -35,6 +40,10 @@ public class UBlockAdditionsLootTableProvider extends FabricBlockLootTableProvid public static final LootCondition.Builder WITHOUT_SILK_TOUCH_AND_GEM_FINDER = WITHOUT_SILK_TOUCH.and(WITH_GEM_FINDER); public static final float[] GEMSTONES_FORTUNE_CHANCE = { 0.1F, 0.14285715F, 0.25F, 1F }; + public static final LootCondition.Builder NEEDS_OCEAN_OR_BEACH_BIOME = + LocationCheckLootCondition.builder(LocationPredicate.Builder.create().biome(BiomeKeys.OCEAN)) + .or(LocationCheckLootCondition.builder(LocationPredicate.Builder.create().biome(BiomeKeys.BEACH))); + public UBlockAdditionsLootTableProvider(FabricDataOutput dataOutput) { super(dataOutput); } @@ -57,12 +66,25 @@ public class UBlockAdditionsLootTableProvider extends FabricBlockLootTableProvid addVanillaDrop(Blocks.DEEPSLATE_DIAMOND_ORE, this::crystalShardDrops); addVanillaDrop(Blocks.OAK_LEAVES, block -> chanceDropWithShears(block, UItems.ACORN, GEMSTONES_FORTUNE_CHANCE)); addVanillaDrop(Blocks.SPRUCE_LEAVES, block -> chanceDropWithShears(block, UItems.PINECONE, GEMSTONES_FORTUNE_CHANCE)); + addVanillaDrop(Blocks.GRAVEL, this::shellDrops); + addVanillaDrop(Blocks.SUSPICIOUS_GRAVEL, this::shellDrops); } private void addVanillaDrop(Block block, Function lootTableFunction) { lootTables.put(new Identifier("unicopiamc", block.getLootTableId().getPath()), lootTableFunction.apply(block)); } + public LootTable.Builder shellDrops(Block block) { + return LootTable.builder().pool(LootPool.builder() + .rolls(ConstantLootNumberProvider.create(1)) + .conditionally(WITHOUT_SILK_TOUCH.and(NEEDS_OCEAN_OR_BEACH_BIOME)) + .with(applyExplosionDecay(block, TagEntry.builder(UTags.Items.SHELLS) + .apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(1))) + ) + .conditionally(TableBonusLootCondition.builder(Enchantments.FORTUNE, GEMSTONES_FORTUNE_CHANCE))) + ); + } + public LootTable.Builder chanceDropWithShears(Block block, ItemConvertible drop, float...chance) { return LootTable.builder() .pool(LootPool.builder() diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java index 051875e7..0d6beac9 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/loot/UChestAdditionsLootTableProvider.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.datagen.providers.loot; import java.util.function.BiConsumer; +import com.minelittlepony.unicopia.UConventionalTags; import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.item.UItems; @@ -60,6 +61,7 @@ public class UChestAdditionsLootTableProvider extends SimpleFabricLootTableProvi .rolls(UniformLootNumberProvider.create(0, 1)) .with(ItemEntry.builder(UItems.GROGARS_BELL).weight(1)) )); + exporter.accept(LootTables.BURIED_TREASURE_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 4)) .with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1)) @@ -68,21 +70,25 @@ public class UChestAdditionsLootTableProvider extends SimpleFabricLootTableProvi exporter.accept(LootTables.SHIPWRECK_SUPPLY_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 6)) .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(3)) + .with(TagEntry.expandBuilder(UConventionalTags.Items.ROTTEN_FISH).weight(1)) )); exporter.accept(LootTables.SHIPWRECK_TREASURE_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 4)) .with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1)) .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(3)) + .with(TagEntry.expandBuilder(UConventionalTags.Items.ROTTEN_FISH).weight(1)) )); exporter.accept(LootTables.UNDERWATER_RUIN_BIG_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 2)) .with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1)) .with(ItemEntry.builder(UItems.SHELLY).weight(4)) .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(8)) + .with(TagEntry.expandBuilder(UConventionalTags.Items.ROTTEN_FISH).weight(1)) )); exporter.accept(LootTables.UNDERWATER_RUIN_SMALL_CHEST, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 4)) .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(1)) + .with(TagEntry.expandBuilder(UConventionalTags.Items.ROTTEN_FISH).weight(1)) )); exporter.accept(LootTables.DESERT_WELL_ARCHAEOLOGY, LootTable.builder().pool(LootPool.builder() @@ -112,17 +118,20 @@ public class UChestAdditionsLootTableProvider extends SimpleFabricLootTableProvi .rolls(UniformLootNumberProvider.create(1, 4)) .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(1)) .with(ItemEntry.builder(UItems.PEARL_NECKLACE).weight(1)) + .with(TagEntry.expandBuilder(UConventionalTags.Items.ROTTEN_FISH).weight(1)) )); exporter.accept(LootTables.FISHING_GAMEPLAY, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 4)) .with(TagEntry.expandBuilder(UTags.Items.SHELLS).weight(2)) + .with(TagEntry.expandBuilder(UConventionalTags.Items.ROTTEN_FISH).weight(1)) )); exporter.accept(LootTables.FISHING_JUNK_GAMEPLAY, LootTable.builder().pool(LootPool.builder() .rolls(UniformLootNumberProvider.create(1, 4)) .with(ItemEntry.builder(UItems.BROKEN_SUNGLASSES).weight(2)) .with(ItemEntry.builder(UItems.WHEAT_WORMS).weight(2)) + .with(TagEntry.expandBuilder(UConventionalTags.Items.ROTTEN_FISH).weight(1)) .with(ItemEntry.builder(UItems.BOTCHED_GEM).weight(4)) )); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index 3e27692b..aad4a126 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -411,6 +411,10 @@ public class URecipeProvider extends FabricRecipeProvider { offerSmelting(exporter, List.of(UItems.BURNED_JUICE, UItems.BURNED_TOAST), RecipeCategory.FOOD, Items.CHARCOAL, 1, 20, "coal"); offerSmelting(exporter, List.of(UItems.HAY_FRIES), RecipeCategory.FOOD, UItems.CRISPY_HAY_FRIES, 1F, 25, "hay_fries"); offerSmelting(exporter, List.of(UItems.ZAP_APPLE), RecipeCategory.FOOD, UItems.COOKED_ZAP_APPLE, 1.2F, 430, "zap_apple"); + offerSmelting(exporter, List.of(Items.TROPICAL_FISH), RecipeCategory.FOOD, UItems.COOKED_TROPICAL_FISH, 1.2F, 230, "fish"); + offerSmelting(exporter, List.of(Items.PUFFERFISH), RecipeCategory.FOOD, UItems.COOKED_PUFFERFISH, 1.2F, 230, "fish"); + offerSmelting(exporter, List.of(Items.AXOLOTL_BUCKET), RecipeCategory.FOOD, UItems.FRIED_AXOLOTL, 2.2F, 230, "fried_axolotl"); + offerSmelting(exporter, List.of(UBlocks.MYSTERIOUS_EGG.asItem()), RecipeCategory.FOOD, UItems.GREEN_FRIED_EGG, 3.8F, 630, "fried_egg"); ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.ZAP_APPLE_JAM_JAR) .input(UItems.COOKED_ZAP_APPLE, 6).criterion(hasItem(UItems.COOKED_ZAP_APPLE), conditionsFromItem(UItems.COOKED_ZAP_APPLE)) diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java index bc248a61..922e19fa 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java @@ -201,7 +201,12 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { ; getOrCreateTagBuilder(UConventionalTags.Items.BANANAS).add(UItems.BANANA); getOrCreateTagBuilder(UConventionalTags.Items.RAW_FISH).add(Items.COD, Items.SALMON, Items.PUFFERFISH, Items.TROPICAL_FISH).addOptionalTag(new Identifier("c", "mollusks")); - getOrCreateTagBuilder(UConventionalTags.Items.COOKED_FISH).add(Items.COOKED_COD, Items.COOKED_SALMON); + getOrCreateTagBuilder(UConventionalTags.Items.COOKED_FISH).add(Items.COOKED_COD, Items.COOKED_SALMON, UItems.COOKED_TROPICAL_FISH, UItems.COOKED_PUFFERFISH, UItems.FRIED_AXOLOTL); + getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_FISH).add(UItems.ROTTEN_COD, UItems.ROTTEN_TROPICAL_FISH, UItems.ROTTEN_SALMON, UItems.ROTTEN_PUFFERFISH); + getOrCreateTagBuilder(ItemTags.FISHES).add( + UItems.COOKED_TROPICAL_FISH, UItems.COOKED_PUFFERFISH, UItems.FRIED_AXOLOTL, + UItems.ROTTEN_COD, UItems.ROTTEN_TROPICAL_FISH, UItems.ROTTEN_SALMON, UItems.ROTTEN_PUFFERFISH + ); getOrCreateTagBuilder(UConventionalTags.Items.COOKED_MEAT) .add(Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.COOKED_MUTTON, Items.COOKED_RABBIT, Items.COOKED_CHICKEN, Items.RABBIT_STEW) .addOptionalTag(new Identifier("c", "cooked_bacon")) diff --git a/src/main/java/com/minelittlepony/unicopia/item/DrinkableItem.java b/src/main/java/com/minelittlepony/unicopia/item/ConsumableItem.java similarity index 84% rename from src/main/java/com/minelittlepony/unicopia/item/DrinkableItem.java rename to src/main/java/com/minelittlepony/unicopia/item/ConsumableItem.java index 23fa0dd1..dba7218d 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/DrinkableItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ConsumableItem.java @@ -11,9 +11,13 @@ import net.minecraft.stat.Stats; import net.minecraft.util.UseAction; import net.minecraft.world.World; -public class DrinkableItem extends Item { - public DrinkableItem(Item.Settings settings) { +public class ConsumableItem extends Item { + + private final UseAction action; + + public ConsumableItem(Item.Settings settings, UseAction action) { super(settings); + this.action = action; } @Override @@ -30,6 +34,6 @@ public class DrinkableItem extends Item { @Override public UseAction getUseAction(ItemStack stack) { - return UseAction.DRINK; + return action; } } diff --git a/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java b/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java index 8217a4c1..80a2e9a5 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UFoodComponents.java @@ -29,6 +29,7 @@ public interface UFoodComponents { FoodComponent OATMEAL_COOKIE = FoodComponents.COOKIE; //builder(2, 0.1F).build(); FoodComponent CHOCOLATE_OATMEAL_COOKIE = builder(3, 0.4F).build(); FoodComponent SCONE = builder(2, 0.2F).build(); + FoodComponent FRIED_EGG = builder(4, 0.4F).build(); FoodComponent WORMS = builder(1, 1.5F).alwaysEdible().meat().build(); FoodComponent INSECTS = builder(1, 0).alwaysEdible().build(); diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 30ff595f..894b6d2d 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -27,6 +27,7 @@ import net.fabricmc.fabric.api.registry.CompostingChanceRegistry; import net.fabricmc.fabric.api.registry.FuelRegistry; import net.minecraft.sound.SoundEvent; import net.minecraft.util.Rarity; +import net.minecraft.util.UseAction; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.Registries; @@ -119,17 +120,17 @@ public interface UItems { Item GOLDEN_OAK_SEEDS = register("golden_oak_seeds", new AliasedBlockItem(UBlocks.GOLDEN_OAK_SPROUT, new Item.Settings()), ItemGroups.NATURAL); Item MUG = register("mug", new Item(new Settings()), ItemGroups.TOOLS); - Item CIDER = register("cider", new DrinkableItem(new Item.Settings().food(UFoodComponents.CIDER).maxCount(16).recipeRemainder(MUG)), ItemGroups.FOOD_AND_DRINK); - Item JUICE = register("juice", new DrinkableItem(new Item.Settings().recipeRemainder(Items.GLASS_BOTTLE).maxCount(16).food(UFoodComponents.JUICE)), ItemGroups.FOOD_AND_DRINK); - Item BURNED_JUICE = register("burned_juice", new DrinkableItem(new Item.Settings().recipeRemainder(Items.GLASS_BOTTLE).maxCount(16).food(UFoodComponents.BURNED_JUICE)), ItemGroups.FOOD_AND_DRINK); + Item CIDER = register("cider", new ConsumableItem(new Item.Settings().food(UFoodComponents.CIDER).maxCount(16).recipeRemainder(MUG), UseAction.DRINK), ItemGroups.FOOD_AND_DRINK); + Item JUICE = register("juice", new ConsumableItem(new Item.Settings().recipeRemainder(Items.GLASS_BOTTLE).maxCount(16).food(UFoodComponents.JUICE), UseAction.DRINK), ItemGroups.FOOD_AND_DRINK); + Item BURNED_JUICE = register("burned_juice", new ConsumableItem(new Item.Settings().recipeRemainder(Items.GLASS_BOTTLE).maxCount(16).food(UFoodComponents.BURNED_JUICE), UseAction.DRINK), ItemGroups.FOOD_AND_DRINK); Item APPLE_PIE = register("apple_pie", new BlockItem(UBlocks.APPLE_PIE, new Item.Settings().maxCount(1)), ItemGroups.FOOD_AND_DRINK); Item APPLE_PIE_HOOF = register("apple_pie_hoof", new AliasedBlockItem(UBlocks.APPLE_PIE, new Item.Settings().maxCount(1)), ItemGroups.FOOD_AND_DRINK); Item APPLE_PIE_SLICE = register("apple_pie_slice", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.PIE)), ItemGroups.FOOD_AND_DRINK); Item CANDIED_APPLE = register("candied_apple", new StagedFoodItem(new Item.Settings().food(UFoodComponents.CANDY).maxDamage(3), () -> Items.STICK), ItemGroups.FOOD_AND_DRINK); - Item LOVE_BOTTLE = register("love_bottle", new DrinkableItem(new Item.Settings().food(UFoodComponents.LOVE_BOTTLE).maxCount(1).recipeRemainder(Items.GLASS_BOTTLE)), ItemGroups.FOOD_AND_DRINK); - Item LOVE_BUCKET = register("love_bucket", new DrinkableItem(new Item.Settings().food(UFoodComponents.LOVE_BUCKET).recipeRemainder(Items.BUCKET)), ItemGroups.FOOD_AND_DRINK); - Item LOVE_MUG = register("love_mug", new DrinkableItem(new Item.Settings().food(UFoodComponents.LOVE_MUG).recipeRemainder(MUG)), ItemGroups.FOOD_AND_DRINK); + Item LOVE_BOTTLE = register("love_bottle", new ConsumableItem(new Item.Settings().food(UFoodComponents.LOVE_BOTTLE).maxCount(1).recipeRemainder(Items.GLASS_BOTTLE), UseAction.DRINK), ItemGroups.FOOD_AND_DRINK); + Item LOVE_BUCKET = register("love_bucket", new ConsumableItem(new Item.Settings().food(UFoodComponents.LOVE_BUCKET).recipeRemainder(Items.BUCKET), UseAction.DRINK), ItemGroups.FOOD_AND_DRINK); + Item LOVE_MUG = register("love_mug", new ConsumableItem(new Item.Settings().food(UFoodComponents.LOVE_MUG).recipeRemainder(MUG), UseAction.DRINK), ItemGroups.FOOD_AND_DRINK); Item GOLDEN_FEATHER = register("golden_feather", new Item(new Item.Settings().rarity(Rarity.UNCOMMON)), ItemGroups.NATURAL); Item GOLDEN_WING = register("golden_wing", new Item(new Item.Settings().rarity(Rarity.UNCOMMON)), ItemGroups.NATURAL); @@ -226,6 +227,16 @@ public interface UItems { Item TURRET_SHELL = register("turret_shell", new Item(new Item.Settings()), ItemGroups.INGREDIENTS); Item SHELLY = register("shelly", new Item(new Item.Settings()), ItemGroups.INGREDIENTS); + Item ROTTEN_COD = register("rotten_cod", new Item(new Item.Settings().food(FoodComponents.ROTTEN_FLESH)), ItemGroups.FOOD_AND_DRINK); + Item ROTTEN_SALMON = register("rotten_salmon", new Item(new Item.Settings().food(FoodComponents.ROTTEN_FLESH)), ItemGroups.FOOD_AND_DRINK); + Item ROTTEN_TROPICAL_FISH = register("rotten_tropical_fish", new Item(new Item.Settings().food(FoodComponents.ROTTEN_FLESH)), ItemGroups.FOOD_AND_DRINK); + Item ROTTEN_PUFFERFISH = register("rotten_pufferfish", new Item(new Item.Settings().food(FoodComponents.ROTTEN_FLESH)), ItemGroups.FOOD_AND_DRINK); + + Item COOKED_TROPICAL_FISH = register("cooked_tropical_fish", new Item(new Item.Settings().food(FoodComponents.COOKED_COD)), ItemGroups.FOOD_AND_DRINK); + Item COOKED_PUFFERFISH = register("cooked_pufferfish", new Item(new Item.Settings().food(FoodComponents.COOKED_COD)), ItemGroups.FOOD_AND_DRINK); + Item FRIED_AXOLOTL = register("fried_axolotl", new ConsumableItem(new Item.Settings().food(FoodComponents.COOKED_CHICKEN).recipeRemainder(Items.BUCKET), UseAction.EAT), ItemGroups.FOOD_AND_DRINK); + Item GREEN_FRIED_EGG = register("green_fried_egg", new Item(new Item.Settings().food(UFoodComponents.FRIED_EGG)), ItemGroups.FOOD_AND_DRINK); + Item CARAPACE = register("carapace", new Item(new Item.Settings()), ItemGroups.INGREDIENTS); Item CLOTH_BED = register("cloth_bed", new FancyBedItem(UBlocks.CLOTH_BED, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL); Item CLOUD_BED = register("cloud_bed", new CloudBedItem(UBlocks.CLOUD_BED, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL); diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 5033eda6..df8a8f2e 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -74,6 +74,14 @@ "item.unicopia.cooked_zap_apple": "Cooked Zap Apple", "item.unicopia.zap_apple": "Zap Apple", "item.unicopia.zap_bulb": "Unripened Zap Apple", + "item.unicopia.rotten_cod": "Rotten Cod", + "item.unicopia.rotten_salmon": "Rotten Salmon", + "item.unicopia.rotten_tropical_fish": "Rotten Tropical Fish", + "item.unicopia.rotten_pufferfish": "Rotten Pufferfish", + "item.unicopia.cooked_tropical_fish": "Cooked Tropical Fish", + "item.unicopia.cooked_pufferfish": "Cooked Pufferfish", + "item.unicopia.fried_axolotl": "Fried Axolotl", + "item.unicopia.green_fried_egg": "Green Fried Egg", "item.unicopia.love_bottle": "Bottle o' Love", "item.unicopia.love_bucket": "Love Bucket", @@ -1639,6 +1647,8 @@ "advancements.unicopia.eat_trick_apple.description": "Bite into a zap apple", "advancements.unicopia.eat_pinecone.title": "Desperation", "advancements.unicopia.eat_pinecone.description": "Eat a pinecone", + "advancements.unicopia.tastes_like_chicken.title": "Tastes Like Chicken", + "advancements.unicopia.tastes_like_chicken.description": "Fry and eat an axolotl", "advancements.unicopia.what_the_hay.title": "What The Hay", "advancements.unicopia.what_the_hay.description": "Eat an entire block of hay", "advancements.unicopia.oats_so_easy.title": "Oats So Easy", diff --git a/src/main/resources/assets/unicopia/textures/item/cooked_pufferfish.png b/src/main/resources/assets/unicopia/textures/item/cooked_pufferfish.png new file mode 100644 index 0000000000000000000000000000000000000000..eef6293b98036298983ac171eba86986ac7de86c GIT binary patch literal 6980 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 Okx9o&J{vK8{=Wg*s#(YY literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/fried_axolotl.png b/src/main/resources/assets/unicopia/textures/item/fried_axolotl.png new file mode 100644 index 0000000000000000000000000000000000000000..c1f00289233c492d62ddab8ac5969a87b2b1dd10 GIT binary patch literal 6561 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 M%DAYHBW4!-8%(>9`Tzg` literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/fried_egg.png b/src/main/resources/assets/unicopia/textures/item/fried_egg.png new file mode 100644 index 0000000000000000000000000000000000000000..55d4a4ac62e72c8b52a52f2abb8f69d635576dd9 GIT binary patch literal 6662 zcmeHMd0Z3M7M_GaLI4p7iWDRS#eigAAdx6rl&Bz4+--G|OdvuQk|2>+H*iI?B5Fl> zf`EccwTRRfts-KzE)Q|3yVkAP_PN`-y_R<-1jIgn?eqQG_m?4e?wNbf`R@6?duB58 zV{vlQP!Fmf6+sXWMMC^2=)2>M;sVFO$89KrP*!8(6Kwkol4>k?@Ezooe+t=C$_DN_I z`(FZBIC4inRFRlW=d*cSwm=N=T)t4sg|CRt6H5h=QV|cl31zP`f>6X2`4wr$#*sQW z;jkT?aJz$3EZ9ztd~s!5y4XGr8|O|SwqqvXu?{LO2aL zv|U2t5Q>Wn*~OVcCX-!VDO7iwhr64bd+#3Jp0ohJz&-(f{{Hm7?EZ8{c(A`eGa@vc z%M%KPf&C@2NPZMsAmrm91XovAcQX-aFy=^yoj7Qn(cJrkZtndN&& z?|Oa}qCbzy1Ly%K#8DIBtSU10cXaVAODoTRUh%kPmr~9vY?0HB(#!M1mdL^&vimQS zPXSH|DyJorm$t}#?)mp$4Bby;ic(HP-p~k7WHjXz?kwvh0C8Uca1B{BWkL)92tx9i zpDe500f0?|Cxj{GKE<1x;CQc3=8ZE-`AkV8O({oy+h%&pY2%IumK1?!UvK>2OjAa? zm*gBZ2bnrm% z_EMV9tW@rSp}rs!llXUl=;H;;o+u>(4<4T7N?2h8^@&ohtbV~PFYNyXP*RF>I zoNf(cmKS%h?dZwp&H(G9yC7~nz^%Z62^(+(SQ=RY;8d$p9#ja!lvV(B`4HqB-IwV| z5bt03K`|7_pfH$Dm3U!E|6zua5#J50XO{14dc3d&s^O@keggs8c^b2PZg&`Ue-698 zDH^c5Rtw=Cr1W9&)f`Z4N>mO`WdjWkXNpz;dNmPp@&LGPM`}UL-kWcwKzRhUu1|!s zllEfl;MTP#m%;wu4j^v>g&!}h%n~Z)GlnL^%7mPJ=JukJDu|Y(uE6!LDxrZIwmMin z$uu8!4X>#;wLWWLtTwyt0+O>}?GNyCGfx*6m#m13 zqnpe|tu6yY5L?O2LRrGWX#Yb~_9s`4YU;-5)_V(ky3*_L#QBUAN?q*MZXqAfiYZ#q z_s}7wi52;*W_*?@^P95=#&jnQjxGr(p}k+()Yfl)PhKDYr#G*BdHBk}hHKmSXWc`P zF|`FF!a{F7+8WzDAeR!9ODGtA{7h>+&!hQamS^CU`!}MFy}VpnF(q`3`vcb|*G=#B zeCYD<_@<4PtNoYl+*#SZ)O)0_HRi_9?Z?>rGue`VwiYXc*A@3)*28Thd-a|*t2|cO z)<$ls_PhPk!X8kvJ96t;Y5KLI{oKhX$FBY&$wCSZSGh7sN2)7w!@`?%XA^jZ8-A%= zIQ#s=CAU_5J%$i`m^dvtNHXie;AdApnNYIUTGXhZKT%x@tcY%ApPY97=chIL-AQvA z1g4Ey|Ede&zEtE?R2*71=ZM&pd8Or+>{~P0H|JEpICCYEIJ<_jx3neV_S^%L%8V!O ze)8o<(H{nUrrb`)b9iKQt zsy6D`sK%(m*fzb%{tFv5*k(f2>6n$S!cuhx8RPz*{S3NJBV&vcC2|u@aafuzA;*l3 z&Phs9=cKD88phy3)F_)20Q8s@rQ7rw28+}tW7u(}VB^Ca2HoyrO_wpo!_#1#(TvfB zY$2P=lG}9C`HVqSdX!nCm5z!Z;(&lN86(YVHAy*~?CflIwt#Ikr*e1_iG;)DbNGA~ zc(5!p3|7>}GFXCfh<1#4%%V2yOje!IK*uprl`+dIV=!Qz-jSc)l$h8FZ?HI206jQ1 z)WqSjxg5Qo(>20kl}`r{M?!Cmu%yf|VVqHz#h7JQWAf>k!5Z8ZLZj}CH)WYK>~u70 z4wixG!PNq*@?KjKe{SxKz$Hl4=}q=15c@Sxt4{k$tk-hGXY6#kCIaD|xUYG4aJM^y zS7M?x-l)#P(^JID82I{9jZv-BNbROp6%i@aVnS9Vk1JpaBO+9+NEIexX;Bfz6$>SN zF<;UJN@1{AQG*)8p#Yq%1024HFA+rWG%UVY8^IEaBe<+cR4ZYrM0~!Qr$teXTGRz% zq*(`5iDq=o3Ww4FRD@QoLWQD87RG~=gaV8uhE)3mF1R!%Ss`Qa+1ytn$r-3s3js352%RCz_G%(Ur^iNHQCv-41dlHe z@I(ThKn#5NubjqWW(!mzj%j}bvd`e#A_X!aEQ;4D0NBTYi!{!Rp;n_g#c0fsF*@I! zI;Ruia?+qyG#<5L0NVLBmD2GxHGs>La@*6#;S!A+op#0_dE*xkJqr9`%M)}KSbv6n zsQro>jb*lA$V{zdt`mJCb2Vo9=&*)$r#rY3SqU;V`ZZZ(pJ_a{0xEFFdZ-x%d zAm6|8o8P$@NwWyp{92>Ut;FTPg5X&hM)0Pm_!K>U9b;z*A5* zye#npDt5xFmWyim(0F7kl8%Hvo40ukjJTQ-CRh-}%^Pn7WNnEr43e#iL^=5m$=NeR zkk{M*k%TLX_?VQ)V|7I*(!G_mL$i%nNAPP-HdXdK+>}-uYOPw*^UTuC6RBrct;_xP z;{3L}fibm(hKeO8>r_`(EuvF=E~W(MR{MtMjv0PusBh8pdN#FXd05Yf4fDzO*IOj_ z*OS{QbyFHwEm>IK`h4g$?$2@CR}MKpea!AT`+HTd9I}Shjc785f7N(%2eM{=aAb2x zJTWFJ=JN8#Ul)wx<-N@AW~u#G{iWSi4TTp&TNG}KNxNc$N}hchdNy0{V~B7)SUU1t zYS7C^yL_GeR8;K#2TS_jDUkC{szL(RPKwzdt=B28p7}ACGj9@s)N*faxHEC5cbSW@ z-ZXOi2Y;i>(zor{wy3DND5*+UH?d$)X*}XOhoU)5K2|2KiRKrR%J%I&UaV4Porsz+ zdF5pB@UJo#l~XQ#_Atux+S8hFw}aeI_3M7B6ZtK5Nv+zHGG+Ptv0HD{v&S-G*dGV4 z8s;VU+N8Vj*+kpE=EFnsET>OzIUKuDNNljhjGt*VXY381nBK@GMW>&5I{m#Jr>{32 zAJLrbJ+-2D<}YSyLFD%v=8WTLeHxPYH5_nScX@jTH=+$|-kUbZ7M?UHp!Lqwb@Luc z28r_p{+Um&OSc*aUJjf6>*LgVq2%(?J3Bt-Jzdztj literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/green_fried_egg.png b/src/main/resources/assets/unicopia/textures/item/green_fried_egg.png new file mode 100644 index 0000000000000000000000000000000000000000..46e85b593525b07d9d255eac13c3f56847339f20 GIT binary patch literal 6709 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 flIYN9L#Me!6jc<3;gZz%uywOV5X35-bpc$&WCg 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/rotten_pufferfish.png b/src/main/resources/assets/unicopia/textures/item/rotten_pufferfish.png new file mode 100644 index 0000000000000000000000000000000000000000..24ade9a54c2cdf2b865d97718727ba77f2611cd3 GIT binary patch literal 6927 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 WUl_}qLl%Y2O literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/rotten_salmon.png b/src/main/resources/assets/unicopia/textures/item/rotten_salmon.png new file mode 100644 index 0000000000000000000000000000000000000000..fc4d53c097708b72ca81d1d05f7fcac6a97cb451 GIT binary patch literal 6986 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 Q{MQD#Y>M>Y`1x7?0B_61KmY&$ literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/rotten_tropical_fish.png b/src/main/resources/assets/unicopia/textures/item/rotten_tropical_fish.png new file mode 100644 index 0000000000000000000000000000000000000000..7c0354025831fcac81c4f6ff32566feb81a16d94 GIT binary patch literal 6649 zcmeHLd0Z3M7M>6wVN-!<0TE+x32OEPl1O9?5)~u}0#>V&WCBqjAqf(21Kjh}y3_@W zwFb0k)mGHDin~xZ+{J1u&lRG*yr!{+28B?%aAj3=H7F^bG~!Wy_w6r zq{Ja!?g8!yf_TZ|W0T?D1sAd_TzfulLlK1h9hNRr%Vhl#GPHpu!5Ja6+YuaeCjt>6 zLi=nGAJB0dTmlF#*86aRQw~a6-J`UJk+qodWlbAeuQgUwc764MMj5 z#e;?;+wVhU2}x8glf!26LSa0c%NMiZE1+^h#aw|{zyWK*=dUAzp@plkA(*4{jYzSPaV+XsIB0e$-Rqlfh83qr$$B5_QtG;T<|Z0N|8)KO{a z8KaddOr4pfnP4#HPbx4K7R{JBYxbPE^UO<@ezI)&ij`%nEESdO)_+m8VPo~S?K{5t z_Pd?C4j!tl`~L8eqsPvkJKu2Ohl`hfymtM@&8Azo@BDoC;iJb-o<4j2%ZrydFPx|S zV`KIQUf#gV$=R9cOu~5)oC7P6OAEdLwVjj?RDv53} zBe?tkkHxAKxl|o|@Q%g&YTI#lx~2HfL}E76zgi)QZlK6BN=BLKn~|0(i}{7YPy%pw zJw2YtrG<4tJ*1Sh%b&%|r4+V|+ogpxbZZU^9J_tNM(z>(3?UA(U$Yz)b$p z+LLmNxxYs+?)x(h7*+)*n(14j=K_(-Ll%PhQ_^yZT#DFba#xCc9J8ndCsqYG^=kbS zNK|H|qxa1Kq$#_>mrEyShMWeFvRE)0Zwwj)9p{769c|k)*^O>7*J4F<%QxP4QsmOS zxqGCP)I}8VYz>eD@jPCT_z`5mSl@KVV!kJm!HC7>UO?i-5!}vE9HRthX*09zy%Qnk zBlZ9Y`*DJ%t9Fs{YDf6#_qvt0hVFnNfAvQwu3tj^ce4dWNx!X|x1KL3mU^~IUy?kRF;yBjW!oob0K(@O_{);v zsck98>xA$YA?4$yj`r}35+`8P~ zc7N&)>uSt>ZWdGq)oxHDrHqm;tFoA@qwRrCxe11Ux;6Y2n~1hcyMKRL0zXJIH8C+s zvX~gEPOnvKvM~fPl}}wPi9Zw>ST}B8Qe|>&Ct4@}jm$}M@57^K(Nf4eqQC6acg3`* zrL%k2)yZ`X;V)a$^L2R_8V;m(agK;A?@>+}TUp!IXI3{(P~h_$je8C^4%&ZZ6Su*$ zFOs@#{_y@GHy?c&eQH1{xmPJ+{;>MQ?Kv zzI(Tat`FRyA2W8YJil2H`M4n=vo^bKm^Q}4G zCKm7K>DJ}{x}z`qm8__uqHbaFkx*S;9LVTi7CpWiAs@*7BSd8+$08o9L$JPO*z@Q2C+#(v*LFK>ji`x{YY4_6Y#6baL8;g1j2dk&6~{ys+I*vgMuUE;J-!@WLP7_8uAw~( zkPns#)v-8CHY+EG8hXQb>25>Neg3lLlISd|8BxLaUTpw6ip5`(um^O zgY~@<)lK5Xe?^P0JP)0m0~|{4PbM`?2f#P6SOLgy714e@x?<8w@rDx#sK~c ztxdKSH4@9SJ=q?!HP)p>rCJw-7**OR7|=EbgC2;$+33jtYG?gxz|qbxy6y5sE9*`N25 z_uYkXn%*LdjY<(7-@KGFqI(o&=Drnmxg5f_P!I6J#2gNz@5U_9`bXQM?apM zMO#-{aeN%RYYIPi;5ssMYctK9U+$CcW4JB6*1G;;ts@ACreHe7feh6&r6gk3;(3nKhwe*Ua08zUXTleSyqVA86}VWv(e5x#-EX`YMI2ddHr` zgI|BWn!9?rGP?1oBHs}sUo-IUtN+=sDq@@S=>%an_4^$W^;W*p$R3_fOZuNma8 zJ~8)eEe=z5(&= Date: Fri, 5 Apr 2024 18:33:24 +0100 Subject: [PATCH 73/73] Move recipes to their own package --- .../unicopia/ability/EarthPonyGrowAbility.java | 4 ++-- .../ability/magic/spell/crafting/SpellCraftingRecipe.java | 2 +- .../ability/magic/spell/crafting/SpellDuplicatingRecipe.java | 1 + .../ability/magic/spell/crafting/SpellEnhancingRecipe.java | 1 + .../magic/spell/crafting/SpellShapedCraftingRecipe.java | 2 +- .../ability/magic/spell/crafting/SpellbookRecipe.java | 2 +- .../client/gui/spellbook/SpellbookCraftingPageContent.java | 2 +- .../java/com/minelittlepony/unicopia/compat/emi/Main.java | 4 ++-- .../unicopia/container/ShapingBenchScreenHandler.java | 2 +- .../unicopia/container/SpellbookScreenHandler.java | 2 +- .../unicopia/datagen/providers/UAdvancementsProvider.java | 1 + .../datagen/providers/recipe/CraftingMaterialHelper.java | 2 +- .../datagen/providers/recipe/GrowingRecipeJsonBuilder.java | 2 +- .../providers/recipe/SpellcraftingRecipeJsonBuilder.java | 3 ++- .../providers/recipe/TrickCraftingRecipeJsonBuilder.java | 2 +- .../unicopia/datagen/providers/recipe/URecipeProvider.java | 2 +- .../unicopia/datagen/providers/tag/UItemTagProvider.java | 3 +-- src/main/java/com/minelittlepony/unicopia/item/UItems.java | 1 + .../unicopia/{item/cloud => recipe}/CloudShapingRecipe.java | 3 +-- .../unicopia/{item => recipe}/GlowingRecipe.java | 4 +++- .../unicopia/{item => recipe}/ItemCombinationRecipe.java | 2 +- .../unicopia/{item => recipe}/JarExtractRecipe.java | 4 +++- .../unicopia/{item => recipe}/JarInsertRecipe.java | 5 ++++- .../unicopia/{item => recipe}/TransformCropsRecipe.java | 2 +- .../minelittlepony/unicopia/{item => recipe}/URecipes.java | 3 +-- .../unicopia/{item => recipe}/ZapAppleRecipe.java | 3 ++- 26 files changed, 37 insertions(+), 27 deletions(-) rename src/main/java/com/minelittlepony/unicopia/{item/cloud => recipe}/CloudShapingRecipe.java (90%) rename src/main/java/com/minelittlepony/unicopia/{item => recipe}/GlowingRecipe.java (93%) rename src/main/java/com/minelittlepony/unicopia/{item => recipe}/ItemCombinationRecipe.java (97%) rename src/main/java/com/minelittlepony/unicopia/{item => recipe}/JarExtractRecipe.java (94%) rename src/main/java/com/minelittlepony/unicopia/{item => recipe}/JarInsertRecipe.java (91%) rename src/main/java/com/minelittlepony/unicopia/{item => recipe}/TransformCropsRecipe.java (99%) rename src/main/java/com/minelittlepony/unicopia/{item => recipe}/URecipes.java (97%) rename src/main/java/com/minelittlepony/unicopia/{item => recipe}/ZapAppleRecipe.java (96%) diff --git a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java index 75cd435f..0454681e 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/EarthPonyGrowAbility.java @@ -10,10 +10,10 @@ import com.minelittlepony.unicopia.ability.data.Hit; import com.minelittlepony.unicopia.ability.data.Pos; import com.minelittlepony.unicopia.block.UBlocks; import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.item.TransformCropsRecipe; -import com.minelittlepony.unicopia.item.URecipes; import com.minelittlepony.unicopia.particle.MagicParticleEffect; import com.minelittlepony.unicopia.particle.ParticleUtils; +import com.minelittlepony.unicopia.recipe.TransformCropsRecipe; +import com.minelittlepony.unicopia.recipe.URecipes; import com.minelittlepony.unicopia.server.world.BlockDestructionManager; import com.minelittlepony.unicopia.util.TraceHelper; import com.minelittlepony.unicopia.util.VecHelper; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellCraftingRecipe.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellCraftingRecipe.java index 99528460..3badf6d4 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellCraftingRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellCraftingRecipe.java @@ -9,7 +9,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.container.inventory.SpellbookInventory; import com.minelittlepony.unicopia.item.EnchantableItem; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; import com.minelittlepony.unicopia.util.InventoryUtil; import com.mojang.datafixers.util.Pair; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellDuplicatingRecipe.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellDuplicatingRecipe.java index 0b29c917..8d228a2c 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellDuplicatingRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellDuplicatingRecipe.java @@ -4,6 +4,7 @@ import com.google.gson.JsonObject; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.container.inventory.SpellbookInventory; import com.minelittlepony.unicopia.item.*; +import com.minelittlepony.unicopia.recipe.URecipes; import com.minelittlepony.unicopia.util.InventoryUtil; import net.minecraft.item.ItemStack; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellEnhancingRecipe.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellEnhancingRecipe.java index 7aebd7e5..d63a2e86 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellEnhancingRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellEnhancingRecipe.java @@ -4,6 +4,7 @@ import com.google.gson.JsonObject; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.container.inventory.SpellbookInventory; import com.minelittlepony.unicopia.item.*; +import com.minelittlepony.unicopia.recipe.URecipes; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellShapedCraftingRecipe.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellShapedCraftingRecipe.java index cc0dcc0f..e07e1ab3 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellShapedCraftingRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellShapedCraftingRecipe.java @@ -2,7 +2,7 @@ package com.minelittlepony.unicopia.ability.magic.spell.crafting; import com.google.gson.JsonObject; import com.minelittlepony.unicopia.item.EnchantableItem; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; import com.minelittlepony.unicopia.util.InventoryUtil; import net.minecraft.inventory.RecipeInputInventory; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellbookRecipe.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellbookRecipe.java index 89043ce8..49b781aa 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellbookRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/crafting/SpellbookRecipe.java @@ -5,7 +5,7 @@ import java.util.List; import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.container.inventory.SpellbookInventory; import com.minelittlepony.unicopia.item.UItems; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; import net.minecraft.item.ItemStack; import net.minecraft.recipe.Recipe; diff --git a/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookCraftingPageContent.java b/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookCraftingPageContent.java index 6350bc98..a6fde947 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookCraftingPageContent.java +++ b/src/main/java/com/minelittlepony/unicopia/client/gui/spellbook/SpellbookCraftingPageContent.java @@ -7,7 +7,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.crafting.SpellbookRecipe; import com.minelittlepony.unicopia.client.gui.DrawableUtil; import com.minelittlepony.unicopia.client.gui.MagicText; import com.minelittlepony.unicopia.container.SpellbookState; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.gui.DrawContext; diff --git a/src/main/java/com/minelittlepony/unicopia/compat/emi/Main.java b/src/main/java/com/minelittlepony/unicopia/compat/emi/Main.java index 9523cce2..4924981f 100644 --- a/src/main/java/com/minelittlepony/unicopia/compat/emi/Main.java +++ b/src/main/java/com/minelittlepony/unicopia/compat/emi/Main.java @@ -15,10 +15,10 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.block.UBlocks; import com.minelittlepony.unicopia.block.state.Schematic; import com.minelittlepony.unicopia.item.EnchantableItem; -import com.minelittlepony.unicopia.item.TransformCropsRecipe; import com.minelittlepony.unicopia.item.UItems; -import com.minelittlepony.unicopia.item.URecipes; import com.minelittlepony.unicopia.item.group.MultiItem; +import com.minelittlepony.unicopia.recipe.TransformCropsRecipe; +import com.minelittlepony.unicopia.recipe.URecipes; import dev.emi.emi.api.EmiPlugin; import dev.emi.emi.api.EmiRegistry; diff --git a/src/main/java/com/minelittlepony/unicopia/container/ShapingBenchScreenHandler.java b/src/main/java/com/minelittlepony/unicopia/container/ShapingBenchScreenHandler.java index 3ff1ac4a..2758a373 100644 --- a/src/main/java/com/minelittlepony/unicopia/container/ShapingBenchScreenHandler.java +++ b/src/main/java/com/minelittlepony/unicopia/container/ShapingBenchScreenHandler.java @@ -1,7 +1,7 @@ package com.minelittlepony.unicopia.container; import com.minelittlepony.unicopia.block.UBlocks; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; diff --git a/src/main/java/com/minelittlepony/unicopia/container/SpellbookScreenHandler.java b/src/main/java/com/minelittlepony/unicopia/container/SpellbookScreenHandler.java index 5f675f85..47a088f1 100644 --- a/src/main/java/com/minelittlepony/unicopia/container/SpellbookScreenHandler.java +++ b/src/main/java/com/minelittlepony/unicopia/container/SpellbookScreenHandler.java @@ -10,7 +10,7 @@ import com.minelittlepony.unicopia.compat.trinkets.TrinketsDelegate; import com.minelittlepony.unicopia.container.inventory.*; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.item.UItems; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; import com.mojang.datafixers.util.Pair; import net.minecraft.enchantment.EnchantmentHelper; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java index a540572c..de390bfb 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/UAdvancementsProvider.java @@ -146,6 +146,7 @@ public class UAdvancementsProvider extends FabricAdvancementProvider { private void generateUnicornTribeAdvancementsTree(Consumer consumer, AdvancementDisplayBuilder.Parent parent) { parent.child(UItems.SPELLBOOK).criterion("has_spellbook", hasItems(UItems.SPELLBOOK)).build(consumer, "books").children(p -> { + // TODO: //ItemPredicate bookPredicate = ItemPredicate.Builder.create().tag(ItemTags.BOOKSHELF_BOOKS).build(); //p.child(Items.BOOK).hidden().frame(AdvancementFrame.CHALLENGE).criterion("has_books", InventoryChangedCriterion.Conditions.items(IntStream.range(0, 9 * 4).mapToObj(i -> bookPredicate).toArray(ItemPredicate[]::new))).build(consumer, "books_books_books"); p.child(UItems.CRYSTAL_SHARD).criterion("has_shard", hasItems(UItems.CRYSTAL_SHARD)).build(consumer, "crystaline").children(pp -> { diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/CraftingMaterialHelper.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/CraftingMaterialHelper.java index 25118dd3..a32f4245 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/CraftingMaterialHelper.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/CraftingMaterialHelper.java @@ -4,7 +4,7 @@ import java.util.Map; import java.util.NoSuchElementException; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; import com.mojang.datafixers.util.Either; import net.fabricmc.fabric.api.tag.convention.v1.ConventionalItemTags; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java index 1daab591..53d44888 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java @@ -7,7 +7,7 @@ import org.jetbrains.annotations.Nullable; import org.spongepowered.include.com.google.common.base.Preconditions; import com.google.gson.JsonObject; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; import com.mojang.serialization.JsonOps; import net.minecraft.advancement.Advancement; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java index ca8d7b58..c8ddf638 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java @@ -15,7 +15,8 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; import com.minelittlepony.unicopia.advancement.TraitDiscoveredCriterion; import com.minelittlepony.unicopia.item.UItems; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; + import net.minecraft.advancement.Advancement; import net.minecraft.advancement.AdvancementRewards; import net.minecraft.advancement.CriterionMerger; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java index 22868e0c..ccccdc12 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java @@ -8,7 +8,7 @@ import org.spongepowered.include.com.google.common.base.Preconditions; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; import net.minecraft.advancement.Advancement; import net.minecraft.advancement.AdvancementRewards; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index aad4a126..0597b525 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -17,7 +17,7 @@ import com.minelittlepony.unicopia.datagen.ItemFamilies; import com.minelittlepony.unicopia.datagen.UBlockFamilies; import com.minelittlepony.unicopia.datagen.providers.recipe.BedSheetPatternRecipeBuilder.PatternTemplate; import com.minelittlepony.unicopia.item.UItems; -import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.recipe.URecipes; import com.minelittlepony.unicopia.server.world.UTreeGen; import com.mojang.datafixers.util.Either; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java index 922e19fa..42365d56 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/tag/UItemTagProvider.java @@ -228,9 +228,8 @@ public class UItemTagProvider extends FabricTagProvider.ItemTagProvider { .addOptionalTag(new Identifier("c", "raw_pork")) .addOptionalTag(new Identifier("c", "lemon_chickens")); getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_MEAT).add(Items.ROTTEN_FLESH); - getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_FISH);//.add(Items.ROTTEN_FLESH); TODO: getOrCreateTagBuilder(UConventionalTags.Items.ROTTEN_INSECT).add(Items.FERMENTED_SPIDER_EYE); - getOrCreateTagBuilder(UConventionalTags.Items.COOKED_INSECT);//.add(Items.FERMENTED_SPIDER_EYE); + getOrCreateTagBuilder(UConventionalTags.Items.COOKED_INSECT);//.add(Items.FERMENTED_SPIDER_EYE); TODO getOrCreateTagBuilder(UConventionalTags.Items.RAW_INSECT).add(Items.SPIDER_EYE, UItems.BUTTERFLY, UItems.WHEAT_WORMS, UBlocks.WORM_BLOCK.asItem()); getOrCreateTagBuilder(UConventionalTags.Items.WORMS).add(UItems.WHEAT_WORMS); getOrCreateTagBuilder(UConventionalTags.Items.STICKS).add(Items.STICK); diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 894b6d2d..5e69e0d6 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -12,6 +12,7 @@ import com.minelittlepony.unicopia.item.cloud.CloudBedItem; import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.item.group.ItemGroupRegistry; import com.minelittlepony.unicopia.item.group.UItemGroups; +import com.minelittlepony.unicopia.recipe.URecipes; import com.terraformersmc.terraform.boat.api.TerraformBoatType; import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry; import com.terraformersmc.terraform.boat.api.item.TerraformBoatItemHelper; diff --git a/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudShapingRecipe.java b/src/main/java/com/minelittlepony/unicopia/recipe/CloudShapingRecipe.java similarity index 90% rename from src/main/java/com/minelittlepony/unicopia/item/cloud/CloudShapingRecipe.java rename to src/main/java/com/minelittlepony/unicopia/recipe/CloudShapingRecipe.java index 4f12f7db..063130fd 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudShapingRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/recipe/CloudShapingRecipe.java @@ -1,7 +1,6 @@ -package com.minelittlepony.unicopia.item.cloud; +package com.minelittlepony.unicopia.recipe; import com.minelittlepony.unicopia.block.UBlocks; -import com.minelittlepony.unicopia.item.URecipes; import net.minecraft.item.ItemStack; import net.minecraft.recipe.Ingredient; diff --git a/src/main/java/com/minelittlepony/unicopia/item/GlowingRecipe.java b/src/main/java/com/minelittlepony/unicopia/recipe/GlowingRecipe.java similarity index 93% rename from src/main/java/com/minelittlepony/unicopia/item/GlowingRecipe.java rename to src/main/java/com/minelittlepony/unicopia/recipe/GlowingRecipe.java index 663dd8a5..32fdfc37 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/GlowingRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/recipe/GlowingRecipe.java @@ -1,4 +1,6 @@ -package com.minelittlepony.unicopia.item; +package com.minelittlepony.unicopia.recipe; + +import com.minelittlepony.unicopia.item.GlowableItem; import net.minecraft.inventory.RecipeInputInventory; import net.minecraft.item.ItemStack; diff --git a/src/main/java/com/minelittlepony/unicopia/item/ItemCombinationRecipe.java b/src/main/java/com/minelittlepony/unicopia/recipe/ItemCombinationRecipe.java similarity index 97% rename from src/main/java/com/minelittlepony/unicopia/item/ItemCombinationRecipe.java rename to src/main/java/com/minelittlepony/unicopia/recipe/ItemCombinationRecipe.java index ccdaa038..7a3b998e 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ItemCombinationRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/recipe/ItemCombinationRecipe.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.item; +package com.minelittlepony.unicopia.recipe; import net.minecraft.inventory.RecipeInputInventory; import net.minecraft.item.ItemStack; diff --git a/src/main/java/com/minelittlepony/unicopia/item/JarExtractRecipe.java b/src/main/java/com/minelittlepony/unicopia/recipe/JarExtractRecipe.java similarity index 94% rename from src/main/java/com/minelittlepony/unicopia/item/JarExtractRecipe.java rename to src/main/java/com/minelittlepony/unicopia/recipe/JarExtractRecipe.java index b480d05e..5d28fd91 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/JarExtractRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/recipe/JarExtractRecipe.java @@ -1,7 +1,9 @@ -package com.minelittlepony.unicopia.item; +package com.minelittlepony.unicopia.recipe; import org.jetbrains.annotations.Nullable; +import com.minelittlepony.unicopia.item.UItems; + import net.minecraft.inventory.RecipeInputInventory; import net.minecraft.item.ItemStack; import net.minecraft.recipe.RecipeSerializer; diff --git a/src/main/java/com/minelittlepony/unicopia/item/JarInsertRecipe.java b/src/main/java/com/minelittlepony/unicopia/recipe/JarInsertRecipe.java similarity index 91% rename from src/main/java/com/minelittlepony/unicopia/item/JarInsertRecipe.java rename to src/main/java/com/minelittlepony/unicopia/recipe/JarInsertRecipe.java index 776a8bc3..694c347a 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/JarInsertRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/recipe/JarInsertRecipe.java @@ -1,4 +1,7 @@ -package com.minelittlepony.unicopia.item; +package com.minelittlepony.unicopia.recipe; + +import com.minelittlepony.unicopia.item.EmptyJarItem; +import com.minelittlepony.unicopia.item.UItems; import net.minecraft.inventory.RecipeInputInventory; import net.minecraft.item.ItemStack; diff --git a/src/main/java/com/minelittlepony/unicopia/item/TransformCropsRecipe.java b/src/main/java/com/minelittlepony/unicopia/recipe/TransformCropsRecipe.java similarity index 99% rename from src/main/java/com/minelittlepony/unicopia/item/TransformCropsRecipe.java rename to src/main/java/com/minelittlepony/unicopia/recipe/TransformCropsRecipe.java index edc9924a..1d914706 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/TransformCropsRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/recipe/TransformCropsRecipe.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.item; +package com.minelittlepony.unicopia.recipe; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/com/minelittlepony/unicopia/item/URecipes.java b/src/main/java/com/minelittlepony/unicopia/recipe/URecipes.java similarity index 97% rename from src/main/java/com/minelittlepony/unicopia/item/URecipes.java rename to src/main/java/com/minelittlepony/unicopia/recipe/URecipes.java index 52aff325..d45af14c 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/URecipes.java +++ b/src/main/java/com/minelittlepony/unicopia/recipe/URecipes.java @@ -1,10 +1,9 @@ -package com.minelittlepony.unicopia.item; +package com.minelittlepony.unicopia.recipe; import java.util.List; import com.google.gson.JsonArray; import com.minelittlepony.unicopia.ability.magic.spell.crafting.*; -import com.minelittlepony.unicopia.item.cloud.CloudShapingRecipe; import net.fabricmc.fabric.api.loot.v2.LootTableEvents; import net.minecraft.loot.LootTable; diff --git a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleRecipe.java b/src/main/java/com/minelittlepony/unicopia/recipe/ZapAppleRecipe.java similarity index 96% rename from src/main/java/com/minelittlepony/unicopia/item/ZapAppleRecipe.java rename to src/main/java/com/minelittlepony/unicopia/recipe/ZapAppleRecipe.java index 82c1d162..a92b956a 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ZapAppleRecipe.java +++ b/src/main/java/com/minelittlepony/unicopia/recipe/ZapAppleRecipe.java @@ -1,8 +1,9 @@ -package com.minelittlepony.unicopia.item; +package com.minelittlepony.unicopia.recipe; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonSyntaxException; +import com.minelittlepony.unicopia.item.UItems; import net.minecraft.item.ItemStack; import net.minecraft.network.PacketByteBuf;