Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by jabelar

  1. The "problem" with the Forge Engery API is that for your case you don't want your energy interchangeable with other energies, whereas FE was designed specifically to help interchange between energies. I believe it is possible to use FE to discriminate the energy type, probably by testing in the getCapability() methods, but is an added complexity. I think the easiest way is to simply make your own capability. There are tutorials for capabilities like mana. An energy system sounds fancy but really only requires an interface for storing energy with some methods for generating, transferring and consuming the energy. In fact you can probably just copy an existing energy system, maybe even the FE system. I don't mean use an existing energy system, but rather make your own capability that has similar code it so it is separate.
  2. The problem is that performance is going to be an issue. A single chunk has 65k positions you need to check, so 20 chunks has over a million positions! Functions that need to consider lots of blocks like rendering the world have very sophisticated ways -- like caching, culling and frustum checking -- to keep the processing work manageable. I think your best hope is to scan chunks as they are loaded and remember it. Even that will give a bit of a performance hit but at least it will be spread out and will only have to be done once. After the initial block counting, you'll also have to handle events for blocks breaking and blocks being placed/changed to keep your counts up to date.
  3. Yes I think you can do that. In the past there were certain substitution APIs but it never really worked well. I think with the modern registries you can directly replace entries, although I haven't tried it.
  4. Also, I figured out a way to work around the problem and get the order correct. It is slightly tricky to implement -- requires reflection, comparator sorting, and client proxy stuff. But I think I got it working so can just tell you how to do it. Let me know if you're interested.
  5. And regarding the other part of the question -- yes it is a lot of work for the Forge community whenever there is a major Minecraft upgrade.
  6. You didn't actually add any attack AI. You added the targeting AI, but not the attack itself. Also, you should not add the targeting AI task to the tasks list but only to the targetTasks list. You need something like EntityAIAttackMelee in the tasks list.
  7. Okay, I submitted issue: https://github.com/MinecraftForge/MinecraftForge/issues/4907
  8. Okay, so I had time to look at this further. I basically extended the Locale class to print out what it was doing and then used reflection to replace the one used in the game. Here is what the prints showed about the order that resources are loaded: My resource pack is jabelar_resource_pack.zip, and my mod is examplemod. If you look at the log, the order is confirmed that the mod resources are loaded after the resource packs. And you can see that the stone ends up with my mod name, not my resource pack name. So it is pretty clear that the order is that mod resources load last. However, I agree with you that that isn't the most useful or obviously expected order -- why not let people make resource packs to further modify a mod? I suppose you could argue though that if a mod is taking the trouble to modify a vanilla resource then it isn't clear what the user would want to do. But I'll ask the question in an Issue against MinecraftForge. Maybe it was purposeful. We'll see...
  9. That actually is not the best strategy from a programming perspective. You should always try to do the most logical approach (i.e. most likely bug-free and most maintainable, which usually implies being simple and readable). Trying to be clever for performance should only be undertaken when you know performance is actually a problem (you should profile your code). Also, your statements about perceived performance are not really true. You said that looping through a lot of blocks can cause lag, but that is not true for this case. Looping through a lot of block POSITIONS can cause lag because the numbers really add up. In a single chunk there are 65k block positions. There are literally millions of block positions in a Minecraft world. However, looping through block TYPES is unlikely to be more than a couple hundred. And in your case your item only works on machines so your list is only going to be like 10 entries long. Also, Java collections are already compiled extremely efficiently. So doing something like a contains() method to check against a set of 10 block types is going to be instantaneous. Regarding lines of code, that shouldn't be a factor in coding in most situations. Being bug-free is the most important thing and you have ability to cut and paste so any repetitive code doesn't really take any extra time (in fact is usually faster than trying to be clever with loops and special conditions). Basically in modern computers you rarely should worry about these things (performance or code size). Performance is only a concern with algorithms that grow exponentially (like searching regions of block positions, pathfinding, and so forth).
  10. What exactly do you mean? You want different patterns for each dye color (different textures for different colors)? Or you want to just change the texture for leather armor generally (one new texture applied in all cases)? Or you want to just change texture in case of dyed any color (two textures, one for un-dyed and one for dyed)?
  11. This is a logical fallacy when talking about proper code development. In most languages the compiler (or in this case JVM) has some leeway in some areas. For example, in some languages the way certain data types are stored can vary so if you depend on that your code might work "without a single problem" for you but then fail in weird ways for someone else. The way to avoid stepping into these subtleties is to understand the allowable variations in the compiler/JVM. In this case I think the main concern is that static initialization order is not guaranteed across classes. Besides registration, modders often run into this with crop blocks where the order of the seed item and the crop block get mixed up and the seed actually gets a null block because the seed gets instantiated before the block does.. So the general principle in coding, and particularly in modding related to singleton instantiation, is that you want to fully control the order and timing of the instantiation to be in proper place.
  12. I'm not really sure why you're so concerned about this. There are dozens of legitimate ways to achieve the result you're after. Each may have different advantages, and some may feel "cleaner" to implement, but as long as it works it is valid. Performance shouldn't be an issue in any reasonable implementation because this will only happen very occasionally in the game. To me the biggest question is whether you might want to use your wrench on machines from vanilla and from other mods. In that case I would take the approach of simply creating a collection (List, Set, Array, whatever suits best) of blocks that are "wrenchable" and then just check if block is member of the list when using the wrench. To me that is the most extendable approach.
  13. You need to override the getSubBlocks() method.
  14. Programming is just logic. So if you want to have your own energy system, you just need the ability to generate, store, transfer and consume a "quantity". You can do that with your own fields, but Minecraft Forge provides the capability system which helps because capabilities can be attached to players, entities, tile entities and items which is all the places you probably need energy functionality. There are various tutorials out there. Here is one that implements a "mana" (magical energy) capability: https://www.planetminecraft.com/blog/forge-tutorial-capability-system/ And some other info on capabilities: https://gist.github.com/williewillus/c8dc2a1e7963b57ef436c699f25a710d http://mcforge.readthedocs.io/en/latest/datastorage/capabilities/ Choonster's example Capability implementation (API, implementation)
  15. You guys aren't answering the topic the original poster asked about. He actually changed his original post a bit, but basically he wants to call a method from a mod but doesn't want to force the other mod as a dependency. That means the code cannot be sure to be available, so diesieben07 has provided a very clever approach to make it optional. It has nothing to do with recipes, and also both of your suggestions don't help with case where he wants to optionally access code from another mod from his mod.
  16. But that's the problem. In Java an instance is null if it doesn't exist at all. But in Minecraft the ItemStack can exist but be empty (usually if the quantity is 0, but can be other conditions like an illegal value for the quantity). So checking if Itemstack != null will always execute because it can't be null. So then if !itemstack.isEmpty() is never true then it means that your itemstack is empty. So you need to figure out why it is empty at that point. In other words, if a condition isn't true that doesn't mean the code was wrong, it can mean that the data isn't what you expect.
  17. Can you post more of your code? it is hard to check over if you have fields like itemstack which I can't see where they are coming from. One obvious thing wrong with your code is you're creating two different EntityItem. You create one but then don't use it because you spawn another one. Are you sure that the itemstack field has something in it at the time you create the EntityItem?
  18. For using git I suggest using a graphical user interface called SourceTree. It is free (and ad-free). I have tutorial here on setting it up (along with github): http://jabelarminecraft.blogspot.com/p/minecraft-forge-publishing-to-github.html
  19. Here's an example of what would work and would not work. Assume that the optional mod has an EntityVampire and in your mod if the other mod is loaded you want to spawn vampires, but if the other mod is not loaded then you want to spawn EntityWitch. Proper Encapsulation Example For proper encapsulation, the interface is designed so that the dummy implementation doesn't see any classes it won't have. For example, in your proxy interface you could have a method called spawnEvilEntity() that is prototyped like this: void spawnEvilEntity(World worldIn, BlockPos posIn); Then in your dummy proxy implementation class you implement the method as: public void spawnEvilEntity(World worldIn, BlockPos posIn) { EntityWitch entity = new EntityWitch(worldIn); entity.setLocationAndAngles(posIn); worldIn.spawnEntity(entity); } And in your active mod proxy implementation class you implement the method as: public void spawnEvilEntity(World worldIn, BlockPos posIn) { EntityVampire entity = new EntityVampire(worldIn); entity.setLocationAndAngles(posIn); worldIn.spawnEntity(entity); } Then you could use this in your main mod code whenever you want to spawn one of these you just call: proxy.spawnEvilEntity(theWorld, thePos); Wrong Way If you expose any classes from the optional mod to the interface it will cause trouble. For example, if instead of actually spawning the mob, if you made a method called createVampire() in your proxy interface like: EntityVampire createVampire(World worldIn, BlockPos posIn); And in your dummy proxy you had: public EntityVampire createVampire(World worldIn, BlockPos posIn) { return null; } And in your active mod proxy you had: public EntityVampire createVampire(World worldIn, BlockPos posIn) { EntityVampire entity = new EntityVampire(worldIn); entity.setLocationAndAngles(posIn); return entity; } In which case you might try to use it this way in your main mod: EntityVampire vampire = proxy.createVampire(theWorld, thePos); if (vampire != null) { theWorld.spawn(vampire); } else { EntityWitch witch = new EntityWitch(worldIn); witch.setLocationAndAngles(posIn); theWorld.spawn(witch); } This will fail because you have your main mod trying to access EntityVampire which may not be available. Not sure if my example is clear but the point is that you need to organize your proxy code so that all the code that depends on the classes from the optional mod are ONLY accessed within the active mod proxy implementation. You cannot expose those classes to the dummy proxy or the rest of your mod. If you get more specific on what you're trying to do, we can give more specific examples.
  20. Okay, I've confirmed what you said -- the mod's lang file will take priority over any resource pack's lang file. I'll spend some time this weekend looking at the code to see if I understand why, and then will try to file an issue assuming I can't find a good reason for it to work this way.
  21. What about the Session class? Is it public? You haven't really given enough code to fully understand what you're trying to do. I'm not familiar with that event, is that a custom event? You said you have dependency to the other mod, are you sure you have that set up properly in your build.gradle and otherwise classpath? And is the other mod properly present for the build purpose?
  22. I probably won't have time to try until the weekend but I will try to check it out.
  23. Also are you sure your lang files are named properly? Depending your pack.mcmeta version the lang file name has different capitalization. What exactly is the contents of your pack.mcmeta, your mod's lang file name, and your resource pack file names?
  24. As I mentioned, Forge specifically says it does not do it that way for lang files. It should do it for textures, models, etc. I'm not sure why they treat lang files different than other resources in resource packs. Also I mentioned that your problem may be that you are not registering your item at the proper time. That might be messing up the order of your lang file access. Did you try registering your item properly and see if it made a difference?
  25. Are you sure your biome is actually being used? Like have you made ChunkGenerator, WorldProvider and all that? Or are you just hoping that your biome will generate on its own in the Overworld? Generally, your code looks like it should work. But you should first make sure your biome is registered properly -- you should be using the RegistryEvent<Biome> event. Secondly, you should confirm that your biome is actually being used -- I would do standard debugging like either add a bunch of console print statements or else set breakpoints nad use Eclipse's debug run configuration to trace the execution. With that you can print out the contents of the spawn lists and such and generally confirm the code is functioning as you expect.
×
×
  • Create New...

Important Information

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