Jump to content

jabelar

Members
  • Posts

    3266
  • Joined

  • Last visited

  • Days Won

    39

Everything posted by jabelar

  1. Do you mean that people can draw freely on the blackboard, or type text on the blackboard? For text it would obviously just be a variation of a sign, except you could send each key as typed. If you want to draw freely, then I think you will need to do some graphics manipulation and send the texture over to others -- you'd have to look at regular Java methods for modifying the PNG.
  2. What do your model JSONs look like?
  3. ResourceLocation call also be constructed to point to a mod's location, like this: ResouceLocation("yourmodid", "thepathtoyourasset") So you should put your modid and path in. The path should be the part after the /assets/yourmodid/ so if you created a music folder for assets then the path would be "music/yourfilename". However, if you're creating a sound from the entity, including the player, then there is a different play sound method available. theEntity.playSound("yourmodid:thepathtoyourasset", 1.0F, 1.0F) You'd change theEntity to whatever entity instance you have. The first 1.0F is the sound volume (you can lower it if you want), and second is the sound pitch (like you can make the sound deeper or higher).
  4. In your drawScreen() method of your GUI you would use a GL.11 alpha setting. I don't know much about GL.11 either but simply look up GL transparency, like at this link: http://relativity.net.au/gaming/java/Transparency.html. I think one approach is that you could create colors with increasing transparency and use those when you draw the GUI. There is probably another way to take the whole "matrix" and change it's transparency.
  5. Unless you turn off all sounds yes. However, you might be able to use reflection. The sound handler has a private field for the sound manager which has a private field for playingSounds map from which you could iterate through and check the ISound returned to find the private resource location. I'm not that strong in reflection but I think that is possible.
  6. Okay, there is the Minecraft.getMinecraft().getSoundHandler().isSoundPlaying(ISound), stopSounds() and stopSound(ISound) methods available. The stopSounds() will stop all sounds. To stop a specific sound, you'd need to have the instance of the ISound to pass to the stopSound() method, which you probably won't have if it is a vanilla sound. But for your own sounds you can stop them this way.
  7. I do it perhaps more simply. In my block I create a method to update the state. For example, I have a tanning rack where you can see the hide turn to a tanned hide and I do it like this: In my block I have: public static void changeBlockBasedOnTanningStatus(int parTanningIngredient, World parWorld, BlockPos parBlockPos) { TileEntity theTileEntity = parWorld.getTileEntity(parBlockPos); parWorld.setBlockState(parBlockPos, BlockSmith.blockTanningRack.getDefaultState().withProperty(TANNING_INGREDIENT, parTanningIngredient), 3); if (theTileEntity != null) { theTileEntity.validate(); parWorld.setTileEntity(parBlockPos, theTileEntity); } } This is called from the TileEntity's update() method when the condition for the change is met. In my case I do it when there is leather in the output slot. So my code looks like this (in the update() method of the TileEntity): // if leather result is in output slot display it if (tanningRackItemStackArray[slotEnum.OUTPUT_SLOT.ordinal()] != null) { BlockTanningRack.changeBlockBasedOnTanningStatus(6, worldObj, pos); } else // display what is in input slot { if (tanningRackItemStackArray[slotEnum.INPUT_SLOT.ordinal()] != null) { Item inputItem = tanningRackItemStackArray[slotEnum.INPUT_SLOT.ordinal()].getItem(); if (inputItem == BlockSmith.cowHide) { BlockTanningRack.changeBlockBasedOnTanningStatus(1, worldObj, pos); } else if (inputItem == BlockSmith.sheepSkin) { BlockTanningRack.changeBlockBasedOnTanningStatus(2, worldObj, pos); } else if (inputItem == BlockSmith.pigSkin) { BlockTanningRack.changeBlockBasedOnTanningStatus(3, worldObj, pos); } else if (inputItem == BlockSmith.horseHide) { BlockTanningRack.changeBlockBasedOnTanningStatus(4, worldObj, pos); } else if (inputItem == Items.rabbit_hide) { BlockTanningRack.changeBlockBasedOnTanningStatus(5, worldObj, pos); } } else { BlockTanningRack.changeBlockBasedOnTanningStatus(0, worldObj, pos); } } I should probably enumerate the tanning ingredients, but basically this shows an easy way to create complex logic that controls the model.
  8. Yeah, I've found you have to do structure generation in multiple passes because some blocks have their metadata automatically changed when placed. For example a torch gets different metadata based on whether there is a wall or not. And like you said doors, beds, etc. rely on order of placement. And it is further complicated with blocks like tripwire because even though the metadata is 0 it will turn into an entityItem (of string) if you place it without a block under it. So I place all regular blocks with metadata 0 first, then place metadata blocks, then any special blocks. Note you need to also consider blocks with inventory, like chests because you may want to populate specific items into them. After that I place entitItems and Entities. Regarding loading the resource from a jar, I use standard Java file access resources in the JAR like this: BufferedReader readIn = new BufferedReader(new InputStreamReader(getClass().getClassLoader() .getResourceAsStream("assets/magicbeans/structures/"+structName+".txt"), "UTF-8")); In my case I'm using text, but with GSON library I think maybe you can pass the reader to the GSON.jsonStreamReader() method.
  9. You're confusing the fact that JSON tags are standard, but your actual JSON tags are not standard. No JSON parser will know what to do with your tags in terms of Minecraft structure generation. Only your mod will understand it whether it is JSON or text. In modern computers there is no issue with file space. I have 11,000 block structures in a text file that is only 400kB. Yes, that is my point about "regular" structures. If you know there will be walls and fills you can certainly use a more concise format. And JSON makes sense for this. However, it depends on how you're making the JSON -- are you manually creating them or trying to capture based on something that is built? Because in the latter case you'll have to detect the regular fills in order to tag them properly. I don't think so. You still have to place every block. As long as you only loop through each position once, I don't think there is any speed advantage either way. What fill methods are you referring to? Anyway, JSON will work of course and is a valid way. I'm just pointing out that there isn't that much advantage to it. Disk space is not an issue, speed won't be different, and complexity is higher with JSON. But it seems that you're comfortable with JSON so certainly go ahead with that.
  10. Yeah, that seems like the next logical step. I'll try that.
  11. JSON is cool and stuff, but honestly I found it is super easy to just use text file where you put the string block name, the metadata, x, y, z. Using the string block name is better than custom ids because theoretically it could save other mod's blocks (you'd need that mod when you generated the structure of course). I think a key point in structure gen is whether the structure is "regular". If it is a cube or a wall, of course the most efficient way is to just list the dimensions and block type without listing every block placed. I think JSON makes sense for this. Most of the structures I use in my mods are irregular, complex shapes that don't lend well to simple fill loops. But it really depends on your mod. Anyway, if you're simply listing block position info I would not use custom ids and I would simply use text format.
  12. Okay, I made some progress based on suspicion that the lighting is causing the trouble. If you trace the code for setBlock, as mentioned before it updates the lighting. There are a few variables that control this and it seems that the whole thing is skipped if the world.provider.hasNoSky is true. So I did a test where I set hasNoSky to true right before the generation loop, then set it back to false immediately after. Sure enough, the generation at height of 133 was just as fast (4 seconds) as generation at ground level. So I have some more work to do to figure out how to surgically disable the light updates just during generation. There are a number of public chunk variables also involved so I've started playing around with changing them. One that I thought would work was to change the heightmap prior to generation, since it seems that if the heightmap and block set position don't have gap it wouldn't update lighting, but that didn't speed it up. So I'll keep looking. But overall I guess my advice is that setBlock is slower the higher you do it, but up to a factor of 5.
  13. I think the GSON library is available/used in Forge.
  14. I guess try running in debug mode, or add console statements to trace the execution to see if everything is executing as expected.
  15. Yes. In this case a tile entity checks for a condition and then generates it. And ideally the code is also useful for generation with an item or command.
  16. What is the error message when it crashes?
  17. Okay, I'll do some more experimenting with the update flags and world gen. Note that this structure needs to be generated during play so it isn't an actual solution for me to do it during world gen, but it still might be an instructive test.
  18. Okay, I've tested generating at a bunch of different Y heights, and it seems to be fairly linear -- the higher you build the structure longer it takes. At height 74, 11k blocks takes 6 seconds At height 85, 11k blocks takes 8.7 seconds At height 100, it takes 13 seconds At height 120, it takes 20 seconds At height 133, it takes 24 seconds I looked through the setBlock() call hierarchy code and there wasn't anything obvious, except there is a fair bit of light value processing. I should also mention that many of my blocks are translucent. So maybe the higher it is, the more time it takes to process the light values below it? EDIT: After looking at it further, I'm getting convinced that the light value updates are what are causing the delay. There is a method called Chunk#recheckGaps() that I suspect is causing the additional delay. There is also another method Chunk#enqueueRelightChecks() that has a comment that specifcally says it can cause up to 1.6seconds lag per chunk. Does that sound plausible to explain why my structure in the clouds is taking so long to generate?
  19. Okay, I found something really interesting. I've been using system milliseconds to measure the execution time. As expected a loop of 11k that does nothing is almost instantaneous -- less than 1 millisecond A loop of 11k that places a dirt block over and over in same location takes 4 seconds. Here is the interesting part, if I generate my structure at Y of 74 it generates in 6 seconds but if I generate at Y of 133 it takes 23 seconds. The structure I'm generating is a castle in the clouds so I want it to generate at 133. Is there any reason why setting blocks at such a height would be so much slower? I'm thinking that maybe there is some optimization that assumes that blocks won't normally be placed that high so maybe it is slower.
  20. I agree that a custom entity item should work. It can check position to see if it is in the fluid.
  21. I'm sure it could work with several different approaches. My main point is that you can identify a chunk by a single block location and you only need X and Z from that. So if all your regions are rectangular, you could just record the X, Z position of two corners and use a loop to check for any chunks in between. So a text format simply like this would specify three regions: region[0].corner[0].posX region[0].corner[0].posZ region[0].corner[1].posX region[0].corner[1].posZ region[1].corner[0].posX region[1].corner[0].posZ region[1].corner[1].posX region[1].corner[1].posZ region[2].corner[0].posX region[2].corner[0].posZ region[2].corner[1].posX region[2].corner[1].posZ Anyway, I think that would be the most minimal data structure that would be sufficient to figure out all protected chunks. But it seems like you're a competent coder, so feel free to use a more formal tagging scheme if you wish.
  22. Yes, I think you can override the block break event and cancel it for chunks you care to protect. In terms of saving a list of chunks to protect, I think you can do it a bit more simply. You don't need 3-d, only 2-d because chunks go all the way in the Y-direction -- so if you have X and Z position you can figure out the chunk. Further, you only have to store the X and Z of one block in the chunk as there are methods to find chunk from X and Z position. I don't think you'd need a JSON, you could simply have a text file with pairs of X and Z positions.
  23. Would you only have to do it once before loading a world and then after that the world could use world save data? In that case I think you could use a Config -- use Config unless there is world save data then use that, and you can change the config based on what is happening in the game. If you need to keep track of multiple saves with different information, you could potentially make your own ID system for the world saves mapping to config info. But otherwise, file operations in Java aren't too hard. So you can take the configuration file path (there is one suggested passed into the pre init event) and make your own files there.
  24. I wrapped my generation code in System.currentTimeMillis() and console says that it takes Time to generate = 20261 milliseconds for 11,000 blocks. So about 20 seconds which means an average of about 500 blocks per second. The last question I have is does this mean the server is effectively not doing anything except generate these blocks for 20 seconds? So gameplay for everyone would be handled by the client until server comes back online? And if the server is busy doing generation, could that cause a timeout on dedicated server?
  25. I started with one pass, then broke it up, and now tried one pass again. My last post above was a one-pass attempt. I think your comment about chunk boundaries is interesting, although I'm generating this in a location that seems to be fully loaded -- basically right beside the player. I'm wondering about the flag 2 for the set block method. If I use flag 0, then can I set the chunks to dirty (or whatever would force an update) right at the end of the generation? Can anyone try simple experiment -- just set 10000 blocks and see if it is as slow as I'm seeing? By the way this is 1.7.10 that I'm testing in.
×
×
  • Create New...

Important Information

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