Search the Community
Showing results for tags 'blocks'.
-
I have been working on a complex block for a mod I'm working on. This block is really unfinished right now, but there is this strange bug that is hindering progress. Basically, this block has a single slot where you put a specific item, then there are three "buttons" on the right like the Enchantment Table. Later on these buttons will have a special purpose so don't worry about them, but right now these buttons just increment a new property on the player as long as they have xp levels. The bug is that whenever you click on one of the three buttons, the items you put in are supposed to decrement, but when you take them out or you reopen the block's gui, the item stack mysteriously "resets", meaning that all the items that were consumed are present again. Here is the Block Entity class (do realize that I am developing this mod in IntelliJ IDEA 2024.1.4 Community Edition): package everyblu.ars_mythos.common.block.tiles; import com.github.alexthe666.iceandfire.item.IafItemRegistry; import everyblu.ars_mythos.client.menus.ArcaneScholarsAnalysisMenu; import everyblu.ars_mythos.common.block.ArcaneScholarsBlock; import everyblu.ars_mythos.common.block.ArsMythosBlockStateProperties; import everyblu.ars_mythos.common.registry.ArsMythosObjectRegistry; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.NonNullList; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.world.*; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bernie.geckolib.animatable.GeoBlockEntity; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.core.animation.AnimatableManager; import software.bernie.geckolib.core.animation.AnimationController; import software.bernie.geckolib.core.object.PlayState; import software.bernie.geckolib.util.GeckoLibUtil; public class ArcaneScholarsTile extends BlockEntity implements GeoBlockEntity, WorldlyContainer, MenuProvider { public final String variant; private final NonNullList<ItemStack> items = NonNullList.withSize(1, ItemStack.EMPTY); public ArcaneScholarsTile(BlockPos pPos, BlockState pBlockState) { super(ArsMythosObjectRegistry.NEW_ARCANE_SCHOLARS_TILE.get(), pPos, pBlockState); this.variant = switch (pBlockState.getValue(ArsMythosBlockStateProperties.ARCANE_SCHOLARS_VARIANT)) { case 1 -> "fire"; case 2 -> "ice"; default -> "lightning"; }; } @Override public void load(@NotNull CompoundTag tag) { super.load(tag); ContainerHelper.loadAllItems(tag, this.items); System.out.println("loaded"); } @Override protected void saveAdditional(@NotNull CompoundTag tag) { if (this.level == null) return; ContainerHelper.saveAllItems(tag, this.items); super.saveAdditional(tag); } private ArcaneScholarsTile getFootPart() { if (this.level == null) return this; BlockEntity nextEntity = this.level.getBlockEntity( this.getBlockPos().relative(this.getBlockState().getValue(ArcaneScholarsBlock.FACING))); if (nextEntity instanceof ArcaneScholarsTile arcaneScholarsTile) return arcaneScholarsTile; return this; } AnimationController<ArcaneScholarsTile> controller; AnimatableInstanceCache factory = GeckoLibUtil.createInstanceCache(this); @Override public void registerControllers(AnimatableManager.ControllerRegistrar controllerRegistrar) { this.controller = new AnimationController<>(this, "controller", 1, (state) -> PlayState.CONTINUE); controllerRegistrar.add(this.controller); } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { return this.factory; } @Override public @NotNull Component getDisplayName() { return Component.literal("Arcane Scholar's Table"); } @Nullable @Override public AbstractContainerMenu createMenu(int pContainerId, @NotNull Inventory pPlayerInventory, @NotNull Player pPlayer) { BlockEntity entity = this.getFootPart(); return new ArcaneScholarsAnalysisMenu(pContainerId, pPlayerInventory, entity); } @Override public int @NotNull [] getSlotsForFace(@NotNull Direction pSide) { return new int[0]; } @Override public boolean canPlaceItemThroughFace(int pIndex, @NotNull ItemStack pItemStack, @Nullable Direction pDirection) { return pDirection == Direction.UP && pItemStack.is(IafItemRegistry.MANUSCRIPT.get()); } @Override public boolean canTakeItemThroughFace(int pIndex, @NotNull ItemStack pStack, @NotNull Direction pDirection) { return false; } @Override public int getContainerSize() { return 1; } @Override public boolean isEmpty() { return this.items.get(0).isEmpty(); } @Override public @NotNull ItemStack getItem(int pSlot) { return this.items.get(0); } @Override public @NotNull ItemStack removeItem(int pSlot, int pAmount) { ItemStack stack = ContainerHelper.removeItem(this.items, pSlot, pAmount); System.out.println(this.items.get(0).getCount()); return stack; } @Override public @NotNull ItemStack removeItemNoUpdate(int pSlot) { return ContainerHelper.takeItem(this.items, pSlot); } @Override public void setItem(int pSlot, @NotNull ItemStack pStack) { this.items.set(pSlot, pStack); if (pStack.getCount() > this.getMaxStackSize()) { pStack.setCount(this.getMaxStackSize()); } if (!pStack.isEmpty()) this.setChanged(); } @Override public boolean stillValid(@NotNull Player pPlayer) { return Container.stillValidBlockEntity(this, pPlayer); } @Override public void clearContent() { this.items.clear(); } } Here is the AbstractContainerMenu: package everyblu.ars_mythos.client.menus; import everyblu.ars_mythos.client.ArsMythosClientRegistry; import everyblu.ars_mythos.common.block.tiles.ArcaneScholarsTile; import everyblu.ars_mythos.common.capabilities.ArcaneResearchDataProvider; import everyblu.ars_mythos.common.helper.ContainerUtils; import everyblu.ars_mythos.common.registry.ArsMythosObjectRegistry; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.ContainerLevelAccess; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BlockEntity; import org.jetbrains.annotations.NotNull; public class ArcaneScholarsAnalysisMenu extends AbstractContainerMenu { private final ArcaneScholarsTile tile; public ArcaneScholarsAnalysisMenu(int index, Inventory playerInventory, FriendlyByteBuf data) { this(index, playerInventory, playerInventory.player.level().getBlockEntity(data.readBlockPos())); } public ArcaneScholarsAnalysisMenu(int index, Inventory playerInventory, BlockEntity entity) { super(ArsMythosClientRegistry.AS_ANALYSIS.get(), index); this.tile = ((ArcaneScholarsTile) entity); ContainerUtils.addPlayerInventoryTo(this, playerInventory); ContainerUtils.addPlayerHotBarTo(this, playerInventory); this.addSlot(new Slot(this.tile, 0, 15, 47)); } @Override public boolean clickMenuButton(@NotNull Player player, int pId) { if (this.tile.isEmpty()) return false; if (player.experienceLevel < 1) return false; player.getCapability(ArcaneResearchDataProvider.RESEARCH_DATA_KEY).ifPresent(research -> research.addOrSubResearch(research.getFireResearch(), 1, 0, 0, true)); player.playSound(SoundEvents.VILLAGER_WORK_CARTOGRAPHER); if (!player.getAbilities().instabuild) { this.tile.removeItem(0, 1); player.experienceLevel--; } return super.clickMenuButton(player, pId); } @Override public @NotNull ItemStack quickMoveStack(@NotNull Player pPlayer, int pIndex) { return ContainerUtils.quickMoveStack(pPlayer, pIndex, this.slots, this, (data) -> this.moveItemStackTo(data.getLeft(), data.getMiddle(), data.getRight(), false), 1); } @Override public boolean stillValid(@NotNull Player pPlayer) { return stillValid( ContainerLevelAccess.create(pPlayer.level(), this.tile.getBlockPos()), pPlayer, ArsMythosObjectRegistry.ARCANE_SCHOLARS_TABLE_FIRE.get()); } public boolean manuscriptsEmpty() { return this.tile.isEmpty(); } } And finally, here is the AbstractContainerScreen (if needed): package everyblu.ars_mythos.client.screens; import com.mojang.blaze3d.systems.RenderSystem; import everyblu.ars_mythos.ArsMythos; import everyblu.ars_mythos.client.menus.ArcaneScholarsAnalysisMenu; import everyblu.ars_mythos.common.capabilities.ArcaneResearchDataProvider; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; import org.jetbrains.annotations.NotNull; public class ArcaneScholarsAnalysisScreen extends AbstractContainerScreen<ArcaneScholarsAnalysisMenu> { public static final ResourceLocation GUI_TEXTURE = ArsMythos.prefix("textures/gui/arcane_scholars_table_analysis.png"); public ArcaneScholarsAnalysisScreen(ArcaneScholarsAnalysisMenu pMenu, Inventory pPlayerInventory, Component pTitle) { super(pMenu, pPlayerInventory, pTitle); } @Override @SuppressWarnings("all") public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { int x = (this.width - this.imageWidth) / 2; int y = (this.height - this.imageHeight) / 2; for(int k = 0; k < 3; ++k) { double d0 = pMouseX - (double)(x + 60); double d1 = pMouseY - (double)(y + 14 + 19 * k); if (d0 >= 0.0D && d1 >= 0.0D && d0 < 108.0D && d1 < 19.0D && this.menu.clickMenuButton(this.minecraft.player, k)) { this.minecraft.gameMode.handleInventoryButtonClick((this.menu).containerId, k); return true; } } return super.mouseClicked(pMouseX, pMouseY, pButton); } @Override @SuppressWarnings("all") protected void renderBg(@NotNull GuiGraphics guiGraphics, float pPartialTick, int pMouseX, int pMouseY) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderTexture(0, GUI_TEXTURE); int x = (this.width - this.imageWidth) / 2; int y = (this.height - this.imageHeight) / 2; guiGraphics.blit(GUI_TEXTURE, x, y, 0, 0, this.imageWidth, this.imageHeight); this.minecraft.player.getCapability(ArcaneResearchDataProvider.RESEARCH_DATA_KEY).ifPresent(research -> guiGraphics.drawString( this.minecraft.font, research.getFireResearch().getLeft().toString(), x + 160, y + 4, 255)); guiGraphics.drawString(this.minecraft.font, String.valueOf(this.minecraft.player.experienceLevel), x + 61, y + 74, 255); for (int k = 0; k < 3; ++k) { if (this.menu.manuscriptsEmpty() || this.minecraft.player.experienceLevel < 1) { guiGraphics.blit(GUI_TEXTURE, x + 60, y + 14 + (19 * k), 0, 185, 108, 19); continue; } guiGraphics.blit(GUI_TEXTURE, x + 60, y + 14 + (19 * k), 0, 166, 108, 19); double d0 = pMouseX - (double)(x + 60); double d1 = pMouseY - (double)(y + 14 + 19 * k); if (d0 >= 0.0D && d1 >= 0.0D && d0 < 108.0D && d1 < 19.0D) { guiGraphics.blit(GUI_TEXTURE, x + 60, y + 14 + (19 * k), 0, 204, 108, 19); } } } @Override public void render(@NotNull GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) { renderBackground(guiGraphics); super.render(guiGraphics, mouseX, mouseY, delta); renderTooltip(guiGraphics, mouseX, mouseY); } } Any help is appreciated.
-
I have been working on recipes for my mod and have come across two errors. ERROR ONE: [19:38:01] [Render thread/ERROR] [minecraft/RecipeManager]: Parsing error loading recipe echoingend:gazite_block com.google.gson.JsonParseException: Map entry 'A' : Failed to parse either. First: Input does not contain a key [type]: MapLike[{"item":"echoingend:gazite"}]; Second: Failed to parse either. First: Not a json array: {"item":"echoingend:gazite"}; Second: No key tag in MapLike[{"item":"echoingend:gazite"}]; Unknown registry key in ResourceKey[minecraft:root / minecraft:item]: echoingend:gazite LINKED CODE: { "type": "minecraft:crafting_shaped", "category": "misc", "key": { "A": { "item": "echoingend:gazite" } }, "pattern": [ "AAA", "AAA", "AAA" ], "result": { "count": 1, "id": "echoingend:gazite_block" } } ERROR TWO: [19:38:01] [Render thread/ERROR] [minecraft/RecipeManager]: Parsing error loading recipe echoingend:gazite com.google.gson.JsonParseException: Unknown registry key in ResourceKey[minecraft:root / minecraft:item]: echoingend:gazite LINKED CODE: { "type": "minecraft:crafting_shapeless", "category": "misc", "ingredients": [ { "item": "echoingend:gazite_block" } ], "result": { "count": 9, "id": "echoingend:gazite" } } The tutorial I was following. The GitHub Repository from the tutorial. My file structure is: data/[MOD ID]/recipe/[ITEM/BLOCK], as it is in the tutorial.
-
i need help making a block generate an explosion im new to modding so i dont know how to do it.
-
how to make animated doors?, maybe geckolib, but i don't know how to code it?
-
I am following a tutorial at youtube and at the part where it is made loot tables for block drops, it dosn't work for me, the blocks that I made dosn't drop anything in survival, everything else works as intended, the link is the git hub repository for the code https://github.com/Matwaua/Zero_To_Automation/tree/not-finished things that I tried: exploding the modded blocks; removing blocks/ from " "random_sequence": "zerotoautomation:blocks/fertilized_dirt" " coping the loot table from another equivalent block, like dirt for fertilized dirt and gravel for andesite gravel using "random_sequence" from another equivalent block
-
I am wanting my block to be used as fuel but I am not sure how. How would I do this? Here is my code for reference: public static final RegistryObject<Block> BLOCK_OF_FIREWOOD = registerBlock("block_of_firewood", () -> new Block(BlockBehaviour.Properties.copy(Blocks.STRIPPED_OAK_LOG))); private static <T extends Block> RegistryObject<T> registerBlock(String name, Supplier<T> block) { RegistryObject<T> toReturn = BLOCKS.register(name, block); registerBlockItem(name, toReturn); return toReturn; } The YouTube video I was following:
-
I'm coding a mod that adds placeable Gunpowder into the game, which behaves similarly to Redstone in terms of placing. I also want it to be flammable, so that it can be used as a fuse. However, the default fire spreading behaviour works well for this - the blocks ignite randomly, and they can burn out without spreading the fire to the next block. I want to make it so that, when the gunpowder is set on fire, instead of the Fire block simply floating above it or going to the side, it should replace the gunpowder block every time. I would also like to make fire spread to gunpowder faster than it does to regular blocks, because that would make it more practical as a fuse. I really don't know how I would go about doing these things. I suppose I could make a function in the gunpowder's block class that detects fire and turns into it separately from regular firetick, but that could have problems with things like Soul Fire, especially in terms of compatibility with mods that add other types of fire. Also, there are a bunch of other sources of fire: Flint and Steel, Fire Charges either from a player's hand or a Dispenser, fireballs shot by Ghasts and Blazes, not to mention any modded sources of fire. Is there any way to just make all sources of fire behave differently for this block?
-
Hi, I was wondering how to make a "screenspace texture" like the background of the end portal (not including the moving stars). This is an example of what I want: I have taken a look at the vanilla shader files, but I don't know how to use the effect for myself. Any help would be great,
-
Hello! I'm having a problem generating data from registered blocks, I've looked through everything and haven't found anything that could be causing this problem, so I come to the Forge community as a last resort. The log information is in a gist with the file data debug.log. This is the project link on GitHub: GitHub: https://github.com/eterium-network/quantum-praeda Solved, the problem was in the structure of the LootTables file generation class. Thank you in advance for the community's help! Original Text:
-
Hey so I'm really new to Java/Minecraft, coding, as I've followed a few tutorials on YouTube for the Minecraft side of java, But I've been trying to figure out how I can make a custom coal block to be smeltable? I have the "coal" object itself ready and working, but I haven't been able to find a way to make a block smeltable, I know I need to do something with "BlockItem" but I don't understand it at all, Heres the github to the project to get a better understanding of what I do have set up: https://github.com/THEKINGSKULL01/TSOTD_1.20.1_Forge This is for Minecraft 1.20.1
-
So I'm trying to get my custom enchantment book to spawn in vanilla loot table chests like jungle temple or desert pyramid, which it'll spawn the enchantment book inside the chest, but it wont have the actual enchantment provided This is for Forge 1.20.1 on intellij, I'm still a very new modder/coder in general,
-
Hello! So I made a custom bed, but the issue is that Villagers don't recognise it and don't sleep in it? Do you know how can I make it work?if Mixins are the answer can you teach me how I can make them work in 1.20.1 and in my case Thank you!
-
I'm make a new Forge mod in version 1.20.1 and add a block to game but texture is shoeing good in my inventory but don't show in Placed block if it is a bug?
-
Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this : The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) : The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock : Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item : @Override public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) { if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) { BlockPos blockPos = pContext.getClickedPos(); BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos)); if (secondBlockPos != null) { createFrozenBlock(pContext, secondBlockPos); } createFrozenBlock(pContext, blockPos); return InteractionResult.SUCCESS; } return super.useOn(pContext); } public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) { BlockState oldState = pContext.getLevel().getBlockState(blockPos); BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null; CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null; if (oldBlockEntity != null) { pContext.getLevel().removeBlockEntity(blockPos); } BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData); pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock); } public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) { BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState(); ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData); return FrozenBlock; }
-
Improper Models and Textures for Pointed Dripstone Block
Wicked3Dee posted a topic in Modder Support
I'm creating a custom block using the 1.20.2 version of the Forge MDK, and this block is basically supposed to be identical to the Pointed Dripstone block in terms of model and behavior, just with a different texture and name. I would use a texture pack for this, but this is just one feature I'm adding in addition to several new mobs and generated structures for my mod, and additionally I don't want to replace the Pointed Dripstone block, I just want to create a second block that looks and acts like it, with a different name and texture. I've created the textures for every blockstate of the Pointed Dripstone block (the thickness and direction), I have a json for all the blockstate variants and individual jsons for each blockstate, and I've registered the block under the "ModBlocks" class as a PointedDripstoneBlock. However, in the game, the new block texture is constantly the "tip" blockstate texture, the background of the texture is black instead of transparent, the shape of the block is not accurate to the Pointed Dripstone block, and the blocks can't be placed on top of each other for some reason. I've tried several different things, and looked up a million variants of this question, but there just isn't anything I can find out there, likely because who the hell mods a pointed dripstone block?? I've included one of the jsons for one of the blockstates just as an example of how they're formatted, the json for the blockstate variants, and the ModBlocks class where this block is registered. I've also included a screenshot of what the block currently looks like in-game, compared to how the Pointed Dripstone block looks. The block is called "Titan Tooth", for reference. Please let me know what I'm getting wrong here, as I'm just going in circles at this point. My code: https://paste.ee/p/JrNWK How it looks in-game: -
I am coding the mod using Intellij community edition with the Adoptium sdk 17 download, all the models i have made using Blockbench, the minecraft version is 1.20.4 and the forge version is 49.0.30. I am trying to make a medieval furnace and i have made the model exceed the 1 block so i have made 3 block models, the medieval furnace thats mentioned previously, the bottom of the furnace that made up the block and the top of the furnace that exceeded the block. I have been following a youtube tutorial by Modding by Kaupenjoe(this is the playlist im following) and he doesnt cover the multiblock function in his tutorial. I have looked to see other solutions but they havent been the right one i have been looking for. I am wanting when the top of the furnace is placed on top and is facing the same direction as the bottom of the furnace and it will let the player interact with the furnace whether they click on the bottom of the furnace or the top of the furnace. Im not entirely sure on what part of my code i should give either im sorry.
-
Hello, I'm trying to make all of the modded blocks to update their states once, or have a conversion for the blockstates. Meaning I have a saved world with the old blockstates, and now in the newer update on which I'm working the states have been changed to work the same but more effective (lower state count). Basically so players could just update to the newer version and their stuff would not break just update/convert... What would be the best approach for this?
-
I have a block already registered in my mod, which I have used in some worlds. The problem arises when in code, I add a property called CURRENT_AGE, when running Minecraft it freezes. In the console it doesn't appear any excpetion except that it stays in this phase: [Render thread/DEBUG] [ne.mi.co.ca.CapabilityManager/CAPABILITIES]: Attempting to automatically register: Lnet/minecraftforge/items/IItemHandler; Does anyone have an idea what it could be? I show the block and its registration public class SoulLichenBlock extends MultifaceBlock implements SimpleWaterloggedBlock, EntityBlock { public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; public static final IntegerProperty SKILL_LEVEL = IntegerProperty.create("soullichen_level", 0, 30); public static final DirectionProperty FACE = DirectionProperty.create("soullichen_face"); public static final DirectionProperty DIRECTION = DirectionProperty.create("soullichen_direction"); public static final IntegerProperty CURRENT_AGE = BlockStateProperties.AGE_25; private final MultifaceSpreader spreader = new MultifaceSpreader(this); private final MultifaceSpreader.DefaultSpreaderConfig config = new MultifaceSpreader.DefaultSpreaderConfig(this); private LivingEntity owner; //private static final Integer MAX_AGE = 25; public SoulLichenBlock(Properties properties) { super(properties); this.registerDefaultState(this .defaultBlockState() .setValue(WATERLOGGED, Boolean.FALSE) .setValue(SKILL_LEVEL, 0) .setValue(FACE, Direction.DOWN) .setValue(DIRECTION, Direction.DOWN) .trySetValue(CURRENT_AGE, 0) ); } public static ToIntFunction<BlockState> emission(int p_181223_) { return (p_181221_) -> MultifaceBlock.hasAnyFace(p_181221_) ? p_181223_ : 0; } public static boolean hasFace(BlockState p_153901_, @NotNull Direction p_153902_) { BooleanProperty booleanproperty = getFaceProperty(p_153902_); return p_153901_.hasProperty(booleanproperty) && p_153901_.getValue(booleanproperty); } protected void createBlockStateDefinition(StateDefinition.@NotNull Builder<Block, BlockState> stateDefinition) { stateDefinition.add(WATERLOGGED).add(SKILL_LEVEL).add(FACE).add(DIRECTION).add(CURRENT_AGE); super.createBlockStateDefinition(stateDefinition); } public @NotNull BlockState updateShape(BlockState p_153302_, @NotNull Direction p_153303_, @NotNull BlockState p_153304_, @NotNull LevelAccessor p_153305_, @NotNull BlockPos p_153306_, @NotNull BlockPos p_153307_) { if (p_153302_.getValue(WATERLOGGED)) { p_153305_.scheduleTick(p_153306_, Fluids.WATER, Fluids.WATER.getTickDelay(p_153305_)); } return super.updateShape(p_153302_, p_153303_, p_153304_, p_153305_, p_153306_, p_153307_); } @SuppressWarnings("deprecation") public @NotNull FluidState getFluidState(BlockState fluidState) { return fluidState.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(fluidState); } public boolean propagatesSkylightDown(BlockState p_181225_, @NotNull BlockGetter blockGetter, @NotNull BlockPos blockPos) { return p_181225_.getFluidState().isEmpty(); } public @NotNull MultifaceSpreader getSpreader() { return this.spreader; } public Optional<MultifaceSpreader.SpreadPos> spreadFromRandomFaceTowardRandomDirection( BlockState p_221620_, LevelAccessor p_221621_, BlockPos p_221622_, RandomSource p_221623_, int skillPoints, int age) { return Direction.allShuffled(p_221623_).stream().filter((p_221680_) -> { return this.config.canSpreadFrom(p_221620_, p_221680_); }).map((p_221629_) -> { return this.spreadFromFaceTowardRandomDirection(p_221620_, p_221621_, p_221622_, p_221629_, p_221623_, false, skillPoints, age); }).filter(Optional::isPresent).findFirst().orElse(Optional.empty()); } public Optional<MultifaceSpreader.SpreadPos> spreadFromFaceTowardRandomDirection( BlockState blockState, LevelAccessor levelAccessor, BlockPos blockPos, Direction face, RandomSource randomSource, boolean aBoolean, int skillPoints, int age) { return Direction.allShuffled(randomSource).stream().map((direction) -> spreadFromFaceTowardDirection(blockState, levelAccessor, blockPos, face, direction, aBoolean, skillPoints, age)) .filter(Optional::isPresent) .findFirst() .orElse(Optional.empty()); } public Optional<MultifaceSpreader.SpreadPos> spreadFromFaceTowardDirection( BlockState blockState, LevelAccessor levelAccessor, BlockPos blockPos, Direction face, Direction direction, boolean aBoolean, int skillPoints, int age) { //DevilRpg.LOGGER.debug("BEGIN ==================================== spreadFromFaceTowardDirection skillPoints {}", skillPoints); return skillPoints < 0 ? Optional.empty() : getSpreadFromFaceTowardDirection(blockState, levelAccessor, blockPos, face, direction, this::canSpreadInto) .flatMap((spreadPos) -> { //DevilRpg.LOGGER.debug("END ================================ spreadFromFaceTowardDirection spreadPos {}", spreadPos); return this.spreadToFace(levelAccessor, spreadPos, aBoolean, skillPoints, direction, age); }); } public boolean canSpreadInto(BlockGetter p_221685_, BlockPos p_221686_, MultifaceSpreader.SpreadPos p_221687_) { BlockState blockstate = p_221685_.getBlockState(p_221687_.pos()); return this.stateCanBeReplaced(p_221685_, p_221686_, p_221687_.pos(), p_221687_.face(), blockstate) && isValidStateForPlacement(p_221685_, blockstate, p_221687_.pos(), p_221687_.face()); } protected boolean stateCanBeReplaced(BlockGetter p_221688_, BlockPos p_221689_, BlockPos p_221690_, Direction p_221691_, BlockState p_221692_) { return p_221692_.isAir() || p_221692_.is(this) || p_221692_.is(Blocks.WATER) && p_221692_.getFluidState().isSource(); } public Optional<MultifaceSpreader.SpreadPos> getSpreadFromFaceTowardDirection(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos, Direction face, Direction direction, MultifaceSpreader.SpreadPredicate spreadPredicate) { //DevilRpg.LOGGER.debug("--- getSpreadFromFaceTowardDirection direction.getAxis() == face.getAxis(): {}", direction.getAxis() == face.getAxis()); ArrayList<Direction> directions = new ArrayList<>(); directions.add(direction); if (direction.getAxis() == face.getAxis()) { if (direction.getAxis().isHorizontal()) { directions = Arrays.stream(Direction.values()).filter(dir -> dir.getAxis().isVertical()).collect(Collectors.toCollection(ArrayList::new)); } if (direction.getAxis().isVertical()) { directions = Arrays.stream(Direction.values()).filter(dir -> dir.getAxis().isHorizontal()).collect(Collectors.toCollection(ArrayList::new)); } } for (Direction directionElement : directions) { /*DevilRpg.LOGGER.debug("--->> getSpreadFromFaceTowardDirection config.isOtherBlockValidAsSource(blockState) {} || " + "hasFace(blockState, face) {} && " + "!hasFace(blockState, direction) {}", config.isOtherBlockValidAsSource(blockState), hasFace(blockState, face), !hasFace(blockState, directionElement));*/ if (config.isOtherBlockValidAsSource(blockState) || hasFace(blockState, face) && !hasFace(blockState, directionElement)) { for (MultifaceSpreader.SpreadType multifacespreader$spreadtype : config.getSpreadTypes()) { MultifaceSpreader.SpreadPos multifacespreader$spreadpos = multifacespreader$spreadtype.getSpreadPos(blockPos, directionElement, face); //DevilRpg.LOGGER.debug("--- test SpreadPos: {} direction {} face {} ", multifacespreader$spreadpos, directionElement, face); if (spreadPredicate.test(blockGetter, blockPos, multifacespreader$spreadpos)) { //DevilRpg.LOGGER.debug("--- spreadPredicate success:"); return Optional.of(multifacespreader$spreadpos); } } } } return Optional.empty(); } public boolean isValidStateForPlacement(@NotNull BlockGetter blockGetter, @NotNull BlockState blockState, @NotNull BlockPos blockPos, @NotNull Direction face) { //DevilRpg.LOGGER.debug("------ isValidStateForPlacement 1st condition: {} && ({} || {})", this.isFaceSupported(face), !blockState.is(this), !hasFace(blockState, face)); if (this.isFaceSupported(face) && (!blockState.is(this) || !hasFace(blockState, face))) { BlockPos blockpos = blockPos.relative(face); //DevilRpg.LOGGER.debug("------ isValidStateForPlacement 2nd condition: canAttachTo {} ", secondCondition); return canAttachTo(blockGetter, face, blockpos, blockGetter.getBlockState(blockpos)); } else { return false; } } @Nullable public BlockState getStateForPlacement(@NotNull BlockState blockState, @NotNull BlockGetter blockGetter, @NotNull BlockPos blockPos, @NotNull Direction face, int skillPoints, Direction direction, int age) { //DevilRpg.LOGGER.debug("--- getStateForPlacement"); boolean isNotValidStateForPlacement = !this.isValidStateForPlacement(blockGetter, blockState, blockPos, face); //DevilRpg.LOGGER.debug("------- isNotValidStateForPlacement: {}", isNotValidStateForPlacement); if (isNotValidStateForPlacement) { return null; } else { BlockState blockstate; if (blockState.is(this)) { blockstate = blockState; } else if (this.isWaterloggable() && blockState.getFluidState().isSourceOfType(Fluids.WATER)) { blockstate = this.defaultBlockState().setValue(BlockStateProperties.WATERLOGGED, Boolean.TRUE); } else { blockstate = this.defaultBlockState(); } //DevilRpg.LOGGER.debug("------- getStateForPlacement -> blockStateResult "); return blockstate .setValue(getFaceProperty(face), Boolean.TRUE) .setValue(SKILL_LEVEL, skillPoints).setValue(FACE, face) .setValue(DIRECTION, direction) .setValue(CURRENT_AGE,age) ; } } public Optional<MultifaceSpreader.SpreadPos> spreadToFace(LevelAccessor levelAccessor, MultifaceSpreader.SpreadPos spreadPos, boolean p_221596_, int skillPoints, Direction direction, int age) { BlockState blockstate = levelAccessor.getBlockState(spreadPos.pos()); //DevilRpg.LOGGER.debug("---> spreadToFace blockstate{} direction: {}", blockstate, direction); return this.placeBlock(levelAccessor, spreadPos, blockstate, p_221596_, skillPoints, direction, age) ? Optional.of(spreadPos) : Optional.empty(); } public boolean placeBlock(LevelAccessor p_221702_, MultifaceSpreader.SpreadPos p_221703_, BlockState p_221704_, boolean p_221705_, int skillPoints, Direction direction, int age) { //DevilRpg.LOGGER.debug("---> placeBlock {} direction {} ", p_221703_, direction); BlockState blockstate = this.getStateForPlacement(p_221704_, p_221702_, p_221703_.pos(), p_221703_.face(), skillPoints, direction, age); if (blockstate != null) { if (p_221705_) { p_221702_.getChunk(p_221703_.pos()).markPosForPostprocessing(p_221703_.pos()); } //DevilRpg.LOGGER.debug("------> setBlock"); return p_221702_.setBlock(p_221703_.pos(), blockstate, 2); } else { return false; } } public long spreadFromFaceTowardAllDirections( BlockState blockState, LevelAccessor levelAccessor, BlockPos blockPos, Direction face, boolean aBoolean, int skillPoints, int age) { return Direction.stream().map((p_221656_) -> spreadFromFaceTowardDirection(blockState, levelAccessor, blockPos, face, p_221656_, aBoolean, skillPoints, age)) .filter(Optional::isPresent).count(); } private boolean isWaterloggable() { return this.stateDefinition.getProperties().contains(BlockStateProperties.WATERLOGGED); } @Override public void setPlacedBy(@NotNull Level level, @NotNull BlockPos blockPos, @NotNull BlockState blockState, @Nullable LivingEntity livingEntity, @NotNull ItemStack itemStack) { super.setPlacedBy(level, blockPos, blockState, livingEntity, itemStack); this.setOwner(livingEntity); } public LivingEntity getOwner() { return this.owner; } private void setOwner(LivingEntity livingEntity) { this.owner = livingEntity; } @Deprecated @Override public void entityInside(@NotNull BlockState blockState, @NotNull Level level, @NotNull BlockPos blockPos, @NotNull Entity entity) { if (entity instanceof LivingEntity /*&& entity.getType() != EntityType.BEE*/ && entity.getType() != ModEntities.LICHEN_SEEDBALL.get()) { entity.makeStuckInBlock(blockState, new Vec3(0.8D, 0.75D, 0.8D)); if (!level.isClientSide /*&& (entity.xOld != entity.getX() || entity.zOld != entity.getZ())*/) { // double d0 = Math.abs(entity.getX() - entity.xOld); // double d1 = Math.abs(entity.getZ() - entity.zOld); // if (d0 >= (double) 0.003F || d1 >= (double) 0.003F) { entity.hurt(level.damageSources().playerAttack((Player) owner), 1.0F); // Aplicar aceleración al movimiento double speedBoost = -0.4; // Ajusta este valor según lo rápido que quieras que sea el impulso double motionX = entity.getX() - entity.xOld; double motionZ = entity.getZ() - entity.zOld; double speed = Math.sqrt(motionX * motionX + motionZ * motionZ); //if (speed > 0.0) { entity.setDeltaMovement(entity.getDeltaMovement().multiply( (motionX / speed) * speedBoost, 0.0, (motionZ / speed) * speedBoost )); // } //} } } } @Nullable @Override public BlockEntity newBlockEntity(@NotNull BlockPos pos, @NotNull BlockState state) { return ModEntityBlocks.SOUL_LICHEN_ENTITY_BLOCK.get().create(pos, state); } @Nullable @Override public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, @NotNull BlockState blockState, @NotNull BlockEntityType<T> type) { return level.isClientSide ? null : (alevel, pos, aBlockstate, blockEntity) -> { if (blockEntity instanceof SoulLichenBlockEntity soulLichenBlockEntity && alevel.getGameTime() % 5 == 0) { soulLichenBlockEntity.tick(blockState, (ServerLevel) alevel, pos, alevel.getRandom()); //DevilRpg.LOGGER.info("-------->tick. this: {}", this.getClass().getSimpleName()); } }; } } This is the registration: public final class ModBlocks { public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, DevilRpg.MODID); ... public static final RegistryObject<SoulLichenBlock> SOUL_LICHEN_BLOCK = BLOCKS.register("soullichen", () -> new SoulLichenBlock( Block.Properties.copy(Blocks.GLOW_LICHEN).lightLevel(SoulLichenBlock.emission(7)).randomTicks() )); }
-
Hi, I'm having an issue with my block entities (it's currently two) where the model isn't rendering correctly. Not only is there no texture, but the custom model also isn't there; it appears as the standard Minecraft square. I'm not sure why this is happening, because I used the exact same method for another block entity and the model works perfectly fine. I checked the .json file and it's referencing everything correctly. Even weirder, the item model is completely fine; it's just an issue when I place it. Below I'll send the .json and the Block class of one of the block entities. If you need any more files, I'd be glad to send them! .json file: { "credit": "Made with Blockbench", "texture_size": [128, 128], "textures": { "0": "darkcollective:block/fabricatormk1", "particle": "darkcollective:block/fabricatormk1" }, "elements": [ { "name": "fabricator", "from": [1, 8, -6], "to": [2, 16, -5], "rotation": {"angle": 45, "axis": "x", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [0.875, 0.125, 1, 1.125], "texture": "#0"}, "east": {"uv": [0.75, 0.125, 0.875, 1.125], "texture": "#0"}, "south": {"uv": [1.125, 0.125, 1.25, 1.125], "texture": "#0"}, "west": {"uv": [1, 0.125, 1.125, 1.125], "texture": "#0"}, "up": {"uv": [1, 0.125, 0.875, 0], "texture": "#0"}, "down": {"uv": [1.125, 0, 1, 0.125], "texture": "#0"} } }, { "name": "fabricator", "from": [0, 8, 0], "to": [16, 16, 16], "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [2, 2, 4, 3], "texture": "#0"}, "east": {"uv": [0, 2, 2, 3], "texture": "#0"}, "south": {"uv": [6, 2, 8, 3], "texture": "#0"}, "west": {"uv": [4, 2, 6, 3], "texture": "#0"}, "up": {"uv": [4, 2, 2, 0], "texture": "#0"}, "down": {"uv": [6, 0, 4, 2], "texture": "#0"} } }, { "name": "fabricator", "from": [1, 0, 0], "to": [15, 8, 16], "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [2, 5, 3.75, 6], "texture": "#0"}, "east": {"uv": [0, 5, 2, 6], "texture": "#0"}, "south": {"uv": [5.75, 5, 7.5, 6], "texture": "#0"}, "west": {"uv": [3.75, 5, 5.75, 6], "texture": "#0"}, "up": {"uv": [3.75, 5, 2, 3], "texture": "#0"}, "down": {"uv": [5.5, 3, 3.75, 5], "texture": "#0"} } }, { "name": "fabricator", "from": [15, 0, 4], "to": [16, 7, 12], "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [4.25, 8.875, 4.375, 9.75], "texture": "#0"}, "east": {"uv": [3.25, 8.875, 4.25, 9.75], "texture": "#0"}, "south": {"uv": [5.375, 8.875, 5.5, 9.75], "texture": "#0"}, "west": {"uv": [4.375, 8.875, 5.375, 9.75], "texture": "#0"}, "up": {"uv": [4.375, 8.875, 4.25, 7.875], "texture": "#0"}, "down": {"uv": [4.5, 7.875, 4.375, 8.875], "texture": "#0"} } }, { "name": "fabricator", "from": [0, 0, 4], "to": [1, 7, 12], "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [6.75, 8.5, 6.875, 9.375], "texture": "#0"}, "east": {"uv": [5.75, 8.5, 6.75, 9.375], "texture": "#0"}, "south": {"uv": [7.875, 8.5, 8, 9.375], "texture": "#0"}, "west": {"uv": [6.875, 8.5, 7.875, 9.375], "texture": "#0"}, "up": {"uv": [6.875, 8.5, 6.75, 7.5], "texture": "#0"}, "down": {"uv": [7, 7.5, 6.875, 8.5], "texture": "#0"} } }, { "name": "fabricator", "from": [1, 16, -14], "to": [2, 17, 2], "rotation": {"angle": 45, "axis": "x", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [8, 3, 8.125, 3.125], "texture": "#0"}, "east": {"uv": [6, 3, 8, 3.125], "texture": "#0"}, "south": {"uv": [10.125, 3, 10.25, 3.125], "texture": "#0"}, "west": {"uv": [8.125, 3, 10.125, 3.125], "texture": "#0"}, "up": {"uv": [8.125, 3, 8, 1], "texture": "#0"}, "down": {"uv": [8.25, 1, 8.125, 3], "texture": "#0"} } }, { "name": "fabricator", "from": [0, 16, 3], "to": [16, 28, 5], "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [2.5, 6.375, 4.5, 7.875], "texture": "#0"}, "east": {"uv": [2.25, 6.375, 2.5, 7.875], "texture": "#0"}, "south": {"uv": [4.75, 6.375, 6.75, 7.875], "texture": "#0"}, "west": {"uv": [4.5, 6.375, 4.75, 7.875], "texture": "#0"}, "up": {"uv": [4.5, 6.375, 2.5, 6.125], "texture": "#0"}, "down": {"uv": [6.5, 6.125, 4.5, 6.375], "texture": "#0"} } }, { "name": "fabricator", "from": [3, 17, 2], "to": [13, 27, 3], "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [6.875, 6.25, 8.125, 7.5], "texture": "#0"}, "east": {"uv": [6.75, 6.25, 6.875, 7.5], "texture": "#0"}, "south": {"uv": [8.25, 6.25, 9.5, 7.5], "texture": "#0"}, "west": {"uv": [8.125, 6.25, 8.25, 7.5], "texture": "#0"}, "up": {"uv": [8.125, 6.25, 6.875, 6.125], "texture": "#0"}, "down": {"uv": [9.375, 6.125, 8.125, 6.25], "texture": "#0"} } }, { "name": "fabricator", "from": [14, 16, -14], "to": [15, 17, 2], "rotation": {"angle": 45, "axis": "x", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [2, 8, 2.125, 8.125], "texture": "#0"}, "east": {"uv": [0, 8, 2, 8.125], "texture": "#0"}, "south": {"uv": [4.125, 8, 4.25, 8.125], "texture": "#0"}, "west": {"uv": [2.125, 8, 4.125, 8.125], "texture": "#0"}, "up": {"uv": [2.125, 8, 2, 6], "texture": "#0"}, "down": {"uv": [2.25, 6, 2.125, 8], "texture": "#0"} } }, { "name": "fabricator", "from": [14, 8, -6], "to": [15, 16, -5], "rotation": {"angle": 45, "axis": "x", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [1.375, 0.125, 1.5, 1.125], "texture": "#0"}, "east": {"uv": [1.25, 0.125, 1.375, 1.125], "texture": "#0"}, "south": {"uv": [1.625, 0.125, 1.75, 1.125], "texture": "#0"}, "west": {"uv": [1.5, 0.125, 1.625, 1.125], "texture": "#0"}, "up": {"uv": [1.5, 0.125, 1.375, 0], "texture": "#0"}, "down": {"uv": [1.625, 0, 1.5, 0.125], "texture": "#0"} } }, { "name": "fabricator", "from": [7, 16, -14], "to": [9, 17, 2], "rotation": {"angle": 45, "axis": "x", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [7.5, 6, 7.75, 6.125], "texture": "#0"}, "east": {"uv": [5.5, 6, 7.5, 6.125], "texture": "#0"}, "south": {"uv": [9.75, 6, 10, 6.125], "texture": "#0"}, "west": {"uv": [7.75, 6, 9.75, 6.125], "texture": "#0"}, "up": {"uv": [7.75, 6, 7.5, 4], "texture": "#0"}, "down": {"uv": [8, 4, 7.75, 6], "texture": "#0"} } }, { "name": "fabricator", "from": [7, 8, -6], "to": [9, 16, -5], "rotation": {"angle": 45, "axis": "x", "origin": [8, 0, 8]}, "faces": { "north": {"uv": [0.125, 0.125, 0.375, 1.125], "texture": "#0"}, "east": {"uv": [0, 0.125, 0.125, 1.125], "texture": "#0"}, "south": {"uv": [0.5, 0.125, 0.75, 1.125], "texture": "#0"}, "west": {"uv": [0.375, 0.125, 0.5, 1.125], "texture": "#0"}, "up": {"uv": [0.375, 0.125, 0.125, 0], "texture": "#0"}, "down": {"uv": [0.625, 0, 0.375, 0.125], "texture": "#0"} } } ], "display": { "thirdperson_righthand": { "rotation": [70, 0, 0], "translation": [0, 1, 0.25], "scale": [0.25, 0.25, 0.25] }, "thirdperson_lefthand": { "rotation": [70, 0, 0], "scale": [0.25, 0.25, 0.25] }, "firstperson_righthand": { "scale": [0.4, 0.4, 0.4] }, "firstperson_lefthand": { "scale": [0.4, 0.4, 0.4] }, "ground": { "scale": [0.4, 0.4, 0.4] }, "gui": { "rotation": [0, 126, 0], "translation": [0, -2.75, 0], "scale": [0.5, 0.5, 0.5] }, "fixed": { "translation": [0, -1.5, 0], "scale": [0.4, 0.4, 0.4] } }, "groups": [ { "name": "fabricator", "origin": [8, 0, 8], "color": 0, "children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] } ] } Block class: private static final VoxelShape SHAPE = makeShape(); public FabricatorMK1(BlockBehaviour.Properties properties) { super(properties); } @Override public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext ctx) { return SHAPE; } @Nullable @Override public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return BlockEntityInit.FABRICATORMK1_ENTITY.get().create(pos, state); } @Override public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) { if(state.getBlock() != newState.getBlock()){ BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof FabricatorMK1Entity){ ((FabricatorMK1Entity) blockEntity).drops(); } } } @Override public RenderShape getRenderShape(BlockState state) { return RenderShape.MODEL; } @Override protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) { super.createBlockStateDefinition(builder); builder.add(HorizontalDirectionalBlock.FACING); } @Nullable @Override public BlockState getStateForPlacement(BlockPlaceContext ctx) { return defaultBlockState().setValue(HorizontalDirectionalBlock.FACING, ctx.getHorizontalDirection().getOpposite()); } @Override public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand interactionHand, BlockHitResult result) { if(!level.isClientSide()) { BlockEntity entity = level.getBlockEntity(pos); if (entity instanceof FabricatorMK1Entity) { NetworkHooks.openScreen(((ServerPlayer)player), (FabricatorMK1Entity)entity, pos); } else { throw new IllegalStateException("Our Container provider is missing!"); } } return InteractionResult.sidedSuccess(level.isClientSide()); } @Nullable @Override public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> type) { if(level.isClientSide()) { return null; } return createTickerHelper(type, BlockEntityInit.FABRICATORMK1_ENTITY.get(), (level1, pos, state1, blockEntity) -> blockEntity.tick(level1, pos, state1)); } public static VoxelShape makeShape(){ VoxelShape SHAPE = Shapes.empty(); SHAPE = Shapes.join(SHAPE, Shapes.box(0.0625, 0.5, -0.375, 0.125, 1, -0.3125), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0, 0.5, 0, 1, 1, 1), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0.0625, 0, 0, 0.9375, 0.5, 1), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0.9375, 0, 0.25, 1, 0.4375, 0.75), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0, 0, 0.25, 0.0625, 0.4375, 0.75), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0.0625, 1, -0.875, 0.125, 1.0625, 0.125), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0, 1, 0.1875, 1, 1.75, 0.3125), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0.1875, 1.0625, 0.125, 0.8125, 1.6875, 0.1875), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0.875, 1, -0.875, 0.9375, 1.0625, 0.125), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0.875, 0.5, -0.375, 0.9375, 1, -0.3125), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0.4375, 1, -0.875, 0.5625, 1.0625, 0.125), BooleanOp.OR); SHAPE = Shapes.join(SHAPE, Shapes.box(0.4375, 0.5, -0.375, 0.5625, 1, -0.3125), BooleanOp.OR); return SHAPE; } I also have a GitHub where you can find the necessary files for the Fabricator (Block entity in question):https://github.com/giornoggiovanna/DarkCollectiveGit Thanks for the help!
-
I have a variant type of dirt and would like to be able to till it into farmland. For texture and behaviour reasons, it needs to be a separate block (e.g. revert back to the variant dirt), so I cannot just have it become farmland. I would like to be able to plant vanilla crops, such as wheat, potatoes, etc. on this farmland. Being able to plant modded CropBlocks from other mods on this farmland would be a plus, but is not necessary. However, CropBlocks such as wheat can only be placed on the vanilla farmland block (not a tag). protected boolean mayPlaceOn(BlockState state, BlockGetter getter, BlockPos pos) { return state.is(Blocks.FARMLAND); } What is the best way to achieve this behaviour? Check for useOns from the seed items and place a modded block identical to the vanilla crop? Does forge add anything that would simplify this?
-
Hello, I am new in this forum here and have quite a complicated question: I want to add a block and item reducer which reduces blocks and items to the elements it is made from. The problem is that I don't know how to add multiple output slits to a block entity. If anyone knows how to solve this, please answer me.
-
I am trying to spawn fluid, but Intellij says " Cannot resolve method 'setBlock(BlockPos, RegistryObject<LiquidBlock>)' " package net.svisvi.jigsawpp.effect; import net.minecraft.core.BlockPos; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.level.Level; import static net.svisvi.jigsawpp.init.JigsawPpModBlocks.PONOS_WATER_BLOCK; public class purgenEffect extends MobEffect { public purgenEffect(MobEffectCategory mobEffectCategory, int color) { super(mobEffectCategory, color); } public void applyEffectTick(LivingEntity pLivingEntity, Level worldin, BlockPos pos) { if (pLivingEntity.level().isClientSide()) { worldin.setBlock(pos, PONOS_WATER_BLOCK); } } }
-
I created a item when you click on block it will generate a skyisland. But it just generate one dirt on where I click. I'm sure it generated because there is an invisible barrel in which the dirt should be. And when I restart the game, the invisible dirt appear. level.setBlockAndUpdate() is the same. Item.java package net.p1nero.skyislandbuilder.item; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.Level; import net.p1nero.skyislandbuilder.utils.SkyIslandGenerator; public class PerlinSkyIslandBuilderItem extends Item { public PerlinSkyIslandBuilderItem(Properties properties) { super(properties); } @Override public InteractionResultHolder<ItemStack> use(Level p_41432_, Player p_41433_, InteractionHand p_41434_) { //TODO: Open setting window return super.use(p_41432_, p_41433_, p_41434_); } @Override public InteractionResult useOn(UseOnContext context) { SkyIslandGenerator skyIslandGenerator = new SkyIslandGenerator(context.getClickedPos(),context.getLevel()); skyIslandGenerator.printSkyIsland(); return super.useOn(context); } } SkyIslandGenerator.java public void printSkyIsland() { double[][] skyIsland = generateSkyIsland(width, height, scale, octaves, persistence, lacunarity, seed, maxHeight*10); int maxHeight = -1; int max_x = 0, max_z = 0; for (int x = 0; x < width; x++) { for (int z = 0; z < height; z++) { if (skyIsland[x][z] > maxHeight) { maxHeight = (int)skyIsland[x][z]; max_x = x; max_z = z; } System.out.print("("+x+','+z+"):"+(int)skyIsland[x][z]+" "); } System.out.println(); } for (int x = 0; x < width; x++) { for (int z = 0; z < height; z++) { for(int y = bottom.getY()+maxHeight ; y>bottom.getY()+maxHeight-skyIsland[x][z] ; y--){ level.setBlock(new BlockPos(bottom.getX()+x-max_x,y,bottom.getZ()+z-max_z), Blocks.DIRT.defaultBlockState(),3); } } } }