
ctbe
Members-
Posts
85 -
Joined
-
Last visited
Everything posted by ctbe
-
[1.12] Is there a way to get the hardness of a block in a non-deprecated way?
ctbe replied to ctbe's topic in Modder Support
Got it. Thanks. -
[1.12] Is there a way to get the hardness of a block in a non-deprecated way?
ctbe replied to ctbe's topic in Modder Support
Thanks for the clarification. I'll continue using that then. -
[1.12] Is there a way to get the hardness of a block in a non-deprecated way?
ctbe replied to ctbe's topic in Modder Support
Thanks. I changed it to use the IBlockState returned from the getDefaultState() method. Though it still goes through the same path. It calls the deprecated method from the non deprecated one in the BlockStateContainer class. Unless I am missing something else. After looking at the classes implementations it feels like there is no other way to achieve it since I see no other method that returns the value of the protected blockHardness other than the deprecated one which is used by the non-deprecated method. -
I do it like this and it works: Blocks.BRICK_BLOCK.getBlockState().getBaseState().getBlockHardness(null, null); Because Blocks.BRICK_BLOCK.getBlockHardness(...) was marked as deprecated. Yet, I noticed that getBlockHardness(null, null) is not using the parameters for anything. It is simply calling another function that in the end, calls the deprecated getBlockHardness function and said function just returns the value of the variable blockHardness of the block in question. It does nothing with the parameters. To be more specific it calls the getBlockHardness of BlockStateContainer which in turn just calls the deprecated getBlockHardness of the Block class which in turn does nothing with the parameters it gets passed. That's why it works with null being passed as parameters. I was thinking that maybe using getBlockState().getBaseState().withProperty(...) could help, but after a while looking through the code, I could find no such a property for hardness. It is all hardcoded in the block registering method registerBlocks() of the Block class. Is there an alternative to using this method that all it does is simply call a deprecated method or is this the only way?
-
Item crafted does not persist, but when taken from creative it persists
ctbe replied to ctbe's topic in Modder Support
Look, I modestly (without arrogance) tell you that I will not argue anymore past this reply. The problem is solved and the thread can fall into forgotten. Here's the thing. That is exactly one of the many kinds of behavior I talk that has been already studied and well documented in texts and academic text books. That last reply was predictable. Try to look for a loophole in what one person has said, then paint the person in bad light with that mistake to justify your actions. The rest of the arguments of the person that committed the mistake will disappear in the eyes of the others. Like they never existed. Nothing they say after will be listened to. The action is very old and documented in newspapers and probably history books. Humans have been doing that for centuries. One person makes fun of another, the other person says "hey, please, stop making fun of me, I don't like it", and the person may stop it, but not before trying to justify its past actions by telling the other person that he/she did wrong first. "But look what this person did first." or "But it's true. Look at this..." That's the kind of arguments. That it was impossible for anyone to help doesn't justify the reply. I am not going to use sarcasm, insult or even make fun of you. Nor will I try to paint you in bad light or try to make it look like I'm better. I'll simply not do it. I'll just say that when I don't understand the question of another person and need more information to help, I query by telling them to provide more information instead of making a statement of "obviousness" that dimly makes fun of the person. I am not telling you to do the same. I'm just saying what I do when I face similar situations and it's not to make you look bad or make it look like I'm better. That's not the point. Since the problem was solved and I am not going to argue past this post about that reply I'd like to lastly make emphasis that I did mentioned above that they were not two different objects. They were the same and contained the exact bytes in memory. 22 bytes to be precise according to the heap dump. They were different instances, which is a different concept. If I compare the objects with the equals() methods, the JVM will return true. Making them not two different objects. Just different instances. -
Item crafted does not persist, but when taken from creative it persists
ctbe replied to ctbe's topic in Modder Support
Nice. I report your post on your dim mockery and nothing happens. I love it. That certainly leaves a lot to say. I faced a problem here and you didn't even try to help. When the problem was solved and the thread could have died with the conclusion of a solution, you reply. Not to help, but to make dim mockery and try to make yourself look like you have so much common sense knowledge on the forge platform. Your reply contributes nothing, but dim mockery and helps no one. The problem was already solved, your reply is out of place. I'd love to see anyone pointing out how your reply is helpful in any aspect and/or helps solve the problem. For it to be so evident, I didn't see you pointing out the so evident solution. I had more to say about some observations I have seen that are meretricious at best, but I'll leave it at that. After all humans like that tend to be described by society with certain words. The behavior has been already studied, well documented, and is somewhat predictable on certain levels. -
Getting EntityPlayer in a TickEvent to call another method.
ctbe replied to Geometrically's topic in Modder Support
Geometrically, I posted an answer in what appears to be an accidental duplicate of this thread. Here To add more information to it, the handler variable in your method has the information you want and you get in the form of a List<EntityPlayer> through the world. From what I understand, you want to broadcast the message to all players, so you would iterate through the list like this World worldIn = handler.world; List<EntityPlayer> playerList = worldIn.playerEntities; for (EntityPlayer player : playerList) { printMessages(player); } I find it odd that the code I posted in the other thread has EntityPlayers. With an 's' at the end. It is supposed to be EntityPlayer. Just to clarify. I hope it helps. -
Item crafted does not persist, but when taken from creative it persists
ctbe replied to ctbe's topic in Modder Support
Yes, my mod is made in Scala. But it's okay. I got it working. The object I was passing to it (modItems.itemStaff) did exist, was initialized and everything was correct, but it wasn't the same object instance I used in the RegistryEvent (RegistryEvent.Register[Item]) to register the item before preInit. The instance of the Item you must pass to new ItemStack when adding a recipe must be the same instance used in the RegistryEvent for the item. If you create a new instance just for the sake of registering a recipe, it will give the impression it works, you will be able to craft and use the item, etc., but it will not persist when you close the world. When you open the world again, the item will disappear from your inventory. I ran into this because I was trying to avoid the use of statics as much as possible. But it's fixed now. For those who might face the same problem, make sure the instance of the item you pass to the ItemStack when registering the recipe with GameRegistry.addShapedRecipe or similar methods from GameRegistry, is the same instance used to register the item in the RegistryEvent before preInit. Thanks for your prompt replies, everyone. -
Getting EntityPlayer in a TickEvent to call another method.
ctbe replied to Geometrically's topic in Modder Support
The handler has a way to get a List of all the players. From the handler you can get the world and from the world you can get said list. For example World worldIn = handler.world; List<EntityPlayers> playerList = worldIn.playerEntities; That returns a List<EntityPlayers>. You iterate through the list players to then pass a specific player to the printMessages method. -
Item crafted does not persist, but when taken from creative it persists
ctbe replied to ctbe's topic in Modder Support
Yes, I can craft it. And use it. My staff does what I programmed it to do. Is there any way I can test if the item the player is holding on hand is registered? Like a method that gives you information about the item the user is holding or something similar. I ask to see if I can somehow debug it. While debugging in the IDE I can see the item modItems.itemStaff has been registered using events as per the documentation recommendations, and exists. It is properly initialized and it has the unlocalized and registry names registered too. Edit: To add more information, I am looking through the logs and when I reopen the world, it says nothing about a missing item or an item being deleted. It just reopens the world without the item in the inventory. When I close it doesn't say anything either about an item failing to save or something similar. Nor when I craft the item. No message is thrown whatsoever. -
Item crafted does not persist, but when taken from creative it persists
ctbe replied to ctbe's topic in Modder Support
Thanks. I fixed it to look like that now, but it still disappears from the inventory when I quit the game. -
Item crafted does not persist, but when taken from creative it persists
ctbe replied to ctbe's topic in Modder Support
Sure. GameRegistry.addShapedRecipe(new ItemStack(modItems.itemStaff), "XRX", "XSX", "XSX", 'R'.asInstanceOf[Character], Items.REDSTONE, 'S'.asInstanceOf[Character], Items.STICK) modItems contains the staff item in a variable called itemStaff. I debugged and the item is present and initialized at the moment the crafting recipe is added. -
[Forge 1.10.2] Create a pickaxe that break unbreakable blocks?
ctbe replied to lethinh's topic in Modder Support
Happy to help. I hope you achieve what you want. Cheers. -
I hope this is not a silly question. For a staff I created in my mod, I added a crafting recipe using GameRegistry.addShapedRecipe(). I passed it a new ItemStack with the item, as well as the other parameters to build the recipe. The recipe works. It gets registered and you can craft the staff in a crafting table, but when you close the world, or the whole minecraft game, and open it again, the staff disappears! The staff is added to the creative tab and you can get the item from creative. When you do get the item from creative, it persists across world closes and opening. But when you craft it, you get the item only for the time the world is open. If you close the world with Save and quit to title, or close the whole minecraft game, the item disapears from your inventory. It does not persist. Is there anything else one has to do for when items are crafted in a crafting table to be saved?
-
You are right. Applied your suggestion.
-
Thanks. It was me then. Before, I was setting the creative tab for my item at the constructor of my item. But because you need the item to exist before registering it and the register event got launched before the creative tab for the mod was even created, what you said was happening. It was setting the item's creative tab to null at creation. I fixed it by creating a method in my item's class that sets the creative tab and manually calling said method at preInit, when I know for sure the creative tab for my mod will already exist.
-
I don't know if I should file a bug, but given that I'm new I'll try to ask first if my methodology is just wrong. When I check the documentation at: https://mcforge.readthedocs.io/en/latest/concepts/registries/ It says at the moment of writing this to use events for registering items When I register my item through events, by subscribing to RegistryEvent.Register[Item] And adequately register the event, I get no items in the creative tab of my mod. However, when I use the ways I find in tutorials, by calling GameRegistry.register at preInit, I get my items in my mod creative tab. According to the documentation this is the old way while the recommended event way of registering happens before preInit. Is this intended? Or a bug? I tried calling both, but you can only register items once. If you do it both the game crashes specifically at preInit because the item was already registered in the event that happens before preInit.
-
If your custom block extends Block, there is no method for setting the material. The variable for Material is protected final and is only edited on construction. And getBlockState() returns a BlockStateContainer object which only has a method for getMaterial(). Not to edit the material. I think it is safe to conclude that there is no way to set the material other than when constructing the block. If there is a way I'd like to know as well since it might be a useful feature.
-
[Forge 1.10.2] Create a pickaxe that break unbreakable blocks?
ctbe replied to lethinh's topic in Modder Support
Since the thread is getting lengthy I will try to explain as best as I can. I tried to achieve what you want on a custom pickaxe and got it working. I got it to break Bedrock and give me the block drop. However, the pickaxe must be enchanted with Silk Touch for the code I am about to provide you to work. The reason is that I use here the harvestBlock method and if it doesn't have Silk Touch it will not harvest anything, at least not bedrock. It may harverst custom unbreakable blocks with an unenchanted pickaxe if those custom blocks have a drop defined for harvest, but not bedrock. For bedrock it needs Silk Touch. Without deviating much from subscribe event, the logic was this: Create an item that extends ItemPickaxe Create a method to subscribe to the Event Handler PlayerInteractEvent.LeftClickBlock inside the class of the custom pickaxe Do the logic inside that created method Get the World, EntityPlayer, BlockPos, IBlockState, Block, and ItemStack into variables (get them from the event variable that gets passed to the method) Check that we work on the logical server Check if the block is an unbreakable block by using the IBlockState getBlockHardness method and checking if the hardness is less than 0 If it is an unbreakable block, harvest it with the harvestBlock method Destroy the block Register the subscribed event handler in the item's constructor The code for the event would be @SubscribeEvent public void onPlayerDig(PlayerInteractEvent.LeftClickBlock event) { World worldIn = event.getWorld(); EntityPlayer player = event.getEntityPlayer(); BlockPos pos = event.getPos(); IBlockState state = worldIn.getBlockState(pos); Block block = state.getBlock(); ItemStack stack = event.getItemStack(); if (!worldIn.isRemote) { if (state.getBlockHardness(worldIn, pos) < 0) { //Block is unbreakable //Harvest it worldIn.getBlockState(pos).getBlock().harvestBlock(worldIn, player, pos, state, null, stack); //Destroy the block worldIn.destroyBlock(pos, false); } } } then the code to register the event would go in the item's constructor like so public CustomPickaxe () { MinecraftForge.EVENT_BUS.register(this); } This last one you need to call. If you don't register the event, it will not work. The code will not run. I hope this helps you at least to get you in the right direction. The code works. Notes: This is a template. Your constructor could have a parameter that passes the ToolMaterial into it, etc. And more code to initialize your tool. Like I mentioned above, the tool must be enchanted with Silk Touch for the block to drop itself. I tested it and it breaks bedrock and drops it. The reason I did not use the code tags is that something is messed up in my editor. It is placing the code on the top and not where I want. If someone from staff wants to edit it and make it look properly when using the code tags then that is okay with me. -
I understand. Thanks for explaining. I could have messed up really bad. I must change my code. I am trying to get which face of the block was hit when a block broke because depending on the face that it was hit, I will perform operations on neighbor blocks. If it was hit on the West or East side I will ignore the East and West offset blocks and work on the North and South offsets. If it was hit on the North and South offsets I will ignore the North and South offsets and work on the East and West offsets. But the block has to first break before I can perform operations on the neighbor blocks. I have an item that extends ItemPickaxe and I override the onBlockDestroyed method which has signature public Boolean onBlockDestroyed(ItemStack stack, World worldIn, IBlockState state, BlockPos pos, EntitiLivingBase entityLiving) I thought I could get the face it was hit from the IBlockState, but I can't find any method that would return it. Or maybe I'm not searching well. To get that information I later thought I could override the onBlockStartBreak method which gets called right before onBlockDestroyed gets called, but that one has less information passed as arguments. onBlockStartBreak has only an ItemStack, BlockPos, and EntityPlayer on its signature.
-
[Forge 1.10.2] Create a pickaxe that break unbreakable blocks?
ctbe replied to lethinh's topic in Modder Support
I noticed once, that when I used methods like world.setBlockToAir(pos); or world.setBlockState... nothing would happen. It resulted that if I used if (!world.isRemote) {world.setBlockToAir(pos);} or if (!world.isRemote) {world.setBlockState...} Then it would work. In the first case, when it wasn't executed on logical server side, you could see the code would run, but quickly turned back to before it's execution and changes where not effective. Even after restarting Minecraft. But that little check of sides, would make the changes persist. I may be wrong, I am new to this, but maybe you could try that. Check the sides. Try to put your code inside if (!world.isRemote) { } If I am wrong, then I welcome corrections. -
In an overridden method that doesn't tell me the facing on which a block was hit after breaking (onBlockDestroyed), I am using FMLClientHandler.instance().getClient() and if it is not null I try to get what face of the block was hit with FMLClientHandler.instance().getClient().objectMouseOver.sideHit. Everything works fine and I have not had any problems. I don't know if this is the best way, it is the only way I found. I call this inside the logical server and I am playing in single player. If the mod is used in a multiplayer server in which the server as well the client have the mod installed, would that cause trouble? If the answer is yes, would there be a preferred way to get the side of the block that was hit?
-
Yes, I was going to change that to use the constants in the Blocks class, but I forgot. Just did that. Thanks for the reminder, very important. About the casing I did not notice because I kept editing my original code without noticing that the changes made it possible to be reduced to one single case. So you are right. I could just do override def onItemUse(player: EntityPlayer, worldIn: World, pos: BlockPos, hand: EnumHand, facing: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): EnumActionResult = { // Do only on logical server side if (!worldIn.isRemote) { // Only if player has torches on inventory if (player.inventory.hasItemStack(new ItemStack(Item.getItemFromBlock(Block.getBlockFromName("TORCH"))))) { var placed = false // Torches cannot be placed on the down side if (facing != EnumFacing.DOWN) { placed = worldIn.setBlockState(pos.offset(facing), Blocks.TORCH.getBlockState().getBaseState().withProperty(BlockTorch.FACING, facing), 2) } if (placed) { // Play sound on torch placed var soundType = Blocks.TORCH.getBlockState().getBlock().getSoundType(Blocks.TORCH.getBlockState().getBaseState(), worldIn, pos, player) worldIn.playSound(null, pos, soundType.getPlaceSound(), SoundCategory.BLOCKS, 1.0f, 0.8F) } } else { return EnumActionResult.FAIL } return EnumActionResult.SUCCESS } return EnumActionResult.FAIL } } and it is reduced and avoiding redundancies. The EnumFacing.DOWN check is necessary in this last one because otherwise it throws an IllegalArgument exception when trying to place the torch on the downside of a block. Since the there is no property for down in the torch facing. Thanks.
-
Thank you very much. A couple of minutes ago I got it. But I appreciate your reply a lot. Thanks. Like in the logic of your example, now it looks more or less like override def onItemUse(player: EntityPlayer, worldIn: World, pos: BlockPos, hand: EnumHand, facing: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): EnumActionResult = { // Do only on logical server side if (!worldIn.isRemote) { // Only if player has torches on inventory if (player.inventory.hasItemStack(new ItemStack(Item.getItemFromBlock(Block.getBlockFromName("TORCH"))))) { var placed = false // Depending on where on the block the staff was used facing match { case EnumFacing.EAST => placed = worldIn.setBlockState(pos.offset(facing), Block.getBlockFromName("TORCH").getBlockState().getBaseState().withProperty(BlockTorch.FACING, EnumFacing.EAST), 2) case EnumFacing.NORTH => placed = worldIn.setBlockState(pos.offset(facing), Block.getBlockFromName("TORCH").getBlockState().getBaseState().withProperty(BlockTorch.FACING, EnumFacing.NORTH), 2) case EnumFacing.SOUTH => placed = worldIn.setBlockState(pos.offset(facing), Block.getBlockFromName("TORCH").getBlockState().getBaseState().withProperty(BlockTorch.FACING , EnumFacing.SOUTH), 2) case EnumFacing.UP => placed = worldIn.setBlockState(pos.offset(facing), Block.getBlockFromName("TORCH").getBlockState().getBaseState().withProperty(BlockTorch.FACING , EnumFacing.UP), 2) case EnumFacing.WEST => placed = worldIn.setBlockState(pos.offset(facing), Block.getBlockFromName("TORCH").getBlockState().getBaseState().withProperty(BlockTorch.FACING, EnumFacing.WEST), 2) case _ => // Nothing } if (placed) { // Play sound on torch placed var soundType = Block.getBlockFromName("TORCH").getBlockState().getBlock().getSoundType(Block.getBlockFromName("TORCH").getBlockState().getBaseState(), worldIn, pos, player) worldIn.playSound(null, pos, soundType.getPlaceSound(), SoundCategory.BLOCKS, 1.0f, 0.8F) return EnumActionResult.SUCCESS } } else { return EnumActionResult.FAIL } return EnumActionResult.SUCCESS } return EnumActionResult.FAIL } } I will add the canPlayerEdit logic as well as the logic to remove the respective item from the inventory when they get placed. Thanks. Edit: I also noticed I need to check where I am placing the torch since if I use the staff on another torch, it places another torch in the air, with the given offset. So I must make sure it is not another torch or a door, etc.