diff --git a/build.gradle b/build.gradle index a203b1be0..f679a558d 100644 --- a/build.gradle +++ b/build.gradle @@ -53,6 +53,7 @@ minecraft { workingDirectory project.file('run') arg '-mixin.config=create.mixins.json' //jvmArgs '-XX:+UnlockCommercialFeatures' // uncomment for profiling + //jvmArgs '-XX:+IgnoreUnrecognizedVMOptions', '-XX:+AllowEnhancedClassRedefinition' // uncomment with jbr property 'forge.logging.console.level', 'info' mods { create { @@ -204,8 +205,18 @@ dependencies { // runtimeOnly fg.deobf("maven.modrinth:rubidium:0.5.3") // implementation fg.deobf("com.railwayteam.railways:railways-1.18.2-1.1.1:all") { transitive = false } // runtimeOnly fg.deobf("maven.modrinth:spark:1.10.38-forge") - //runtimeOnly fg.deobf("curse.maven:forbidden-arcanus-309858:4729924") - //runtimeOnly fg.deobf("curse.maven:valhelsia-core-416935:3886212") + // runtimeOnly fg.deobf("curse.maven:forbidden-arcanus-309858:4729924") + // runtimeOnly fg.deobf("curse.maven:valhelsia-core-416935:3886212") + // implementation fg.deobf("curse.maven:modern-ui-352491:5229350") + // runtimeOnly fg.deobf("curse.maven:sophisticated-storage-619320:5194748") + // runtimeOnly fg.deobf("curse.maven:sophisticated-core-618298:5296312") + // runtimeOnly fg.deobf("curse.maven:functional-storage-556861:5271589") + // runtimeOnly fg.deobf("curse.maven:titanium-287342:5151207") + // runtimeOnly fg.deobf("curse.maven:storage-drawers-223852:3807626") + // implementation fg.deobf("curse.maven:ftb-chunks-forge-314906:4494633") + // implementation fg.deobf("curse.maven:architectury-api-419699:4521465") + // implementation fg.deobf("curse.maven:ftb-library-forge-404465:4396792") + // implementation fg.deobf("curse.maven:ftb-teams-forge-404468:4579981") // https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497 // Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 1f49b621b..5bf7609d5 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -3329,7 +3329,7 @@ c2b075008849e152f20e8da946e89c9722325df6 data/create/loot_tables/blocks/content_ 69b4b25d7d271458177fbbaeba2c797daccc38a2 data/create/loot_tables/blocks/contraption_controls.json 28856dc862efc6bcc421d035d26386740458f868 data/create/loot_tables/blocks/controller_rail.json 2c2785e39e1891dff2c50cba93e814b56d935154 data/create/loot_tables/blocks/controls.json -3abf04f6132955275ad490668cd28f481afb4ec2 data/create/loot_tables/blocks/copper_backtank.json +ac15351000c44cf0924e8e3b3c6d92e3d54bb084 data/create/loot_tables/blocks/copper_backtank.json 6697e619d5c6dcb81aad4f5c88ba319d13665b35 data/create/loot_tables/blocks/copper_bars.json 8010db6b2427536c74312c85425b3ba83abc363c data/create/loot_tables/blocks/copper_casing.json ea5fb942c8dfb792daac538e09d286ac120aa199 data/create/loot_tables/blocks/copper_door.json @@ -3590,7 +3590,7 @@ afdff197c9d1a6940e988c00435135f9705fd0e5 data/create/loot_tables/blocks/metal_gi b83a90fbe83906b171fc0de6bdc2d9aa3a8c542e data/create/loot_tables/blocks/millstone.json 5c1df8443043b3fe3b665dba348e2ff188bcbe31 data/create/loot_tables/blocks/minecart_anchor.json 1e73d28fdd2e54910074aeadbe5617425a8ae656 data/create/loot_tables/blocks/mysterious_cuckoo_clock.json -a5fa8fdc10efe534e5c7d8bdb687f226b39f63ef data/create/loot_tables/blocks/netherite_backtank.json +188de41337119f55117c48eeb8d31cdf12cebd76 data/create/loot_tables/blocks/netherite_backtank.json 2e21a06c0d671e543bffecb0b67d97b51fa83ddc data/create/loot_tables/blocks/nixie_tube.json f6b4095a518a01081f3663d7268d67063bdb44ee data/create/loot_tables/blocks/nozzle.json d378be8f13fc7ed625813eae3a50b68e8706a297 data/create/loot_tables/blocks/oak_window.json @@ -4251,7 +4251,7 @@ fe6620822b1c90527c6b77ab6f6e25873d19487c data/create/recipes/crushing/compat/the 2670e2454e82fd7dc44e896e40771bce9c515285 data/create/recipes/crushing/copper_ore.json 4106006671af487158d165c8211553028585ebb3 data/create/recipes/crushing/crimsite.json b2ba06eb5bcc907f16e4605fc53f31aa35bc2cfd data/create/recipes/crushing/crimsite_recycling.json -c0f2d4de4d00504607a8f3e2d1327d754835eebe data/create/recipes/crushing/deepslate_coal_ore.json +57a02cc2631a232a6bad5e772b622983087ecb18 data/create/recipes/crushing/deepslate_coal_ore.json 81ae6cf7b0f7dbf8f4966a4670121919de7b5391 data/create/recipes/crushing/deepslate_copper_ore.json 2f9f26daadda2d291989bccd2b0ea5f85e3ef5ae data/create/recipes/crushing/deepslate_diamond_ore.json ae3070fc3ae237192949ad06ebb8a4c157f7e832 data/create/recipes/crushing/deepslate_emerald_ore.json @@ -4265,6 +4265,7 @@ c42d105c8567c0844fcd811349093c2d754ea7d0 data/create/recipes/crushing/diamond_or f2b1c52cde3ecd83f021eff5114375e2f6526d90 data/create/recipes/crushing/diorite.json 38e958ba2e12daeed2fb0bc65a9ab9e04c98b816 data/create/recipes/crushing/diorite_recycling.json 1327589e844cb587a02167e4428fd604350d60e1 data/create/recipes/crushing/emerald_ore.json +23623c1aa357e96b791019d64bdaf0124652baaf data/create/recipes/crushing/gilded_blackstone.json b26b1f0dccf2ffb194ce12173890a83e93369b39 data/create/recipes/crushing/glowstone.json 159ac6c38b0232fa9bf3ed5e7ea8e23854c96f22 data/create/recipes/crushing/gold_ore.json 55c0656723bd5a87089965651fe268b2d2956771 data/create/recipes/crushing/golden_horse_armor.json @@ -5012,7 +5013,7 @@ e6aa8895186358e9d069f5a99909132be49f3bf1 data/create/recipes/diorite_from_stone_ a90268d38f976327ff5e1b87ff1d72ca2d1ebad6 data/create/recipes/dripstone_block_from_stone_types_dripstone_stonecutting.json 27d9bf05a610447e90314e658dbbcd191f378fc9 data/create/recipes/dripstone_pillar_from_stone_types_dripstone_stonecutting.json d81ceba2946286d374801e698a4ca2116395cbad data/create/recipes/emptying/builders_tea.json -318ab703224ff1d6f7200675e1e0a4c138b28456 data/create/recipes/emptying/compat/alexsmobs/lava_bottle.json +d62f4682fe6cc61df5a1c0231a2004a4ee78a329 data/create/recipes/emptying/compat/alexsmobs/lava_bottle.json c26d003e921720308c05ad7b9f3cb57de94a10a8 data/create/recipes/emptying/compat/farmersdelight/milk_bottle.json 60c0edfb5b759e4f13427b631861f503f8552923 data/create/recipes/emptying/compat/neapolitan/milk_bottle.json 20b7c7c62fa2e33199e08188dd8836844a6d9cfd data/create/recipes/emptying/honey_bottle.json @@ -5027,7 +5028,7 @@ c2f40d447fbac4b4975e578fe32635658b73ebf7 data/create/recipes/exposed_copper_tile 133e79f78a7f2c2f63ac7695d2be57d56e8955f4 data/create/recipes/filling/blaze_cake.json 642e96ce5dd2f31e7a33c6ef4060eecb0bf2aa86 data/create/recipes/filling/builders_tea.json 1367357fc36adc4b67467d90589ef91e657380a4 data/create/recipes/filling/chocolate_glazed_berries.json -61a770607d872ace2be80c3391fba4225182282f data/create/recipes/filling/compat/alexsmobs/milk_bottle.json +61a770607d872ace2be80c3391fba4225182282f data/create/recipes/filling/compat/alexsmobs/lava_bottle.json 08dde80a4761e430eaaa18fb813885d307b25bd1 data/create/recipes/filling/compat/byg/lush_grass_block.json 0e79248178f8c1690b4e5a5ad2ffaf63711ad3c7 data/create/recipes/filling/compat/farmersdelight/milk_bottle.json bcfbc3d6617e32732a1e186059694c4880e2d2e4 data/create/recipes/filling/compat/neapolitan/milk_bottle.json diff --git a/src/generated/resources/data/create/loot_tables/blocks/copper_backtank.json b/src/generated/resources/data/create/loot_tables/blocks/copper_backtank.json index 9083fd8b2..f06a7a321 100644 --- a/src/generated/resources/data/create/loot_tables/blocks/copper_backtank.json +++ b/src/generated/resources/data/create/loot_tables/blocks/copper_backtank.json @@ -8,18 +8,14 @@ { "type": "minecraft:item", "functions": [ - { - "function": "minecraft:copy_name", - "source": "block_entity" - }, { "function": "minecraft:copy_nbt", "source": "block_entity", "ops": [ { - "source": "Air", - "target": "Air", - "op": "replace" + "source": "VanillaTag", + "target": "{}", + "op": "merge" } ] }, @@ -28,8 +24,8 @@ "source": "block_entity", "ops": [ { - "source": "Enchantments", - "target": "Enchantments", + "source": "Air", + "target": "Air", "op": "replace" } ] diff --git a/src/generated/resources/data/create/loot_tables/blocks/netherite_backtank.json b/src/generated/resources/data/create/loot_tables/blocks/netherite_backtank.json index 4418da818..337fb1e51 100644 --- a/src/generated/resources/data/create/loot_tables/blocks/netherite_backtank.json +++ b/src/generated/resources/data/create/loot_tables/blocks/netherite_backtank.json @@ -8,18 +8,14 @@ { "type": "minecraft:item", "functions": [ - { - "function": "minecraft:copy_name", - "source": "block_entity" - }, { "function": "minecraft:copy_nbt", "source": "block_entity", "ops": [ { - "source": "Air", - "target": "Air", - "op": "replace" + "source": "VanillaTag", + "target": "{}", + "op": "merge" } ] }, @@ -28,8 +24,8 @@ "source": "block_entity", "ops": [ { - "source": "Enchantments", - "target": "Enchantments", + "source": "Air", + "target": "Air", "op": "replace" } ] diff --git a/src/generated/resources/data/create/recipes/crushing/deepslate_coal_ore.json b/src/generated/resources/data/create/recipes/crushing/deepslate_coal_ore.json index 1a7b72c05..6cf1a77d8 100644 --- a/src/generated/resources/data/create/recipes/crushing/deepslate_coal_ore.json +++ b/src/generated/resources/data/create/recipes/crushing/deepslate_coal_ore.json @@ -7,11 +7,12 @@ ], "results": [ { - "item": "minecraft:coal" + "item": "minecraft:coal", + "count": 2 }, { "item": "minecraft:coal", - "chance": 0.75 + "chance": 0.25 }, { "item": "create:experience_nugget", @@ -22,5 +23,5 @@ "chance": 0.125 } ], - "processingTime": 250 + "processingTime": 300 } \ No newline at end of file diff --git a/src/generated/resources/data/create/recipes/crushing/gilded_blackstone.json b/src/generated/resources/data/create/recipes/crushing/gilded_blackstone.json new file mode 100644 index 000000000..df163c327 --- /dev/null +++ b/src/generated/resources/data/create/recipes/crushing/gilded_blackstone.json @@ -0,0 +1,23 @@ +{ + "type": "create:crushing", + "ingredients": [ + { + "item": "minecraft:gilded_blackstone" + } + ], + "results": [ + { + "item": "minecraft:gold_nugget", + "count": 18 + }, + { + "item": "create:experience_nugget", + "chance": 0.75 + }, + { + "item": "minecraft:blackstone", + "chance": 0.125 + } + ], + "processingTime": 400 +} \ No newline at end of file diff --git a/src/generated/resources/data/create/recipes/emptying/compat/alexsmobs/lava_bottle.json b/src/generated/resources/data/create/recipes/emptying/compat/alexsmobs/lava_bottle.json index b9a1453cc..5840cfd98 100644 --- a/src/generated/resources/data/create/recipes/emptying/compat/alexsmobs/lava_bottle.json +++ b/src/generated/resources/data/create/recipes/emptying/compat/alexsmobs/lava_bottle.json @@ -16,7 +16,7 @@ ], "conditions": [ { - "modid": "atmospheric", + "modid": "alexsmobs", "type": "forge:mod_loaded" } ] diff --git a/src/generated/resources/data/create/recipes/filling/compat/alexsmobs/milk_bottle.json b/src/generated/resources/data/create/recipes/filling/compat/alexsmobs/lava_bottle.json similarity index 100% rename from src/generated/resources/data/create/recipes/filling/compat/alexsmobs/milk_bottle.json rename to src/generated/resources/data/create/recipes/filling/compat/alexsmobs/lava_bottle.json diff --git a/src/main/java/com/simibubi/create/AllInteractionBehaviours.java b/src/main/java/com/simibubi/create/AllInteractionBehaviours.java index 31c518c5f..0c857e93d 100644 --- a/src/main/java/com/simibubi/create/AllInteractionBehaviours.java +++ b/src/main/java/com/simibubi/create/AllInteractionBehaviours.java @@ -3,6 +3,8 @@ package com.simibubi.create; import java.util.ArrayList; import java.util.List; +import com.simibubi.create.content.contraptions.behaviour.FenceGateMovingInteraction; + import org.jetbrains.annotations.Nullable; import com.simibubi.create.content.contraptions.behaviour.DoorMovingInteraction; @@ -75,6 +77,15 @@ public class AllInteractionBehaviours { } return null; }); + + FenceGateMovingInteraction fenceGateBehavior = new FenceGateMovingInteraction(); + registerBehaviourProvider(state -> { + if (state.is(BlockTags.FENCE_GATES)) { + return fenceGateBehavior; + } + return null; + }); + } public interface BehaviourProvider { diff --git a/src/main/java/com/simibubi/create/compat/Mods.java b/src/main/java/com/simibubi/create/compat/Mods.java index 909569e04..105256b58 100644 --- a/src/main/java/com/simibubi/create/compat/Mods.java +++ b/src/main/java/com/simibubi/create/compat/Mods.java @@ -18,11 +18,15 @@ public enum Mods { CONNECTIVITY, CURIOS, DYNAMICTREES, + FUNCTIONALSTORAGE, OCCULTISM, PACKETFIXER, + SOPHISTICATEDBACKPACKS, + SOPHISTICATEDSTORAGE, STORAGEDRAWERS, TCONSTRUCT, - XLPACKETS; + XLPACKETS, + MODERNUI; private final String id; diff --git a/src/main/java/com/simibubi/create/compat/curios/Curios.java b/src/main/java/com/simibubi/create/compat/curios/Curios.java index 97eea93e2..7adbb59be 100644 --- a/src/main/java/com/simibubi/create/compat/curios/Curios.java +++ b/src/main/java/com/simibubi/create/compat/curios/Curios.java @@ -43,13 +43,16 @@ public class Curios { modEventBus.addListener(Curios::onClientSetup); GogglesItem.addIsWearingPredicate(player -> resolveCuriosMap(player) - .map(curiosMap -> curiosMap.get("head")) - .map(stacksHandler -> { - // Check all the Head slots for Goggles existing - int slots = stacksHandler.getSlots(); - for (int slot = 0; slot < slots; slot++) - if (AllItems.GOGGLES.isIn(stacksHandler.getStacks().getStackInSlot(slot))) - return true; + .map(curiosMap -> { + for (ICurioStacksHandler stacksHandler : curiosMap.values()) { + // Search all the curio slots for Goggles existing + int slots = stacksHandler.getSlots(); + for (int slot = 0; slot < slots; slot++) { + if (AllItems.GOGGLES.isIn(stacksHandler.getStacks().getStackInSlot(slot))) { + return true; + } + } + } return false; }) diff --git a/src/main/java/com/simibubi/create/compat/jei/category/MechanicalCraftingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/MechanicalCraftingCategory.java index 33e0c5239..334c065dd 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/MechanicalCraftingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/MechanicalCraftingCategory.java @@ -99,16 +99,21 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory= recipe.getIngredients() + .size()) + break; + if (recipe.getIngredients() + .get(pIndex) + .isEmpty()) + continue; + matrixStack.pushPose(); + matrixStack.translate(col * 19 * scale, row * 19 * scale, 0); + matrixStack.scale(scale, scale, scale); + AllGuiTextures.JEI_SLOT.render(matrixStack, 0, 0); + matrixStack.popPose(); + } matrixStack.popPose(); diff --git a/src/main/java/com/simibubi/create/compat/storageDrawers/StorageDrawers.java b/src/main/java/com/simibubi/create/compat/storageDrawers/StorageDrawers.java deleted file mode 100644 index 854decc6d..000000000 --- a/src/main/java/com/simibubi/create/compat/storageDrawers/StorageDrawers.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.simibubi.create.compat.storageDrawers; - -import com.simibubi.create.compat.Mods; -import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; - -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.items.IItemHandler; - -public class StorageDrawers { - - public static boolean isDrawer(BlockEntity be) { - return be != null && Mods.STORAGEDRAWERS.id() - .equals(be.getType() - .getRegistryName() - .getNamespace()); - } - - public static float getTrueFillLevel(IItemHandler inv, FilteringBehaviour filtering) { - float occupied = 0; - float totalSpace = 0; - - for (int slot = 1; slot < inv.getSlots(); slot++) { - ItemStack stackInSlot = inv.getStackInSlot(slot); - int space = inv.getSlotLimit(slot); - int count = stackInSlot.getCount(); - if (space == 0) - continue; - - totalSpace += 1; - if (filtering.test(stackInSlot)) - occupied += count * (1f / space); - } - - if (totalSpace == 0) - return 0; - - return occupied / totalSpace; - } - -} diff --git a/src/main/java/com/simibubi/create/compat/thresholdSwitch/FunctionalStorage.java b/src/main/java/com/simibubi/create/compat/thresholdSwitch/FunctionalStorage.java new file mode 100644 index 000000000..2ec66a935 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/thresholdSwitch/FunctionalStorage.java @@ -0,0 +1,22 @@ +package com.simibubi.create.compat.thresholdSwitch; + +import com.simibubi.create.compat.Mods; + +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraftforge.items.IItemHandler; + +public class FunctionalStorage implements ThresholdSwitchCompat { + + @Override + public boolean isFromThisMod(BlockEntity blockEntity) { + return blockEntity != null && Mods.FUNCTIONALSTORAGE.id() + .equals(blockEntity.getType() + .getRegistryName() + .getNamespace()); + } + + @Override + public long getSpaceInSlot(IItemHandler inv, int slot) { + return inv.getSlotLimit(slot); + } +} diff --git a/src/main/java/com/simibubi/create/compat/thresholdSwitch/SophisticatedStorage.java b/src/main/java/com/simibubi/create/compat/thresholdSwitch/SophisticatedStorage.java new file mode 100644 index 000000000..bc200b598 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/thresholdSwitch/SophisticatedStorage.java @@ -0,0 +1,29 @@ +package com.simibubi.create.compat.thresholdSwitch; + +import com.simibubi.create.compat.Mods; + +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraftforge.items.IItemHandler; + +public class SophisticatedStorage implements ThresholdSwitchCompat { + + @Override + public boolean isFromThisMod(BlockEntity be) { + if (be == null) + return false; + + String namespace = be.getType() + .getRegistryName() + .getNamespace(); + + return + Mods.SOPHISTICATEDSTORAGE.id().equals(namespace) + || Mods.SOPHISTICATEDBACKPACKS.id().equals(namespace); + } + + @Override + public long getSpaceInSlot(IItemHandler inv, int slot) { + return ((long) inv.getSlotLimit(slot) * inv.getStackInSlot(slot).getMaxStackSize()) / 64; + } + +} diff --git a/src/main/java/com/simibubi/create/compat/thresholdSwitch/StorageDrawers.java b/src/main/java/com/simibubi/create/compat/thresholdSwitch/StorageDrawers.java new file mode 100644 index 000000000..a5055e017 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/thresholdSwitch/StorageDrawers.java @@ -0,0 +1,25 @@ +package com.simibubi.create.compat.thresholdSwitch; + +import com.simibubi.create.compat.Mods; + +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraftforge.items.IItemHandler; + +public class StorageDrawers implements ThresholdSwitchCompat { + + @Override + public boolean isFromThisMod(BlockEntity blockEntity) { + return blockEntity != null && Mods.STORAGEDRAWERS.id() + .equals(blockEntity.getType() + .getRegistryName() + .getNamespace()); + } + + @Override + public long getSpaceInSlot(IItemHandler inv, int slot) { + if (slot == 0) + return 0; + + return inv.getSlotLimit(slot); + } +} diff --git a/src/main/java/com/simibubi/create/compat/thresholdSwitch/ThresholdSwitchCompat.java b/src/main/java/com/simibubi/create/compat/thresholdSwitch/ThresholdSwitchCompat.java new file mode 100644 index 000000000..841769c34 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/thresholdSwitch/ThresholdSwitchCompat.java @@ -0,0 +1,12 @@ +package com.simibubi.create.compat.thresholdSwitch; + +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraftforge.items.IItemHandler; + +public interface ThresholdSwitchCompat { + + boolean isFromThisMod(BlockEntity blockEntity); + + long getSpaceInSlot(IItemHandler inv, int slot); + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/AbstractContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/AbstractContraptionEntity.java index a23fb5e6e..795513952 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/AbstractContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/AbstractContraptionEntity.java @@ -212,14 +212,18 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit Vec3 transformedVector = getPassengerPosition(passenger, 1); if (transformedVector == null) return; + + float offset = -1 / 8f; + if (passenger instanceof AbstractContraptionEntity) + offset = 0.0f; callback.accept(passenger, transformedVector.x, - transformedVector.y + SeatEntity.getCustomEntitySeatOffset(passenger) - 1 / 8f, transformedVector.z); + transformedVector.y + SeatEntity.getCustomEntitySeatOffset(passenger) + offset, transformedVector.z); } public Vec3 getPassengerPosition(Entity passenger, float partialTicks) { if (contraption == null) return null; - + UUID id = passenger.getUUID(); if (passenger instanceof OrientedContraptionEntity) { BlockPos localPos = contraption.getBearingPosOf(id); @@ -234,7 +238,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit BlockPos seat = contraption.getSeatOf(id); if (seat == null) return null; - + Vec3 transformedVector = toGlobalVector(Vec3.atLowerCornerOf(seat) .add(.5, passenger.getMyRidingOffset() + ySize - .15f, .5), partialTicks) .add(VecHelper.getCenterOf(BlockPos.ZERO)) diff --git a/src/main/java/com/simibubi/create/content/contraptions/IDisplayAssemblyExceptions.java b/src/main/java/com/simibubi/create/content/contraptions/IDisplayAssemblyExceptions.java index c99054f41..983f67c37 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/IDisplayAssemblyExceptions.java +++ b/src/main/java/com/simibubi/create/content/contraptions/IDisplayAssemblyExceptions.java @@ -22,15 +22,13 @@ public interface IDisplayAssemblyExceptions { if (!tooltip.isEmpty()) tooltip.add(Components.immutableEmpty()); - tooltip.add(IHaveGoggleInformation.componentSpacing.plainCopy() - .append(Lang.translateDirect("gui.assembly.exception") - .withStyle(ChatFormatting.GOLD))); + Lang.translate("gui.assembly.exception").style(ChatFormatting.GOLD) + .forGoggles(tooltip); String text = e.component.getString(); Arrays.stream(text.split("\n")) .forEach(l -> TooltipHelper.cutStringTextComponent(l, Palette.GRAY_AND_WHITE) - .forEach(c -> tooltip.add(IHaveGoggleInformation.componentSpacing.plainCopy() - .append(c)))); + .forEach(c -> Lang.text(c.getString()).forGoggles(tooltip))); return true; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/OrientedContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/OrientedContraptionEntity.java index 13dc64607..4882e858e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/OrientedContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/OrientedContraptionEntity.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions; import static com.simibubi.create.foundation.utility.AngleHelper.angleLerp; +import static com.simibubi.create.foundation.utility.AngleHelper.wrapAngle180; import java.util.Optional; import java.util.UUID; @@ -353,7 +354,7 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity { return false; OrientedContraptionEntity parent = (OrientedContraptionEntity) riding; prevYaw = yaw; - yaw = -parent.getViewYRot(1); + yaw = wrapAngle180(getInitialYaw() - parent.getInitialYaw()) - parent.getViewYRot(1); return false; } @@ -496,7 +497,7 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity { Vec3 anchorVec = super.getAnchorVec(); return anchorVec.subtract(.5, 0, .5); } - + @Override public Vec3 getPrevAnchorVec() { Vec3 prevAnchorVec = super.getPrevAnchorVec(); @@ -571,7 +572,7 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity { Vec3 passengerPosition = parent.getPassengerPosition(this, partialTicks); if (passengerPosition == null) return Vec3.ZERO; - + double x = passengerPosition.x - Mth.lerp(partialTicks, this.xOld, this.getX()); double y = passengerPosition.y - Mth.lerp(partialTicks, this.yOld, this.getY()); double z = passengerPosition.z - Mth.lerp(partialTicks, this.zOld, this.getZ()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/behaviour/FenceGateMovingInteraction.java b/src/main/java/com/simibubi/create/content/contraptions/behaviour/FenceGateMovingInteraction.java new file mode 100644 index 000000000..340dc0b56 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/behaviour/FenceGateMovingInteraction.java @@ -0,0 +1,28 @@ +package com.simibubi.create.content.contraptions.behaviour; + +import com.simibubi.create.content.contraptions.Contraption; + +import net.minecraft.core.BlockPos; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.block.FenceGateBlock; +import net.minecraft.world.level.block.state.BlockState; + +public class FenceGateMovingInteraction extends SimpleBlockMovingInteraction { + + @Override + protected BlockState handle(Player player, Contraption contraption, BlockPos pos, BlockState currentState) { + SoundEvent sound = currentState.getValue(FenceGateBlock.OPEN) ? SoundEvents.FENCE_GATE_CLOSE + : SoundEvents.FENCE_GATE_OPEN; + float pitch = player.level.random.nextFloat() * 0.1F + 0.9F; + playSound(player, sound, pitch); + return currentState.cycle(FenceGateBlock.OPEN); + } + + @Override + protected boolean updateColliders() { + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/elevator/ElevatorContactEditPacket.java b/src/main/java/com/simibubi/create/content/contraptions/elevator/ElevatorContactEditPacket.java index 81d331d54..2a8a4487d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/elevator/ElevatorContactEditPacket.java +++ b/src/main/java/com/simibubi/create/content/contraptions/elevator/ElevatorContactEditPacket.java @@ -27,14 +27,14 @@ public class ElevatorContactEditPacket extends BlockEntityConfigurationPacket ItemRenderer itemRenderer = Minecraft.getInstance() .getItemRenderer(); - boolean blockItem = itemRenderer.getModel(heldItem, null, null, 0) - .isGui3d(); + BakedModel bakedModel = itemRenderer.getModel(heldItem, null, null, 0); + boolean blockItem = bakedModel.isGui3d(); ms.pushPose(); TransformStack.cast(ms) @@ -46,7 +47,7 @@ public class PlacardRenderer extends SafeBlockEntityRenderer .translate(0, 0, 4.5 / 16f) .scale(blockItem ? .5f : .375f); - itemRenderer.renderStatic(heldItem, TransformType.FIXED, light, overlay, ms, buffer, 0); + itemRenderer.render(heldItem, TransformType.FIXED, false, ms, buffer, light, overlay, bakedModel); ms.popPose(); } diff --git a/src/main/java/com/simibubi/create/content/decoration/steamWhistle/WhistleBlockEntity.java b/src/main/java/com/simibubi/create/content/decoration/steamWhistle/WhistleBlockEntity.java index 70b8fecce..d5ab6925a 100644 --- a/src/main/java/com/simibubi/create/content/decoration/steamWhistle/WhistleBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/decoration/steamWhistle/WhistleBlockEntity.java @@ -112,8 +112,7 @@ public class WhistleBlockEntity extends SmartBlockEntity implements IHaveGoggleI String[] pitches = Lang.translateDirect("generic.notes") .getString() .split(";"); - MutableComponent textComponent = Components.literal(spacing); - tooltip.add(textComponent.append(Lang.translateDirect("generic.pitch", pitches[pitch % pitches.length]))); + Lang.translate("generic.pitch", pitches[pitch % pitches.length]).forGoggles(tooltip); return true; } diff --git a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlock.java b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlock.java index 8848aa392..62f78e3c8 100644 --- a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlock.java +++ b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlock.java @@ -1,11 +1,15 @@ package com.simibubi.create.content.equipment.armor; +import java.util.List; import java.util.Optional; import com.simibubi.create.AllBlockEntityTypes; import com.simibubi.create.AllEnchantments; import com.simibubi.create.AllShapes; import com.simibubi.create.content.kinetics.base.HorizontalKineticBlock; +import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement; +import com.simibubi.create.content.schematics.requirement.ItemRequirement; +import com.simibubi.create.content.schematics.requirement.ItemRequirement.ItemUseType; import com.simibubi.create.foundation.block.IBE; import net.minecraft.core.BlockPos; @@ -13,8 +17,6 @@ import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.core.NonNullList; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.network.chat.Component; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; @@ -34,6 +36,7 @@ import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition.Builder; @@ -41,13 +44,14 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.level.storage.loot.LootContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraftforge.common.util.FakePlayer; -public class BacktankBlock extends HorizontalKineticBlock - implements IBE, SimpleWaterloggedBlock { +public class BacktankBlock extends HorizontalKineticBlock implements IBE, SimpleWaterloggedBlock, ISpecialBlockItemRequirement { public BacktankBlock(Properties properties) { super(properties); @@ -81,9 +85,9 @@ public class BacktankBlock extends HorizontalKineticBlock } @Override - public BlockState updateShape(BlockState state, Direction direction, BlockState neighbourState, - LevelAccessor world, BlockPos pos, BlockPos neighbourPos) { - if (state.getValue(BlockStateProperties.WATERLOGGED)) + public BlockState updateShape(BlockState state, Direction direction, BlockState neighbourState, LevelAccessor world, + BlockPos pos, BlockPos neighbourPos) { + if (state.getValue(BlockStateProperties.WATERLOGGED)) world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); return state; } @@ -114,16 +118,46 @@ public class BacktankBlock extends HorizontalKineticBlock if (stack == null) return; withBlockEntityDo(worldIn, pos, be -> { - be.setCapacityEnchantLevel(EnchantmentHelper.getItemEnchantmentLevel(AllEnchantments.CAPACITY.get(), stack)); - be.setAirLevel(stack.getOrCreateTag() - .getInt("Air")); - if (stack.isEnchanted()) - be.setEnchantmentTag(stack.getEnchantmentTags()); + be.setCapacityEnchantLevel( + EnchantmentHelper.getItemEnchantmentLevel(AllEnchantments.CAPACITY.get(), stack)); + CompoundTag vanillaTag = stack.getOrCreateTag(); + be.setAirLevel(vanillaTag.getInt("Air")); if (stack.hasCustomHoverName()) be.setCustomName(stack.getHoverName()); + + CompoundTag nbt = stack.serializeNBT(); + CompoundTag forgeCapsTag = nbt.contains("ForgeCaps") ? nbt.getCompound("ForgeCaps") : null; + be.setTags(vanillaTag, forgeCapsTag); }); } + @Override + @SuppressWarnings("deprecation") + // Re-adding ForgeCaps to item here as there is no loot function that can modify + // outside of the vanilla tag + public List getDrops(BlockState pState, LootContext.Builder pBuilder) { + List lootDrops = super.getDrops(pState, pBuilder); + + BlockEntity blockEntity = pBuilder.getOptionalParameter(LootContextParams.BLOCK_ENTITY); + if (!(blockEntity instanceof BacktankBlockEntity bbe)) + return lootDrops; + + CompoundTag forgeCapsTag = bbe.getForgeCapsTag(); + if (forgeCapsTag == null) + return lootDrops; + + return lootDrops.stream() + .map(stack -> { + if (!(stack.getItem() instanceof BacktankItem)) + return stack; + + ItemStack modifiedStack = new ItemStack(stack.getItem(), stack.getCount(), forgeCapsTag.copy()); + modifiedStack.setTag(stack.getTag()); + return modifiedStack; + }) + .toList(); + } + @Override public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { @@ -150,30 +184,21 @@ public class BacktankBlock extends HorizontalKineticBlock @Override public ItemStack getCloneItemStack(BlockGetter blockGetter, BlockPos pos, BlockState state) { Item item = asItem(); - if (item instanceof BacktankItem.BacktankBlockItem placeable) { + if (item instanceof BacktankItem.BacktankBlockItem placeable) item = placeable.getActualItem(); - } - ItemStack stack = new ItemStack(item); Optional blockEntityOptional = getBlockEntityOptional(blockGetter, pos); + CompoundTag forgeCapsTag = blockEntityOptional.map(BacktankBlockEntity::getForgeCapsTag) + .orElse(null); + CompoundTag vanillaTag = blockEntityOptional.map(BacktankBlockEntity::getVanillaTag) + .orElse(new CompoundTag()); int air = blockEntityOptional.map(BacktankBlockEntity::getAirLevel) .orElse(0); - CompoundTag tag = stack.getOrCreateTag(); - tag.putInt("Air", air); - ListTag enchants = blockEntityOptional.map(BacktankBlockEntity::getEnchantmentTag) - .orElse(new ListTag()); - if (!enchants.isEmpty()) { - ListTag enchantmentTagList = stack.getEnchantmentTags(); - enchantmentTagList.addAll(enchants); - tag.put("Enchantments", enchantmentTagList); - } - - Component customName = blockEntityOptional.map(BacktankBlockEntity::getCustomName) - .orElse(null); - if (customName != null) - stack.setHoverName(customName); + ItemStack stack = new ItemStack(item, 1, forgeCapsTag); + vanillaTag.putInt("Air", air); + stack.setTag(vanillaTag); return stack; } @@ -187,7 +212,7 @@ public class BacktankBlock extends HorizontalKineticBlock public Class getBlockEntityClass() { return BacktankBlockEntity.class; } - + @Override public BlockEntityType getBlockEntityType() { return AllBlockEntityTypes.BACKTANK.get(); @@ -198,4 +223,12 @@ public class BacktankBlock extends HorizontalKineticBlock return false; } + @Override + public ItemRequirement getRequiredItems(BlockState state, BlockEntity blockEntity) { + Item item = asItem(); + if (item instanceof BacktankItem.BacktankBlockItem placeable) + item = placeable.getActualItem(); + return new ItemRequirement(ItemUseType.CONSUME, item); + } + } diff --git a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlockEntity.java b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlockEntity.java index 20f3c4518..181e5b1bb 100644 --- a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlockEntity.java @@ -2,6 +2,8 @@ package com.simibubi.create.content.equipment.armor; import java.util.List; +import javax.annotation.Nullable; + import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; import com.simibubi.create.AllSoundEvents; @@ -16,8 +18,6 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction.Axis; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.util.Mth; import net.minecraft.world.Nameable; @@ -35,20 +35,25 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable private Component customName; private int capacityEnchantLevel; - private ListTag enchantmentTag; + + private CompoundTag vanillaTag; + private CompoundTag forgeCapsTag; public BacktankBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); defaultName = getDefaultName(state); - enchantmentTag = new ListTag(); + vanillaTag = new CompoundTag(); + forgeCapsTag = null; } public static Component getDefaultName(BlockState state) { if (AllBlocks.NETHERITE_BACKTANK.has(state)) { - AllItems.NETHERITE_BACKTANK.get().getDescription(); + AllItems.NETHERITE_BACKTANK.get() + .getDescription(); } - return AllItems.COPPER_BACKTANK.get().getDescription(); + return AllItems.COPPER_BACKTANK.get() + .getDescription(); } @Override @@ -115,21 +120,29 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable compound.putInt("Air", airLevel); compound.putInt("Timer", airLevelTimer); compound.putInt("CapacityEnchantment", capacityEnchantLevel); + if (this.customName != null) compound.putString("CustomName", Component.Serializer.toJson(this.customName)); - compound.put("Enchantments", enchantmentTag); + + compound.put("VanillaTag", vanillaTag); + if (forgeCapsTag != null) + compound.put("ForgeCapsTag", forgeCapsTag); } @Override protected void read(CompoundTag compound, boolean clientPacket) { super.read(compound, clientPacket); int prev = airLevel; - capacityEnchantLevel = compound.getInt("CapacityEnchantment"); airLevel = compound.getInt("Air"); airLevelTimer = compound.getInt("Timer"); - enchantmentTag = compound.getList("Enchantments", Tag.TAG_COMPOUND); + capacityEnchantLevel = compound.getInt("CapacityEnchantment"); + if (compound.contains("CustomName", 8)) this.customName = Component.Serializer.fromJson(compound.getString("CustomName")); + + vanillaTag = compound.getCompound("VanillaTag"); + forgeCapsTag = compound.contains("ForgeCapsTag") ? compound.getCompound("ForgeCapsTag") : null; + if (prev != 0 && prev != airLevel && airLevel == BacktankUtil.maxAir(capacityEnchantLevel) && clientPacket) playFilledEffect(); } @@ -149,8 +162,7 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable @Override public Component getName() { - return this.customName != null ? this.customName - : defaultName; + return this.customName != null ? this.customName : defaultName; } public int getAirLevel() { @@ -166,20 +178,21 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable this.customName = customName; } - public Component getCustomName() { - return customName; - } - - public ListTag getEnchantmentTag() { - return enchantmentTag; - } - - public void setEnchantmentTag(ListTag enchantmentTag) { - this.enchantmentTag = enchantmentTag; - } - public void setCapacityEnchantLevel(int capacityEnchantLevel) { this.capacityEnchantLevel = capacityEnchantLevel; } + + public void setTags(CompoundTag vanillaTag, @Nullable CompoundTag forgeCapsTag) { + this.vanillaTag = vanillaTag; + this.forgeCapsTag = forgeCapsTag; + } + + public CompoundTag getVanillaTag() { + return vanillaTag; + } + + public CompoundTag getForgeCapsTag() { + return forgeCapsTag; + } } diff --git a/src/main/java/com/simibubi/create/content/equipment/goggles/GoggleOverlayRenderer.java b/src/main/java/com/simibubi/create/content/equipment/goggles/GoggleOverlayRenderer.java index 31d59b51c..b3eba8f5a 100644 --- a/src/main/java/com/simibubi/create/content/equipment/goggles/GoggleOverlayRenderer.java +++ b/src/main/java/com/simibubi/create/content/equipment/goggles/GoggleOverlayRenderer.java @@ -4,10 +4,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; import com.simibubi.create.CreateClient; +import com.simibubi.create.compat.Mods; import com.simibubi.create.content.contraptions.IDisplayAssemblyExceptions; import com.simibubi.create.content.contraptions.piston.MechanicalPistonBlock; import com.simibubi.create.content.contraptions.piston.PistonExtensionPoleBlock; @@ -16,6 +18,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.ValueBox; import com.simibubi.create.foundation.gui.RemovedGuiUtils; import com.simibubi.create.foundation.gui.Theme; import com.simibubi.create.foundation.gui.element.GuiGameElement; +import com.simibubi.create.foundation.mixin.accessor.MouseHandlerAccessor; import com.simibubi.create.foundation.outliner.Outline; import com.simibubi.create.foundation.outliner.Outliner.OutlineEntry; import com.simibubi.create.foundation.utility.Color; @@ -26,6 +29,7 @@ import com.simibubi.create.infrastructure.config.AllConfigs; import com.simibubi.create.infrastructure.config.CClient; import net.minecraft.client.Minecraft; +import net.minecraft.client.MouseHandler; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -154,9 +158,8 @@ public class GoggleOverlayRenderer { if (!tooltip.isEmpty()) tooltip.add(Components.immutableEmpty()); - tooltip.add(IHaveGoggleInformation.componentSpacing.plainCopy() - .append(Lang.translateDirect("gui.goggles.pole_length")) - .append(Components.literal(" " + poles))); + Lang.translate("gui.goggles.pole_length").text(" " + poles) + .forGoggles(tooltip); } if (tooltip.isEmpty()) { @@ -205,14 +208,44 @@ public class GoggleOverlayRenderer { colorBorderBot.scaleAlpha(fade); } - RemovedGuiUtils.drawHoveringText(poseStack, tooltip, posX, posY, width, height, -1, colorBackground.getRGB(), - colorBorderTop.getRGB(), colorBorderBot.getRGB(), mc.font); - - GuiGameElement.of(item) .at(posX + 10, posY - 16, 450) .render(poseStack); + + if (!Mods.MODERNUI.isLoaded()) { + // default tooltip rendering when modernUI is not loaded + RemovedGuiUtils.drawHoveringText(poseStack, tooltip, posX, posY, width, height, -1, colorBackground.getRGB(), + colorBorderTop.getRGB(), colorBorderBot.getRGB(), mc.font); + + poseStack.popPose(); + + return; + } + + /* + * special handling for modernUI + * + * their tooltip handler causes the overlay to jiggle each frame, + * if the mouse is moving, guiScale is anything but 1 and exactPositioning is enabled + * + * this is a workaround to fix this behavior + */ + MouseHandler mouseHandler = Minecraft.getInstance().mouseHandler; + Window window = Minecraft.getInstance().getWindow(); + double guiScale = window.getGuiScale(); + double cursorX = mouseHandler.xpos(); + double cursorY = mouseHandler.ypos(); + ((MouseHandlerAccessor) mouseHandler).create$setXPos(Math.round(cursorX / guiScale) * guiScale); + ((MouseHandlerAccessor) mouseHandler).create$setYPos(Math.round(cursorY / guiScale) * guiScale); + + RemovedGuiUtils.drawHoveringText(poseStack, tooltip, posX, posY, width, height, -1, colorBackground.getRGB(), + colorBorderTop.getRGB(), colorBorderBot.getRGB(), mc.font); + + ((MouseHandlerAccessor) mouseHandler).create$setXPos(cursorX); + ((MouseHandlerAccessor) mouseHandler).create$setYPos(cursorY); + poseStack.popPose(); + } public static BlockPos proxiedOverlayPosition(Level level, BlockPos pos) { diff --git a/src/main/java/com/simibubi/create/content/equipment/wrench/IWrenchable.java b/src/main/java/com/simibubi/create/content/equipment/wrench/IWrenchable.java index 73e61afc2..8abcca734 100644 --- a/src/main/java/com/simibubi/create/content/equipment/wrench/IWrenchable.java +++ b/src/main/java/com/simibubi/create/content/equipment/wrench/IWrenchable.java @@ -22,6 +22,8 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.world.BlockEvent; public interface IWrenchable { @@ -54,16 +56,26 @@ public interface IWrenchable { Level world = context.getLevel(); BlockPos pos = context.getClickedPos(); Player player = context.getPlayer(); - if (world instanceof ServerLevel) { - if (player != null && !player.isCreative()) - Block.getDrops(state, (ServerLevel) world, pos, world.getBlockEntity(pos), player, context.getItemInHand()) - .forEach(itemStack -> { - player.getInventory().placeItemBackInInventory(itemStack); - }); - state.spawnAfterBreak((ServerLevel) world, pos, ItemStack.EMPTY); - world.destroyBlock(pos, false); - playRemoveSound(world, pos); + + if (!(world instanceof ServerLevel serverLevel)) + return InteractionResult.SUCCESS; + + BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(world, pos, world.getBlockState(pos), player); + MinecraftForge.EVENT_BUS.post(event); + if (event.isCanceled()) + return InteractionResult.SUCCESS; + + if (player != null && !player.isCreative()) { + Block.getDrops(state, serverLevel, pos, world.getBlockEntity(pos), player, context.getItemInHand()) + .forEach(itemStack -> { + player.getInventory() + .placeItemBackInInventory(itemStack); + }); } + + state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY); + world.destroyBlock(pos, false); + playRemoveSound(world, pos); return InteractionResult.SUCCESS; } diff --git a/src/main/java/com/simibubi/create/content/fluids/FluidPropagator.java b/src/main/java/com/simibubi/create/content/fluids/FluidPropagator.java index bad5e0007..b5811a2eb 100644 --- a/src/main/java/com/simibubi/create/content/fluids/FluidPropagator.java +++ b/src/main/java/com/simibubi/create/content/fluids/FluidPropagator.java @@ -174,7 +174,7 @@ public class FluidPropagator { if (PumpBlock.isPump(connectedState) && connectedState.getValue(PumpBlock.FACING) .getAxis() == side.getAxis()) return false; - if (VanillaFluidTargets.shouldPipesConnectTo(connectedState)) + if (VanillaFluidTargets.canProvideFluidWithoutCapability(connectedState)) return true; if (BlockHelper.hasBlockSolidSide(connectedState, reader, connectedPos, side.getOpposite()) && !AllBlockTags.FAN_TRANSPARENT.matches(connectedState)) diff --git a/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainRenderer.java b/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainRenderer.java index d803e31dc..e3a9c4957 100644 --- a/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainRenderer.java +++ b/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainRenderer.java @@ -19,6 +19,7 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.util.Mth; @@ -78,8 +79,8 @@ public class ItemDrainRenderer extends SmartBlockEntityRenderer DEFAULT_IMPACTS = new HashMap<>(); - public static final Map DEFAULT_CAPACITIES = new HashMap<>(); - public static final Map>> GENERATOR_SPEEDS = new HashMap<>(); + public static final Map DEFAULT_IMPACTS = new ConcurrentHashMap<>(); + public static final Map DEFAULT_CAPACITIES = new ConcurrentHashMap<>(); + public static final Map>> GENERATOR_SPEEDS = new ConcurrentHashMap<>(); public static void setDefaultImpact(ResourceLocation blockId, double impact) { DEFAULT_IMPACTS.put(blockId, impact); diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java index c7241ed53..cd5af645f 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java @@ -30,6 +30,7 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.AxisDirection; @@ -194,14 +195,12 @@ public class BeltRenderer extends SafeBlockEntityRenderer { boolean slopeAlongX = beltFacing .getAxis() == Axis.X; + Minecraft mc = Minecraft.getInstance(); + ItemRenderer itemRenderer = mc.getItemRenderer(); boolean onContraption = be.getLevel() instanceof WrappedWorld; for (TransportedItemStack transported : be.getInventory() .getTransportedItems()) { - ms.pushPose(); - TransformStack.cast(ms) - .nudge(transported.angle); - float offset; float sideOffset; float verticalMovement; @@ -228,6 +227,18 @@ public class BeltRenderer extends SafeBlockEntityRenderer { .getAxis() == Axis.Z); float slopeAngle = onSlope ? tiltForward ? -45 : 45 : 0; + Vec3 itemPos = beltStartOffset.add( + be.getBlockPos().getX(), + be.getBlockPos().getY(), + be.getBlockPos().getZ()) + .add(offsetVec); + + if (this.shouldCullItem(itemPos)) { + continue; + } + + ms.pushPose(); + TransformStack.cast(ms).nudge(transported.angle); ms.translate(offsetVec.x, offsetVec.y, offsetVec.z); boolean alongX = beltFacing @@ -238,12 +249,15 @@ public class BeltRenderer extends SafeBlockEntityRenderer { ms.translate(alongX ? sideOffset : 0, 0, alongX ? 0 : sideOffset); int stackLight = onContraption ? light : getPackedLight(be, offset); - ItemRenderer itemRenderer = Minecraft.getInstance() - .getItemRenderer(); + boolean renderUpright = BeltHelper.isItemUpright(transported.stack); - boolean blockItem = itemRenderer.getModel(transported.stack, be.getLevel(), null, 0) - .isGui3d(); - int count = (int) (Mth.log2((int) (transported.stack.getCount()))) / 2; + BakedModel bakedModel = itemRenderer.getModel(transported.stack, be.getLevel(), null, 0); + boolean blockItem = bakedModel.isGui3d(); + + int count = 0; + if (mc.player.getEyePosition(1.0F).distanceTo(itemPos) < 16) + count = (int) (Mth.log2((int) (transported.stack.getCount()))) / 2; + Random r = new Random(transported.angle); boolean slopeShadowOnly = renderUpright && onSlope; @@ -264,7 +278,7 @@ public class BeltRenderer extends SafeBlockEntityRenderer { } if (renderUpright) { - Entity renderViewEntity = Minecraft.getInstance().cameraEntity; + Entity renderViewEntity = mc.cameraEntity; if (renderViewEntity != null) { Vec3 positionVec = renderViewEntity.position(); Vec3 vectorForOffset = BeltHelper.getVectorForOffset(be, offset); @@ -289,7 +303,7 @@ public class BeltRenderer extends SafeBlockEntityRenderer { } ms.scale(.5f, .5f, .5f); - itemRenderer.renderStatic(null, transported.stack, TransformType.FIXED, false, ms, buffer, be.getLevel(), stackLight, overlay, 0); + itemRenderer.render(transported.stack, TransformType.FIXED, false, ms, buffer, stackLight, overlay, bakedModel); ms.popPose(); if (!renderUpright) { diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/transport/BeltInventory.java b/src/main/java/com/simibubi/create/content/kinetics/belt/transport/BeltInventory.java index 42b0939f6..1d1b80b05 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/transport/BeltInventory.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/transport/BeltInventory.java @@ -378,6 +378,8 @@ public class BeltInventory { float min = offset; float max = offset + 1; for (TransportedItemStack stack : items) { + if (toRemove.contains(stack)) + continue; if (stack.beltPosition > max) continue; if (stack.beltPosition > min) diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java b/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java index 3395f9393..0a5248c5f 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java @@ -50,13 +50,15 @@ public class ItemHandlerBeltSegment implements IItemHandler { return ItemStack.EMPTY; amount = Math.min(amount, transported.stack.getCount()); - ItemStack extracted = simulate ? transported.stack.copy().split(amount) : transported.stack.split(amount); + ItemStack extracted = simulate ? transported.stack.copy() + .split(amount) : transported.stack.split(amount); if (!simulate) { if (transported.stack.isEmpty()) - this.beltInventory.toRemove.add(transported); - this.beltInventory.belt.setChanged(); - this.beltInventory.belt.sendData(); + beltInventory.toRemove.add(transported); + else + beltInventory.belt.notifyUpdate(); } + return extracted; } diff --git a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerRenderer.java b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerRenderer.java index 3ce20684f..031f162ce 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerRenderer.java +++ b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerRenderer.java @@ -34,6 +34,7 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; @@ -89,9 +90,8 @@ public class DeployerRenderer extends SafeBlockEntityRenderer tooltip, boolean isPlayerSneaking) { - tooltip.add(componentSpacing.plainCopy().append(Lang.translateDirect("gui.gauge.info_header"))); + Lang.translate("gui.gauge.info_header").forGoggles(tooltip); return true; } diff --git a/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmRenderer.java b/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmRenderer.java index 429cefa25..284f9c31b 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmRenderer.java +++ b/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmRenderer.java @@ -19,6 +19,7 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.util.Mth; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; @@ -45,9 +46,8 @@ public class ArmRenderer extends KineticBlockEntityRenderer { ItemRenderer itemRenderer = Minecraft.getInstance() .getItemRenderer(); - boolean isBlockItem = - hasItem && (item.getItem() instanceof BlockItem) && itemRenderer.getModel(item, be.getLevel(), null, 0) - .isGui3d(); + BakedModel bakedModel = itemRenderer.getModel(item, be.getLevel(), null, 0); + boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem) && bakedModel.isGui3d(); VertexConsumer builder = buffer.getBuffer(be.goggles ? RenderType.cutout() : RenderType.solid()); BlockState blockState = be.getBlockState(); @@ -102,7 +102,7 @@ public class ArmRenderer extends KineticBlockEntityRenderer { .multiply(msLocal.last() .pose()); - itemRenderer.renderStatic(item, TransformType.FIXED, light, overlay, ms, buffer, 0); + itemRenderer.render(item, TransformType.FIXED, false, ms, buffer, light, overlay, bakedModel); ms.popPose(); } @@ -141,13 +141,13 @@ public class ArmRenderer extends KineticBlockEntityRenderer { .renderInto(ms, builder); transformHead(msr, headAngle); - + if (inverted) msr.rotateZ(180); - + claw.transform(msLocal) .renderInto(ms, builder); - + if (inverted) msr.rotateZ(180); diff --git a/src/main/java/com/simibubi/create/content/kinetics/saw/SawRenderer.java b/src/main/java/com/simibubi/create/content/kinetics/saw/SawRenderer.java index 926b7332a..750ca9371 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/saw/SawRenderer.java +++ b/src/main/java/com/simibubi/create/content/kinetics/saw/SawRenderer.java @@ -134,7 +134,7 @@ public class SawRenderer extends SafeBlockEntityRenderer { if (alongZ) ms.mulPose(Vector3f.YP.rotationDegrees(90)); ms.mulPose(Vector3f.XP.rotationDegrees(90)); - itemRenderer.renderStatic(stack, ItemTransforms.TransformType.FIXED, light, overlay, ms, buffer, 0); + itemRenderer.render(stack, ItemTransforms.TransformType.FIXED, false, ms, buffer, light, overlay, modelWithOverrides); break; } diff --git a/src/main/java/com/simibubi/create/content/logistics/depot/DepotRenderer.java b/src/main/java/com/simibubi/create/content/logistics/depot/DepotRenderer.java index 5f830e91d..3d53879fa 100644 --- a/src/main/java/com/simibubi/create/content/logistics/depot/DepotRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/depot/DepotRenderer.java @@ -16,6 +16,7 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.Direction.Axis; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -104,8 +105,8 @@ public class DepotRenderer extends SafeBlockEntityRenderer { TransformStack msr = TransformStack.cast(ms); int count = (int) (Mth.log2((int) (itemStack.getCount()))) / 2; boolean renderUpright = BeltHelper.isItemUpright(itemStack); - boolean blockItem = itemRenderer.getModel(itemStack, null, null, 0) - .isGui3d(); + BakedModel bakedModel = itemRenderer.getModel(itemStack, null, null, 0); + boolean blockItem = bakedModel.isGui3d(); ms.pushPose(); msr.rotateY(angle); @@ -131,7 +132,7 @@ public class DepotRenderer extends SafeBlockEntityRenderer { ms.translate(0, -3 / 16f, 0); msr.rotateX(90); } - itemRenderer.renderStatic(itemStack, TransformType.FIXED, light, overlay, ms, buffer, 0); + itemRenderer.render(itemStack, TransformType.FIXED, false, ms, buffer, light, overlay, bakedModel); ms.popPose(); if (!renderUpright) { diff --git a/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelMovementBehaviour.java b/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelMovementBehaviour.java index 9b461c5f9..69e417134 100644 --- a/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelMovementBehaviour.java @@ -74,8 +74,7 @@ public class FunnelMovementBehaviour implements MovementBehaviour { FilterItemStack filter = context.getFilterFromBE(); int filterAmount = context.blockEntityData.getInt("FilterAmount"); boolean upTo = context.blockEntityData.getBoolean("UpTo"); - if (filterAmount <= 0) - filterAmount = hasFilter ? 64 : 1; + filterAmount = hasFilter ? filterAmount : 1; ItemStack extract = ItemHelper.extract(context.contraption.getSharedInventory(), s -> filter.test(world, s), diff --git a/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelBlockEntity.java b/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelBlockEntity.java index b2f248fea..3fe40f41d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelBlockEntity.java @@ -784,20 +784,13 @@ public class BrassTunnelBlockEntity extends BeltTunnelBlockEntity implements IHa if (allStacks.isEmpty()) return false; - tooltip.add(componentSpacing.plainCopy() - .append(Lang.translateDirect("tooltip.brass_tunnel.contains")) - .withStyle(ChatFormatting.WHITE)); + Lang.translate("tooltip.brass_tunnel.contains").style(ChatFormatting.WHITE).forGoggles(tooltip); for (ItemStack item : allStacks) { - tooltip.add(componentSpacing.plainCopy() - .append(Lang.translateDirect("tooltip.brass_tunnel.contains_entry", - Components.translatable(item.getDescriptionId()) - .getString(), - item.getCount())) - .withStyle(ChatFormatting.GRAY)); + Lang.translate("tooltip.brass_tunnel.contains_entry", + Components.translatable(item.getDescriptionId()).getString(), item.getCount()) + .style(ChatFormatting.GRAY).forGoggles(tooltip); } - tooltip.add(componentSpacing.plainCopy() - .append(Lang.translateDirect("tooltip.brass_tunnel.retrieve")) - .withStyle(ChatFormatting.DARK_GRAY)); + Lang.translate("tooltip.brass_tunnel.retrieve").style(ChatFormatting.DARK_GRAY).forGoggles(tooltip); return true; } diff --git a/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java b/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java index 9d82d5ce4..ee4292c77 100644 --- a/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java @@ -380,6 +380,9 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf inserter = BlockEntityBehaviour.get(level, be.getBlockPos(), InvManipulationBehaviour.TYPE); } + if (be instanceof BasinBlockEntity) + filter = null; // Do not test spout outputs against the recipe filter + IItemHandler targetInv = be == null ? null : be.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite()) .orElse(inserter == null ? null : inserter.getInventory()); @@ -402,16 +405,21 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf if (targetInv == null) break; - if (!ItemHandlerHelper.insertItemStacked(targetInv, itemStack, true) - .isEmpty()) + + ItemStack remainder = ItemHandlerHelper.insertItemStacked(targetInv, itemStack, true); + if (remainder.getCount() == itemStack.getCount()) continue; if (filter != null && !filter.test(itemStack)) continue; - update = true; - ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), false); - iterator.remove(); visualizedOutputItems.add(IntAttached.withZero(itemStack)); + update = true; + + remainder = ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), false); + if (remainder.isEmpty()) + iterator.remove(); + else + itemStack.setCount(remainder.getCount()); } for (Iterator iterator = spoutputFluidBuffer.iterator(); iterator.hasNext();) { @@ -547,9 +555,9 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf if (simulate) return true; - for (ItemStack itemStack : outputItems) { - spoutputBuffer.add(itemStack.copy()); - } + for (ItemStack itemStack : outputItems) + if (!itemStack.isEmpty()) + spoutputBuffer.add(itemStack.copy()); if (!externalTankNotPresent) for (FluidStack fluidStack : outputFluids) spoutputFluidBuffer.add(fluidStack.copy()); @@ -604,7 +612,9 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf public static HeatLevel getHeatLevelOf(BlockState state) { if (state.hasProperty(BlazeBurnerBlock.HEAT_LEVEL)) return state.getValue(BlazeBurnerBlock.HEAT_LEVEL); - return AllTags.AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) && BlockHelper.isNotUnheated(state) ? HeatLevel.SMOULDERING : HeatLevel.NONE; + return AllTags.AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) && BlockHelper.isNotUnheated(state) + ? HeatLevel.SMOULDERING + : HeatLevel.NONE; } public Couple getTanks() { diff --git a/src/main/java/com/simibubi/create/content/processing/basin/BasinInventory.java b/src/main/java/com/simibubi/create/content/processing/basin/BasinInventory.java index 0c88d4d0d..63121355d 100644 --- a/src/main/java/com/simibubi/create/content/processing/basin/BasinInventory.java +++ b/src/main/java/com/simibubi/create/content/processing/basin/BasinInventory.java @@ -13,16 +13,29 @@ public class BasinInventory extends SmartInventory { super(slots, be, 16, true); this.blockEntity = be; } - + @Override public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { - // Only insert if no other slot already has a stack of this item - for (int i = 0; i < getSlots(); i++) + int firstFreeSlot = -1; + + for (int i = 0; i < getSlots(); i++) { + // Only insert if no other slot already has a stack of this item if (i != slot && ItemHandlerHelper.canItemStacksStack(stack, inv.getStackInSlot(i))) return stack; + if (inv.getStackInSlot(i) + .isEmpty() && firstFreeSlot == -1) + firstFreeSlot = i; + } + + // Only insert if this is the first empty slot, prevents overfilling in the + // simulation pass + if (inv.getStackInSlot(slot) + .isEmpty() && firstFreeSlot != slot) + return stack; + return super.insertItem(slot, stack, simulate); } - + @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { ItemStack extractItem = super.extractItem(slot, amount, simulate); diff --git a/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java b/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java index 9a86e0066..0db6e6eec 100644 --- a/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java +++ b/src/main/java/com/simibubi/create/content/processing/basin/BasinRecipe.java @@ -149,13 +149,22 @@ public class BasinRecipe extends ProcessingRecipe { if (simulate) { if (recipe instanceof BasinRecipe basinRecipe) { recipeOutputItems.addAll(basinRecipe.rollResults()); - recipeOutputFluids.addAll(basinRecipe.getFluidResults()); - recipeOutputItems.addAll(basinRecipe.getRemainingItems(basin.getInputInventory())); + + for (FluidStack fluidStack : basinRecipe.getFluidResults()) + if (!fluidStack.isEmpty()) + recipeOutputFluids.add(fluidStack); + for (ItemStack stack : basinRecipe.getRemainingItems(basin.getInputInventory())) + if (!stack.isEmpty()) + recipeOutputItems.add(stack); + } else { recipeOutputItems.add(recipe.getResultItem()); if (recipe instanceof CraftingRecipe craftingRecipe) { - recipeOutputItems.addAll(craftingRecipe.getRemainingItems(new DummyCraftingContainer(availableItems, extractedItemsFromSlot))); + for (ItemStack stack : craftingRecipe + .getRemainingItems(new DummyCraftingContainer(availableItems, extractedItemsFromSlot))) + if (!stack.isEmpty()) + recipeOutputItems.add(stack); } } } diff --git a/src/main/java/com/simibubi/create/content/redstone/analogLever/AnalogLeverBlockEntity.java b/src/main/java/com/simibubi/create/content/redstone/analogLever/AnalogLeverBlockEntity.java index 3902009ff..53b0c6b83 100644 --- a/src/main/java/com/simibubi/create/content/redstone/analogLever/AnalogLeverBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/redstone/analogLever/AnalogLeverBlockEntity.java @@ -79,7 +79,7 @@ public class AnalogLeverBlockEntity extends SmartBlockEntity implements IHaveGog @Override public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { - tooltip.add(componentSpacing.plainCopy().append(Lang.translateDirect("tooltip.analogStrength", this.state))); + Lang.translate("tooltip.analogStrength", this.state).forGoggles(tooltip); return true; } diff --git a/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java b/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java index f623407a0..0163ed260 100644 --- a/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/redstone/thresholdSwitch/ThresholdSwitchBlockEntity.java @@ -2,7 +2,10 @@ package com.simibubi.create.content.redstone.thresholdSwitch; import java.util.List; -import com.simibubi.create.compat.storageDrawers.StorageDrawers; +import com.simibubi.create.compat.thresholdSwitch.FunctionalStorage; +import com.simibubi.create.compat.thresholdSwitch.SophisticatedStorage; +import com.simibubi.create.compat.thresholdSwitch.StorageDrawers; +import com.simibubi.create.compat.thresholdSwitch.ThresholdSwitchCompat; import com.simibubi.create.content.redstone.DirectedDirectionalBlock; import com.simibubi.create.content.redstone.FilteredDetectorFilterSlot; import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlock; @@ -42,6 +45,12 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity { private TankManipulationBehaviour observedTank; private VersionedInventoryTrackerBehaviour invVersionTracker; + private static final List COMPAT = List.of( + new FunctionalStorage(), + new SophisticatedStorage(), + new StorageDrawers() + ); + public ThresholdSwitchBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); onWhenAbove = .75f; @@ -104,27 +113,32 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity { if (targetBlockEntity instanceof ThresholdSwitchObservable observable) { currentLevel = observable.getPercent() / 100f; - } else if (StorageDrawers.isDrawer(targetBlockEntity) && observedInventory.hasInventory()) { - currentLevel = StorageDrawers.getTrueFillLevel(observedInventory.getInventory(), filtering); - } else if (observedInventory.hasInventory() || observedTank.hasInventory()) { if (observedInventory.hasInventory()) { - + // Item inventory IItemHandler inv = observedInventory.getInventory(); if (invVersionTracker.stillWaiting(inv)) { occupied = prevLevel; totalSpace = 1f; - + } else { invVersionTracker.awaitNewVersion(inv); for (int slot = 0; slot < inv.getSlots(); slot++) { ItemStack stackInSlot = inv.getStackInSlot(slot); - int space = Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slot)); + + int finalSlot = slot; + long space = COMPAT + .stream() + .filter(compat -> compat.isFromThisMod(targetBlockEntity)) + .map(compat -> compat.getSpaceInSlot(inv, finalSlot)) + .findFirst() + .orElseGet(() -> (long) Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(finalSlot))); + int count = stackInSlot.getCount(); if (space == 0) continue; - + totalSpace += 1; if (filtering.test(stackInSlot)) occupied += count * (1f / space); @@ -209,7 +223,7 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity { this.updateCurrentLevel(); invVersionTracker.reset(); })); - + behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this)); InterfaceProvider towardBlockFacing = diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java b/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java index 1ecb77e29..f26940d4c 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java @@ -2,10 +2,14 @@ package com.simibubi.create.foundation.blockEntity.renderer; import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; +import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; public abstract class SafeBlockEntityRenderer implements BlockEntityRenderer { @Override @@ -23,4 +27,21 @@ public abstract class SafeBlockEntityRenderer implements return !be.hasLevel() || be.getBlockState() .getBlock() == Blocks.AIR; } + + public boolean shouldCullItem(Vec3 itemPos) { + Frustum frustum = Minecraft.getInstance().levelRenderer.capturedFrustum != null ? + Minecraft.getInstance().levelRenderer.capturedFrustum : + Minecraft.getInstance().levelRenderer.cullingFrustum; + + AABB itemBB = new AABB( + itemPos.x - 0.25, + itemPos.y - 0.25, + itemPos.z - 0.25, + itemPos.x + 0.25, + itemPos.y + 0.25, + itemPos.z + 0.25 + ); + + return !frustum.isVisible(itemBB); + } } diff --git a/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java b/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java index b39035f11..b985cfbb4 100644 --- a/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java +++ b/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java @@ -435,11 +435,10 @@ public class BuilderTransformers { .when(survivesExplosion) .setRolls(ConstantValue.exactly(1)) .add(LootItem.lootTableItem(drop.get()) - .apply(CopyNameFunction.copyName(CopyNameFunction.NameSource.BLOCK_ENTITY)) .apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY) - .copy("Air", "Air")) + .copy("VanillaTag", "{}", CopyNbtFunction.MergeStrategy.MERGE)) .apply(CopyNbtFunction.copyData(ContextNbtProvider.BLOCK_ENTITY) - .copy("Enchantments", "Enchantments"))))); + .copy("Air", "Air"))))); }); } diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/CrushingRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/CrushingRecipeGen.java index ee78cbec9..33223bb04 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/CrushingRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/CrushingRecipeGen.java @@ -93,13 +93,15 @@ public class CrushingRecipeGen extends ProcessingRecipeGen { DEEP_GOLD_ORE = deepslateOre(() -> Items.DEEPSLATE_GOLD_ORE, AllItems.CRUSHED_GOLD::get, 2.25f, 350), DEEP_DIAMOND_ORE = deepslateOre(() -> Items.DEEPSLATE_DIAMOND_ORE, () -> Items.DIAMOND, 2.25f, 450), DEEP_EMERALD_ORE = deepslateOre(() -> Items.DEEPSLATE_EMERALD_ORE, () -> Items.EMERALD, 2.25f, 450), - DEEP_COAL_ORE = deepslateOre(() -> Items.DEEPSLATE_COAL_ORE, () -> Items.COAL, 1.75f, 250), + DEEP_COAL_ORE = deepslateOre(() -> Items.DEEPSLATE_COAL_ORE, () -> Items.COAL, 2.25f, 300), DEEP_REDSTONE_ORE = deepslateOre(() -> Items.DEEPSLATE_REDSTONE_ORE, () -> Items.REDSTONE, 7.5f, 350), DEEP_LAPIS_ORE = deepslateOre(() -> Items.DEEPSLATE_LAPIS_ORE, () -> Items.LAPIS_LAZULI, 12.5f, 350), NETHER_GOLD_ORE = netherOre(() -> Items.NETHER_GOLD_ORE, () -> Items.GOLD_NUGGET, 18, 350), NETHER_QUARTZ_ORE = netherOre(() -> Items.NETHER_QUARTZ_ORE, () -> Items.QUARTZ, 2.25f, 350), + GILDED_BLACKSTONE = ore(Items.BLACKSTONE, () -> Items.GILDED_BLACKSTONE, () -> Items.GOLD_NUGGET, 18, 400), + RAW_COPPER_ORE = rawOre(() -> Items.RAW_COPPER, AllItems.CRUSHED_COPPER::get, 1), RAW_ZINC_ORE = rawOre(AllItems.RAW_ZINC::get, AllItems.CRUSHED_ZINC::get, 1), RAW_IRON_ORE = rawOre(() -> Items.RAW_IRON, AllItems.CRUSHED_IRON::get, 1), diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/FillingRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/FillingRecipeGen.java index c5f6c2a6b..9e967348b 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/FillingRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/FillingRecipeGen.java @@ -62,7 +62,7 @@ public class FillingRecipeGen extends ProcessingRecipeGen { .output(Items.GLOWSTONE_DUST)), - AM_LAVA = create(Mods.AM.recipeId("milk_bottle"), b -> b.require(Fluids.LAVA, 250) + AM_LAVA = create(Mods.AM.recipeId("lava_bottle"), b -> b.require(Fluids.LAVA, 250) .require(Items.GLASS_BOTTLE) .output(1, Mods.AM, "lava_bottle", 1) .whenModLoaded(Mods.AM.getId())), diff --git a/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java b/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java index befb004b2..5d54e13cf 100644 --- a/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java +++ b/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java @@ -49,6 +49,14 @@ public class FluidHelper { public static boolean isLava(Fluid fluid) { return convertToStill(fluid) == Fluids.LAVA; } + + public static boolean isSame(FluidStack fluidStack, FluidStack fluidStack2) { + return fluidStack.getFluid() == fluidStack2.getFluid(); + } + + public static boolean isSame(FluidStack fluidStack, Fluid fluid) { + return fluidStack.getFluid() == fluid; + } @SuppressWarnings("deprecation") public static boolean isTag(Fluid fluid, TagKey tag) { diff --git a/src/main/java/com/simibubi/create/foundation/fluid/FluidIngredient.java b/src/main/java/com/simibubi/create/foundation/fluid/FluidIngredient.java index ba85a3dc2..9f1eccaf0 100644 --- a/src/main/java/com/simibubi/create/foundation/fluid/FluidIngredient.java +++ b/src/main/java/com/simibubi/create/foundation/fluid/FluidIngredient.java @@ -152,8 +152,7 @@ public abstract class FluidIngredient implements Predicate { @Override protected boolean testInternal(FluidStack t) { - if (!t.getFluid() - .isSame(fluid)) + if (!FluidHelper.isSame(t, fluid)) return false; if (tagToMatch.isEmpty()) return true; @@ -201,17 +200,14 @@ public abstract class FluidIngredient implements Predicate { protected TagKey tag; - @SuppressWarnings("deprecation") @Override protected boolean testInternal(FluidStack t) { - if (tag == null) { - for (FluidStack accepted : getMatchingFluidStacks()) - if (accepted.getFluid() - .isSame(t.getFluid())) - return true; - return false; - } - return t.getFluid().is(tag); + if (tag != null) + return FluidHelper.isTag(t, tag); + for (FluidStack accepted : getMatchingFluidStacks()) + if (FluidHelper.isSame(accepted, t)) + return true; + return false; } @Override diff --git a/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java b/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java index af1adfc9d..e5da669a1 100644 --- a/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java +++ b/src/main/java/com/simibubi/create/foundation/item/TooltipHelper.java @@ -6,7 +6,6 @@ import java.util.LinkedList; import java.util.List; import com.google.common.base.Strings; -import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation; import com.simibubi.create.foundation.utility.Components; import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Lang; @@ -30,15 +29,11 @@ public class TooltipHelper { } public static void addHint(List tooltip, String hintKey, Object... messageParams) { - Component spacing = IHaveGoggleInformation.componentSpacing; - tooltip.add(spacing.plainCopy() - .append(Lang.translateDirect(hintKey + ".title")) - .withStyle(ChatFormatting.GOLD)); + Lang.translate(hintKey + ".title").style(ChatFormatting.GOLD).forGoggles(tooltip); Component hint = Lang.translateDirect(hintKey); List cutComponent = cutTextComponent(hint, Palette.GRAY_AND_WHITE); for (Component component : cutComponent) - tooltip.add(spacing.plainCopy() - .append(component)); + Lang.text(component.getString()).forGoggles(tooltip); } public static String makeProgressBar(int length, int filledLength) { @@ -54,7 +49,7 @@ public class TooltipHelper { public static Style styleFromColor(ChatFormatting color) { return Style.EMPTY.applyFormat(color); } - + public static Style styleFromColor(int hex) { return Style.EMPTY.withColor(hex); } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/accessor/MouseHandlerAccessor.java b/src/main/java/com/simibubi/create/foundation/mixin/accessor/MouseHandlerAccessor.java new file mode 100644 index 000000000..d837c06f0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/accessor/MouseHandlerAccessor.java @@ -0,0 +1,16 @@ +package com.simibubi.create.foundation.mixin.accessor; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import net.minecraft.client.MouseHandler; + +@Mixin(MouseHandler.class) +public interface MouseHandlerAccessor { + + @Accessor("xpos") + void create$setXPos(double xPos); + + @Accessor("ypos") + void create$setYPos(double yPos); +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java index 4c3715fb6..94a639161 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java @@ -49,4 +49,7 @@ public class AngleHelper { return diff; } + public static float wrapAngle180(float angle) { + return (angle + 180) % 360 - 180; + } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/LangBuilder.java b/src/main/java/com/simibubi/create/foundation/utility/LangBuilder.java index 564b6131f..161f52dd4 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/LangBuilder.java +++ b/src/main/java/com/simibubi/create/foundation/utility/LangBuilder.java @@ -2,10 +2,15 @@ package com.simibubi.create.foundation.utility; import java.util.List; +import com.simibubi.create.compat.Mods; + import joptsimple.internal.Strings; import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.util.Mth; import net.minecraft.world.entity.player.Player; public class LangBuilder { @@ -29,7 +34,7 @@ public class LangBuilder { * Appends a localised component
* To add an independently formatted localised component, use add() and a nested * builder - * + * * @param langKey * @param args * @return @@ -40,7 +45,7 @@ public class LangBuilder { /** * Appends a text component - * + * * @param literalText * @return */ @@ -50,7 +55,7 @@ public class LangBuilder { /** * Appends a colored text component - * + * * @param format * @param literalText * @return @@ -61,7 +66,7 @@ public class LangBuilder { /** * Appends a colored text component - * + * * @param color * @param literalText * @return @@ -72,7 +77,7 @@ public class LangBuilder { /** * Appends the contents of another builder - * + * * @param otherBuilder * @return */ @@ -82,7 +87,7 @@ public class LangBuilder { /** * Appends a component - * + * * @param customComponent * @return */ @@ -95,7 +100,7 @@ public class LangBuilder { /** * Applies the format to all added components - * + * * @param format * @return */ @@ -107,7 +112,7 @@ public class LangBuilder { /** * Applies the color to all added components - * + * * @param color * @return */ @@ -150,11 +155,20 @@ public class LangBuilder { public void forGoggles(List tooltip, int indents) { tooltip.add(Lang.builder() - .text(Strings.repeat(' ', 4 + indents)) + .text(Strings.repeat(' ', getIndents(Minecraft.getInstance().font, 4 + indents))) .add(this) .component()); } + public static final float DEFAULT_SPACE_WIDTH = 4.0F; // space width in vanilla's default font + static int getIndents(Font font, int defaultIndents) { + int spaceWidth = font.width(" "); + if (DEFAULT_SPACE_WIDTH == spaceWidth) { + return defaultIndents; + } + return Mth.ceil(DEFAULT_SPACE_WIDTH * defaultIndents / spaceWidth); + } + // private void assertComponent() { @@ -162,4 +176,4 @@ public class LangBuilder { throw new IllegalStateException("No components were added to builder"); } -} \ No newline at end of file +} diff --git a/src/main/java/com/simibubi/create/infrastructure/debugInfo/DebugInformation.java b/src/main/java/com/simibubi/create/infrastructure/debugInfo/DebugInformation.java index ac34ab7b3..120392857 100644 --- a/src/main/java/com/simibubi/create/infrastructure/debugInfo/DebugInformation.java +++ b/src/main/java/com/simibubi/create/infrastructure/debugInfo/DebugInformation.java @@ -26,6 +26,7 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.ModList; import net.minecraftforge.forgespi.language.IModInfo; +import oshi.SystemInfo; /** * Allows for providing easily accessible debugging information. @@ -86,6 +87,7 @@ public class DebugInformation { .put("Java Version", SystemReportAccessor.getJAVA_VERSION()) .put("JVM Flags", getMcSystemInfo("JVM Flags")) .put("Memory", () -> getMcSystemInfo("Memory")) + .put("Total Memory", getTotalRam()) .put("CPU", getCpuInfo()) .putAll(listAllGraphicsCards()) .buildTo(DebugInformation::registerBothInfo); @@ -129,6 +131,13 @@ public class DebugInformation { return cards.isEmpty() ? List.of(new InfoEntry("Graphics cards", "none")) : cards; } + public static String getTotalRam() { + long availableMemory = new SystemInfo().getHardware().getMemory().getAvailable(); + long totalMemory = new SystemInfo().getHardware().getMemory().getTotal(); + long usedMemory = totalMemory - availableMemory; + return String.format("%s bytes (%s MiB) / %s bytes (%s MiB)", usedMemory, usedMemory / 1049000, totalMemory, totalMemory / 1049000); + } + public static String getCpuInfo() { String name = tryTrim(getMcSystemInfo("Processor Name")); String freq = getMcSystemInfo("Frequency (GHz)"); diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index a911f646d..1bc660abe 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -42,3 +42,6 @@ public net.minecraft.client.model.AgeableListModel f_102012_ # bodyYOffset public net.minecraft.client.gui.components.CommandSuggestions f_93866_ # suggestions public net.minecraft.client.gui.components.CommandSuggestions$SuggestionsList (Lnet/minecraft/client/gui/components/CommandSuggestions;IIILjava/util/List;Z)V # + +public net.minecraft.client.renderer.LevelRenderer f_172938_ # cullingFrustum +public net.minecraft.client.renderer.LevelRenderer f_109442_ # capturedFrustum diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index 63c44c55f..a434994ce 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -29,6 +29,7 @@ "accessor.AgeableListModelAccessor", "accessor.GameRendererAccessor", "accessor.HumanoidArmorLayerAccessor", + "accessor.MouseHandlerAccessor", "accessor.ParticleEngineAccessor", "client.BlockDestructionProgressMixin", "client.CameraMixin",