
Wirkungsquantum
Members-
Posts
13 -
Joined
-
Last visited
Everything posted by Wirkungsquantum
-
3 simple ( hopefully ) questions from a beginner.
Wirkungsquantum replied to doku's topic in Modder Support
You're very welcome, I'm glad that for once i was the one who could help someone on this forum instead of just being the one asking all the questions as i have been until now^^. edit: Come to think about it, that formulation *might* appear a bit odd, i simply wanted to say that i'm glad that I was able to give something back. -
3 simple ( hopefully ) questions from a beginner.
Wirkungsquantum replied to doku's topic in Modder Support
That can be done ^^ The onBlockPlacedBy() function (as the name implies) is a function that gets called everytime the block containing it gets placed in the World. @Override public void onBlockPlacedBy(World theWorld, int blockX, int blockY, int blockZ, EntityLiving thePlayer) { System.out.println("The Block has been placed"); } If you copy this into your block everytime the block gets placed the sentence "The Block has been placed" would be printed out into your console window. To get a grasp of how tile entities work i would recommend to you the tutorial that can be found in the forge wiki as well as having look in the thread i mentioned before. A very important thing to understand is that single blocks in a minecraft world aren't objects, in the sense of single instance of a class, but references to the block-class itself. That is why we need metadata to determine qualities that belong to a subgroup of the blocks you get from that class, for example another texture. But as metadata is somewhat limited we often times must use tile entities as these actually are single instances of a class and thus can save all the data you could wish for, such as a random texture index. In order for that to work properly you also need to use so called NBTTags (again the mentioned thread as well as the wiki are quite helpful here). Now as the onBlockPlacedBy() function gets a World-object (which is the active world) you can access your tile entities by using: YourTileEntity tile = (YourTileEntity)theWorld.getBlockTileEntity(blockX, blockY, blockZ); So here is a example on what your function could look like: @Override public void onBlockPlacedBy(World theWorld, int blockX, int blockY, int blockZ, EntityLiving thePlayer) { YourTileEntity tile = (YOurTileEntity)theWorld.getBlockTileEntity(blockX, blockY, blockZ); Random randomIntGen = new Random(YourMaxValue); int randomInt = randomIntGem.nextInt(); tile.setRandomIndex(randomInt); } YourTileEntity should than be able to handle the number (get it, save it, send it to the client etc.) I would think for now you should have something to do ^^ -
3 simple ( hopefully ) questions from a beginner.
Wirkungsquantum replied to doku's topic in Modder Support
That is quite true, but you can compensate that by using the line: playerAngle = Math.abs(playerAngle) % 360; However if you still dislike the idea of using the angle i have a diffrent solution for you: public void setDirection(double playerX, double playerY, double playerZ){ double diffX = xCoord - playerX +0.5, diffZ = zCoord - playerZ + 0.5; if(side == Side.CLIENT) playerY -= 1.62; if(playerY % 1 >= 0.5)playerY = (int)playerY+1; else playerY = (int)playerY; if((int)(playerY-1) < yCoord){ if (Math.abs(diffX)>=Math.abs(diffZ)){ if(diffX > 0){ if(playerZ > zCoord) this.direction ="UWN"; else this.direction ="UWS"; }else{ if(playerZ > zCoord) this.direction ="UEN"; else this.direction ="UES"; } }else{ if(diffZ > 0){ if(playerX > xCoord) this.direction ="UNE"; else this.direction ="UNW"; }else{ if(playerX > xCoord) this.direction ="USE"; else this.direction ="USW"; } } }else{ if (Math.abs(diffX)>=Math.abs(diffZ)){ if(diffX > 0){ if(playerZ > zCoord) this.direction ="DWN"; else this.direction ="DWS"; }else{ if(playerZ > zCoord) this.direction ="DEN"; else this.direction ="DES"; } }else{ if(diffZ > 0){ if(playerX > xCoord) this.direction ="DNE"; else this.direction ="DNW"; }else{ if(playerX > xCoord) this.direction ="DSE"; else this.direction ="DSW"; } } } } This should work just as good. I don't know how to solve your first problem but the third one *could* ( i think) be solved by assigning the random texture index in the onBlockPlacedBy() function and saving it in a tile entity. Thus the random value would be generated just once and after that always be the same for that one block. -
3 simple ( hopefully ) questions from a beginner.
Wirkungsquantum replied to doku's topic in Modder Support
I only just solved this problem (rotating the texture) so here is my solution. Consider that it can be done either by using metadata or tile entities. I had to use tile entities as to many of my blocks metdata entries were already taken and thus not free to determine diffrent sides. One thing you might want to do is have a look at the thread i opened not long ago titled: "Client appears not to be writing to NBT" It contains all you need to know about saving the direction and rereading it when the world is loaded. What you also need (and even though it is contained in that thread i will re-post it here) is a function that determines the direction, mine is overly precise as i need diffrent parts of my data triple for diffrent blocks. setDirection function: public void setDirection(double playerHeight, float playerAngle){ Side side = FMLCommonHandler.instance().getEffectiveSide(); playerAngle = Math.abs(playerAngle) % 360; if(side == Side.CLIENT) playerHeight -= 1.62; if(playerHeight % 1 >= 0.5)playerHeight = (int)playerHeight+1; else playerHeight = (int)playerHeight; if(this.direction.equals("NotSetYet")){ if(playerHeight+1 < yCoord){ if(playerAngle>= 0 && playerAngle< 45){this.direction ="USE";} if(playerAngle>= 45 && playerAngle< 90){this.direction ="UES";} if(playerAngle>= 90 && playerAngle<135){this.direction ="UEN";} if(playerAngle>=135 && playerAngle<180){this.direction ="UNE";} if(playerAngle>=180 && playerAngle<225){this.direction ="UNW";} if(playerAngle>=225 && playerAngle<270){this.direction ="UWN";} if(playerAngle>=270 && playerAngle<315){this.direction ="UWS";} if(playerAngle>=315 && playerAngle<360){this.direction ="USW";} }else{ if(playerAngle>= 0 && playerAngle< 45){this.direction ="DSE";} if(playerAngle>= 45 && playerAngle< 90){this.direction ="DES";} if(playerAngle>= 90 && playerAngle<135){this.direction ="DEN";} if(playerAngle>=135 && playerAngle<180){this.direction ="DNE";} if(playerAngle>=180 && playerAngle<225){this.direction ="DNW";} if(playerAngle>=225 && playerAngle<270){this.direction ="DWN";} if(playerAngle>=270 && playerAngle<315){this.direction ="DWS";} if(playerAngle>=315 && playerAngle<360){this.direction ="DSW";} } } } Next i will give an example on how to set and interpret this triple: @Override public void onBlockPlacedBy(World theWorld, int blockX, int blockY, int blockZ, EntityLiving thePlayer) { NosTileEntity tile; switch(theWorld.getBlockMetadata(blockX, blockY, blockZ)){ case 1: case 5: case 6: case 8: tile = (NosTileEntity)theWorld.getBlockTileEntity(blockX, blockY, blockZ); tile.setDirection(thePlayer.posY,thePlayer.rotationYaw);break; default: break; } } public int getBlockTextureFromSideAndMetadataAndDirection(int side, int metadata, String direction){ switch(metadata){ case 1: switch(direction.charAt(1)){ case 'N':{if(side == 3 || side == 4)return 1; else return 2;} case 'E':{if(side == 3 || side == 5)return 1; else return 2;} case 'S':{if(side == 3 || side == 4)return 2; else return 1;} case 'W':{if(side == 3 || side == 5)return 2; else return 1;} default :return 255; } case 5: if(direction.charAt(0) == 'D'){return 6;}else{return 7;} case 6: if(direction.charAt(0) == 'D'){return 13;}else{return 14;} case 8: if(direction.equals("UNE")||direction.equals("UEN")){if(side == 3 || side == 5) return 9; else return 8;} if(direction.equals("UES")||direction.equals("USE")){if(side == 3 || side == 4) return 9; else return 8;} if(direction.equals("USW")||direction.equals("UWS")){if(side == 2 || side == 4) return 9; else return 8;} if(direction.equals("UWN")||direction.equals("UNW")){if(side == 2 || side == 5) return 9; else return 8;} if(direction.equals("DNE")||direction.equals("DEN")){if(side == 3 || side == 5)return 11; else return 10;} if(direction.equals("DES")||direction.equals("DSE")){if(side == 3 || side == 4)return 11; else return 10;} if(direction.equals("DSW")||direction.equals("DWS")){if(side == 2 || side == 4)return 11; else return 10;} if(direction.equals("DWN")||direction.equals("DNW")){if(side == 2 || side == 5)return 11; else return 10;} default: return 255; } } By now i assume you realized that the metadata values 1,5,6 and 8 of my block are blocks that can be rotated/place facing diffrent sides. I think this is all you should need, if you have further questions on this I'll do my best to help. -
Client appears not to be writing to NBT
Wirkungsquantum replied to Wirkungsquantum's topic in Modder Support
Thanks diesieben07, at first i was still somewhat unsure on how to implement those functions properly so i had a look at the ironchests mod's code and eventually got my code to work. I will put all the functions etc. necessary in this post so as that a) you (or anyone else for that matter) can tell me whether there is something that could be done in a more efficient way b) anyone who has the same a or a related problem might look the solution up in this thread. Tile Entity: @Override public Packet getDescriptionPacket(){ NBTTagCompound nbt = new NBTTagCompound(); nbt.setString("DIRECTION", this.direction); return new Packet132TileEntityData(xCoord,yCoord,zCoord,1,nbt); } public void setDirection(String newDirection){ this.direction = newDirection; worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } @Override public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt) { this.direction = pkt.customParam1.getString("DIRECTION"); } public String getDirection(){ return this.direction; } //Aditionally here's my function to determine a blocks direction relative to the player placing it: public String direction = "NotSetYet"; public void setDirection(double playerHeight, float playerAngle){ Side side = FMLCommonHandler.instance().getEffectiveSide(); playerAngle = Math.abs(playerAngle) % 360; if(side == Side.CLIENT) playerHeight -= 1.62; if(playerHeight % 1 >= 0.5)playerHeight = (int)playerHeight+1; else playerHeight = (int)playerHeight; if(this.direction.equals("NotSetYet")){ if(playerHeight+1 < yCoord){ if(playerAngle>= 0 && playerAngle< 45){this.direction ="USE";} if(playerAngle>= 45 && playerAngle< 90){this.direction ="UES";} if(playerAngle>= 90 && playerAngle<135){this.direction ="UEN";} if(playerAngle>=135 && playerAngle<180){this.direction ="UNE";} if(playerAngle>=180 && playerAngle<225){this.direction ="UNW";} if(playerAngle>=225 && playerAngle<270){this.direction ="UWN";} if(playerAngle>=270 && playerAngle<315){this.direction ="UWS";} if(playerAngle>=315 && playerAngle<360){this.direction ="USW";} }else{ if(playerAngle>= 0 && playerAngle< 45){this.direction ="DSE";} if(playerAngle>= 45 && playerAngle< 90){this.direction ="DES";} if(playerAngle>= 90 && playerAngle<135){this.direction ="DEN";} if(playerAngle>=135 && playerAngle<180){this.direction ="DNE";} if(playerAngle>=180 && playerAngle<225){this.direction ="DNW";} if(playerAngle>=225 && playerAngle<270){this.direction ="DWN";} if(playerAngle>=270 && playerAngle<315){this.direction ="DWS";} if(playerAngle>=315 && playerAngle<360){this.direction ="DSW";} } } } -
Hello community, the other day i had request about some problems i had with texturing a block, it was recommended to me to have a look into packet handling and client server communications. The first thing i did was to figure out whether it was the server or the client having the problem by doing this: public void readFromNBT(NBTTagCompound nbt){ super.readFromNBT(nbt); this.direction = nbt.getString("DIRECTION"); Side side = FMLCommonHandler.instance().getEffectiveSide(); if(side != null && side == Side.SERVER){System.out.println("Server read");} if(side != null && side == Side.CLIENT){System.out.println("Client read");} } public void writeToNBT(NBTTagCompound nbt){ super.writeToNBT(nbt); //System.out.println(this.direction); nbt.setString("DIRECTION", this.direction); Side side = FMLCommonHandler.instance().getEffectiveSide(); if(side != null && side == Side.SERVER){System.out.println("Server wrote");} if(side != null && side == Side.CLIENT){System.out.println("Client wrote");} } It turned out the server is working perfectly fine and that, much to my surprise, it is the client not working properly. It does neither save to or read from NBT. Thus my first question is: Is this a normal behaviour? And the second: Do i have to somehow force the client to write and read on its own or can this only be solved by using packets? If so, are there any tutorials other than "http://www.minecraftforge.net/wiki/How_to_use_NBT_Tag_Compound" about how to do this you guys know about? (Google wasn't much of help) I *assume* i will need to use packets in order to have other clients see the same thing as the one who set the block does. I was surprised to see that EE3 (looked it up on github) appears not be using any sort of client server communications for its nbt tags. Well, i hope someone can advice me on this // update: Some testing with the furnace showed me that it is a normal thing that the client does not read/write to nbt. Yet i'm not really sure where, when und how to send/receive packages i hope that further studying of opensource mods will help me with this. Help on this however would still be appreciated.
-
Thanks for your advice, i will have a look into how to do that tomorrow as it is already have past eleven in the evening over here. I hope i can now get it to work on my own, but there also a chance that might have further questions about how to do this properly. ^^
-
Hello kind helper, I'm having a problem with the texturing of one of my blocks, this appears to be due to it having too many (well, 2) tile entities. What it should do: I place the block, a lil algo determines its direction and the textures get assigned to the blocks sides with respect to that direction, the direction gets saved in the tile entity that belongs to the block(well, the position) and once the world gets reloaded the block will show the correct textures. What it does. I place the block, a lil algo determines its direction and the textures get assigned to the blocks sides with respect to that direction, the direction gets saved in a tile entity that belongs to the block and once the world gets reloaded the block shows the default textures indicating that something isn't working properly. I can be sure that the direction gets saved properly i added a System.out to the readFromNBT function outputting the correct values on reloading the world. The Tile entity that gets loaded by my getTexture function however outputs the default direction. What i did then in order to determine wether my tile entity or works or not is the following: I added a function @Override public boolean onBlockActivated(World world, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { if(this.hasTileEntity(world.getBlockMetadata(par2, par3, par4))){ NosTileEntity tile = (NosTileEntity) world.getBlockTileEntity(par2, par3, par4); System.out.println(tile.getDirection()); return true; } return false; } As you can see it tells me the direction saved in the tile entity on right clicking the block, the correct one if the entity works properly, the default value if it does not. And this is where i start getting confused as the output i received was the following: 2013-01-11 18:43:03 [iNFO] [sTDOUT] NotSetYet //the default value 2013-01-11 18:43:03 [iNFO] [sTDOUT] EAS // the correct value (east) So rightclicking a block once gives me 2 output values. Are there two block or entities saved in this direction? I have no idea, so if anyone could help me with this, it would be much appreciated. // i turned to the wiki for help, and it had some advice on how to use tile entities but my specific problem could not be solved by anything i found there. p.s.: The code might contain some odd things (like the damageDropped function) this is due to the fact that I'm currently working on moving from relying on metadata alone to (mostly) relying on (you guessed it) tile entities. The Block package newOldStuff.blocks; import java.util.List; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.BlockLog; import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import newOldStuff.NosCommonProxy; public class NosTimberFrameBlock extends BlockContainer { private static final String[] subNames = { "Plain", "Diagonally-striped", "Diagonlly-crossed", "Vertically-striped", "Horizontally-striped", "Y-shaped", "Elhaz-shaped","Plain-crossed","Split"}; public NosTimberFrameBlock (int id) { super(id, Material.wood); setBurnProperties(blockID, 3, 10); setHardness(2.0F); setResistance(4.0F); setStepSound(soundWoodFootstep); setCreativeTab(CreativeTabs.tabBlock); setBlockName("Timber Frame"); } @Override public int getBlockTexture(IBlockAccess blockAccess, int blockX, int blockY, int blockZ, int side) { if(side == 0 || side == 1)return 0; int metadata = blockAccess.getBlockMetadata(blockX, blockY, blockZ); NosTileEntity tile; switch(metadata){ case 1: case 5: case 6: case 8: tile = (NosTileEntity) blockAccess.getBlockTileEntity(blockX, blockY, blockZ); return getBlockTextureFromSideAndMetadataAndDirection(side, metadata, tile.getDirection()); default:return this.getBlockTextureFromSideAndMetadata(side, metadata); } } public int getBlockTextureFromSideAndMetadataAndDirection(int side, int metadata, String direction){ switch(metadata){ case 1: if(direction == "NOR"){if(side == 3 || side == 4)return 1; else return 2;} if(direction == "EAS"){if(side == 3 || side == 5)return 1; else return 2;} if(direction == "SOU"){if(side == 3 || side == 4)return 2; else return 1;} if(direction == "WES"){if(side == 3 || side == 5)return 2; else return 1;} case 5: if(direction=="DNW"){return 6;}else{return 7;} case 6: if(direction=="DNW"){return 13;}else{return 14;} case 8: default: return 255; } } @Override public boolean onBlockActivated(World world, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { if(this.hasTileEntity(world.getBlockMetadata(par2, par3, par4))){ NosTileEntity tile = (NosTileEntity) world.getBlockTileEntity(par2, par3, par4); System.out.println(tile.getDirection()); return true; } return false; } @Override public int getBlockTextureFromSideAndMetadata (int side, int metadata) { if(side == 0 || side == 1) return 0; switch(metadata){ case 0: return 0; case 1: return 1; case 2: return 3; case 3: return 4; case 4: return 5; case 5: return 6; case 6: return 13; case 7: return 12; case 8: return 10; default: return 255; } } @Override public void onBlockPlacedBy(World theWorld, int blockX, int blockY, int blockZ, EntityLiving thePlayer) { NosTileEntity tile; switch(theWorld.getBlockMetadata(blockX, blockY, blockZ)){ case 1:tile = (NosTileEntity)theWorld.getBlockTileEntity(blockX, blockY, blockZ);tile.setDirection(thePlayer.posX,thePlayer.posZ);break; case 5: case 6:tile = (NosTileEntity)theWorld.getBlockTileEntity(blockX, blockY, blockZ);tile.setDirection(thePlayer.posY);break; } } @Override public String getTextureFile () { return NosCommonProxy.ordinaryBlocks; } @Override public int damageDropped (int metadata) { if(metadata==9)return 1; if(metadata==10)return 1; if(metadata==11)return 1; if(metadata==12)return 6; if(metadata==13)return 5; return metadata; } @SideOnly(Side.CLIENT) public void getSubBlocks(int unknown, CreativeTabs tab, List subItems) { for (int i = 0; i < 9; i++) { subItems.add(new ItemStack(this, 1, i)); } } public static String getSubName(int metadata){ if(metadata==9)return subNames[1] + " " + "Timber Frame"; if(metadata==10)return subNames[1] + " " + "Timber Frame"; if(metadata==11)return subNames[1] + " " + "Timber Frame"; if(metadata==12)return subNames[6] + " " + "Timber Frame"; if(metadata==13)return subNames[5] + " " + "Timber Frame"; return subNames[metadata] + " " + "Timber Frame"; } @Override public boolean hasTileEntity(int metadata){ switch(metadata){ case 1:return true; case 5:return true; case 6:return true; case 8:return true; default:return false; } } @Override public TileEntity createNewTileEntity(World world){ try{return new NosTileEntity();} catch (Exception var3){throw new RuntimeException(var3);} } @Override public TileEntity createTileEntity(World world, int metadata) { return createNewTileEntity(world); } } The Entity package newOldStuff.blocks; import net.minecraft.block.BlockContainer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; public class NosTileEntity extends TileEntity{ private String direction = "NotSetYet"; public void setDirection(double playerY){ if(playerY<yCoord) {this.direction = "DNW";} else {this.direction = "UPW";} } public void setDirection(double playerX, double playerZ){ double diffX = (double)xCoord + 0.5 - playerX, diffZ = (double)zCoord + 0.5 -playerZ; if (Math.abs(diffX)>=Math.abs(diffZ)){ if(diffX>0){this.direction = "WES";} else{this.direction = "EAS";} }else{ if(diffZ>0){this.direction = "SOU";} else{this.direction = "NOR";} } } public void setDirection(double playerX, double playerY, double playerZ){ //implement } public String getDirection(){ return this.direction; } @Override public void readFromNBT(NBTTagCompound nbt){ super.readFromNBT(nbt); this.direction = nbt.getString("DIRECTION"); //System.out.println("Tile X:"+xCoord+" Y:"+yCoord+" Z:"+zCoord+" Richtung:"+this.direction); } @Override public void writeToNBT(NBTTagCompound nbt){ super.writeToNBT(nbt); //System.out.println(this.direction); nbt.setString("DIRECTION", this.direction); } }
-
Since i wanted to have a look in this anyway i did a bit sooner than i originally planned to, here is what i figured out: 1.Have your own Block class: (I will use code examples from my own litle mod) package NewOldStuff; import net.minecraft.block.Block; import net.minecraft.block.material.Material; public class nosBlock extends Block { public nosBlock (int id, int texture, Material material) { super(id, texture, material); } @Override public String getTextureFile () { return nosCommonProxy.BLOCK_PNG; } } 2.Have a class that extends BlockStairs (as keepcalm already suggested): package NewOldStuff; import net.minecraft.block.Block; import net.minecraft.block.BlockStairs; import net.minecraft.block.material.Material; public class nosStairs extends BlockStairs { public nosStairs (int id, Block block, int par3) { super(id, block, par3); } @Override public String getTextureFile () { return nosCommonProxy.BLOCK_PNG; } } 3.Now create a new Block with the texture you would like to use and use that Block to create some new stairs: public static Block strawBL = new nosBlock(3502, 2, Material.cactus) .setHardness(0.5F).setStepSound(Block.soundGrassFootstep) .setBlockName("strawBL").setCreativeTab(CreativeTabs.tabBlock); public static Block strawRF = new nosStairs(3503, strawBL, 1) .setHardness(0.5F).setStepSound(Block.soundGrassFootstep) .setBlockName("strawBL").setCreativeTab(CreativeTabs.tabBlock); 4.Register your new Stairs as any other Block, but not your "helper-block", unless you want to be able to use it in-game too LanguageRegistry.addName(strawRF, "Straw Thatch"); MinecraftForge.setBlockHarvestLevel(strawRF, "axe", 1); GameRegistry.registerBlock(strawRF); 5.Works: _________________ I still have to figure out how to correct the lighting.
-
which i have done already: Also it is not net.minecraft.src.Block any longer: You can also look that up in the tutorial: http://www.minecraftforge.net/wiki/Tutorials/Basic_Blocks Here it says import net.minecraft.block.Block; Wuppy's tutorial appears to be older (18th August) than this one (13th December) Anyhow, thank you for your input, maybe you can think of another possible reason?
-
Good day, i only just started modding for minecraft the other day using the tutorials on the wiki. It worked perfectly fine until i tried to add a new block. While it still worked with the minecraft version emulated by eclipse my "ordinary" minecraft gives me the above error message. I used the "import net.minecraft.block.Block;" line just as in the tutorial, i assume otherwise the eclipse-minecraft would have had some error of its own. So now my question is: Does anyone have any idea why this might be happening? I myself am clueless for now, and using the search function did not really help me. Please inform me if additional information are required though i didn't see a sticky about a specific form for requests in this sub-forum.