Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by jabelar

  1. General understanding mostly comes from having good Java understanding and using your IDE to explore the source code. Modding is really an exercise in reverse engineering and that is more of a collection of specific topics than an overall topic. So even if it seems limiting to follow a tutorial that is very specific, if you do enough of those your knowledge will become generalized. Other than that, there are several collections of tutorials that are worthwhile looking at: - TheGreyGhost has already linked his awesome effort to provide a comprehensive example - Bedrockminer has set of tutorials: http://bedrockminer.jimdo.com/modding-tutorials/ - CoolAlias has set of tutorials: http://www.minecraftforge.net/wiki/CoolAliasTutorials - I've got some too: http://jabelarminecraft.blogspot.com/ We all have different approaches in teaching, also we have specialties. For example, TheGreyGhost is providing a full working example and he also specialized in things like block rendering. I like people to learn the hard way -- I give ideas but not fully working code because I think the best learning happens that way and I specialize in custom entities.
  2. You may be able to push and pop some GL11 transformation using render events. Like in a pre-render event push matrix, do a transform that rotates by 180, then pop the matrix in post-render? I haven't tried such a thing, but seems like maybe the right direction to try.
  3. Trace the execution to check that whenever the state changes that a packet is sent as expected and that the value extracted from the packet is as expected. You can trace either with console statements (I usually use them because it is a bit easier to play the game at same time as tracing execution) or use breakpoints and watch values in debug mode of your IDE.
  4. I don't see anything obviously wrong after quick scan of your code. What I do in these situations is to override the setDead() method. You just call super.setDead() but you can then put console statements there, and more importantly you can put a breakpoint and go into debug mode to try to figure out what called the method. Then it might give you a clue -- was it a despawn, was it suffocating because you placed it partially in a block?
  5. Maybe you can handle the clicking on the hotbar and related input / keybind ect. that are used when player wants to put something in the hand?
  6. I glad to hear you were able to figure this out. You're off to a good start. We like helping people who can take a bit of direction and do the work to learn the rest.
  7. Yes, that would work. I think I would do it like this in your tile entity: 1) create a hashmap field for mapping entities to their previous position 2) scan for entities in a bounding box around the tile entity with a getEntititesWithinAABB() type function and store that in a List or ArrayList. 3) update the hashmap keys by removing any entities that are no longer within range, and adding any new ones in range. 4) process the hashmap values (representing the previous position) as I mentioned above -- i.e. compare with current value, take action as needed. 5) update the hashmap values by setting the previous position to value of current position. Note that you can store all three dimensions (x, y, z) of a position in a Vec3 so your hashmap could map entity to Vec3. Definitely a bit of coding needed with this approach, but it should work.
  8. A couple things. First of all, you should follow standard convention for capitalization of class names. It should be "new TutorialItem()" etc. Secondly, as mentioned in programming sometimes the difference is just style. There are even other ways to do it, like creating a Blocks and Items class and creating the instances there (similar to the way vanilla does it). As long as you have a public static instance somewhere that is created before the registration I think it should all be good. So you should choose what is most natural to your thought process. Some people like to brainstorm all the fields and declare them but then only initialize them when they are needed. I personally mix it, I initialize some in the declaration if I know what the default value will be, and leave some uninitialized if it may change.
  9. Maybe someone like diesieben07 can shed more light on how the substitution alias actually works. Like does the substitution mean that every check for == as well as instanceof will return true? Because the vanilla code mixes the two methods of checking for class in some code. You might want to test it yourself. After the substitution does Blocks.fire instanceof BlockFire return true (where BlockFire is your custom class and not vanilla class)? One thing I wonder about is the class naming. is your block called BlockFire? (I can't check your pastebin because my work blocks access to that site and I'm at work.) Maybe you should change it to have a name that doesn't overlap the vanilla name, as it may cause some mixup in imports.
  10. In that thread, TheGreyGhost gives the solution. Create your own field to remember the previous tick's position. Then each tick you compare current position to that previous position, do what you need to do, and then always update the previous position field with the current position.
  11. Yes, and it also seems to be to reduce network traffic as well since it is also a "tracking" distance. I had previously thought that despawning was used for view distance culling as well, but found that they are separate. I think it is interesting that the client actually kills the entity when it does view distance culling though. I think most video games simply don't render it but would still keep it alive (but suspended). As mentioned the way the client actually kills the entity causes me some grief because the server keeps sending my custom packets assuming it is still there (since the entity is still alive on the server). Oh well, now I know.
  12. If you compare your constructor to the built-in RenderLeashKnot, they do it differently. Instead of a constructor that takes nothing and passes render manager to the super constructor, they take the render manager as a parameter and pass that. Maybe the render manager you're passing isn't the right one for some reason and so you're rendering doesn't get processed. Try copying the constructor from RenderLeashKnot instead of what you're using.
  13. Whenever you're doing something where there is something similar in vanilla Minecraft, you don't need a tutorial. Just look at the source for that similar thing. There are lots of GUI classes with buttons, and a couple with text fields (if you mean input field). So just look at those and copy what you need for your version. That's how the people who write tutorials figure it out, so you might as well do the same.
  14. You're right -- I was looking at 1.7.10 version of the class which doesn't have that constructor. I'm stumped. You seem to be doing the right things. Maybe double-check that your client proxy code is actually running by putting a console statement by the renderer registration. Also put console statement in the constructor of the render class. Maybe you'll find that it isn't being registered or constructed.
  15. That's interesting, thanks. However my problem actually wasn't despawning. I think despawning is server side deciding to cull unneeded entities based on distance from player and age, etc. However the client also seems to use the tracking range parameter in the entity registration to independently (not through despawn methods) set the entity to dead, just on the client side. In other words, I think the entity is still existing on the server but was just killed on the server. When you get close enough (within tracking range I guess), the client seems to create a new entity to track the one that the server had kept. It kinda makes sense, but was a surprise to me. Basically the trace was like this: - constructs successfully on both server and client when spawned with egg. - packets happily sync the entity AI state on the client as long as you stay close - server checks despawn every tick as evidenced by event and canDespawn() method both being called. client doesn't do any despawn check. - if you get far (which wasn't that far in my case due to high posY of the entity) the entity is setDead() only on client side, without going through the despawn event or canDespawn() method. - packet system starts complaining that it can't find the entity I was sending info about. - when I get close to the (now invisible) entity it re-appears on client. - if I prevent the client from setting dead, instead of it going invisible it just stops in place, and when I get close it spawns a second entity which acts normally (but original is still "stuck" in place). - setting the tracking range really large (800000) fixed all this.
  16. One thing that looks wierd to me is that in your render class constructor you call super constructor passing the render manager in. Is that a valid super constructor? The Render class doesn't seem to have that constructor, or maybe I'm blind? The vanilla RenderLeashKnot doesn't do what you're doing either. I'm not sure what issue that might cause, but maybe your renderer isn't even being constructed properly?
  17. I think your problem may be that in your render() method you call super.doRender() -- you should just call doRender() (not the super method).
  18. Yeah, that was it. I forgot about the tracking distance in the registration. I had it at 80 which wouldn't even cover the soaring height...
  19. I put "despawning" in quotes because I think my problem isn't true despawning as I'll explain below. I have a custom eagle entity which is working quite well -- it can fly up to a soaring height, then soar around high in the air, dive to attack prey, find perches and even be tamed. However, one problem I'm having I can't seem to figure out. I think it has to do with de-spawning. Basically if the eagle is far away it disappears. I believe this is standard de-spawn behavior. I don't want this for two reasons -- due to the eagle already being high up it seems to disappear frequently (I think because the distance is greater due to it being in the air) and also don't want it to despawn when tamed. So I thought it would be as simple as overrideing the canDespawn() method, checking for being tamed and distance and only calling super method if I'm willing to allow despawn. It still seemed to despawn though, so I tried to print console statements in the canDespawn() method but that spammed the console because it is checked every tick. So instead I overrode the setDead() method and just put in a console statement there and found something interesting -- the setDead() was only being called on the client when the entity was disappearing. I thought that was odd, because I expect setting dead would originate on server. It also causes real problems because the server continues to send packets for that entity which now can't be found on the client. Furthermore it was interesting that it was being called at all because I had the canDespawn() returning false. So basically it seems that the setDead() method is being called on the client by something other than the despawn code. Any theories on why the client would setDead() on its own while the server continues to think entity is alive and no despawn check called? To further investigate I overrode the setDead() to not call super method -- i.e never set dead. When that happens, if the eagle is far away it suddenly stops in mid-air, then if I get closer a duplicate appears that is flying where it should be! All this seems to indicate that client is setting dead when the player is at some distance from the player, but server doesn't agree and keeps entity alive. I'm probably missing something fundamental -- but I really thought that simply overriding canDespawn() would be sufficient. I also tried overrideing the AllowDespawn event to give result.DENY but the entity still got set dead.
  20. I also have a tutorial on doing version checking, using txt or whatever file. It checks against a string on a web page (could be github, that's the way I do it) and can display a message to the player if the mod is out of date. http://jabelarminecraft.blogspot.com/p/minecraft-forge-1721710-making-mod.html
  21. When trying to modify vanilla behavior, you should consider the following approaches (in this order). 1) Look for public methods, fields and registries. The vanilla code has a lot of public scope stuff -- like entity AI is in a list that is public so you can simply modify it directly. 2) Events. There are events for many of the things that modders are interested in, and the events allow you to change and even cancel the vanilla behavior. 3) Java reflection. Java is a funny language and reflection allows you to access a lot of vanilla stuff that is technically out of scope. 4) ASM and transformer techniques.
  22. To further explain, each creative tab is supposed to have a unique id number (just a sequential int). That is what the first parameter means. If you use an id that is already used that will create trouble, so you need to find the next available one, which is what lars' recommendation does. You'll find a similar thing in networking where each packet type needs to be registered with a unique id. "Underneath the hood" of Minecraft the blocks, items and entities have unique ID numbers as well, but in recent versions of Forge that has been mostly hidden from any need to interact directly with them.
  23. Do you want to replace a certain block type with another block type, or do you want a true fresh re-gen? If you're just replacing blocks you could try the technique mentioned in the section called "Replace All Generated Blocks With Different Block" on this tutorial page: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-modding-quick-tips.html. The basic idea is to handle the PopulateChunkEvent.
  24. How complicated and varied are your formulae? If there is any regularity you could come up with your own notation that is easy to transform, like how linear algebraic equations can be represented by a matrix. I guess technically that is still a "parser" but it would be very easy to implement as a calculation.
  25. I would go as far as to say you should always check the source for methods you're calling because sometimes they don't work like you might expect. In fact some are actually mis-named -- like the Entity#getLastAttacker() actually gets the last thing the entity attacked, not the last attacker of the entity (because the lastAttacked field is also mis-named). And over time there have been many methods that have gotten abandoned and aren't used like you might expect.
×
×
  • Create New...

Important Information

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