Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by jabelar

  1. Well rotating the yaw will help it look better going up a hill, but if you look how vanilla mobs go up and down it is more of just a jump. Again it depends on your movement code -- if your code actually checks the yaw direction and will move it upwards when yaw is rotated then it might work. But I think it would be hard to get the math just right. Instead I'm saying if you come up to a block and the movement code wants to go into it, you move it but also move it to top of that block. Not a rotation but actual movement.
  2. You can make a mod any way you want. It is your mod. However, it is good to listen to players who use your mod as well. There is no standard, but there is common sense. If a rare but useful item becomes easy to get then some people won't like it because it will change the game too much.
  3. I think the stepHeight is used by pathfinding code in the navigator. If you're controlling the movement directly I think you'd have to process the steps yourself -- like if you know that the entity wants to go in a certain direction where there is a block in the way, check that there is room above the block for your entity and move it up.
  4. To clarify a bit more. While it is possible to read from the actual config file every time you need one of the config settings, that causes a file read access which can affect performance. So best practice is to read the config file once during the mod initialization and store the values in public fields that can then be accessed in your code. So assuming you have it set up that way, in the command processing code what you want to invoke is a config "sync" method which both writes to the config file but also updates any fields that are supposed to hold values read from the config file.
  5. To expand on this. Yes you do need a getMetaFromState() method but that doesn't have to do anything. Regarding the tileEntityTinyBlock field, you need to understand an important concept -- a Block instance is a "singleton". There is only one instance of each block class in the whole game, no matter how many of those blocks are placed in the world. Instead of creating an instance for every block placed, the location and metadata is simply recorded in a 3d array of chunk data. However, a tile entity is not a singleton, but rather an instance is created each time it is placed. This is why you can't place a large number of tile entities as it will use up a lot of memory, processing power and networking (to sync client). But the good thing is you can do complicated coding that processes every tick in a tile entity. So it doesn't make sense for the block to have a field for the tile entity instance as there will be hundreds (possibly) of the tile entity but only one block instance. So the field would only end up with the last tile entity assigned, not remembering each. To put it one more way -- when you set the metadata of a block you're not actually setting data in a block instance but rather setting the metadata in the array of chunk data.
  6. Yeah, the terminology for "nested" versus "inner" confuses me sometimes. I wish they just called them static nested and non-static nested. Instead non-static nested is called inner. I realize the terminology makes sense in terms of access of the outside class members, but still seems a bit inconsistent. I was remembering (rightly) that all inner classes require an instance, but inner class is basically "non-static nested" class. There is no such thing as "static inner".
  7. I'm not sure what you mean by "Java graphics". Any Java application with advanced graphics uses some graphics library. In case of Minecraft/Forge it uses OpenGL through the GL11 library. It is pretty standard -- you set up a "matrix", set blending modes, do translations, rotations and scaling, then draw quads.
  8. Isn't one issue with nested classes that you need an instance of the outer class to create an instance of the inner class. So using it for items like in Ernio's example, you'd have to make an ItemCore instance that is just for purpose of allowing inner classes to be instantiated, even though the itemCore instance is never otherwise used/registered as an item in Forge. Seems a little convoluted just for naming convenience, especially since you have a good, cleaner alternative: I think it makes more sense for naming to have the standard Items class where you have nicely named instances of the items as member fields (not classes).
  9. It is usually bad practice to cast something without checking that it is an instanceof the class you're casting to. So check that worldObj.getTileEntity() instanceof TileEntityBaseFurnace. After that, I think you just need to do standard debug. Put console/logger statements in each of the parts of the code, such as the message processing, to confirm that the information is getting synced as you expect. In the code you posted above, put in statements that print out the location and what block is in that position. You should quickly be able to figure out what is wrong just by following the execution of your code.
  10. There may be better ways to do it, but just think of the tile entity as something that stores data that you can use to bridge the other things you want to do. For example, you could create a couple block properties to indicate your 24 textures and various rotations but instead of saving those as metadata you would convert those to an integer that is stored in NBT of your tile entity. Then, if you need to change the texture during the game you would do that through the tile entity (i.e. you interact with the block and then change the value stored in the tile entity) and also update the block state. Then you would just take those block states and map them to textures in the JSON files, just like other 1.8 blocks. In other words, the "official" value of the block state is maintained by the tile entity and you just make sure you sync the actual block state whenever you load game or interact in way that is supposed to change the state.
  11. A tile entity is basically a class that can provide some "intelligence" for a given block position in the world. Not every block can have such intelligence because it would take up too much memory, processing power and networking to make it work. But for blocks that are somewhat rarer it is possible to use them. A block has metadata which is limited to the 4 bits. But the tile entity has NBT data which is essentially unlimited. So the idea is that you can easily store an int value in tile entity to cover your 255 texture states. The metadata for the block still exists as well, so it is possible to use both if you want. Another important point is that the block properties used in the block state is not actually limited to 4 bits, rather just the information you want to save/load is limited to 4 bits. So you can use your tile entity (which can store more information in its save/load) and then update the corresponding block states to match, which then can determine the model or texture or whatever of the block. Tile entities also have the advantage that they can be "ticked" if you want them to be -- so they can process game logic every tick. But that will use up some CPU processing so you should only use if the block will be quite rare.
  12. Also I think that the API portion of your code should not be obfuscated so that means in your build you need to specify the API part. I haven't done an API in a while so can't remember the details, but there should be some tutorial out there. Another tip I would give is that to make a good API you should use it yourself. For example, if your mod adds vampire mobs and you have an API for making new vampires then in your own mod whenever you want a new vampire you should invoke it through the API. This will help prevent bugs in the API (since you'll encounter any problem yourself) and will make sure it is easy to use and complete.
  13. That's wrong but is a common misunderstanding. If any code you reference has a class or method that is @SideOnly then you MUST use a proxy to manage your code. This is because an @SideOnly is not even loaded into Java on the other side and will therefore crash Java. The world.isRemote check can be used when your code is running (or at least allowed to run) on both sides.
  14. Did you read my tutorial? I have a list there of course.
  15. I have a custom furnace tutorial here: http://jabelarminecraft.blogspot.com/p/minecraft-modding-containers.html Note that it is for 1.8, so you might need to adapt bits of it for 1.7.10 or earlier. But it should give you the general idea. For recipe part you can either implement actual recipes, or just use basic logic in your Container class. In either case, the Container should check what is in the input slots and if some conditions are met (match a recipe, or you can use if statements) you update the output slot.
  16. While it is good to consider mod compatibility of course, most compatibility issues are very specific and should just be handled when discovered. The only case of true incompatibility would be if some other mod depends on the day cycle occurring in certain amount of real time. But in most cases, the logic would work out fine -- if something in one mod is supposed to happen after three days and the user also installs Ernio's mod to extend the days longer, then it probably should change the amount of time for the other mod. That would certainly change the gameplay, but changing the gameplay is the point of a mod. The other cases of incompatibility would occur if the other mod improperly uses the world time for anything other than checking where in the daylight cycle the game is (otherwise they should use total world time). For example, I think if you actually decremented the world time that could cause some logic problems in other mods if they happen to check if the time has passed a certain value and you cause the time to hop back and forth over that value. Anyway, my main point is that general compatibility is a worthy goal but most compatibility issues are specific. When they arise you can contact the mod authors to understand how to possibly modify your or their mod for better compatibility.
  17. I have a tutorial on events here: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-event-handling.html
  18. I think the first thing to ask is whether you really want to control variants using block states at all, versus just creating different custom blocks for each type (they can all extend a common type to share most of their code). While block states aren't that hard, it means that you need to process them in many cases (for the models, for the drops, for any other difference in behavior). I personally would suggest using block states mostly for things that can actually change during the game (i.e. an actual "state"). If it will always stay the same for that block during the game, I would suggest that it may be easier to manage them as separate extended classes. For example, if I were making wooden chairs I might make a BlockChair class and then extend it into BlockChairAcacia, BlockChairOak, etc. For those latter classes, you'd only have a little bit of code to write. Since an acacia chair never turns into an oak chair, I personally think it is more logical to do it this way, it saves metadata space for other needed block state information, and probably will lead to less bugs for beginning programmers. But if you're confident in your understanding of block states and metadata you can certainly do it that way too. To further explain the general idea, you need to understand that what you're registering is an instance of the class. So for each instance you can set (either using methods in your class or making a constructor to apply them) the value of the block state. Then you can create all the various instances you want with different block state values, and then just use the GameRegistry.registerBlock() method to assign each unlocalized names.
  19. FYI, EntityTameable already implements IEntityOwnable, so you don't need to explicitly implement it in your class (although I don't think it hurts). You need to also post your model class code and your code for registering your renderer. Thanks.
  20. There is an EntityStruckByLightningEvent. it will give the entity struck. You can then cause more damage to the entity using methods for attacking the entity (check out how lightning normally applies it). I think you could also use the EntityHurtEvent and check if damage source is lightning and if so you could increase the damage.
  21. Yes, of course. I'm gonna be blatant here and say that an object oriented language is impossible without pass-by-reference and anything else would be completely counter-intuitive. Sure, but old-school languages have an explicit indication for it. C++ has the &, and C (I know it isn't an OO language) can simulate pass by reference (sure it is really passing a pointer by value) with *, and C# has the ref indicator. Java is a surprise for people like me coming from those languages. Anyway, the proper terminology is an almost endless debate so we don't need to repeat that here. I'm just saying I see a lot of people, including me, mistakenly modifying a referenced object passed in and I think Java is more prone to that than other OO languages due to lack of explicitness. I like Java, but it has some built in "laziness" compared to stricter languages.
  22. I wonder if the lightning bolt needs to hit a block. So maybe you should spawn it at the position under the entity that was hit. You can get entityHit from the moving object position, then calculate the block below the entity position. Note that depending on which version you're using the math might be different because I think in 1.7.10 and earlier that on the server side the position doesn't take account the eye height. Anyway, that's the only thing I can think of as otherwise it looks correct to me.
  23. You're digging into it as well as I could. In case you didn't know, the 0.017453292F is just for the conversion between degrees and radians (pi / 180 = 0.017453292). The trigonometry in the second case looks pretty equivalent to the first case. The cosine of the yaw gives the "rotationX", the sine of the yaw gives the "rotationZ", etc. When you run the debugger, can you watch the values of the f1, f2, etc. to see if they make sense when used by the render method?
  24. Yeah, I know the semantic argument ("it's by value but it is the value of the reference"), but for practical purposes Java is passing the pointer which is not expected if you come from another programming language where you need to explicitly indicate when the parameter is a pointer. And further Java's inconsistency with primitive types not passing that way adds further confusion when starting with Java. In addition to this thread, there was another also created today with same problem -- someone not realizing they were modifying the list parameter passed into their method. And CoolAlias (and I know I do) forget about it sometimes. So it is definitely a pain point that you have to learn a few times the hard way.
×
×
  • Create New...

Important Information

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