Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by jabelar

  1. While this is technically true it is misleading. Assuming you want all the players to see the particles then you want to initiate the spawning of particles on server side. You don't actually spawn them there, but that is where you call the "spawn" methods that actually send packets to the client that do the actual spawning.
  2. The reason why you need packet handlers is because this is a networked game consisting of code running on a server and other code running on clients. Even when playing single player it uses networking to communicate between the code running for server and client. You shouldn't need any packet libraries or anything. Forge already provides the simple network wrapper. I have a tutorial here (which also references other good tutorials): http://jabelarminecraft.blogspot.com/p/minecraft-forge.html.
  3. When modifying vanilla behavior, I suggest investigating these strategies that are already available before doing core mod or similar. 1) Use public methods, fields and registries. The vanilla classes have a lot of stuff that is already public scope. For example, if you want to modify the AI of any entity you have direct access to the list of tasks and can clear and add your own. 2) Use events. For many of the the things that modders care about there are events. Using items, generating worlds, spawning entities, dying, getting hurt, getting struck by lightning, etc. Many events can be "cancelled" meaning you can cancel the vanilla behavior completely and insert your own behavior. Especially interesting is you can use events to replace vanilla stuff with your own custom 3) Use Java reflection. In the cases where you don't already have public access to vanilla fields, you can use Java reflection to make them public then modify them. So basically any field and method in the vanilla classes is available to access. 4) Use byte code manipulation, access transformers, and other more advanced techniques. Really you need to share what you're trying to actually achieve if you want us to help.
  4. In either case, the log tells exactly what is wrong. It is nothing specific to AI itself, but is concurrent modification meaning he is modifying something (usually collection like List) unsafely. Just a general coding error.
  5. While I haven't tried it myself (I plan to though because this has bugged me for a long time), a friend said you can get around the hard-coded limitation as follows: You have to edit the forge-jar for that. What you do is open the jar that gradle downloaded and automatically includes in the buildpath for you. It is at C:/Users/<user>/.gradle/caches/minecraft/net/minecraftforge/forge/1.8-11.14.3.1450/snapshot/<YYYYMMDD>/forgeSrc-<version>.jar. There should be a file named log4j2.xml in there, extract it and edit the line where it says <AppenderRef ref="FmlSysOut" level="INFO" /> to <AppenderRef ref="FmlSysOut" level="DEBUG" /> Save and override the file in the jar. You should now see debug output on your console. The only thing is you have to remember to repeat this every time the workspace is refreshed. Which is every time the version is changed and you used setupDecompWorkspace. Try it out and let me know if it works. I don't have time at the moment.
  6. The error log tells you exactly what is wrong. It tells you the error and even the line that the error is happening. In this case, most of that log is saying you have missing textures. It has nothing to do with your AI. Fix the texture problems that it is listing.
  7. Again, I think you're going about it the wrong way by trying to use 1.8 to do an "active" correction of a 1.7.10 save that has difficulty loading. Instead you want to convert between save formats yourself. Instead I think you want to essentially process the first recreation of the world yourself. I could see several ways to do this: 1) create a mod for 1.7.10 that can save the world in 1.8 format 2) create a mod for 1.8 that reads a 1.7.10 save file and does its own loading (that works) 3) if there is difficult doing the above because of ID mismatches, then create an intermediate save format that helps with that. Like save some information like unlocalized name for each ID and use that to match things up. Ultimately it is similar to how I do my own structures. I build something and have a mod that allows me to save a portion of a world in my own format. Then in my other mods I have ability to load that structure. You just need to do similar thing on much larger scale (which needs to be extremely efficient so needs to follow mostly how vanilla does the saves). But I think trying to load 1.7.10 save directly into 1.8 and then trying to handle the errors is more difficult and maybe not really possible.
  8. Yes, that is pretty much what I did -- I search multiple positions around the player's head since it really doesn't need to be exactly in same place each time. I also use a tile entity to detect when the player has moved far away and then it self-destructs. There is probably some room for optimization though.
  9. You can make it work underwater. Instead of looking for air blocks you'd look for water blocks and your light-emitting block could extend water so it would look and act like water but otherwise do the stuff that I did (i.e. have tile entity that tracks whether it should be destroyed as player moves farther away). Instead of just destroying it you might want to replace it back with water block. Anyway, the general idea should work under water, but instead of an air-like block you'd use a water-like block.
  10. yes, the way I'm doing it is to find a space around the player's head, which presumably should already be free so collisions with other blocks shouldn't be an issue. In the case of being underwater though there is not space and so the light goes out, and same thing if you're entirely surrounded by tall grass, but that I think is realistic. Jeffry, definitely you should see about extending the method. I probably did effectively make it like a BlockAir, so perhaps extending that would be a more logical approach. I mostly did the code to prove that it was possible, but I'm sure there are some issues with the way I'm doing it, but it seems to work well enough to be worthwhile for some mods. One thing I want to do when I get around to it is to vary the light value based on the light value of the item. Right now they all cast the same amount of light. This would be pretty easy to fix, but I haven't got around to it. Overall though I was pretty happy with the result.
  11. A lot of organization is a matter of style. On the bigger mods I've worked on, the classes are usually first grouped by whether they are client (like renderers and models) or common, then simply grouped by type (entities, items, blocks, ai, etc.) Regarding your specific question about registration, I prefer to have ability to control the order of the registration as in some cases it matters (like with crops the order that the ItemSeed and BlockCrop are registered matters). So I don't register in the constructor of the class. But if you make a registration method in your class and call that, that would still give you control of order. I would look at big open source mods by solid coders and try following their organization. Additionally, the organization depends a bit on how big the mod is. A simple mod with a couple blocks doesn't need a complex organization, but a comprehensive mod with entities, structures, packets, guis, etc. needs good organization.
  12. Actually, I found way to do it without Dynamic Lights. It seems to work pretty well: here is video showing the result: I wrote a tutorial on how to do this here: http://jabelarminecraft.blogspot.com/p/minecraft-modding-making-hand-held.html
  13. I haven't done it but it seems to me the issue is mostly with the save data needing conversion. I would think that one approach would be to make a mod for 1.7.10 that does a special save (maybe initiated by a server command) that mimics 1.8 save format. So take the world save code from 1.8 and port that to 1.7.10 then just invoke it. Just a thought...
  14. I made a transparent colored sphere for my Magic Beans Mod which as an effect when a certain entity magically appeared. I have described how to render a sphere about halfway down this tutorial page I wrote: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-quick-tips-gl11-and.html
  15. Yeah it depends on what version of Forge you're using. Originally there was no mouse event available in the GUI, and at some point they added it (but it is the separate GuiScreenEvent mouse event that fires_
  16. You can draw a vector easily. A vector is just three values indicating the distance away from something of the "end" of the vector relative to its origin. So look up how to draw a line and then simply draw a line from player eye position to the eye position plus the vector coordinates. Anyway, back to my previous post, it seems that the attempted code is much too complex. Why all the ATAN and other stuff? Just dot product the celestial angle (converted to a nomalized vector) and look vector and you're done.
  17. One thing I was wondering: Minecraft is faking a dome-shaped sky over a flat world, so it makes the apogee of the sun/moon always pass directly overhead the player. That is good for purposes of the calculation required for this mod, but I'm not entirely certain whether that makes the rotation point actually at the player. It is possible below the player somewhere inside the ground. If the rotation point for the sky is actually below the player, then for accurate angle you would need to know how far away the sun/moon is and use trigonometry to adjust the celestial angle relative to the player. The good news is that the trigonometry shouldn't be hard -- you can approximate the triangle as a right angle because the angle discrepancy is probably small. Anyway, assuming for the moment that the sky does rotate around the player. In that case I think the code you posted is way more complicated than it needs to be. I think look vector is normalized (length 1.0) and so if you create a normalized vector from the celestial angle I think if you just take the dot product of the look vector and the celestial vector, if the length of the result is close to 1.0 then I think that means you're looking along the celestial vector. That's it. Just convert celestial angle to a normalized vector, dot product with look vector and check if result is close to 1.0.
  18. I don't think you need custom packets for this. Inventories can be synced by built in methods if you make them part of a Container along with an IGuiHandler. The IGuiHandler is what syncs up the client and server for you. I have a tutorial for inventory GUIs for blocks, but I'm fairly certain it would work same way for any inventory: http://jabelarminecraft.blogspot.com/p/minecraft-modding-blocks-with-guis.html
  19. Are you really trying to hash with an itemstack or an item? Neither your hashcode() or equals() processes the size of the stack, and they only look at the item in the stack, so you're really hashing items, not itemstacks. Is that what you want to do? Why is your hashcode so complicated? Can't you just add the metadata to the item id (and add the stack size if you want to actually hash stacks)? What's all the multiplication and the 31 for? The hashcode does not have to be unique, although I think it is supposed to at least be sort of unique. The main thing though is to include each of the factors that you care about that make the key unique. For your equals() if you really mean to hash stacks and not just items then you should also check that the stack size is the same. Lastly, to debug these sorts of issues is easy. Just use System.out.println() statements at each point in the code to print out information useful to trace what is going on. Like print out the metadata and id and resulting hashcode and see what's going on when you use your custom item stack.
  20. Perfect, thanks. That was the info I needed.
  21. I've been helping a mod team create an animation system for entities that has turned out really well, except for one thing: sometimes sounds and animations that are initiated at same time on server (i.e. in an AI class) get out of sync so that the animation happens a couple seconds after sound starts playing. Now first off, I realized that sound sync isn't something that vanilla Minecraft really doesn't care much about, since when a vanilla cow makes a moo sound the cow itself doesn't do any animation. That's just one of the quirky fun styles of Minecraft. I'm pretty sure sounds are probably handled on their own thread and I think that when game is lagging, I've noticed sounds get out of sync before. Like you'll hear a block break and then later it will visually break. Can others confirm that this sort of sound sync problem happens when game starts to lag, even with vanilla? My code is pretty simple in this regard. On server, in an AI class it will decide to play a sound and also to send a packet to update the animation ID. On client for debug purpose I handle the PlaySoundAtEntityEvent and also have message on when animation packet is received, and those both happen. The animation packet simply updates the entity state, and the model class for the entity will see that change on next tick and will start the animation. I can share some code if needed, but since this is work for a group mod I can't share too much. Mostly I'm interested in knowing: a) Does even vanilla sounds get out of sync? e.g. hear block break a couple seconds before you see it break? b) Has anyone solved this sort of problem before? c) Is there a way to play the sound only on the client? If so, then I could have sound played there rather than sent from server and perhaps that could help. Right now the playsound methods I use I believe send packets to all clients which then play the sound...
  22. I agree with Ernio. Checking things every tick is sometimes necessary if a condition can occur in any tick and you need to handle it immediately. The game already does a bazillion things per tick so a few position checks isn't going to be noticeable. As Ernio mentioned though it is unnecessary to check every living tick but instead use player tick. If you're really worried about it, profile the time it takes to execute. I'm sure you'll find it is trivial.
  23. I think the first thing to consider is what type of entities and animations you're doing. For something stiff, simple and robotic or cyclical you can get by just doing same thing that vanilla entity models to -- use a bit of trigonometry to move things based on the swing progress parameter passed into the set rotation angles method. For anything that is more complex, I like to do it like real animators -- they don't use math but instead create a number of "keyframe" poses in an animation program and then let the computer figure out the "tweens" (the positions in between as it moves). I'm helping a big mod team with creating such a system. I've used Tabula to create a bunch of poses, and then put them in as assets then read them into an array. I have another array that indicates the order the poses should happen and the number of ticks it should take to move between the poses. Then each tick I have methods that calculate the amount of adjustment of rotation, position and offset for each block in the model. I'm hoping to write a tutorial on this at some point, but basically I hope you get the idea. Such a system can allow much more complex and natural animations than doing math can do.
  24. I think you're missing an important point about how Minecraft handles blocks. There is only every one instance of each block. This is because in a Minecraft world there are millions of block positions and so instantiating the class for each position would cause memory and performance problems. So instead, the blocks in the world are actually not separate blocks, but instead are actually a map of positions of types of blocks. This means that if you change anything in the block class it will affect all the blocks of the same type in the world. However, there are certain things that happen based on the block position. For example, breaking a block obviously only happens to the position you're hitting. So what you need to do, as suggested above, is to somehow remember (probably with a list of block positions) all the positions of unbreakable blocks you want. Then you need to handle the block breaking event and check if the block the player is trying to break matches a position on your list of unbreakable blocks. If it is on the list, then cancel the event so the block doesn't actually break. Anyway, the key point is that you can't change the block instance because that will affect all the blocks in the world.
  25. Well, if you're changing a lot of stuff in the way the inventory GUI works, I'd make a whole replacement inventory GUI. Subscribe to the open gui event and open your version instead. Copy the vanilla class and then edit it to your liking.
×
×
  • Create New...

Important Information

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