diff --git a/gradle.properties b/gradle.properties index b8aa2e22..5b4f0579 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ fabric_version=0.100.0+1.21 maven_group = eu.pb4 -mod_version = 0.9.7 +mod_version = 0.9.8 minecraft_version_supported = ">=1.20.5-" diff --git a/polymer-blocks/src/main/java/eu/pb4/polymer/blocks/api/BlockResourceCreator.java b/polymer-blocks/src/main/java/eu/pb4/polymer/blocks/api/BlockResourceCreator.java index c4ea4f72..7649b7a1 100644 --- a/polymer-blocks/src/main/java/eu/pb4/polymer/blocks/api/BlockResourceCreator.java +++ b/polymer-blocks/src/main/java/eu/pb4/polymer/blocks/api/BlockResourceCreator.java @@ -16,19 +16,24 @@ import net.minecraft.block.Waterloggable; import net.minecraft.registry.Registries; import net.minecraft.state.property.Properties; +import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; import java.nio.charset.StandardCharsets; import java.util.*; public final class BlockResourceCreator { + private static final PolymerBlockModel EMPTY = PolymerBlockModel.of(Identifier.of("polymer", "block/empty")); private final Map> states; final Map models; private final ResourcePackCreator creator; private final Runnable onRegister; private final BlockExtBlockMapper blockMapper; + private final EnumMap emptyBlocks = new EnumMap<>(BlockModelType.class); + private boolean registered = false; + private boolean registeredEmpty = false; public static BlockResourceCreator of(ResourcePackCreator creator) { if (CompatStatus.POLYMC) { @@ -38,7 +43,7 @@ public static BlockResourceCreator of(ResourcePackCreator creator) { return new BlockResourceCreator(creator, new BlockExtBlockMapper(BlockMapper.createDefault()), () -> {}); } - protected BlockResourceCreator(ResourcePackCreator creator, BlockExtBlockMapper blockMapper, Runnable onRegister) { + BlockResourceCreator(ResourcePackCreator creator, BlockExtBlockMapper blockMapper, Runnable onRegister) { this.states = new HashMap<>(DefaultModelData.USABLE_STATES); this.models = new HashMap<>(DefaultModelData.MODELS); this.creator = creator; @@ -50,7 +55,7 @@ public BlockMapper getBlockMapper() { return this.blockMapper; } - protected void registerEvent() { + private void registerEvent() { if (!this.registered) { PolymerBlockUtils.requireStrictBlockUpdates(); creator.creationEvent.register((b) -> { @@ -63,15 +68,29 @@ protected void registerEvent() { } } + @Nullable + public BlockState requestEmpty(BlockModelType type) { + var x = this.emptyBlocks.get(type); + if (x != null) { + return x; + } + x = requestBlock(type, EMPTY); + this.emptyBlocks.put(type, x); + if (!this.registeredEmpty) { + this.registeredEmpty = true; + this.creator.addAssetSource("polymer-blocks"); + } + return x; + } + @Nullable public BlockState requestBlock(BlockModelType type, PolymerBlockModel... model) { var states = this.states.get(type); - if (states.size() != 0) { + if (!states.isEmpty()) { this.registerEvent(); - var state = states.remove(0); + var state = states.removeFirst(); models.put(state, model); - if (state.getBlock() instanceof Waterloggable) { this.blockMapper.stateMap.put(state, DefaultModelData.SPECIAL_REMAPS .getOrDefault(state, (state.getBlock() instanceof LeavesBlock diff --git a/polymer-blocks/src/main/java/eu/pb4/polymer/blocks/api/PolymerBlockResourceUtils.java b/polymer-blocks/src/main/java/eu/pb4/polymer/blocks/api/PolymerBlockResourceUtils.java index d9f8ab20..05cceb61 100644 --- a/polymer-blocks/src/main/java/eu/pb4/polymer/blocks/api/PolymerBlockResourceUtils.java +++ b/polymer-blocks/src/main/java/eu/pb4/polymer/blocks/api/PolymerBlockResourceUtils.java @@ -20,6 +20,11 @@ public static BlockState requestBlock(BlockModelType type, PolymerBlockModel mod return CREATOR.requestBlock(type, model); } + @Nullable + public static BlockState requestEmpty(BlockModelType type) { + return CREATOR.requestEmpty(type); + } + @Nullable public static BlockState requestBlock(BlockModelType type, PolymerBlockModel... model) { return CREATOR.requestBlock(type, model); diff --git a/polymer-blocks/src/main/resources/assets/polymer/models/block/empty.json b/polymer-blocks/src/main/resources/assets/polymer/models/block/empty.json new file mode 100644 index 00000000..d2ceb220 --- /dev/null +++ b/polymer-blocks/src/main/resources/assets/polymer/models/block/empty.json @@ -0,0 +1,6 @@ +{ + "textures": { + "particle": "polymer:block/empty" + }, + "elements": [] +} diff --git a/polymer-blocks/src/main/resources/assets/polymer/textures/block/empty.png b/polymer-blocks/src/main/resources/assets/polymer/textures/block/empty.png new file mode 100644 index 00000000..4d7beb80 Binary files /dev/null and b/polymer-blocks/src/main/resources/assets/polymer/textures/block/empty.png differ diff --git a/polymer-blocks/src/testmod/java/eu/pb4/blocktest/EmptyBlock.java b/polymer-blocks/src/testmod/java/eu/pb4/blocktest/EmptyBlock.java new file mode 100644 index 00000000..05b6ac56 --- /dev/null +++ b/polymer-blocks/src/testmod/java/eu/pb4/blocktest/EmptyBlock.java @@ -0,0 +1,24 @@ +package eu.pb4.blocktest; + +import eu.pb4.polymer.blocks.api.BlockModelType; +import eu.pb4.polymer.blocks.api.PolymerBlockModel; +import eu.pb4.polymer.blocks.api.PolymerBlockResourceUtils; +import eu.pb4.polymer.blocks.api.PolymerTexturedBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.util.Identifier; + +public class EmptyBlock extends Block implements PolymerTexturedBlock { + private final BlockState polymerBlockState; + + public EmptyBlock(Settings settings, BlockModelType type) { + super(settings); + this.polymerBlockState = PolymerBlockResourceUtils.requestEmpty(type); + + } + + @Override + public BlockState getPolymerBlockState(BlockState state) { + return this.polymerBlockState; + } +} diff --git a/polymer-blocks/src/testmod/java/eu/pb4/blocktest/TestInitializer.java b/polymer-blocks/src/testmod/java/eu/pb4/blocktest/TestInitializer.java index e2a5fbb1..c97cabcb 100644 --- a/polymer-blocks/src/testmod/java/eu/pb4/blocktest/TestInitializer.java +++ b/polymer-blocks/src/testmod/java/eu/pb4/blocktest/TestInitializer.java @@ -1,15 +1,19 @@ package eu.pb4.blocktest; import eu.pb4.polymer.blocks.api.BlockModelType; +import eu.pb4.polymer.core.api.item.PolymerBlockItem; import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.minecraft.block.Blocks; +import net.minecraft.component.DataComponentTypes; import net.minecraft.item.Item; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; +import java.util.Locale; + public class TestInitializer implements ModInitializer { //public static final PolymerItemGroupUtils ITEM_GROUP = PolymerItemGroupUtils.create(Identifier.of("test/textured_blocks"), Text.literal("Textured blocks"), () -> new ItemStack(Items.BAMBOO)); @@ -24,6 +28,9 @@ public void onInitialize() { register(BlockModelType.VINES_BLOCK, "block/table"); register(BlockModelType.BIOME_PLANT_BLOCK, "block/steel_block"); register(BlockModelType.KELP_BLOCK, "block/titan_ore_nether"); + registerEmpty(BlockModelType.KELP_BLOCK); + registerEmpty(BlockModelType.VINES_BLOCK); + registerEmpty(BlockModelType.PLANT_BLOCK); } public static void register(BlockModelType type, String modelId) { @@ -33,4 +40,14 @@ public static void register(BlockModelType type, String modelId) { Registry.register(Registries.ITEM, id, new TestItem(new Item.Settings(), block, modelId)); } + + public static void registerEmpty(BlockModelType type) { + var id = Identifier.of("blocktest", "empty/" + type.name().toLowerCase(Locale.ROOT)); + var block = Registry.register(Registries.BLOCK, id, + new EmptyBlock(FabricBlockSettings.copy(Blocks.DIAMOND_BLOCK), type)); + + Registry.register(Registries.ITEM, id, new PolymerBlockItem(block, new Item.Settings() + .component(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, true), + block.getPolymerBlockState(block.getDefaultState()).getBlock().asItem())); + } } diff --git a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/PolymerImplUtils.java b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/PolymerImplUtils.java index fe7571e9..6c796b32 100644 --- a/polymer-core/src/main/java/eu/pb4/polymer/core/impl/PolymerImplUtils.java +++ b/polymer-core/src/main/java/eu/pb4/polymer/core/impl/PolymerImplUtils.java @@ -322,7 +322,9 @@ public static void callItemGroupEvents(Identifier id, ItemGroup itemGroup, List< ItemGroupEvents.modifyEntriesEvent(RegistryKey.of(RegistryKeys.ITEM_GROUP, id)).invoker().modifyEntries(fabricCollector); ItemGroupEvents.MODIFY_ENTRIES_ALL.invoker().modifyEntries(itemGroup, fabricCollector); } catch (Throwable e) { - PolymerImpl.LOGGER.warn("Failed to execute Fabric Item Group event!", e); + if (PolymerImpl.LOG_MORE_ERRORS) { + PolymerImpl.LOGGER.warn("Failed to execute Fabric Item Group event!", e); + } } } } diff --git a/polymer-core/src/testmod/java/eu/pb4/polymertest/AnimatedBlock.java b/polymer-core/src/testmod/java/eu/pb4/polymertest/AnimatedBlock.java index 529c27ec..3112bf26 100644 --- a/polymer-core/src/testmod/java/eu/pb4/polymertest/AnimatedBlock.java +++ b/polymer-core/src/testmod/java/eu/pb4/polymertest/AnimatedBlock.java @@ -22,10 +22,12 @@ import net.minecraft.state.property.BooleanProperty; import net.minecraft.util.DyeColor; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ColorHelper; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.random.Random; import net.minecraft.world.World; +import net.minecraft.world.biome.source.BiomeCoords; import net.minecraft.world.chunk.WorldChunk; import org.jetbrains.annotations.Nullable; import org.joml.Matrix4x3f; @@ -92,10 +94,9 @@ public CustomHolder(ServerWorld world) { this.planetElement.setTeleportDuration(1); this.entity = this.addElement(new EntityElement<>(EntityType.SHEEP, world)); entity.entity().setColor(DyeColor.PINK); - entity.setOffset(new Vec3d(0, 0.5, 0)); - + entity.setOffset(new Vec3d(0, 1, 0)); this.centralElement.setGlowing(true); - this.centralElement.setGlowColorOverride(0xfdffba); + this.centralElement.setGlowColorOverride(0x000000); this.animate(); } @@ -104,6 +105,18 @@ protected void onTick() { this.animate(); } + @Override + protected void onAttachmentSet(HolderAttachment attachment, @Nullable HolderAttachment oldAttachment) { + if (attachment instanceof ChunkAttachment chunkAttachment) { + var pos = BlockPos.ofFloored(attachment.getPos()); + this.centralElement.setGlowColorOverride(ColorHelper.Abgr.toAbgr(chunkAttachment.getChunk().getBiomeForNoiseGen( + BiomeCoords.fromBlock(pos.getX()), + BiomeCoords.fromBlock(pos.getY()), + BiomeCoords.fromBlock(pos.getZ()) + ).value().getWaterColor())); + } + } + public void animate() { if (this.tick % 3 == 0) { this.centralElement.setTransformation(new Matrix4x3f().rotateY(this.tick / 200f).rotateX(MathHelper.PI / 16).scale(2.2f)); diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/ElementHolder.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/ElementHolder.java index dead49e5..b72b6354 100644 --- a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/ElementHolder.java +++ b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/ElementHolder.java @@ -210,15 +210,25 @@ public HolderAttachment getAttachment() { } public void setAttachment(@Nullable HolderAttachment attachment) { + var oldAttachment = this.attachment; this.attachment = attachment; if (attachment != null) { if (this.currentPos == Vec3d.ZERO && attachment.canUpdatePosition()) { this.updateInitialPosition(); } attachment.updateCurrentlyTracking(new ArrayList<>(this.players)); + this.onAttachmentSet(attachment, oldAttachment); + } else if (oldAttachment != null) { + this.onAttachmentRemoved(oldAttachment); } } + protected void onAttachmentSet(HolderAttachment attachment, @Nullable HolderAttachment oldAttachment) { + } + + protected void onAttachmentRemoved(HolderAttachment oldAttachment) { + } + public Vec3d getPos() { if (this.currentPos == Vec3d.ZERO && attachment != null && attachment.canUpdatePosition()) { this.currentPos = attachment.getPos(); diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/attachment/ChunkAttachment.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/attachment/ChunkAttachment.java index 2dbadcd4..ed60cb60 100644 --- a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/attachment/ChunkAttachment.java +++ b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/api/attachment/ChunkAttachment.java @@ -126,4 +126,8 @@ public Vec3d getPos() { public ServerWorld getWorld() { return (ServerWorld) this.chunk.getWorld(); } + + public WorldChunk getChunk() { + return this.chunk; + } } diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/mixin/block/ServerChunkManagerMixin.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/mixin/block/ServerChunkManagerMixin.java new file mode 100644 index 00000000..79b76167 --- /dev/null +++ b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/mixin/block/ServerChunkManagerMixin.java @@ -0,0 +1,34 @@ +package eu.pb4.polymer.virtualentity.mixin.block; + +import com.llamalad7.mixinextras.sugar.Local; +import eu.pb4.polymer.virtualentity.impl.HolderAttachmentHolder; +import eu.pb4.polymer.virtualentity.impl.HolderHolder; +import net.minecraft.server.world.ServerChunkManager; +import net.minecraft.world.chunk.WorldChunk; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(ServerChunkManager.class) +public class ServerChunkManagerMixin { + @Inject(method = "tickChunks", at = @At(value = "INVOKE", target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V")) + private void tickElementHoldersEvenIfBlocksDont(CallbackInfo ci, @Local List chunkList) { + chunkList.forEach(this::tickHolders); + } + + @Unique + private void tickHolders(ServerChunkManager.ChunkWithHolder chunkWithHolder) { + var holo = ((HolderAttachmentHolder) chunkWithHolder.chunk()).polymerVE$getHolders(); + + if (!holo.isEmpty()) { + var arr = holo.toArray(HolderHolder.HOLDER_ATTACHMENTS); + for (int i = 0; i < arr.length; i++) { + arr[i].tick(); + } + } + } +} diff --git a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/mixin/block/ServerWorldMixin.java b/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/mixin/block/ServerWorldMixin.java deleted file mode 100644 index baa03a6e..00000000 --- a/polymer-virtual-entity/src/main/java/eu/pb4/polymer/virtualentity/mixin/block/ServerWorldMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package eu.pb4.polymer.virtualentity.mixin.block; - -import eu.pb4.polymer.virtualentity.impl.HolderAttachmentHolder; -import eu.pb4.polymer.virtualentity.impl.HolderHolder; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.world.chunk.WorldChunk; -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 java.util.ArrayList; -import java.util.List; - -@Mixin(ServerWorld.class) -public abstract class ServerWorldMixin { - - @Inject(method = "tickChunk", at = @At("TAIL")) - private void polymerVE$tickChunk(WorldChunk chunk, int randomTickSpeed, CallbackInfo ci) { - var holo = ((HolderAttachmentHolder) chunk).polymerVE$getHolders(); - - if (!holo.isEmpty()) { - var arr = holo.toArray(HolderHolder.HOLDER_ATTACHMENTS); - for (int i = 0; i < arr.length; i++) { - arr[i].tick(); - } - } - } -} diff --git a/polymer-virtual-entity/src/main/resources/polymer-virtual-entity.accesswidener b/polymer-virtual-entity/src/main/resources/polymer-virtual-entity.accesswidener index 15409951..1a2b745a 100644 --- a/polymer-virtual-entity/src/main/resources/polymer-virtual-entity.accesswidener +++ b/polymer-virtual-entity/src/main/resources/polymer-virtual-entity.accesswidener @@ -1,3 +1,4 @@ accessWidener v1 named accessible class net/minecraft/server/world/ServerChunkLoadingManager$EntityTracker +accessible class net/minecraft/server/world/ServerChunkManager$ChunkWithHolder diff --git a/polymer-virtual-entity/src/main/resources/polymer-virtual-entity.mixins.json b/polymer-virtual-entity/src/main/resources/polymer-virtual-entity.mixins.json index 2b602775..0f70bd4a 100644 --- a/polymer-virtual-entity/src/main/resources/polymer-virtual-entity.mixins.json +++ b/polymer-virtual-entity/src/main/resources/polymer-virtual-entity.mixins.json @@ -25,13 +25,13 @@ "accessors.InteractionEntityAccessor", "accessors.ItemDisplayEntityAccessor", "accessors.PlaySoundFromEntityS2CPacketAccessor", - "accessors.TextDisplayEntityAccessor", "accessors.ServerChunkLoadingManagerAccessor", + "accessors.TextDisplayEntityAccessor", "block.FallingBlockEntityMixin", "block.PistonBlockEntityMixin", "block.PistonBlockMixin", - "block.ServerWorldMixin", "block.ServerChunkLoadingManagerMixin", + "block.ServerChunkManagerMixin", "block.WorldChunkMixin", "compat.ip_ImmPtlChunkTracking", "compat.ip_PlayerChunkLoadingMixin"