TheGreyGhost
Members-
Posts
3280 -
Joined
-
Last visited
-
Days Won
8
Everything posted by TheGreyGhost
-
Ah, no the item renderers are different, they set the origin relative to the item (see http://greyminecraftcoder.blogspot.com.au/2013/09/custom-item-rendering-using.html) and it could be very tricky to figure out where the block goes relative to this origin I'd suggest moving your line rendering into the RenderWorldLast event. Then you get the player origin which you need; check to see if the player is holding the item. eg something like this @ForgeSubscribe public void drawSelectionBox(RenderWorldLastEvent event) { RenderGlobal context = event.context; assert(context.mc.renderViewEntity instanceof EntityPlayer); EntityPlayer player = (EntityPlayer)context.mc.renderViewEntity; ItemStack currentItem = player.inventory.getCurrentItem(); float partialTick = event.partialTicks; if (currentItem != null && currentItem.getItem() == myItemWhichDrawsLines) { MovingObjectPosition target = currentItem.getItem().getMovingObjectPositionFromPlayer(player.worldObj, player, true); // check target to see if it's a block, if so take the coordinates and subtract the EntityPlayer.getPosition and draw to 0,0,0 } -TGG
-
Hi What are the symptoms? Perhaps it crashes if not placed by a player? Based on the JavaDoc, par5EntityLivingBase should be null if placed by a structure. -TGG
-
Hi Which method are you drawing this in? the coordinates of the origin are often different. In many of them, the origin is set to the player's eyes (0,0,0). So if you are using block coordinates, you need to subtract the player position EntityPlayer.getPosition(partialTick); can be useful for that. so to draw from a block coordinate to the player's eyes, you would draw from [blockx-playerx, blocky-playery, blockz-playerz] to [0, 0, 0] A bit of trial and error often helps you guess the right offsets... -TGG
-
[1.7.2][SOLVED]SpawnParticle not working
TheGreyGhost replied to CoderAce_'s topic in Modder Support
Hi A random guess - is this event running on the server and not the client? I think spawning particles only works on the client. -TGG -
Solved: Using missing texture, unable to load:
TheGreyGhost replied to TheGreyGhost's topic in Modder Support
It looks like the handling of Resources has been changed yet again. FolderResourcePack:: protected InputStream getInputStreamByName(String par1Str) throws IOException { return new BufferedInputStream(new FileInputStream(new File(this.resourcePackFile, par1Str))); // breakpoint here } --> look in this.resourcePackFile (may need to continue several times until you find the right one). or alternatively protected InputStream getInputStreamByName(String par1Str) throws IOException { System.out.println("this.resourcePackFile:" + this.resourcePackFile.toString()); // todo: debugging only, remove return new BufferedInputStream(new FileInputStream(new File(this.resourcePackFile, par1Str))); } -TGG -
[1.7.2] Custom Tools Causing Crash on Use
TheGreyGhost replied to Fergoman007's topic in Modder Support
Hi Which tool causes the crash? I'd suggest you make a backup copy of the class, get rid of everything except the tool that crashes, then try again. If it still doesn't work, repost the "slimmed down" class. -TGG -
Ah, I see. I just had a look and they've obviously changed the handling of Resources yet again. Try a breakpoint in SimpleReloadableResourceManager::getResource and look in this.domainResourceManagers - see screenshot https://www.dropbox.com/s/7v3xouub45cxk4e/ScreenShot.png alternatively FolderResourcePack:: protected InputStream getInputStreamByName(String par1Str) throws IOException { return new BufferedInputStream(new FileInputStream(new File(this.resourcePackFile, par1Str))); // breakpoint here } --> look in this.resourcePackFile (may need to continue several times until you find the right one). or alternatively protected InputStream getInputStreamByName(String par1Str) throws IOException { System.out.println("this.resourcePackFile:" + this.resourcePackFile.toString()); // todo: debugging only, remove return new BufferedInputStream(new FileInputStream(new File(this.resourcePackFile, par1Str))); } -TGG
-
[1.7.2] Custom Tools Causing Crash on Use
TheGreyGhost replied to Fergoman007's topic in Modder Support
Hi Your custom tool appears to have been allocated an id of -1. Just a guess: have you registered it properly? -TGG -
Hi A bit of background info on Blocks here http://greyminecraftcoder.blogspot.com.au/2013/07/blocks.html and here http://greyminecraftcoder.blogspot.com.au/2013/10/the-most-important-minecraft-classes_9.html if you have 16 types or less, use metadata. Vanilla wood uses this, for example. oak, birch, etc -TGG
-
Howdy all I'm trying to set up unit testing for some of my classes (using JUnit) and it's doing my head in trying to set up the FMLLog so it doesn't crash when the class under test writes to it. eg if my class under test has if (!backupListing.hasKey(BACKUP_LISTING_VERSION_TAG) || !backupListing.hasKey(BACKUP_LISTING_PATHS_TAG)) { FMLLog.warning("Invalid backuplisting file (missing tag): " + backupListingPath.toString()); return retval; } then when it is called by my test class, it gives me a NullPointerException caused by this line in FMLRelaunchLog::configureLogging File logPath = new File(minecraftHome, logFileNamePattern); because minecraftHome and logFileNamePattern are both not set properly. I haven't been able to find a way to set them up. Anyone else figured out a straightforward way to do this? (Other than replacing all my calls to FMLLog with a wrapper, that is) -TGG
-
Hi You mean - nearby blocks light up if the laser is shining? Yes I think it's possible, but it will be tricky because the block lighting would need to be updated. It would probably look something like putting transparent (invisible) blocks along the path of the beam and causing them to emit light for the blocklight calculations. Some info on lighting here, to give you an idea of how vanilla works it. http://greyminecraftcoder.blogspot.com.au/2013/08/lighting.html -TGG
-
Hi When you use a ResourceLocation, Forge converts it to a full path using this code FolderResourcePack:: protected boolean makeFullPath(String par1Str) { return (new File(this.basePath, par1Str)).isFile(); } If you find the vanilla FolderResourcePack and put a breakpoint in there, then look at the value of this.basePath, it will show you what the base path is. You might need to "continue" a couple of times until the right ResourcePath comes up because there are several different ones and only one of them is yours (you will know it when you see it). Alternatively add the following line and then look in the console output after running FolderResourcePack:: protected boolean makeFullPath(String par1Str) { System.out.println("FolderResourcePack::makeFullPath basePath = " + this.basePath); // ToDo: debugging, remove return (new File(this.basePath, par1Str)).isFile(); } -TGG
-
yes that's right Yeah Colour is my own custom class which I didn't include. Just change it to numbers, eg GL11.glColor4f(0, 0, 0, 0.4); // semi-transparent black or GL11.glColor4f(1, 0, 0, 0.4); // semi-transparent red etc (You know about Red, Green, Blue, Alpha yes?) No worries, it's a bit complicated in parts but it sure taught me a lot. -TGG
-
Hi You could try posting your request on the appropriate forum on http://www.planetminecraft.com/ Plenty of folks there with some skill at graphic design; you might find someone who wants to collaborate with you. Most folks here probably prefer coding, is my guess. Personally, I suck at making logos. -TGG
-
Hi This code draws black semi-transparent lines, if you fiddle with it you might be able to get what you want... If you want to draw a series of connected lines (bendy laser?) then tessellator.startDrawing(GL11.GL_LINE_STRIP); can be useful to. A great guide on OpenGL here http://www.glprogramming.com/red/index.html -TGG
-
Hi Did you try the suggestions in this post? http://www.minecraftforge.net/forum/index.php/topic,11963.msg62174.html#msg62174 -TGG
-
[1.7.2 - FIXED] Crafting Error NullPointerException
TheGreyGhost replied to Bektor's topic in Modder Support
Hi Are you sure you're using Forge version 1024? In my version 1024, there is no func_92103_a and my CraftingManager.java:234 doesn't match yours But anyway, I'm pretty certain that your CMSstuff.cobaltwood or CMSstuff.cobaltingot is still null at the point you construct your ARecipes. Do you know how to use the integrated debugger? (Breakpoints and watches etc)? If so, I'd suggest you put a breakpoint in your addRecipesForCraftingTable and inspect the values of cobaltwood and cobaltingot. (If you don't know... it's well worth your time spending a couple of hours to learn, I reckon) http://www.vogella.com/tutorials/EclipseDebugging/article.html or https://www.jetbrains.com/idea/webhelp/debugging.html and -TGG -
[Solved] NullPointerException at custom canInfuse() method
TheGreyGhost replied to Feronzed's topic in Modder Support
Hi The reason it's not comparing properly is what sequitiri said in his last post. If you compare objects in Java using ==, you are comparing whether they are the same object, not whether they have the same contents. This is very important to keep in mind otherwise you'll have no end of strange bugs and headaches. This link talks about it a bit more, for Strings. http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java You could what Sequitiri suggested to fix this (i.e. create your "Three Input Items" class and give it an equals method), alternatively if you're just starting out you could compare the ItemStacks manually using ItemStack.areItemStacksEqual(itemstack1, itemstack2) And come to think of it, you probably don't need your List, I think you could just use Map<ItemStack[], RecipeInfusionTable> instead eg something like private static Map<ItemStack[], RecipeInfusionTable> recipeMap = new HashMap(); for (Map.Entry<ItemStack [], RecipeInfusionTable> input : recipeMap.entrySet()) { if ( ItemStack.areItemStacksEqual(input.getKey()[0], firstInput) && ItemStack.areItemStacksEqual(input.getKey()[1], secondInput) && ItemStack.areItemStacksEqual(input.getKey()[2], thirdInput) { found my recipe return result; } } I haven't compiled it so the syntax might not be right but the idea should work - assuming you don't mind that the order of the matching has to be exactly the same (first item must match first recipe item, second item must match second item, etc). -TGG -
Hi If you're using the RenderLiving methods, you can set the Entity.renderYawOffset in your Entity.onLivingUpdate code ; something like private int rotationStartTicks; @Override public void onLivingUpdate() super.onLivingUpdate(); double newYaw = 0.0; final double ROTATION_ANGLE_PER_TICK = 18.0; if (entityheadcrab.onGround = true) { rotationStartTicks = ticksExisted; } else { newYaw += (ticksExisted - rotationStartTicks) * ROTATION_ANGLE_PER_TICK; } renderYawOffset = newYaw; } I haven't compiled this but I reckon the basic idea should work. Alternatively, your glRotate code might work if you put it here - but I'm not 100% certain of that. public void renderHeadcrab(EntityHeadcrab entityheadcrab, double x, double y, double z, float yaw, float partialTick) { GL11.glPushMatrix(); if(entityheadcrab.onGround = false) { GL11.glRotatef(60.0F,1.0F,0.0F,0.0F); GL11.glRotatef(60.0F,0.0F,1.0F,0.0F); GL11.glRotatef(60.0F,0.0F,0.0F,1.0F); } super.doRenderLiving(entityheadcrab, x, y, z, yaw, partialTick); GL11.glPopMatrix(); } -TGG
-
[1.6.4] [Solved] shouldSideBeRendered() Problem.
TheGreyGhost replied to SackCastellon's topic in Modder Support
Hi BlockBreakable:: * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given * coordinates. Args: blockAccess, x, y, z, side public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int x, int y, int z, int side) { int i1 = par1IBlockAccess.getBlockId(x, y, z); return !this.localFlag && i1 == this.blockID ? false : super.shouldSideBeRendered(par1IBlockAccess, x, y, z, side); } x,y,z is the coordinates of the adjacent block, not the block being rendered. -TGG -
Hi The math usually uses sin and cos because this gives nice "smooth" animations instead of jerky changes in direction, a bit like a swinging pendulum. It's hard to explain this in a few lines, this link might give you a bit of an idea about how sine and cosine make the motions "smooth", but to really properly understand it you probably need to study up a bit on trigonometry. http://www2.seminolestate.edu/lvosbury/SineCosine.htm An example from the ocelot code: this.ocelotBackLeftLeg.rotateAngleX = MathHelper.cos(animationTime * 0.6662F) * 1.0F * maximumSwingAngle; this.ocelotBackRightLeg.rotateAngleX = MathHelper.cos(animationTime * 0.6662F + 0.3F) * 1.0F * maximumSwingAngle; this.ocelotFrontLeftLeg.rotateAngleX = MathHelper.cos(animationTime * 0.6662F + (float)Math.PI + 0.3F) * 1.0F * maximumSwingAngle; this.ocelotFrontRightLeg.rotateAngleX = MathHelper.cos(animationTime * 0.6662F + (float)Math.PI) * 1.0F * maximumSwingAngle; this.ocelotTail2.rotateAngleX = 1.7278761F + ((float)Math.PI / 10F) * MathHelper.cos(animationTime) * maximumSwingAngle; this.ocelotTail2.rotateAngleX = 1.7278761F + ((float)Math.PI / 10F) * MathHelper.cos(par1) * par2; If we just look at the backleftleg - we are changing the rotation angle around the x axis, which is the side of the ocelot, so the leg is swinging forwards and backwards. If you have the function angle = cos(animationTime) it converts the animationTime into an angle For example if animationTime is in seconds: when animationTime is 0, cos(0) = 1 so the angle is set to 1. animationTime increases a bit, say to about 0.5. cos(0.5) is about 0.87, so the angle is set to 0.87 at 1 second, cos(1) = 0.54 at 1.5 seconds, cos(1.5) is approximately 0 at 2 seconds, cos (2) is approximately -0.4 And if you keep increasing the time, you'll find that the cos() oscillates smoothly between +1 and -1 in a repeating cycle. So you've converted your animationTime in seconds into a smoothly swinging angle back and forth. Every 6.3 seconds or so, the animation repeats (the exact number is 2 * Math.PI). There are a couple of extra tricks - if you want the animation to move faster or slower, you multiply the animationTime by a larger or smaller number. If you want the angle to swing by larger amounts, you multiply the cos by a larger number. If you've got two animations and you want to delay one of them a bit (i.e. one of the legs swings ahead of the other one) you add a delay time to your animation time So in the ocelot example, this.ocelotFrontLeftLeg.rotateAngleX = MathHelper.cos(animationTime * 0.6662F + (float)Math.PI + 0.3F) * 1.0F * maximumSwingAngle; we are slowing down the animation a bit (* 0.6662F) and we are delaying it a bit Math.PI + 0.3F and we are making the leg swing more (* maximumSwingAngle). Choosing the correct values is pretty much a matter of trial and error, with some hints based on vanilla code. If you're animating something similar to a vanilla creature, I'd suggest you look at the values it uses to get a good starting point. -TGG
-
[Solved] NullPointerException at custom canInfuse() method
TheGreyGhost replied to Feronzed's topic in Modder Support
Hi Looks to me like RecipeInfusionTable.getRecipe is returning a null RecipeInfusionTable. If you try to call .getOutput() on a null object, it will crash. -TGG -
(unsolved)(1.7.2) Manually Creating Mob Models
TheGreyGhost replied to Sanocon's topic in Modder Support
Hi You might try downloading this bloke's code, he knows what he's doing as far as I can tell. https://github.com/coolAlias/ZeldaSwordSkills The classes you're interested are for example https://github.com/coolAlias/ZeldaSwordSkills/blob/master/src/zeldaswordskills/client/model/ModelOctorok.java https://github.com/coolAlias/ZeldaSwordSkills/blob/master/src/zeldaswordskills/entity/EntityOctorok.java https://github.com/coolAlias/ZeldaSwordSkills/blob/master/src/zeldaswordskills/client/render/entity/RenderOctorok.java He actively contributes to this forum occasionally so might be willing to talk to you direct, too. I'm not sure the code is for 1.7.2, might be 1.6.4, but it isn't much different in any case. -TGG -
Hi Your glRotatef are right but probably in the wrong place. They need to go just before you render your model. Show us your render code? eg from RendererLivingEntity protected void renderModel(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4, float par5, float par6, float par7) { this.bindEntityTexture(par1EntityLivingBase); if (!par1EntityLivingBase.isInvisible()) { // put your rotates here - eg if you want to rotate about the vertical axis: GL11.glRotatef(angle, 0.0, 1.0, 0.0); this.mainModel.render(par1EntityLivingBase, par2, par3, par4, par5, par6, par7); } // etc } -TGG