Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by jabelar

  1. Well, it depends what you mean by "forced". Of course in Java you can extend and @Override most stuff, or create your own custom fluid system, etc. So what fluids are you interested in handling. Basically there are the vanilla fluids, forge fluids and then other weird fluid systems other mods might have. If you're worried about trying to handle other mods' non-Forge fluid systems then you'd have to either look at their source/API or you have to work with their developer to ensure compatibility. But this is the same for all mod compatibility issues. Many modders follow the forge intended APIs but some go off and do things differently. I personally would just follow Choonster's advice and handle the vanilla and forge fluids for now.
  2. Okay, I just figured out the answer to my second question, but it is indeed a bit circular. The Fluid#setBlock() method is called by the BlockFluidBase constructor. So basically you create the fluid instance, pass it into the block constructor and it passes itself back to the fluid. It is a bit dangerous in my opinon to have a bunch of setters on Fluid that you expect people to invoke directly and have one that you shouldn't. Would have been better to have some sort of map, or the registry itself do the association...
  3. So I noticed that in the forge Fluid class that it has a getColor() method but no setColor() method. I'm not entirely certain what that color does but it seems to affect how a bucket is displayed? But it is weird that there is no setColor() method because it means you have to extend Fluid for your custom fluid when otherwise you could just call all the setters to make a custom fluid. Is that color important? Does that mean we need to extend Fluid rather than just instantiate it with setters if we want custom color? Where does the color for the overlay when you're submersed in the liquid get set (like when you're under water everything looks blue)? I know I can handle the overlay event but is it supposed to be set somewhere? Also, it seems that the BlockFluid and the Fluid classes are a bit circular. The BlockFluid takes a Fluid as a constructor parameter but Fluid class also needs a setBlock() to be set. Am I missing something? So when you're instantiating your block and fluid I'm guessing you first instantiate the fluid, then you instantiate the block while passing the fluid instance, and then you set the resulting block instance back to the fluid? I guess you can also just create an instance of the fluid with new Fluid() for the block constructor, but seems a bit wasteful and also seems like potential for a bug if you have both classes pointing at each other...
  4. yeah, markDirty() is easy to forget. Didn't think of that.
  5. Note that one of the difficulties with replacing a block like bed, is that the specific Blocks.BED instance is used throughout the code. I really, really wish that everywhere instances were checked that they were changed to instanceof type checks as that would make modding much easier -- imagine if all you have to do is extend the BlockBed and all the other code that checks for beds would accept your custom bed. So you can't just create your own custom bed and register it normally, but you need to actually replace the Blocks.BED instance with an instance of your own bed. The good news is that it is a public field so I think you can simply reassign it. But I'm just pointing out to take care that you need all the code that checks for == Blocks.BED to work for your custom bed.
  6. I don't think you should have to do any loading or saving. Rather you should just set and get it from the world storage and it will load and save when needed. Since it is world data you don't need to do anything when entity joins world, rather it will already be loaded when the world is loaded. You probably need to set it when the world is first created though, there is the WorldEvent.Load event that is appropriate for that. And generally you'd also set it anytime the information changes, although in your case I think you only generate it one time, right? So I think just do it in the WorldEvent.Load check if the data already is there and if not generate and set it.
  7. 1. Yes. At "compile time" there is no compiler relation at all between the JSONs and the item and block classes. The JSON matches based on the string registry names which it doesn't know about until the registration events are run. So recipes are only matched at run time. As long as the items and blocks are registered prior to the recipes I think you're good. For example I've created recipes that change based on configuration settings (requires restart of Minecraft to take effect) because the configuration loads before you register the recipes. You can also create conditions in your recipes and change the conditions in your code to change the behavior of the recipes. I give a few tips on these topics here: http://jabelarminecraft.blogspot.com/p/minecraft-modding-ore-dictionary.html 2. You can still implement old-school recipes I think by creating your own IRecipe implementations. They could be a "template" that you construct with different parameters. I haven't tried it but have seen mention of such an approach in other threads. 3. If you're extending or implementing the class it is your code, so I think you'd just override the appropriate methods while doing some string processing to take the portion of the name you care about. For example, there is string function for whether a string contains a substring, so if for example the full name contains "OreIron" then you could consider it a match and it should pick up all the variants. All the above is really just about Java. Pretty anything you want to do can be done. You could create your own asset format instead of JSON if you wanted to and use your own Java file handling, you could use reflection and replace major portions of the built-in system, and so forth.
  8. As mentioned, the code is in the onBlockActivated() method of the BlockBed class. You need to not allow allow the respawn but also the biome cannot be biome.HELL. You have two choices to fix it -- change the biome of your world or replace the bed block with your own custom block.
  9. How do you know it isn't working besides the final effect? To debug things you either need to trace the code in debug mode or you need to add a bunch of console or logger statements to help you understand which parts of your code is executing. I personally put a console statement at the beginning of EVERY method and watch to see that they are all be called as expected. If they are being called as expected I make the console statements more descriptive to indicate the key values at the time of execution, and usually add a few more console statements anywhere there is a branch (if statement) or loop (to monitor the looping). As long as you can see the operation of your code, you can easily debug it yourself.
  10. Thanks for the feedback. Yeah, with tutorials there is a balance in terms of telling people to copy code or not.
  11. How did you associate your class with the actual world or map save data? For your world save data to work I think you have instantiate it and add it to the MapStorage either for the dimension or for the save file. If you want it per dimension then you call the world#perWorldStorage() methods to set your world data into the storage map, if you want it per save file then you call the world#getMapStorage() method to set your world data to that storage map. At least that how I think it works...
  12. LivingSpawnEvent is a parent event. It has three children including the AllowDespawn event, so it gets fired occasionally by entities in the world. Instead you should handle either the CheckSpawn or SpecialSpawn event.
  13. I have a tutorial on custom triggering of advancements here:http://jabelarminecraft.blogspot.com/p/minecraft-modding-custom-triggers-aka.html
  14. I have a tutorial on setting up sourcetree and github here: http://jabelarminecraft.blogspot.com/p/minecraft-forge-publishing-to-github.html
  15. The issue arises because of my existing codebase, where all the unlocalized/registry names were tucked within each class and so now collecting them all in the registration class is painful. From an older version of my mod I had unlocalized name / registry name set in my constructors and so when I create a public static field I would simply call new MyCustomItem1() and so forth and to register them I would pull up the unlocalized name. So in my registration (which previously was in a proxy) it would look like this: public static final customItem1 = new MyCustomItem1(); public static final customItem2 = new MyCustomItem2(); ... public static final customItem50 = new MyCustomItem50(); and I would register them simply by the old methods where I could do: GameRegistry.registerItem(customItem1, customItem1.getUnlocalizedName()); GameRegistry.registerItem(customItem2, customItem2.getUnlocalizedName()); .... GameRegistry.registerItem(customItem50, customItem50.getUnlocalizedName()); So to convert to @ObjectHolder I have to go to dozens of item classes, dozens of block classes, sound instances sprinkled throughout my code and such and find the actual unlocalized name string and copy it over into annotations and it would be easier to continue to use a method similar to the above. The problem is that maintaining mods across versions becomes a fulltime job if you've got even a few significant code bases. Not a big deal but it adds up. I appreciate all the efforts to keep improving Forge, but it is a bit disheartening every time a new approach is used. Converting IEEPs to capabilities, achievements to advancements, recipes to JSON etc. Depending on what your mod focuses on it can actually be a significant rewrite. So I'm just being lazy and whining. It is taking a few hours per mod, but I am converting over to Object Holder method...
  16. Thanks guys. As discussed I understood that lookup would be somewhat of a performance hit, although frankly the vanilla code uses lookups a lot. But yeah I meant store it for access as well. Lex, regarding your statement about "your own stuff should be simple as hell", the problem with your example is the names of the fields. They either need to match the registry name (which is kinda weird because they use the underscore style naming) or you have to further add additional object holder annotations to match it all up. Furthermore, for my own stuff there is stuff I'm porting in which case knowing the registry name actually takes a bit of work -- I have to go into each of my classes and copy the text out and put it into the annotation. Anyway, I just wanted to make sure they were functionally equivalent in case I was missing something fundamental about the object holder concept. Thanks!
  17. Is there any technical reason that the object holder injection is better than using the getValue() method of the registry itself and storing that in a public field? Are they equivalent? Or is there a performance or logical reason that object holder is preferred method? I'm asking because I'm porting some older mods and in most I set the registry name within the block or item constructor so if I use injection now I have to go through all my blocks and items and dig up the registry names and copy those into the object holder annotations. Seems easier for me to simply to use the getValue() and retrieve the registry name instead rather than hard-coding it into annotations. Just being lazy, but it made me think about how the injection works and mostly I just want to understand whether it is equivalent -- I plan to mostly use object holder in the future.
  18. This forum isn't for people to do the work for you. What have you tried so far? Did you look at all the examples Choonster already gave you? Did you look at the github source code for other mods that do similar things?
  19. It really depends on whether he means he wants an entirely fresh ore generation or whether he simply wants his ores to replace other mods' ores. The idea of "replace ore generation" can have either meaning. Does he want to change the actual generation (different locations) or the ores that are generated? Even if he wants to change the generation itself, he can certainly use the OreGenEvent.Post event and basically undo everything (replace with stone) and then generate what he wants. Actually, the mod he references even has open source code here: https://github.com/RedGear/Geocraft Interestingly they seem to be using the chunk save and load and then world tick to figure out which chunks haven't been replaced and replacing them, or something like that ... I only looked briefly.
  20. Also, how are you testing this in your IDE? If you don't specify the username and password in the Eclipse run configuration then each time you load the game you are actually a different player which could cause some confusion if you were setting spawn point then saving and quitting and then running again from the IDE. Just pointing that out because I often forget this and run into trouble when testing mod code that relies on player-specific info.
  21. I'm not sure why you're looking for an event. Isn't the change something you have code to know when it happens? Like if you're creating a server command to make a change then you would do the save at that time, wouldn't you? Like in your command code. Anyway, yes I have often gone through trouble of making my own settings file. I don't even normally go through trouble of JSON as I usually just reserve each line for a setting and I know which line is which so I don't even have to do much parsing -- just read in each line and convert the string to a value for my field, and vice versa when I need to save. Not really too hard.
  22. It does seem like they're using the wrong method in the Ore Dictionary. That method really shouldn't be public as it seems to just be a convenience method used by the dictionary. Instead to actually access the dictionary they should use something related to the getOres type method, or the OreIngredient getMatchingStacks() method. I'm not that familiar with the ore dictionary use, but it does seem that the repairable methods are missing the proper use of the ore dictionary...
  23. What I said works for client and server as far as I know. The config is saved and processed on the server. It is true that you only need a GUI if you want to let the client adjust things and I guess on the server you would use a command. It really depends on what your config is going to do. For example, many config changes require Minecraft to restart. If you have one of those on the server then you probably can just replace the .cfg file directly instead of worrying about in-game modification. If the .cfg thing isn't working for you, it is pretty simple to just make your own text file to control the stuff you care about. Minecraft is just Java so it has ability to modify files in folders where it has permissions. I've done that for my own structure capture code in the past.
  24. For a while Forge was trying to create a "substitution" system. I think it was working in 1.10 but I never used it. But if that is still available you might try that. Look at the GameRegistry.addSubstitutionAlias() method. Othewise I've had success by allowing it to generate during world gen but replacing it when the chunk is populated (PopulateChunkEvent). I have a tutorial on doing this here (scroll down the page to where it talks about replacing all blocks of a certain type): http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-modding-quick-tips.html
×
×
  • Create New...

Important Information

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