From c59b9366f6337ef19a2d5741ba6684e35fed0702 Mon Sep 17 00:00:00 2001 From: Sollace <sollacea@gmail.com> Date: Sun, 24 Mar 2024 22:08:11 +0000 Subject: [PATCH 01/14] 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<Advancement> 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 <sollacea@gmail.com> Date: Sun, 24 Mar 2024 23:06:26 +0000 Subject: [PATCH 02/14] 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<Advancement> 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<Advancement> 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 <sollacea@gmail.com> Date: Mon, 25 Mar 2024 00:41:10 +0000 Subject: [PATCH 03/14] 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<Direction, VoxelShape> 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 <sollacea@gmail.com> Date: Mon, 25 Mar 2024 00:41:42 +0000 Subject: [PATCH 04/14] 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<Direction.Axis> AXIS = Properties.AXIS; + private static final BooleanProperty TOP = Properties.NORTH; + private static final BooleanProperty BOTTOM = Properties.SOUTH; private static final Map<Direction, BooleanProperty> 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<Direction.Axis, VoxelShape[]> 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<Block, BlockState> 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 <sollacea@gmail.com> Date: Mon, 25 Mar 2024 18:06:50 +0000 Subject: [PATCH 05/14] 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<Advancement> 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 <sollacea@gmail.com> Date: Mon, 25 Mar 2024 18:08:40 +0000 Subject: [PATCH 06/14] 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<? extends HostileEntity> 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<T extends LivingEntity> extends ActiveTargetGoal<T> { + public TargetGoal(SpecterEntity specter, Class<T> 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<ButterflyEntity> BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.create(SpawnGroup.AMBIENT, ButterflyEntity::new) @@ -74,6 +76,11 @@ public interface UEntities { EntityType<IgnominiousBulbEntity> IGNOMINIOUS_BULB = register("ignominious_bulb", FabricEntityTypeBuilder.<IgnominiousBulbEntity>create(SpawnGroup.MISC, IgnominiousBulbEntity::new) .trackRangeChunks(8) .dimensions(EntityDimensions.fixed(3, 2))); + EntityType<SpecterEntity> 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 <T extends Entity> EntityType<T> register(String name, FabricEntityTypeBuilder<T> builder) { EntityType<T> 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<BiomeSelectionContext> 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<FootprintParticleEffect> FACTORY = ParticleFactoryHelper.of(FootprintParticleEffect::new, FootprintParticleEffect::new); + + protected FootprintParticleEffect(ParticleType<FootprintParticleEffect> type, StringReader reader) throws CommandSyntaxException { + this(ParticleFactoryHelper.readFloat(reader)); + } + + protected FootprintParticleEffect(ParticleType<FootprintParticleEffect> 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<MagicParticleEffect> UNICORN_MAGIC = register("unicorn_magic", FabricParticleTypes.complex(MagicParticleEffect.FACTORY)); DefaultParticleType CHANGELING_MAGIC = register("changeling_magic", FabricParticleTypes.simple()); DefaultParticleType BUBBLE = register("bubble", FabricParticleTypes.simple()); + ParticleType<FootprintParticleEffect> FOOTPRINT = register("footprint", FabricParticleTypes.complex(FootprintParticleEffect.FACTORY)); ParticleType<BlockStateParticleEffect> DUST_CLOUD = register("dust_cloud", FabricParticleTypes.complex(BlockStateParticleEffect.PARAMETERS_FACTORY)); ParticleType<OrientedBillboardParticleEffect> RAINBOOM_RING = register("rainboom_ring", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY)); ParticleType<TargetBoundParticleEffect> RAINBOOM_TRAIL = register("rainboom_trail", FabricParticleTypes.complex(TargetBoundParticleEffect.FACTORY)); - @Deprecated - ParticleType<OrientedBillboardParticleEffect> MAGIC_RUNES = register("magic_runes", FabricParticleTypes.complex(OrientedBillboardParticleEffect.FACTORY)); - DefaultParticleType RAIN_DROPS = register("rain_drops", FabricParticleTypes.simple()); ParticleType<SphereParticleEffect> 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 <sollacea@gmail.com> Date: Mon, 25 Mar 2024 18:09:16 +0000 Subject: [PATCH 07/14] 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<? extends ButterflyEntity> 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<ButterflyEntity> BUTTERFLY = register("butterfly", FabricEntityTypeBuilder.create(SpawnGroup.AMBIENT, ButterflyEntity::new) + EntityType<ButterflyEntity> 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<MagicProjectileEntity> THROWN_ITEM = register("thrown_item", FabricEntityTypeBuilder.<MagicProjectileEntity>create(SpawnGroup.MISC, MagicProjectileEntity::new) .trackRangeBlocks(100) From 2ac6970e04a2360c60b0a8eb3a14c3d65435075c Mon Sep 17 00:00:00 2001 From: Sollace <sollacea@gmail.com> Date: Mon, 25 Mar 2024 18:09:48 +0000 Subject: [PATCH 08/14] 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 extends Block> 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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 F{sHtDu_^!n literal 0 HcmV?d00001 diff --git a/src/main/resources/data/c/tags/items/raw_insects.json b/src/main/resources/data/c/tags/items/raw_insects.json index 4a791552..ad219e8b 100644 --- a/src/main/resources/data/c/tags/items/raw_insects.json +++ b/src/main/resources/data/c/tags/items/raw_insects.json @@ -2,7 +2,8 @@ "replace": false, "values": [ "minecraft:spider_eye", + "unicopia:butterfly", "unicopia:wheat_worms", - "unicopia:butterfly" + "unicopia:worm_block" ] } From 380c35fcc6b2d66cd957842cf39a789eb3c00d85 Mon Sep 17 00:00:00 2001 From: Sollace <sollacea@gmail.com> Date: Mon, 25 Mar 2024 18:10:12 +0000 Subject: [PATCH 09/14] 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<Composite> 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 <sollacea@gmail.com> Date: Mon, 25 Mar 2024 18:11:31 +0000 Subject: [PATCH 10/14] 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 <sollacea@gmail.com> Date: Mon, 25 Mar 2024 18:11:50 +0000 Subject: [PATCH 11/14] 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<Text> 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 <sollacea@gmail.com> Date: Mon, 25 Mar 2024 19:13:56 +0000 Subject: [PATCH 12/14] 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 <sollacea@gmail.com> Date: Mon, 25 Mar 2024 19:57:21 +0000 Subject: [PATCH 13/14] #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 <sollacea@gmail.com> Date: Tue, 26 Mar 2024 00:04:00 +0000 Subject: [PATCH 14/14] 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<T extends Entity> implements Physics, Copyable<Entity @Override public void tick() { if (isGravityNegative()) { + if (isGravityNegative() && !entity.isSneaking() && entity.isInSneakingPose()) { + float currentHeight = entity.getDimensions(entity.getPose()).height; + float sneakingHeight = entity.getDimensions(EntityPose.STANDING).height; + + entity.move(MovementType.SELF, new Vec3d(0, -(currentHeight - sneakingHeight), 0)); + entity.setPose(EntityPose.STANDING); + } + if (entity.getY() > 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<PlayerEntity> 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<PlayerEntity> 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<C get().initAi(goalSelector, targetSelector); } - @Inject(method = "tickNewAi", at = @At("HEAD")) - public void beforeTickAi(CallbackInfo into) { - if (get().getPhysics().isGravityNegative()) { - ((RotatedView)getWorld()).pushRotation((int)getY()); - } - } - - @Inject(method = "tickNewAi", at = @At("RETURN")) - public void afterTickAi(CallbackInfo into) { - ((RotatedView)getWorld()).popRotation(); - } - @Inject(method = "prefersNewEquipment(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemStack;)Z", at = @At("HEAD"), cancellable = true) private void onPrefersNewEquipment(ItemStack newStack, ItemStack oldStack, CallbackInfoReturnable<Boolean> 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<EntityDimensions> 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<BlockDestructionManager> destructions = BlockDestructionManager.create((World)(Object)this); - private int recurseCount = 0; - private final Stack<Integer> rotations = new Stack<>(); private boolean mirrorEntityStatuses; - @Override - public Stack<Integer> 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<Boolean> 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<E extends LivingEntity> { 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<Float> 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<Living<?>> { + + 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<Creature> { + 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<Integer> rotations = new Stack<>(); + + @Override + public Stack<Integer> 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<Boolean> 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