Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by jabelar

  1. You might want to check out TheGreyGhost's tutorial on block renderers: http://greyminecraftcoder.blogspot.com/2013/07/block-rendering.html
  2. I get a little confused on this... I want to use a custom asset (in this case a text file with a massive array in it). It isn't suitable for a config file (too much info and not really user options). But the file path to the assets of course varies from computer to computer. I want to use standard Java file methods, like FileReader and FileWriter, to access the file. I think ResourceLocation can help, but can't quite figure out how to get the absolute file path needed for FileReader and FileWriter. So assuming I put my array.txt file into my mod's asset directory what would I pass as the absolute path to the FileReader. E.g.how do I make this work?: bufferedReader = new BufferedReader(new FileReader(whatDoIPutHere+"array.txt")); Or instead of standard Java file access is there some sort of Forge file access I should use instead?
  3. Are you actually making a furnace that you want to burn forever, or do you mean just some standard block? I think for furnaces you want to look at how they handle fuel. If you look in the TileEntityFurnace class you'll see a field called currentItemBurnTime and one called furnaceBurnTime that control how long the fuel burns. If your furnace is extending TileEntityFurnace you can @Override the updateEntity() method so it never does the decrement of the furnaceBurnTime.
  4. Why do you think it doesn't work? the setSize() method (assuming your class is an extension of something in the Entity class hierarchy is the right method -- you can check the source and it changes the boundingBox. By the way, if you press F3+B while playing the game, it will make all the entity hitboxes visible. I recommend this whenever people are making custom models or otherwise mucking around with hitboxes so you can see what is really going on.
  5. Just to be technically correct, they are not "extensions" of ItemFood because that would imply they ARE separate classes that extend ItemFood. What you mean to say is they are "instances" of ItemFood.
  6. Coolalias is reliable. I'm at dentist right now so can't really review his example but maybe later. Just look through it or pm him.
  7. You may want to consider testing the "raw" keyboard input, either within the Keyboard class or even with just basic Java. The KeyInputEvent seems to be filtered a bit. So maybe try the KeyBoard.isKeyDown() method -- you'd have to cycle through the letter keys or something and if any are down within certain timeframe you could assume that the user is "typing".
  8. Yes, that looks like the right idea. I find it is easiest to get the model correct by stopping all the rotations until you are sure all the rotation points are correct. So I suggest commenting out all rotations for now to confirm that you got this part right.
  9. Hey, the proxy thing isn't so complicated but does require a bit of understanding. Basically, rendering, sound and user input (keyboard / mouse) only really make sense on the client side. Minecraft could have loaded all classes on server side (and tested isRemote before calling them to avoid calling client side stuff) but they figured that was wasteful so they made some classes @SideOnly. That means the class or method so annotated doesn't even "exist" when running on that side. The issue then is that you need to be aware if any of your code is calling classes that only exist on client side because they will crash if called from the server. To solve this, there is the idea of a "proxy" class. This is actually two classes, but only only one or the other is loaded as the proxy instance. The client side has overrides for the server side (since there is always a server, it is mostly client stuff that causes trouble) and includes the client only stuff. So you can call the same method like proxy.preInit() and it will do different stuff depending on which side is calling it. You maybe can get the idea if you look at the main class and the CommonProxy and ClientProxy classes in some of my mods. Here is the code for the mod that I was discussing at beginning of this thread: https://github.com/jabelar/WildAnimalsPlus-1.7.10/tree/master/src/main/java/com/blogspot/jabelarminecraft/wildanimals
  10. While it is good to be generally aware of performance burden, and of course don't do something downright stupid, the common wisdom in programming is concentrate on being logically correct, readable and extensive and only do perf optimization if you find a real problem. A modern computer can do a ton of stuff quickly -- imagine all the other stuff that Minecraft is doing every tick! -- so unless you're doing massive searches across every block or something aberrant like being excessively recursive, just code so it works well and don't worry so much about the perf (unless you find an issue).
  11. In your tile entity, the if statements are suspiciously complicated. First of all I don't think you need to test what the metadata is in the if statements. It is okay to set the meta data even if it is already the same value. Perhaps you think it is better for performance but you're actually adding performance burden by testing for it before you know if you write it. In other words, writing it every time isn't any more burden than checking it every time. You should also be able to get rid of the whole updateBlock flag as well. The if else construct won't proceed to the else once it finds a true, and since you test for highest values first it should never fall through to the next one anyway. Next, since your meta test values are all 12.5 apart, you don't need any if statements at all! You can just set the metadata to be = 7 - charge / 12.5 (although you have to also round it and ensure it doesn't go below 0). So I think you can replace all that first part of your updateEntity() method with: if (cd2 == 0 && mana <= manaCap) { cd2 = MANA_CD; if (mana < manaCap)mana += 5.2755f; float charge = ((mana / 2) / (80)) * 100; System.out.println("Charge: "+ charge); System.out.println("Mana: "+ mana+"/"+manaCap); int metaData = (int) (7 - charge / 12.5); if (metaData < 0) { metaData = 0; } System.out.println("Metadatra: "+ metaData); getWorldObj().setBlockMetadataWithNotify(xCoord, yCoord, zCoord, metaData, flag); System.out.println("----------"); } else cd2--; Notice that I've also printed out the metadata value. I think it would be interesting to see if the console prints out the value you expect. If it doesn't print at all, then it means that the if statement isn't testing true. I'm not really sure what your cd2 and cd1 are supposed to represent, and I'm suspicious that there is still some logical error there. But anyway, simplify the code such as I explained above -- simpler code is easier to debug. And post the console output so we can understand which code paths are occurring.
  12. I think this is difficult. The key events seem to be suppressed when some GUIs are opened. As you found out, it is easy to detect that chat is open, and you can also process the chat input before it is actually sent to server, but not sure you can get it key by key. What are you trying to achieve exactly?
  13. No, in this case he's asking about child parts of the model. Child parts are the right way to do manage complex animations, but rotation points need to be changed from the Techne original rotation points. In answer to the original question: the rotation point of a child part is *relative* to the parent part. So if you had an original rotation point before you made it a child, you need to subtract the parent's rotation point after you make it a child. in other words just take the x, y, z of the rotation point and subtract the values from the parent. Basically the child's rotation point should indicate where it is based from the parent's rotation point. I hope you get the idea.
  14. No, what I'm saying is that for functions you figure out you can make a method in your own class that calls the other method. Like this: public void markBlockForRenderUpdate(int parX, int parY, int parZ) { World.func_147479_m(parX, parY, parZ); } It is still bit of a pain, but can help improve the readability and might save you some headache for those methods you use a lot.
  15. As you yourself mention, the spawning code looks correct. It is probably something else with your actual entity. Does your entity have a model so you can see it? Or are you trying to "see" it by noticing its effect? To debug things I usually add console statements throughout the code to help trace the logic. For example, every time it finds an entity to set in the web, print something out that indicates the entity "set entity X in web" sort of output. I usually put in a console statement in every method just to confirm it is even being run. And anywhere you have an if statement it is good to have console statement to indicate which path the code took. Also, it is REALLY important to use @Override annotation. I usually set up my Eclipse to check (and add) the @Override on save. This is because any typo or mistake with parameter list means that the method you think is being called won't be called. Like maybe your onUpdate() is never being called because it might contain a mistake in the override.
  16. I'm not sure how the MCP project works (I think they're the guys coming up with the human-readable names), but maybe you can submit stuff you figure out. Keep in mind that all this stuff is done by volunteers as a community project. Maybe you can contribute as well For my own sanity, where possible I'll extend the vanilla block and @Override, create wrapper methods, or even just add comments for what I can to be more readable.
  17. It really depends on how you want it to work. For example, if your mod did special rendering to "vampire" entities then you could make an IVampire interface and expose it as an API. then anyone that wanted your mod to treat their entity as a "vampire" could have their entity class implement IVampire. But you could also do it other ways, like you could have the special rendering method (or even whole class) in your API and other mods could call those methods, or extend your class. You could try to get other mods to implement methods that you could call. In that case you would make a Java interface with those methods, and put that in the API. For example if you wanted to be able to check the "magicka" level of all entities, then you could have a getMagicka() method in the Java interface and you could hope that other modders would implement it so you could check magicka in their custom entities. Maybe you want other mods to be able to use your blocks, items or entities. In that case you could put a placeBlock(), a createItem() and a spawnEntity() method in your API. Other people then could call those from their code and then use your stuff in their mods. There are a lot of possibilities, and multiple ways to implement an API. Do you have a specific idea on what you want to do?
  18. Many of the methods are the same, but just using the SRG names again. So you can often compare the 1.6.4 source with the 1.7.10 to guess what the equivalent functions are. Based on the argument set and the rest of the code (which should be easy to see if it is equivalent) you should have fairly high confidence in figuring them out. I have also run into situations where I had to get into the code that was less readable, but for me it is rare even on 1.7.10. I guess I'm just digging around in more common areas of modding...
  19. I wonder if you can do something where it teleports to the other dimension for just one tick to get the information it needs (i.e. that there is a good location for the portal) and then comes back. You would store the information about portal location in some public fields in your main class (i.e. so they will be available across dimensions), and then you would do the generation of the corresponding portal when you actually want to move between the dimensions. Anyway, just saying that it seems like at some point you have to actually switch dimensions just to set up the system, so if you can somehow briefly do it (you would probably have to intercept the rendering for a moment so the user didn't notice the switch) to get the work done that you need. Just a suggestion.
  20. i usually do it differently, following how things like EntityWolf and such do it. The Renderer class mostly just associates the model and texture to the entity. The Model class is usually where I do the animations and actually rendering -- there is a render() method in the Model class. Also, you need to make sure you register the model to the renderer -- you should post your code for where you register the renderer class (usually in ClientProxy). Anyway, I think the animation usually happens in the model class but I guess for player bipeds it might be different.
  21. jabelar

    Events

    You can learn more at my tutorial: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-event-handling.html Anyway, events are meant to be used -- they are purposeful hooks to allow modders to intercept common points where different behavior may be useful. If you have custom classes, then instead of events it is usually more logical to use their methods (@Override things like onUpdate). Events are more applicable to modifying behavior of vanilla classes. Some examples: - if you wanted something to happen when a vanilla block is broken by a vanilla item, use an event (probably BlockBreak) - if you wanted something to happen when a custom block is broken by a vanilla item, use method in custom block. - if you wanted something to happen when a vanilla block is broken by a custom item, use method in custom item. - if you wanted something to happen when a custom block is broken by a custom item, use method in either custom block or item. So basically first consider if the code can run in your custom classes. If not, events are quite acceptable. In terms of the specific event to use, it is better to use the one that is most specific. For example, if you want to modify the player drops you could use either LivingDropsEvent or PlayerDropsEvent, but in the former you'd have to check if the entity was the player each time which is a bit wasteful. The events that can cause real perf problems are the tick events. For the most part, Minecraft runs a LOT of code every tick, so a bit of code isn't too big of a deal. But if you're doing complicated things like testing every block in the world every tick, you will cause trouble. In those cases you need to use techniques for perf optimization (basically just make sure nothing is executing unnecessarily). But tick events are really useful if you want to do processing across a lot of different classes. For example, if you wanted to do something special if three players all were within some special area it makes more logical sense to check for that in a tick event than to have each player class trying to check it. Overall, events are great. I get "addicted" to them sometimes as they are logically an easy way to think about certain code, but you should check for other methods that may already be available to your need before going to events.
  22. Hi. I think you're probably not properly syncing client and server. I'm not sure how much you know about this, but many classes, including TileEntity, run on both client and server side. However, often the logic to change a field only happens on one side (for example user input only comes in on client, and placing blocks only occurs on server side) so you need to ensure that the data is sync'ed between the instance on each side. The NBT on its own is primarily about saving and loading data. This does not by itself ensure that client and server is sync'ed. Instead you often have to send a description packet containing that NBT back and forth. For good tutorial check out: http://www.minecraftforge.net/wiki/Tile_Entities Hope that helps.
  23. Regarding old initialization, you have the declaration and you will set it equal to current later on, but where do you actually initialize it (set if first time)? You test it before you set it to current. I suppose that might work because if it is null it would still test true, but not really good programming practice -- you should actually initialize (set it to something) the field before you use it. Regarding console statements you currently have them all commented out. Can you uncomment them and see what the logger is putting out? It should tell you a lot. Regarding the coding style the only reason I mention it is that the more complicated, unnecessary code can cause bugs. The simpler the better. Regarding the player name, I disagree that other players would be affected -- the event passes a player field which will be unique already, and then you get the itemstack from that player. So for each time the event handler executes it should only process one player. Since you're not storing anything outside the method it shouldn't affect other players as far as I can see (I could be wrong). Anyway, enable all the console statements. Tracing the code execution like that usually can tell you a lot.
  24. Well diesieben07 is pretty knowledgeable so if there was a "clean" way he'd probably know it. I guess my question is what your actual objection to the way you're doing it is? I assume you're handling a chunk event and then doing some inspection of the chunk. Seems like a logical way to do it. In modding, since we're trying to affect other existing code without directly modifying it, there are only a few "clean" methods for modding: 1) Resource assets can be directly replaced -- not really a mod, but rather resource pack. 2) Use public fields and methods in vanilla classes, where available. 3) Use registries where available. 4) Use events where available. 5) Use Java reflection 6) Use access transformers (ASM) You might want to consider Java reflection. Otherwise, if there is not specific methods, registries, events for what you want to do then a bit of "hacky" might be the right thing.
  25. It is possible that the chunk needs to be explicitly saved again after you've replaced the blocks. There is a public field called isModified which maybe you should set to true. It seems to be checked by a method called needsSaving() which likely ensures it will be saved.
×
×
  • Create New...

Important Information

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