Jump to content

treebranch

Members
  • Posts

    40
  • Joined

  • Last visited

Everything posted by treebranch

  1. I don't have any other ideas, but I'm sure there's a better way. Hopefully somebody here knows. Waiting for a pull request to get approved only sounds the way to go if you're patient.
  2. I "fixed" this by overriding the hitEntity, onBlockDestroyed, and onItemUse methods to call my own copy/paste of ItemStack.damageItem, which passes a stack of Items.WOODEN_AXE to EntityLivingBase.renderBrokenItemStack instead of my axe's stack. It's extremely hard to look at, but it works. If anybody has a better solution please let me know still. public class ItemImprovisedAxe extends ItemAxe { public ItemImprovisedAxe() { super(ItemTier.WOOD, 7.0f, -3.0f, new Item.Properties().addToolType(ToolType.AXE, 1).defaultMaxDamage(33).group(ItemGroup.TOOLS)); this.setRegistryName(ModInfo.MODID, "improvised_axe"); } private final ItemStack WOODEN_AXE_STACK = new ItemStack(Items.WOODEN_AXE); // from ItemStack private void damageItem(ItemStack stack, int amount, EntityLivingBase entityIn) { if (!(entityIn instanceof EntityPlayer) || !((EntityPlayer)entityIn).abilities.isCreativeMode) { if (/*this*/stack.isDamageable()) { if (/*this*/stack.attemptDamageItem(amount, entityIn.getRNG(), entityIn instanceof EntityPlayerMP ? (EntityPlayerMP)entityIn : null)) { //entityIn.renderBrokenItemStack(/*this*/stack); entityIn.renderBrokenItemStack(WOODEN_AXE_STACK); Item item = /*this*/stack.getItem(); /*this*/stack.shrink(1); if (entityIn instanceof EntityPlayer) { ((EntityPlayer)entityIn).addStat(StatList.ITEM_BROKEN.get(item)); } /*this*/stack.setDamage(0); } } } } @Override public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) { //stack.damageItem(2, attacker); damageItem(stack, 2, attacker); return true; } @Override public boolean onBlockDestroyed(ItemStack stack, World worldIn, IBlockState state, BlockPos pos, EntityLivingBase entityLiving) { if (!worldIn.isRemote && state.getBlockHardness(worldIn, pos) != 0.0F) { //stack.damageItem(1, entityLiving); damageItem(stack, 1, entityLiving); } return true; } @Override public EnumActionResult onItemUse(ItemUseContext p_195939_1_) { World world = p_195939_1_.getWorld(); BlockPos blockpos = p_195939_1_.getPos(); IBlockState iblockstate = world.getBlockState(blockpos); Block block = BLOCK_STRIPPING_MAP.get(iblockstate.getBlock()); if (block != null) { EntityPlayer entityplayer = p_195939_1_.getPlayer(); world.playSound(entityplayer, blockpos, SoundEvents.ITEM_AXE_STRIP, SoundCategory.BLOCKS, 1.0F, 1.0F); if (!world.isRemote) { world.setBlockState(blockpos, block.getDefaultState().with(BlockRotatedPillar.AXIS, iblockstate.get(BlockRotatedPillar.AXIS)), 11); if (entityplayer != null) { //p_195939_1_.getItem().damageItem(1, entityplayer); damageItem(p_195939_1_.getItem(), 1, entityplayer); } } return EnumActionResult.SUCCESS; } else { return EnumActionResult.PASS; } } }
  3. My item class extends ItemAxe. It has a texture and behaves the same way as normal axes. When it's destroyed due to having 0 durability, the particles that appear are the purple missing texture image. I can't figure out why this happens. Here's the item class: public class ItemImprovisedAxe extends ItemAxe { public ItemImprovisedAxe() { super(ItemTier.WOOD, 7.0f, -3.0f, new Item.Properties().addToolType(ToolType.AXE, 1).defaultMaxDamage(33).group(ItemGroup.TOOLS)); this.setRegistryName(ModInfo.MODID, "improvised_axe"); } } Here's src/main/resources/assets/[modid]/models/item/improvised_axe.json: { "parent": "item/handheld", "textures": { "layer0": "modid:item/improvised_axe" } } The 16x16 texture is src/main/resources/assets/[modid]/textures.item/improvised_axe.png
  4. 1.13.x documentation is lacking. I don't think you'll find what you're looking for. In general I'd say just do what works for you, unless there's documentation explaining to do something else, with adequate examples, in which case do that instead.
  5. You could use ObfuscationReflectionHelper. All you need is to get your hands on the GuiIngameForge instance. I looked and it seems like they're setting a field called rayTraceBlock and rayTraceFluid. A grep in ~/.gradle/caches/forge_gradle reveals that the names of those fields are "field_211537_g" and "field_211538_h" respectively. An example of setting one of the fields: ObfuscationReflectionHelper.setPrivateValue(GuiIngameForge.class, guiIngameForge, entity.rayTrace(20.0D, 0.0F, RayTraceFluidMode.NEVER), "field_211537_g"); I'm not sure how you can get an instance of GuiIngameForge, but Minecraft.getInstance().ingameGUI gives you an instance of GuiIngame, which GuiIngameForge extends.
  6. Thanks for your help. I've probably viewed over half the 1.13.x related threads on this forum in an attempt to learn, and not everything is helpful. I'm new to Java and Forge so sometimes the smallest details are invaluable to me. While we're at it, there's a few events that never fired for me on MinecraftForge.EVENT_BUS and I had to find workarounds. Namely ChunkDataEvent.Load and PlayerEvent.NameFormat. I assumed these were Forge bugs or things that hadn't been implemented yet, but maybe it's another case of wrong bus? EDIT: They're on the right bus, it's just Forge's fault I guess. Anyways thanks.
  7. The more you know. I'll mark this as solved. Where can I find detailed documentation for this so I don't run into similar confusions later?
  8. Thank you for this info. Is the event bus provided by `FMLJavaModLoadingContext.get()` the only one in which RegistryEvent.Register will fire?
  9. Yes, using EVENT_BUS.register(this) in the main mod class. That's how I did all of my events, until I hit the register event. Simply it doesn't work, but I wish it did so I could have consistency in my code. This is event in its own class alone with the EventBusSubscriber annotation (this works perfectly): @Mod.EventBusSubscriber(modid = ModInfo.MODID, bus = Mod.EventBusSubscriber.Bus.MOD) public class RegisterItems { @SubscribeEvent public static void onRegisterItems(RegistryEvent.Register<Item> event) { event.getRegistry().registerAll( // item registration stuff here ); } } This is the same class, but rewritten without the @Mod.EventBusSubscriber annotation, and instead registered to the event bus from the main mod class (this never fires): public class RegisterItems { @SubscribeEvent public void onRegisterItems(RegistryEvent.Register<Item> event) { event.getRegistry().registerAll( // item registration stuff here ); } } (And the main mod class): @Mod(ModInfo.MODID) public class ExampleMod { public ExampleMod() { MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(new RegisterItems()); } // more events down here } And finally, this is how I was doing it originally, where I ended up hitting the dead end with the register event (this never fires, despite every other event in my mod working this way): @Mod(ModInfo.MODID) public class ExampleMod { public ExampleMod() { MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent public void onRegisterItems(RegistryEvent.Register<Item> event) { event.getRegistry().registerAll( // item registration stuff here ); } // tons of other events down here which work perfectly }
  10. I'm just trying to understand why this happens. My mod is very large now, and all my events fire by simply calling MinecraftForge.EVENT_BUS.register(this) in the constructor of the main mod class, which houses all of said events. Everything fires except the RegistryEvent.Register<T> event. I got stuck on this and couldn't figure out why it was the only event that wasn't firing, and it was only until I put it as a static method in its own separate class, annotated with @Mod.EventBusSubscriber, that it finally began to work. I even tried registering that class using EVENT_BUS.register and it's the same problem. It's the only event that has to be in a class annotated with @Mod.EventBusSubscriber. Am I doing something wrong or is this on Forge's side?
  11. They also still have to finish the 1.13.2 update, since it doesn't have everything ported over yet.
  12. Well I'm new to forge, but if I were you, the first thing I'd do is look into the generation for the main End island, since it's a single structure surrounded by void.
  13. So does this mean there's no performance difference between object.field and object.getField()?
  14. I'm relatively new to Java, and to Forge, and this has been bugging me for a bit. Often times I'll realize I have to call a getter function (e.g. Minecraft.getInstance) every time an event is fired. So to get around this I'll sometimes create a field in the class and set it once. Or in the case of a loop I'll store the value in a local variable and refer back to the variable. I'm used to doing this in languages like C, where optimization and garbage collection isn't exactly the same concept as it is in Java. So my question is, how much of this is necessary? Does it really matter if I call the getter functions a bunch? Does it add any overhead? Memory leaks? Anything? Why are there so many? Sorry if this is more of a Java question. I'm really only using Java for Forge and so the answer will have a significant impact on how I write mods. Thanks ?
  15. treebranch

    ~~

    If I wasn't working on my own project already I'd definitely give it a try. I'm sure somebody will help you, good luck.
  16. I'm trying to change the nametag hovering above other player entities client-side. PlayerEvent.NameFormat doesn't seem to be implemented in Forge 1.13.x; specifically it never fires and the player.refreshDisplayName method doesn't exist or is inaccessible. What's the best way to do this on Forge 1.13.x?
  17. I just want to add that you shouldn't need a loop for this. Trying to slow down the loop would mean freezing the thread and that won't do what you want. You have to think in events. The client tick event will fire every tick (20 times per second on a server that's running properly) and ticks are like game logic steps, it's more the kind of loop you're thinking of. Checking the player's health once in that event will check it every tick. If you want to do something, say, every X ticks, try keeping a counter in your class and incrementing it during the tick event. Never do it in an actual loop since if my understanding of Forge events is correct then you'll just freeze the game by prolonging that tick forever.
  18. As a Java beginner with a very low IQ for networking code, I'm happy to use my random seed approach instead, but if I ever have to implement it in the future I'll use your link as a reference. Thanks.
  19. Thanks. I've been here, but I hit another dead end because apparently there's no IMessage interface anymore. If you know where that went I'll be ecstatic. But in the meantime I've solved all my problems by just using entity.getUniqueID().getMostSignificantBits() as the seed for my random number generator on both the client and the server.
  20. I solved this by editing the display names of the client-side entities in Minecraft.getInstance().world during TickEvent.ClientTickEvent. However I have another problem. The code that assigns the nametag involves random numbers and needs to be done on the server, otherwise there's desync problems where both sides see a different number. It uses NBT tags to store that info per-mob, but removing the assignment code from the client doesn't work, since the client never receives the server-stored version of the NBT value. How can I fix this? I might make another thread if I can't figure it out, but if anyone knows off the top of their head it'd be great, since I'm still a Forge noob. Edit: I'm probably going to use SimpleImpl for this, because the example in the docs shows how to send a simple int over the network, and that's exactly what I want to do. Edit 2: Forget that, it looks like SimpleImpl simply isn't implemented in 1.13. That or the docs aren't updated. Anyway this issue is still open.
  21. My mod enables custom names for all living entities and changes their display names. There's a section of the nametag that I need to color separately for each client. Essentially I need something like PlayerEvent.NameFormat but for living entities.
  22. It's because Forge doesn't support newer versions of Java. I suspect you probably have OpenJDK 11 or OpenJDK 12. You'll have to download an older Java runtime, then point Foge to it. I had luck with the files here: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html Get the Linux x64 tar.gz file and extract it somewhere. Then go to the profile settings for Forge and change the Java executable to the older one. I think you need to enable advanced settings.
×
×
  • Create New...

Important Information

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