Jump to content

Block Break Event/api for 1.6.2?


drazuam

Recommended Posts

I'm writing a mod that needs to make logs of broken blocks;  Keepcalm's block break API would be perfect for the event I need, but it hasn't been updated in seven months, and implements interfaces that have been removed.

 

So

 

Does anybody know any good block break event or api (coremod?) for 1.6.2 forge?

Link to comment
Share on other sites

Forge essentials seemed a bit heavy when I last used it on a forge server...  And on top of that, all I would want is one function that would be used client side.  The mod I'm making is a client-utility, and doesn't even have a serverside :P

 

As far as yours goes, I would very much like a link and/or permission to use whatever you have :D

I'm not too experienced in forge/mcp yet, so I wouldn't really understand how to make a coremod to support a block break event

Link to comment
Share on other sites

Forge essentials seemed a bit heavy when I last used it on a forge server...

didnt know :\ i tought that it was actually good (i use my own version of "essentials" and i dont have any problems on my server

 

let me pack up the coremod and ill send it to you (either PM if it accept files or in this thread, or mediafire/dropbox/etc)

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

yeah i feel you, this is also why i made my own version and didnt use essentials (also because shop sucks but thats another story)

 

btw i didnt forget you its just i dont have access to my dev env right now xD and i also need to make SURE it works before sending it to you

(like work in dev env, real client and real server)

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

i jsut realised this ..im using ASM to insert stuff into the ItemInWorldManager class and that class is only used server side, so it would work if you're playing single player, but not if you're playing on a server :\, still want it ?

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

And on top of that, all I would want is one function that would be used client side.  The mod I'm making is a client-utility, and doesn't even have a serverside :P

 

contradicts

 

This mod was meant to be used on a server lol.

 

my core only notify server side, but you could always send a packet

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

  • 2 weeks later...

@gotolink: yeah thats what i tought too BUT

http://www.minecraftforge.net/forum/index.php/topic,3094.msg20926.html#msg20926, one of my very first thread :')

give it a read you'll understand why RIGHT_CLICK_BLOCK is wrong :\

 

@dies if they are havign bukkit overhead they are doing it wrong

also, left_blick_block also has a bug with it and cant be use fully as a block break event (video demonstration:

in this video i am adding exp everytime a Left_click_block event is fired, which obviously isnt enough, i would also like to know how gotolink does that)

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

@gotolink: yeah thats what i tought too BUT

http://www.minecraftforge.net/forum/index.php/topic,3094.msg20926.html#msg20926, one of my very first thread :')

give it a read you'll understand why RIGHT_CLICK_BLOCK is wrong :\

I never tried to canceled it...but this doesn't sound good indeed.

 

So much Bukkit overhead .... Hurts my eyes...

And also @GotoLink: Action.LEFT_CLICK_BLOCK fires only once, when the block is first clicked... How do you get the notified at the point where it actually gets broken? TickHandlers?

I store the info and use a TickHandler to run checks, yes. Obviously, it is limited to one block break per player per tick, but i doubt it make any difference for players.

Link to comment
Share on other sites

The canceling is only one concern I have. Also RIGHT_CLICK_BLOCK gets fired before the block get's placed, so you have to do all the calculations minecraft does to figure out where the block would be placed yourself (again!). Because x, y, z of the event give you the block being clicked, not the block being placed.

You have the face of the click, it isn't so hard to move to the neighbouring block... ???

At worst, 6 cases in a switch :P

I store the info and use a TickHandler to run checks, yes. Obviously, it is limited to one block break per player per tick, but i doubt it make any difference for players.

Ouch. But do what you must lol.

I'd be glad to hear more convenient strategies :)

Link to comment
Share on other sites

Plus: Special casing tall grass (and the forge hook for that), checking if the player is actually allowed to place a block here (spawn protection, adventure mode, space might be occupied already [torches!]), etc. etc. That's not what I want to do.

Why would you check that ? you don't have to place the block... :o

 

And more reliable, too. Because if you just check one tick later if the block has been placed you can't be sure it was actually the player.

Just inject some code via ASM everywhere removeBlockByPlayer gets called.

Not convenient at all. Plus, i can tell who is breaking the block with reflection.

Link to comment
Share on other sites

because we need a block place event too

 

 

and reflection is slower, sure asm takes some time to implement but once its working its native java speed. since block place/break event are one of the few things preventing forge from being a good high population mod it would be nice to have those integrated within standard forge.

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • 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 this raport to lounch the game The game crashed whilst rendering screen Error: java.lang.NullPointerException: Cannot invoke "net.minecraft.client.gui.components.Button.m_252907_()" because "this.serverBrowser$grabbedMultiplayerButton" is null Kod zakończenia: -1 And full message:   https://ntpd.eu/N3gq6
    • EDIT: I had to declare the library like a mod (using the @Mod annotation and adding the mods.toml + pack.mcmeta files). By doing this it works now Hi everyone  I'm trying to create an internal library for all my mods, and inside it I have a method that registers an Item public static RegistryObject<Item> registerItem(final DeferredRegister<Item> registry, final String name, final Supplier<Item> itemSupplier) { return registry.register(name, itemSupplier); } When the method is called from a mod, Forge raises this error   Exception message: java.lang.LinkageError: loader constraint violation: loader 'SECURE-BOOTSTRAP' @6bedbc4d wants to load class net.minecraftforge.registries.DeferredRegister. A different class with the same name was previously loaded by 'TRANSFORMER' @6d672bd4. (net.minecraftforge.registries.DeferredRegister is in module [email protected] of loader 'TRANSFORMER' @6d672bd4, parent loader 'bootstrap') Both the version of Forge included in the library's build.gradle and the mod's build.gradle are the same. I've never done this, so there's a good chance I'm configuring something wrong. This is the build.gradle file of the library (which is part of a multi-module project)   plugins { id 'net.minecraftforge.gradle' version '[6.0.24,6.2)' } repositories { gradlePluginPortal() maven { name = 'MinecraftForge' url = 'https://maven.minecraftforge.net/' } } java.toolchain.languageVersion = JavaLanguageVersion.of(21) minecraft { mappings channel: 'official', version: minecraft_version reobf = false copyIdeResources = true } dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" implementation('net.sf.jopt-simple:jopt-simple:5.0.4') { version { strictly '5.0.4' } } } tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' }  
    • Hello i wanna make a modded server for me and my friends and the game is crashing when i use items that pop-up and UI and we cannot place modded blocks.  Here is the video i take so it's more easy for you guys to see.   Help please! Thanks
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.