Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by jabelar

  1. It is important in modding to learn how to help yourself. So in this case, it seems like you just have question about making particles generally. So have you looked at all the vanilla and open source mods that generate particles? Have you looked for any recent tutorials on particles? Then for the dragon specifically generating the particles, have you looked at the vanilla dragon code to understand how it attacks and how the head position is tracked? Based on that can you use a forge hook like an attack event and your understanding of the dragon code to generate the particles? When experienced modders answer questions on forums, even they often look things up. So best thing is to learn to look it up yourself? To do that, look at all the similar things you can think of and then put it together.
  2. Well, as long as it is valid, yes. But since it is a registry system I wouldn't call it an "id" but rather the "key" for the related collection. So you can get the list of keys from the appropriate registry and then pick a random one from the list. Find the registry and then look at the available methods to get ideas on how to get the keys. Picking a random one then just requires typical Java technique -- I'm pretty sure you can just google "get random entry from Java list" to get examples.
  3. Yes, but that is also not what I'm asking. That wouldn't be a problem. I'm saying is what if I register two different DimensionTypes with different IDs but both have the same name or same suffix. I think that would cause trouble, wouldn't it?
  4. Well I don't think that is fully true as you do have to register both. The registration of DimensionType.register() method is really an extension of the enum (goes through EnumHelper). But the ordinal of the enum isn't really the ID rather it is a field. But in any case if you look at the Call Hierarchy of the DimensionType.getID() and getByID() methods you'll see they are are called all over directly (i.e. not the ID from the DimensionManager registration). Check it out but it seems pretty likely that it needs to be unique. Since both have to be unique and since vanilla+Forge uses the same ID for both you might as well use the same (unique one) for both. Nevertheless, my concern is whether the name and suffix fields of your custom DimensionType also need to be unique. I'm suspecting they do because they are used for world saves among other things.
  5. I haven't looked at modding dimensions for a while so maybe I'm missing something. But a DimensionType not only takes an ID, but also a name, a filenaming suffix, etc. When registering a new DimensionType, you can find a free id by calling the DimensionManager.isDimensionRegistered() in a loop. However, there is nothing stopping the use of a duplicate name and/or suffix. It seems that duplicate names or suffix could cause problems, as they are used for things like world saves. Or is the modID somehow used to create uniqueness? Like if I create a dimension type with name "mars", and another mod also did so, does that create a conflict or not?
  6. Maybe it is memory leak on the client. Implementing networking often leads to memory leaks if you don't manage the buffers or keep creating buffers without releasing them. Have you checked the memory usage over time?
  7. Your latest version is pointing to a version you don't have in your list. The idea is that you're supposed to list all your versions in the one section and then the promos will point so some of those that you want to recommend. Note I switch the sections around as well to put the promos first because eventually your list of version history will probably get large so makes more sense to have the promos at the top.
  8. It should be unique for each explosion, the event should be called each time the explosion is called. So you can create a unique list of blocks from the affected blocks in each event. What exactly are you trying to achieve anyway?
  9. Cool Actually this is the type of question that the forum is intended for. You had done your research, hit an issue, and needed advice. As long as people have made a credible attempt at doing something, everyone here is happy to help. And it is "related to Forge" since it is regarding how to make use of the events Forge provided. But yeah, in general if you hit the end of the road with a given approach, it is often best to go back and rethink things a bit. Glad it worked out.
  10. Okay, that is an interesting situation. You basically want some of the vanilla block interaction but not all of it. In this case I would recommend handling the RightClickBlock event and handling the case of your block (and cancel the event to avoid the further processing). On the client you would not return the SUCCESS since that would cause the arm swing, but on the server you would. I think you can make that work, but still might be a bit tricky. Normally you don't use events on your own things, but in this case it does seem the best way to intercept the vanilla behavior.
  11. Hmmm. There isn't any nice way to do it. If you are looking for explosions from a custom explosive then you could probably extend the Explosion class and override the behavior to give yourself a hook. But if you want to handle vanilla explosions basically I think what you will need to do is to handle the explosion detonate event and copy the list of affected blocks from the event and store it in a public field. Then in the harvest block event you should check if the block position is in that list. Then you should clear the copy of the list every tick, probably in a server tick handler.
  12. Well here are some general best practices about performance optimization, which may not all apply to your case but worth thinking about: 1) Profile before spending a lot of time with optimizations. Don't spend time optimizing stuff that doesn't have significant impact in overall performance. I often see people make some clever, usually less "readable" and more bug-prone, optimization where it isn't needed. You want readability and simplicity (for avoiding bugs) in your code when you can, so only compromise that where performance requires it. 2) When nesting conditions or loops, when having conditions that && together always test the least likely (or the thing most likely to cause you to exit) thing first. For example, testing if world is remote and then testing if player is holding sword is backwards because it would be much better to exit quickly the 99.9% time the player is not holding the sword. Basically always look for ways to exit loops and methods as early as possible. 3) When testing conditions that || together always test the most likely (or the thing most likely to cause you to continue). In the previous example, if you wanted to continue if the world was remote or the player was holding the sword you should test for world is remote first. 4) In inner loops it is usually where it is worth coding super optimized. For example, in your code where you have the offsets for each of the enum facing, there may be a benefit for just directly adding 1 instead. Modern compilers are super optimized though so you should experiment. But I generally feel that you want to "flatten" the inner loop so call as few methods and conversions as possible.
  13. What are you trying to do? Are you making custom blocks and worried about where the results will be used? Or are you using methods from blocks and wanting to make sure they lead to result you want? Generally, if you're writing a method for custom blocks you should have it return the logically correct value. You shouldn't worry about which side it will be used. Remember, the reason any game logic runs on the client is because the client needs to predict what the server will do. So best is to make sure client gets same values as server. Then if the client does use that method it gets the right value, and if it doesn't use the method then who cares? In what case would you want the client to get a result that doesn't match the server?
  14. Do it the other way around. Check if you're on server and then check the conditions. Frankly it can be hard to know which methods run and return valid values on each side unless you trace it. If you have a couple methods you are specifically concerned about, just use the debugger or some console print statements to confirm. In the console statements it will tell you if it is running on the server or client ("main" thread).
  15. Well, you can easily just create a counter yourself. Set it when the entity attacks, decrement it each tick in an update method, and us it in the render or model code to rotate the mouth or other thing you want to animate.
  16. Maybe your original assumption about needing the original breaking block to be gone is wrong. All these events are still fired in the same game tick. So why can't you go ahead and turn all the blocks above into falling blocks even if the block in the break event isn't actually converted yet? And if that is really a problem, then in the break event just create a "list" of BlockPos that should be checked later during the tick?
  17. Cool. Sometimes when something just doesn't seem right it is worth continuing to dig in even if you think you've got a work around. Feels a lot better to fix it properly!
  18. I really don't get why this isn't working for you. I have tile entities in my mods and I simply implement the ITickable interface and I can watch them process things per tick exactly as expected. I don't do any of this scheduling updates stuff. You can try my example mod and look at the TileEntityCompactor here: https://github.com/jabelar/ExampleMod-1.12/blob/master/src/main/java/com/blogspot/jabelarminecraft/examplemod/tileentities/TileEntityCompactor.java
  19. Can't you also just handle the LivingDropsEvent, test if the entity is a pig and add your item to the list? I guess maybe that wouldn't be a proper realization of the loot table system, but it works pretty darn good for just adding an item regardless of the rest of the loot system.
  20. What exactly are you talking about? Are these entities a custom entity of yours? And your concern is that if player attacks then you might register a hit against them instead of the original entity? I think you could it by handling the PlayerEvent.AttackEntityEvent and checking if the entity hit is instanceof your invisible entity class. If it is, search the immediate area for the original entity and replace the event's target entity with the original entity.
  21. Draco18s, the reason he's using the living update event is that he actually wants many types of entities to do the same and just started with the player. Yes, the phases allow you to get some control of your code versus the original. Usually the START is cancellable to allow you to fully replace the vanilla code whereas the END would simply augment the vanilla code. The debugger is a feature of your IDE (probably Eclipse but maybe you're using IDEA or something else) that allows you to inspect code execution by methods such as setting breakpoints which will stop execution and let you see the value of various fields at that point. There are plenty of tutorials on such things. It is very useful but I often prefer using console statements instead because I like to watch behavior in real-time -- like actually play the game while watching some value change. But debugger is something you should absolutely become comfortable with. Now to your actual problem about the change not being saved it seems a bit odd. As Draco18s mentioned, the set block state method should be sufficient. However, I think it is a problem with the sides. The tick event actually gets called four times per tick -- once for each phase and then per side. I have the feeling that your code is only true on the client side. This is because I think player motion is controlled primarily on the client side (still enforced on the server to prevent cheating) to avoid glitchiness waiting for server synchronization. So to debug this I would set a breakpoint on the if statement and check the value of the motion fields and such. You may find that motion is 0 on server and so never sets the block. But the server is side where saves happen. You could also prove this theory by deleting the check for motion and simply always changing the block under the entity. If you find that that saves properly, it implies that the check for motion was the issue. If that is indeed the problem, you could create a server-side check for "motion" by simply subtracting previous positions from current positions (and be sure to take the absolute value). By the way, you have a bug in your code because motion can be negative. So your if statement would also not trigger if you walked in certain direction.
  22. Well it is a "cheat" in the sense that ITickable should not need any such silliness. Think about it -- a furnace happily cooks something as an ITickable and any animated tile entity is happily updated every tick. You should really find the root cause of the problem. But if it works I guess use it. Something is still wrong with your implementation in my opinion though and it might bite you later.
  23. You can always get a list of available events by looking at the Type Hierarchy for the Event class. Just make sure you open up the subclasses as well because some events have useful sub-events. It is worth going through regularly as new events are added fairly often, plus familiarity usually is helpful when you come up with new modding ideas you already know there are events to hook into. I think you're right that there probably isn't an event specific to what you want. By the way, for things that might be generally interesting that you want added to Forge you can go to the github MinecraftForge project and create an Issue, or even better you can create a Pull Request that fixes the issue. One thing you might be able to do is hook into the block's NeighborNotifyEvent and figure out what caused it. The worst case is just use a tick event and iterate through all the entities in the world (or using the living update event and process that entity) and see what they're standing on. You'd probably find some useful code in the Entity#move() method as it checks thing like whether it can walk on things.
  24. I still would question the whole "1 to 10k damage" concept. I can't imagine any situation where 1/100th of a percent health would make a difference in game play or even be perceivable. What you should do is map out all the weapons and damage effects you want to make and then only use as much resolution as needed to cover that. Also if you want more resolution can't you register a new attribute to use in combination with normal health? Like what if the main health was 1 to 1024 and second one counted 1/1024ths of health. Similarly you could use a capability for the extra resolution.
×
×
  • Create New...

Important Information

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