jabelar
Members-
Posts
3266 -
Joined
-
Last visited
-
Days Won
39
Everything posted by jabelar
-
Well, yes. But you need to follow Java practices for passing collections as varargs. I think generally you need a toArray() sort of conversion. This is explained in this article: http://programming.guide/java/passing-list-to-vararg-method.html Also, I'm a bit confused on what you want. Do you want to actually generate the structures in ALL biomes? Remember that list will contain ocean and nether and so forth. But of course you can create your own sublists by removing stuff you don't want. In particular you can use the BiomeDictionary to help algorithmically filter out things by type.
-
This is standard Java, which frankly we get a bit grumpy here about supporting since it is pretty easy to google. But it is a nice day, so I'll be nice! The error means that there is no such method. Your code is trying to call EnumFacing.getDirectionFromEntityLiving() but you're passing an EntityLivingBase as the placer. But the method requires an EntityLiving. There is no way for the code to be sure that something you typed as EntityLivingBase is an EntityLiving. EntityLiving are always EntityLivingBase, but not all EntityLivingBase are necessarily EntityLiving so it is an error. Even if every EntityLivingBase in Minecraft is extended to EntityLiving, the compiler cannot assume that is always true. In this case, as a coder you know that the placer field will actually be an EntityLiving. So you should "cast" the placer to EntityLiving before you pass it to the EnumFacing method. Look up casting in Java if you don't understand this.
-
[1.12.2] Entity AI not attacking (methods not getting called)
jabelar replied to Turbo Pig's topic in Modder Support
There are two task lists for a reason. The targeting is separate. So I don't think you should add the melee AI to the targetTasks, but rather to the regular tasks list. Also, generally the priority means that if a higher priority (lower priority number) task is already executing then it will prevent yours. So you want to give the melee a priority that makes sense. There is also a concept of "mutex" bits which further controls how different AI works together. I explain this more in my tutorial: http://jabelarminecraft.blogspot.com/p/minecraft-forge-1721710-custom-entity-ai.html -
How does the findNearestStructure function work?
jabelar replied to Calous's topic in Modder Support
Well, a list can contain BlockPos and can also take in entries for any custom class you create. If you want more information, like a special name for the location of course you can use another collection type like a Map. But in any case you need a list-like collection. So you can just have list of BlockPos and if you don't want to list every block in your "structure" then you just need to record some BlockPos that you consider a marker for the location -- maybe the center, or maybe you have a special block, or maybe just the "seed" for your procedural generation. So just a list. Pretty sure the structure finding ultimately is implemented as a list (or similar collection). -
So, you can get the registry instance in the RegistryEvent.Register<Biome> event. Even if you're not registering your own biome you can handle it. The event.getRegistry().getValues() returns a List<Biome> that can be stored in your own field for later reference. However, there is no guarantee that another mod isn't going to register more biomes after your chance to handle the event. So probably better to store the registry itself and grab the values later (maybe in the init loading phase) or if you're only looking up biomes occasionally performance probably isn't big concern and you can look it up whenever it makes sense. So, the steps would be: 1) make a class that is registered as an event handler, and have a method that subscribes to the event bus that handles the RegistryEvent.Register<Biome> case. 2) In that event handling method you would assign the registry to a public static field that you can access from elsewhere in your code. So something like this: /** /* This class would probably also be the one where you register your own biomes, if you /* do that in your mod. Otherwise can be its own class dedicated for this purpose. **/ @ObjectHolder(MainMod.MODID) // in case you're actually also registering biomes public class ModBiomes { // field to contain registry for later reference public final static IForgeRegistry<Biome> registry = null; @Mod.EventBusSubscriber(modid = MainMod.MODID) public static class RegistrationHandler { /** * Register this mod's {@link Biome}s. * * @param event The event */ @SubscribeEvent public static void onEvent(final RegistryEvent.Register<Biome> event) { System.out.println("Storing biome registry"); registry = event.getRegistry(); // Register any of your own biomes here as well // example: registry.register(new BiomeCloud().setRegistryName(MainMod.MODID, ModWorldGen.CLOUD_NAME)); // DEBUG System.out.println("Registry key set = " + registry.getKeys()); System.out.println("Registry value list = " + registry.getValues()); } } } Then later, you can just get the List<Biome> by referring to ModBiomes.registry.getValues(). Again I suggest you grab this in the init phase of your mod loading (where you'll be guaranteed that all other mods have added their biomes). You can put that list also into a public static field or not depending on how you intend to use the values.
-
It isn't enough to just call the method from the proxy. The method itself also needs to be in the proxy, or else properly side-only. By having the method in your ModItems class which gets loaded on dedicated server you'll create the situation where just having that method there will cause trouble since it references classes (Minecraft) that "don't exist" as far as it is concerned.
-
It works fine for me. If I print the registry keys and values I get: [21:59:22] [main/INFO] [STDOUT]: [com.blogspot.jabelarminecraft.examplemod.init.ModBiomes$RegistrationHandler:onEvent:56]: Registry key set = [minecraft:ocean, minecraft:plains, minecraft:desert, minecraft:extreme_hills, minecraft:forest, minecraft:taiga, minecraft:swampland, minecraft:river, minecraft:hell, minecraft:sky, minecraft:frozen_ocean, minecraft:frozen_river, minecraft:ice_flats, minecraft:ice_mountains, minecraft:mushroom_island, minecraft:mushroom_island_shore, minecraft:beaches, minecraft:desert_hills, minecraft:forest_hills, minecraft:taiga_hills, minecraft:smaller_extreme_hills, minecraft:jungle, minecraft:jungle_hills, minecraft:jungle_edge, minecraft:deep_ocean, minecraft:stone_beach, minecraft:cold_beach, minecraft:birch_forest, minecraft:birch_forest_hills, minecraft:roofed_forest, minecraft:taiga_cold, minecraft:taiga_cold_hills, minecraft:redwood_taiga, minecraft:redwood_taiga_hills, minecraft:extreme_hills_with_trees, minecraft:savanna, minecraft:savanna_rock, minecraft:mesa, minecraft:mesa_rock, minecraft:mesa_clear_rock, minecraft:void, minecraft:mutated_plains, minecraft:mutated_desert, minecraft:mutated_extreme_hills, minecraft:mutated_forest, minecraft:mutated_taiga, minecraft:mutated_swampland, minecraft:mutated_ice_flats, minecraft:mutated_jungle, minecraft:mutated_jungle_edge, minecraft:mutated_birch_forest, minecraft:mutated_birch_forest_hills, minecraft:mutated_roofed_forest, minecraft:mutated_taiga_cold, minecraft:mutated_redwood_taiga, minecraft:mutated_redwood_taiga_hills, minecraft:mutated_extreme_hills_with_trees, minecraft:mutated_savanna, minecraft:mutated_savanna_rock, minecraft:mutated_mesa, minecraft:mutated_mesa_rock, minecraft:mutated_mesa_clear_rock, examplemod:cloud] [21:59:22] [main/INFO] [STDOUT]: [com.blogspot.jabelarminecraft.examplemod.init.ModBiomes$RegistrationHandler:onEvent:57]: Registry value list = [net.minecraft.world.biome.BiomeOcean@217fd3c, net.minecraft.world.biome.BiomePlains@1736273c, net.minecraft.world.biome.BiomeDesert@36eb8e07, net.minecraft.world.biome.BiomeHills@2a20da9f, net.minecraft.world.biome.BiomeForest@6f2864c3, net.minecraft.world.biome.BiomeTaiga@c2f7c63, net.minecraft.world.biome.BiomeSwamp@5cba890e, net.minecraft.world.biome.BiomeRiver@4d770bcd, net.minecraft.world.biome.BiomeHell@28a3fc34, net.minecraft.world.biome.BiomeEnd@7736c41e, net.minecraft.world.biome.BiomeOcean@5f911d24, net.minecraft.world.biome.BiomeRiver@3de383f7, net.minecraft.world.biome.BiomeSnow@31de27c, net.minecraft.world.biome.BiomeSnow@7ebfe01a, net.minecraft.world.biome.BiomeMushroomIsland@35c00c, net.minecraft.world.biome.BiomeMushroomIsland@6cd7dc74, net.minecraft.world.biome.BiomeBeach@20556566, net.minecraft.world.biome.BiomeDesert@e4ef4c0, net.minecraft.world.biome.BiomeForest@5ca8bd01, net.minecraft.world.biome.BiomeTaiga@7b10472e, net.minecraft.world.biome.BiomeHills@70e5737f, net.minecraft.world.biome.BiomeJungle@180cc0df, net.minecraft.world.biome.BiomeJungle@64f33dee, net.minecraft.world.biome.BiomeJungle@61c58320, net.minecraft.world.biome.BiomeOcean@10e4ee33, net.minecraft.world.biome.BiomeStoneBeach@13f182b9, net.minecraft.world.biome.BiomeBeach@5ee0cf64, net.minecraft.world.biome.BiomeForest@69c227fd, net.minecraft.world.biome.BiomeForest@14c5283, net.minecraft.world.biome.BiomeForest@1eb7ec59, net.minecraft.world.biome.BiomeTaiga@46748b04, net.minecraft.world.biome.BiomeTaiga@3e71a1f8, net.minecraft.world.biome.BiomeTaiga@5d4a34ff, net.minecraft.world.biome.BiomeTaiga@7cbede2b, net.minecraft.world.biome.BiomeHills@1ef04613, net.minecraft.world.biome.BiomeSavanna@215c6ec0, net.minecraft.world.biome.BiomeSavanna@2b19b346, net.minecraft.world.biome.BiomeMesa@4e789704, net.minecraft.world.biome.BiomeMesa@5751e53e, net.minecraft.world.biome.BiomeMesa@4e45fbd0, net.minecraft.world.biome.BiomeVoid@43b45ce4, net.minecraft.world.biome.BiomePlains@73e93c3a, net.minecraft.world.biome.BiomeDesert@1835b783, net.minecraft.world.biome.BiomeHills@456b140f, net.minecraft.world.biome.BiomeForest@2459333a, net.minecraft.world.biome.BiomeTaiga@1e6bd367, net.minecraft.world.biome.BiomeSwamp@2bd7f686, net.minecraft.world.biome.BiomeSnow@3601549f, net.minecraft.world.biome.BiomeJungle@5b2c7186, net.minecraft.world.biome.BiomeJungle@1b9c716f, net.minecraft.world.biome.BiomeForestMutated@33f2cf82, net.minecraft.world.biome.BiomeForestMutated@bea283b, net.minecraft.world.biome.BiomeForest@73852720, net.minecraft.world.biome.BiomeTaiga@22854f2b, net.minecraft.world.biome.BiomeTaiga@7ae0a26, net.minecraft.world.biome.BiomeTaiga@5ddf5118, net.minecraft.world.biome.BiomeHills@7b9d1a4, net.minecraft.world.biome.BiomeSavannaMutated@7845ee8a, net.minecraft.world.biome.BiomeSavannaMutated@5f35370b, net.minecraft.world.biome.BiomeMesa@16c8e9b8, net.minecraft.world.biome.BiomeMesa@7030b74c, net.minecraft.world.biome.BiomeMesa@27d6267e, com.blogspot.jabelarminecraft.examplemod.worldgen.BiomeCloud@4d34baec]
-
Code isn't magic, it is very logical. So you can solve any such problem just by observing the execution. You should not be trying to just modify code and see if it fixes it. Instead, put in console print statements at every point in the code that matters. For example, at the beginning of the read from NBT you should put a statement that prints out the tag, and then after the deserialization you should print out the item. Why worry about the item being zero if you find that the tag is empty? Or maybe the method isn't even being called when you expect? You need to work backwards to find at what point the data stops matching the expected behavior. Your IDE (Eclipse or whatever you're using) also provides debugging mode which can help you trace the execution of the vanilla classes. Put a breakpoint on the read from NBT method and see what the data is. If the data is bad, then put a breakpoint where that method is called and see what is happening there. If that data is bad put a breakpoint at an earlier point. In programming you should never just write code and say "the result is wrong so I'm stuck". Computers are fully logical, so the reason will be obvious if you just watch the execution.
-
Sure it is a forge registry so the actual singleton instances are registered.
-
In your first snippet above, the read is on the client side and in your second it is on the server side. You need to trace what is happening on each side step by step. For example, in the second case on the server what was in the tag passed into the read from NBT? You need to basically follow basic debugging. If a value isn't what you expect, then work backwards and see if the data going into the code is also not what you expect. So Item is zero so you need to go next step and see if the tag data was correct.
-
[1.12.2] Registering a fluid without the block?
jabelar replied to turbodiesel4598's topic in Modder Support
What do you mean that the "fluid texture goes missing"? Do you mean you can't see a universal bucket full of it in your inventory? Because without a block or item as a fluid handler a fluid won't show up in your inventory except in a universal bucket. I'm not aware of needing a block for texture to show up in the universal bucket -- the fluid itself has texture resources. Also maybe describe more about what you're trying to do/expect to happen. Without a block you can't place the fluid on its own in the world, so I'm assuming you are putting it into some other existing tank? -
I don't see anything obvious but have you traced your code? Using debugger or console statements you should simply confirm what is going on. If you print out what the tag is like in the write and read, if you confirm that the packets are working, and so forth, it should be really simple to see what is going wrong.
-
You need to carefully choose the type of "clone" or copy you are doing. You can always replace the chunk passed into the event with a new chunk, rather than trying to selectively replacing fields within the chunk. But make sure you understand the difference between deep and shallow cloning. You may need to do a "deep" clone.
-
Because now there is the event-based biome registration you can use ForgeRegistries.BIOMES.getValues() to get all the biomes. I believe this method would give all the biomes available in the game across all world types. To determine if a biome is for the nether or end, you can use the BiomeDictionary and use the getTypes() method to check if the biome is of Type.NETHER or Type.END. You could similarly use the dictionary to rule out any other categories of biome appropriate to your need.
-
In a case where code is in a class that doesn't have @SideOnly annotation, you're right that you it is best to only reference classes that are known to be loaded. However, in this case if you're on the client it is probably best to use the Minecraft method to get the player. So this is a case where you can use your proxy. In your client proxy create a method called getPlayer() that returns the Minecraft.getMinecraft().player and in the server proxy create a method with same name that returns null. To be doubly sure, in the event you can also check if the world is remote. Anyway, using the proxy will ensure that the whatever side you're on, the method called only references classes that exist on that side.
-
Well, the event does pass the actual chunk, so I suppose you might be able to manipulate it directly. For example, maybe you can assign it to a "shallow clone" of the chunk it is supposed to be looped from. A shallow clone means that the Chunk itself is a separate instance but all the fields point to the same memory as the fields in the other. People that know more about advanced Java than me can probably advise on whether this is viable, but it is the first thing I would try because then things like entities and blocks would not need any additional synchronization. If that didn't work, then I would try a deep copy -- meaning actually copy every block and entity and such into the chunk. I'm not sure the most efficient way to do this, but I know chunk generators uses a ChunkPrimer to do the placement then convert that to a chunk. You'd need to figure out the best way to keep them synchronized though, especially if there are entities and such involved. If that didn't work, then I would try replacing the whole chunk generator with one that repeats. Again you'd need to think about how to keep the looped chunks synced up in terms of any changes and entities. All the above are assuming creating an actual chunk is needed. It may be possible though that you can get the effect just by doing rendering. I'm not sure but it actually might be simple to make a modified world renderer that gets the data from looped chunk data. The only only trick would be that technically there would be chunks being loaded that are not being rendered and so you'd have to protect against things like entities wandering from those chunks into the rendered ones, and such.
-
I'm wondering if the logic for things like isHandActive() are getting a bit screwed up for your implementation. If you trace the call hierarchy you find that the Minecraft#proccessKeyBinds() method will only stop the use if the isHandActive() returns true. For example, you should double check your onItemRightClick() and compare with the ItemBow implementation for example to make sure you're properly setting the hand active in the first place. Part of the problem is that an item like yours is sort of a mix between vanilla item behaviors. For example, food consumes the actual item stack and checks the maximum use duration so there is code that checks to see if the item stack becomes empty, but you have a separate concept of ammo. And a bow has a concept of use but only fires once at the end of use. So I suspect that you're not quite handling some piece of the vanilla logic correctly. Maybe it is the active hand stuff. Or maybe the max use duration stuff. The other issue is that NBT isn't automatically synced between sides. It will get synced, but maybe not as quickly as you might need for your logic. So you might want to force the sync by explicitly sending an item update packet. Regarding "synchronization" though I'm not sure what you are concerned about in your console trace you posted. It looks like the client side (MAIN) detects the firing and sends that to the server which then starts firing. There is of course the problem that you should also see the client detect the stopped using, but otherwise it looks normal to me. What did you expect to see?
-
If you mean animating the texture (and not the actual model), then you can add the metadata file with the same texture name and in your model you can set how the animation progresses. Look at lava and water block model json and texture to get the idea.
-
I wouldn't say never. However, I agree that in many / most cases it isn't appropriate. If you have a targeted answer to the question I think it can be appropriate. The problem with most people replying to old threads is that they aren't trying to give a conclusion to the thread, most people are saying something like "I have same problem" which is entirely unhelpful, and another set of people are adding an answer which isn't really properly addressing the problem in the first place. Maybe it is just me though, but seeing an old question that was never properly answered does bother me. The internet is becoming a place where information is accessible indefinitely and so even if something was posted five years ago, it can be very likely to come up in a Google search today. I would actually like it to work the other way -- an old thread should have the actual answer and any new questions on the same topic should be referred back to the old thread. This is sort of how StackOverflow works -- many new questions are closed as "duplicates" although admittedly even that gets debated sometimes depending on how close the question really is. In other words, in some help systems the first time the question is asked is considered the place where the definitive answer should be. In any case, people here definitely dislike necro posting and I agree that in most cases people resurrecting old posts are doing so wrongly so worth sticking to the rule.
-
To trace this sort of thing you should use console statements of IDE debugger to trace the execution. For example, with a console statement it would quickly become apparent if the method is being called more than once per tick. The code looks generally correct to me, so I assume that the method is being called mutliple times in your problem case.
-
[1.12.2] Checking if the player's inventory is full?
jabelar replied to Differentiation's topic in Modder Support
Okay, but do you mean "full" in that there is something in every slot, or that every slot is actually full (max stack size)? -
How are you registering your item models? I think the ModelLoader.setCustomModelResourceLocation() method can take metadata values. So one approach is to have separate JSON for each subtype and register them accordingly by metadata.
-
I think we're getting more strict to "police" things now. It frankly gets wearing answering questions that a quick google could have answered. I personally don't get the aversion to picking up old threads if they were not properly concluded though. I feel like that helps the people that might get that thread in a search. The tricky thing on the internet is simply not knowing who is on the other end. For all we know it can be a kid, or someone with a mental disability, or maybe somebody who needs a cheery outlet for an otherwise depressing life. So I like to err on the side of kindness. However, like a coach I also like to give some "tough love" to someone who I think is capable of getting to the next level. So if someone is hopeless, I'm usually kind cause I figure they may have some problems. If someone is posting some credible code but asking a lazy question I usually will push them to learn to help themselves. So apparent inconsistencies in responses may actually have a basis. Anyway, your desire to help is welcome here. Please don't be put off by this situation.
-
I think it is actually helpful to tell people "go away, that's a basic Java issue". The reason is that ideally we teach people to help themselves, and so that means people should (a) learn to realize that their question has nothing to do with Minecraft and is generic to Java or their IDE, and (b) learn to realize that there are amazing resources (better than here) for learning Java. So for this sort of problem I'd love people to go -- my IDE is complaining so I will google "cannot be resolved to a type" and get great answers like https://stackoverflow.com/questions/15794821/eclipse-error-cannot-be-resolved-to-a-type So it is actually more helpful to tell people to go somewhere else for such problems. They'll become stronger programmers.