TheGreyGhost
Members-
Posts
3280 -
Joined
-
Last visited
-
Days Won
8
Everything posted by TheGreyGhost
-
Hi The code would look something like boolean myKeyOfInterestIsDown = false; [code]MyClientTickHandlerMethod() { boolean newKeyDown = Keyboard.isKeyDown(MY_KEY_OF_INTEREST); if (newKeyDown) { if (!myKeyOfInterestIsDown) { //send a custom packet to the server to say "I have just received a keypress for MY_KEY_OF_INTEREST" - i.e. when the key goes from up to down } } myKeyOfInterestIsDown = newKeyDown; } [/code] look at the start of KeyBoard for the suitable keycodes eg public static final int KEY_Q = 0x10; -->Keyboard.isKeyDown(KEY_Q); There are two main ways I've found helpful when interacting with the vanilla code. The first is to use one of the many Forge registries or hooks, to add custom blocks, items, or get called when particular things happen. This is very common. Unfortunately the documentation is a bit patchy so it's not always easy to know what's available. A typical strategy I use is to identify an item or block or whatever that does something similar to what I need. Then I'll look at the vanilla code and trace it through until I figure out how it works, and usually I will stumble over a forge hook or event along the way. The second strategy which is harder and less robust is to override an existing vanilla class and replace any references to it from other vanilla code. For example, you can overwrite GameSettings.keyBindForward with your own class derived from KeyBinding. This is usually not necessary and is often not possible. A third strategy which I haven't had to use yet is to edit the base classes to overwrite the vanilla. ("base mod") This will probably break everytime Minecraft is updated. A fourth strategy you will hear occasionally is reflection / ASM. I would avoid this like the plague because it is fragile and very hard to debug. I had my fill of self-modifying code back in my days of programming assembly and am not keen to go back!! -TGG
-
Hi Try this.... public TickHandler() { gs = Minecraft.getMinecraft().gameSettings; intLeft = new KeyBindingInterceptor(gs.keyBindAttack); intRight = new KeyBindingInterceptor(gs.keyBindUseItem); gs.keyBindAttack = intLeft; gs.keyBindUseItem = intRight; intLeft.setInterceptionActive(true); intRight.setInterceptionActive(true); } This replaces the vanilla key bindings with the interceptor, which will stop the vanilla code from receiving any keypresses while the interception is active, and will also keep the intLeft and intRight updated with the latest keypresses. If you're just interested in clicks (rather than the user holding the button down), then all you need is if (intLeft.retrieveClick()) { // left was clicked you don't need to use isKeyDown(). But just to be clear - do you need to stop the vanilla code from receiving the clicks? or do you just want to tell when the user has clicked so you can do something extra? -TGG
-
Hi Hmmm well I'm out of my depth now. My only suggestion is that Blocks are rendered in two passes, opaque first and partially transparent second. you could perhaps try that, i.e. render your no-glass model first, then a separate model with smoky glass second. pure guessing on my part. -TGG
-
Hi It looks to me like the bounding box for your TileEntity is too small. When the bounding box is off the screen (outside the "frustrum") Minecraft thinks "OK the player can't see the TileEntity anymore so I don't need to draw it". That's a pure guess and I'm not sure how to fix it. But it might point you in the right direction. Overriding TileEntity.getRenderBoundingBox() looks promising. The default is to use the bounding box of the associated block, and it looks like your TileEntity might span over several blocks? -TGG
-
Detecting when a user logs into a server?
TheGreyGhost replied to snocavotia's topic in Modder Support
Hi NetLoginHandler.initializePlayerConnection() has a forge call to FMLNetworkHandler.handleClientConnection() which contains this fragment: case LOGIN_RECEIVED: // mods can try and kick undesireables here String modKick = NetworkRegistry.instance().connectionReceived(netLoginHandler, netLoginHandler.myTCPConnection); which I think you can access using NetworkRegistry.registerConnectionHandler. There also appears to be handlers for playerLoggedIn, clientLoggedIn, and a couple of others. See IConnectionHandler. That's all I know, I've never actually tried this. But it does look promising. -TGG -
Hi Not exactly, partialTickTime helps you synchronise your animations better if the frame rate is uneven. I'd suggest that there's a reasonably easy way to fix your problem with the model file being updated by multiple tile entites... i.e. don't update it in multiple tile entities. Give responsibility for the updating to a single place in your code, eg a TickHandler which is called once per tick. -TGG
-
Hi You need to keep track of what each sword is made of - eg copper, iron, lead, or whatever. The vanilla code does it like this public class ItemSword extends Item { private final EnumToolMaterial toolMaterial; public ItemSword(int par1, EnumToolMaterial par2EnumToolMaterial) { super(par1); this.toolMaterial = par2EnumToolMaterial; and creates it using (for example) public static Item swordIron = new ItemSword(11, EnumToolMaterial.IRON); public static Item swordWood = new ItemSword(12, EnumToolMaterial.WOOD); public static Item swordStone = new ItemSword(16, EnumToolMaterial.STONE); You can't add to the EnumToolMaterial, but you can create a field of your own (can be an int, doesn't have to be an enum) and make the materials whatever you like. -TGG
-
Particles stop spawning! Server/Client desynch?
TheGreyGhost replied to Frepo's topic in Modder Support
Hi The general rules are- The server holds the master copy of the world, and things which affect the state of the world (blocks, changes to entities, movement, etc) are nearly always calculated on the server and the results sent to any clients which are affected (nearby). Things like rendering are usually done on the client only, likewise user interactions. In some cases, the client and the server do the same calculations in parallel to help make the game more responsive, but if there is a clash down the track (eg the position of an entity) then the server takes priority. Some classes are only ever called on the server side (eg the ones in that server-side chart) Some classes are only ever called on the client side (eg the ones in that client-side chart) - and often the methods are marked as @SideOnly(Side.CLIENT) Some are called in both- if you see a vanilla method with .isRemote() in it, you can be reasonably confident that both sides might call it (otherwise there would be no point in checking it). If the method you're looking at isn't one of the classes in the charts above, and none of the methods have .isRemote() in it, then you usually can't be sure which sides (or both) call it. Perhaps other folks on the forum have a more reliable method of telling. If I had more technical knowledge I'd run a coverage checker and find out, maybe I'll do that one of these days... -TGG -
Hi I'm not sure I understand your question correctly, but it sounds to me like you have many swords made of different materials all within the one class, and each sword should only be repaired by its corresponding material eg copper ingot for copper sword iron ingot for iron sword lead ingot for lead sword Very much like the vanilla ItemSword with wood, stone, diamond, etc If so, your isRepairable might look something like ItemSword.getIsRepairable, except that you have to add your own ingots public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { switch (materialIamMadeOf) { case iron: { return ingotIron == par2ItemStack.itemID ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); } case copper: { return ingotCopper == par2ItemStack.itemID ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); } etc -TGG
-
Hi I think that in order to see the back of the lamp, you should turn off "back face culling" GL11.glDisable(GL11.GL_CULL_FACE); I'm not sure why the candle is not visible. What happens if you remove the glass panes from your model, can you see it then? -TGG
-
Hi If I understand you right, you know how to read keypresses from Keyboard, but you're not sure how to get them from each client to the server? You need to use a custom packet for that - each time the client presses your key of interest, you need to read that on the client (eg in a tick handler), send a packet to the server, then have the server process the packet. http://www.minecraftforge.net/wiki/Packet_Handling -TGG PS this link might also be useful http://greyminecraftcoder.blogspot.com.au/2013/10/user-input.html
-
Hi Yes that's right, I was using this class to capture the left & right clicks when a certain item is being held, and the tick handler was checking the intercepted keyhandler once per tick using .retrieveClick But just to be clear, your code doesn't need to call copyClickInfoFromOriginal itself. Is is called by the vanilla code (the vanilla code calls isPressed(), which calls copyClickInfoFromOriginal) I'm not sure that the comment you've added in the code is correct. The vanilla code never sees interceptedKeyBinding.pressTime because the GameSettings.keyBindAttack is pointing to the KeyBindingInterceptor. To stop the code from receiving left clicks, turn interception on and check for the clicks in your tickhandler using retrieveClick. When you turn interception off, the clicks go through to the vanilla code again. -TGG
-
Hi I'm not sure exactly what you want to do, but I think these links might help http://greyminecraftcoder.blogspot.com.au/2013/08/rendering-items.html http://greyminecraftcoder.blogspot.com.au/2013/09/custom-item-rendering-using.html http://greyminecraftcoder.blogspot.com.au/2013/09/sample-code-for-rendering-items.html -TGG
-
Hi I have created something similar to let you intercept the left and right clicks, it works pretty well for me. https://gist.github.com/TheGreyGhost/7033821 Some background info too that might be helpful http://greyminecraftcoder.blogspot.com.au/2013/10/user-input.html -TGG
-
[MC 1.6.2] How do I make an item take damage after each use
TheGreyGhost replied to Elite_Forges's topic in Modder Support
Hi Hmm that's a bummer What I mean is for example ItemStack dirtStack = new ItemStack(Block.dirt); ItemStack matchAnyDamageValueItemStack = new ItemStack(MyItem, 1, 32767); GameRegistry.addRecipe(new ItemStack(Block.cobblestone), "xy", "yx", 'x', dirtStack, 'y', matchAnyDamageValueItemStack); That way the recipe should match your item regardless of its damage value. (You said you've already figured out how to damage the item by 1 every time it is crafted with?) -TGG -
Hi Sorry dude, I'm at a loss now. If I were running this on my machine, I would put a breakpoint here in RenderManager.renderEntityWithPosYaw: render = this.getEntityRenderObject(entityToRender); // retrieves your custom renderer here then trace into getEntityRenderObject and see why my entityToRender is not matching any of the classes registered in RenderManager.entityRenderMap. -TGG
-
Hi Maybe I misunderstand your code, but doesn't this line set your background colour to grey (opaque black?) Tessellator.instance.setColorRGBA_F(0, 0, 0, 0.25F); If you want a white background, you need Tessellator.instance.setColorRGBA_F(1, 1, 1, 0.25F); ? -TGG
-
Hi So what you are basically trying to do is In your entity onUpdate: (1) create a bounding box centred around where the projectile currently is. (2) find all entities within that bounding box (3) loop through them all: (a) if this isn't a valid target, ignore it (b) calculate the distance from the target to the projectile. If it's less than the shortest distance found so far, this is now your closest target. (4) change motionX, motionY, motionZ to point to the closest target You can probably copy the onUpdate code from EntityThrowable and tweak it to add the code above. It looks like you've figured out (1) and (2) already, just need to code up the rest. It won't do anything fancy like check whether the missile can actually see the target (blocks in the way), but you could add that later if you really want, once the basics are working? -TGG PS It looks like this bloke is also doing something very similar to what you want, perhaps you should message him too... http://www.minecraftforge.net/forum/index.php/topic,13829.0.html
-
[MC 1.6.2] How do I make an item take damage after each use
TheGreyGhost replied to Elite_Forges's topic in Modder Support
Hi I don't have any working code, so if that's a problem you should stop reading now :-P I think I might be able to help you get one step further what what you've figured out already- ShapedRecipes: .checkMatch() and in particular if (itemstack1 != null || itemstack != null) { if (itemstack1 == null && itemstack != null || itemstack1 != null && itemstack == null) { return false; } if (itemstack.itemID != itemstack1.itemID) { return false; } if (itemstack.getItemDamage() != 32767 && itemstack.getItemDamage() != itemstack1.getItemDamage()) { return false; } } This is probably the reason that your item stops crafting when it's been damaged. Luckily it looks like you can create your own MyRecipe implements IRecipe to change the matching to whatever you want (i.e. ignoring damage). Alternatively, if you put your Item in the Recipe as an ItemStack with damage of 32767, I think it will match regardless of the damage of the tool. -TGG -
Hi I've had a look through the code and I have to admit I don't really understand what you're trying to do. In particular this bit if(electrolysisItemStacks[6] != null && electrolysisItemStacks[6].getItem() == Elementum.upgrade){ finishTime = 1200 /(this.electrolysisItemStacks[6].stackSize + 1); } won't electrolysisItemStacks[6] always be null, since you only just created it? Perhaps you could write a paragraph describing to us in more detail how your furnace should work, eg (1) The furnace will have an extra seven slots (2) Each slot can hold an Elementum (3) The more slots are filled with Elementum, the faster the smelting time according to the formula xxx (etc) But anyway, to help you track down why your code isn't working the way you expect, I'd suggest you add logging code at key points, eg: if (this.isBurning() && this.canSmelt()) { ++this.electrolysisCookTime; System.out.println("Current electrolysisCookTime:" + this.electrolysisCookTime + " -> " + finishTime); if (this.electrolysisCookTime == finishTime) { this.electrolysisCookTime = 0; this.smeltItem(); flag1 = true; } } and public TileEntityElectrolysisMachine() { electrolysisItemStacks = new ItemStack[7]; electrolysisBurnTime = 0; currentItemBurnTime = 0; electrolysisCookTime = 0; speedModifier = 0; if(electrolysisItemStacks[6] != null && electrolysisItemStacks[6].getItem() == Elementum.upgrade){ finishTime = 1200 /(this.electrolysisItemStacks[6].stackSize + 1); } else { finishTime = 1200; } System.out.println("finishTime = " + finishTime); } -TGG
-
Hi OK, I understand your confusion now. I'd recommend you spend a bit of time doing some practice tutorials about inheritance in Java and especially how to override methods when you extend base classes. Otherwise you'll struggle for days and get really frustrated because Minecraft uses that all the time. http://docs.oracle.com/javase/tutorial/java/concepts/inheritance.html http://docs.oracle.com/javase/tutorial/java/IandI/index.html http://www.tutorialspoint.com/java/java_inheritance.htm Unfortunately I can't really recommend any good tutorials for learning Java because I have come from C++, but perhaps some of the other folks on this forum could help. -TGG
-
@Draco Really? I haven't tested my mod on a server build yet, guess I should try that before I release it..! Thanks for the heads up! :-) @Storm Dude, breakpoints and watchpoints are awesome, you absolutely have to learn how to use them, you'll wonder how you even managed without them try http://www.vogella.com/articles/EclipseDebugging/article.html In the meantime, you could use System.out.println("I got here"); to see what the vanilla code is doing when it tries to render your Entity: eg RenderManager.renderEntityWithPosYaw public void renderEntityWithPosYaw(Entity entityToRender, double x, double y, double z, float yaw, float partialTickTime) { System.out.println("RenderManager.renderEntityWithPosYaw"); Render render = null; try { render = this.getEntityRenderObject(entityToRender); // retrieves your custom renderer here if (render != null && this.renderEngine != null) { // snip try { System.out.println("render.doRender"); render.doRender(entityToRender, x, y, z, yaw, partialTickTime); } Based on what you've said so far, it sounds like the vanilla code is not properly mapping your EntitySpear to RenderSpear, but I can't tell why. Oh, and I'd suggest you add @Override just before your RenderSpear.doRender, just in case there is some subtle mistake there (doesn't look like it, but good practice anyway...) -TGG
-
Hi You're right that adding your own enum would be difficult. Luckily you don't need to. In canBlockStay: The first four if statements check whether the cactus is next to another one. The last one checks whether the block beneath the cactus will support its growth. So why not change the call to canSustainPlant to your own checking code? @Override canBlockStay in MyCustomCactus.canBlockStay and you're laughing. -TGG /** * Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants. */ public boolean canBlockStay(World par1World, int x, int y, int z) { if (par1World.getBlockMaterial(x - 1, y, z).isSolid()) { return false; } else if (par1World.getBlockMaterial(x + 1, y, z).isSolid()) { return false; } else if (par1World.getBlockMaterial(x, y, z - 1).isSolid()) { return false; } else if (par1World.getBlockMaterial(x, y, z + 1).isSolid()) { return false; } else { int blockBeneathMe = par1World.getBlockId(x, y - 1, z); return blocksList[blockBeneathMe] != null && blocksList[blockBeneathMe].canSustainPlant(par1World, x, y - 1, z, ForgeDirection.UP, this); } }