Jump to content

coolAlias

Members
  • Posts

    2805
  • Joined

  • Last visited

Posts posted by coolAlias

  1. If you want your entire model to be semi-transparent, you don't need any extra layers. Instead, you want to make those same GL11 calls (the ones you see in Slimes) before your model renders, and make sure your model texture has an alpha layer (you can do this in your photo-editing software, such as GIMP).

     

    Just make sure to disable/re-enable whatever settings you changed after you are done - best way is this:

    GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
    // make your GL setting change, e.g. enable alpha transparency
    // render your model and all that jazz
    GL11.glPopAttrib();
    

  2. The thing is, if you cancel the RIGHT_CLICK_BLOCK event, it sets 'useBlock' to false, so the #onBlockActivated method gets skipped and returns false, allowing the Item's (Eye of Ender) #onItemRightClick function to be called, spawning in the entity.

     

    Since you are concerned about vanilla blocks, one solution would be to focus instead on the client-side and subscribe to MouseEvent and KeyInputEvent, check for keyUseItem, and do some preprocessing before allowing the click to proceed.

     

    As mentioned earlier, the event is literally fired constantly while right-click is pressed, so you WILL be getting the event firing potentially dozens of times, though usually only once or twice. Stopping the client-side key input that triggers this would allow you to limit this to once per click (i.e. by unsetting the key after it is pressed, so continuing to hold it down does not send any further input).

     

    We could probably better assist you if you provided some actual details on what exactly you are trying to accomplish, as in your first post it sounded like you were interested in handling interactions with your block.

     

    What exact interaction are you trying to prevent? Just spawning eyes of ender? Use EntityJoinWorldEvent and cancel for any EntityEnderEye that you encounter. If it's something else, please elaborate.

  3. Thanks... But how do i make it so getHeldItem() is not null?

    You DON'T. You can't help it if a player clicks with nothing in their hand, but you CAN check for it. Null-checking is a very basic concept which you seem to sort of understand, but you are checking the wrong object for null:

    object.method() <-- this will crash if the object is null
    
    player.getHeldItem() <-- returns an ItemStack, or possibly null if not holding anything; would crash if player was null (null.getHeldItem() fails)
    
    player.getHeldItem().getItem() <-- returns the Item contained in the ItemStack, thus it crashes if getHeldItem() returns null instead of an actual ItemStack (player.null.getItem() ... yeah, nope)
    
    player.getHeldItem().getItem().method() <-- would crash if Item returned from getItem() was null, but that should never be the case
    

    If at any time an object (such as player, or the result of a method such as getHeldItem()) is possible to be null, you need to null-check or you WILL crash when that object is null and you try to access a class field or method using it.

  4. Only thing I can think of is that the action packet got sent twice - this happens sometimes, since when the player right clicks, if it is held down a little bit it continuously tries to right-click action on the block. No idea why it would give you bedrock, though.

     

    Try printing out the BlockPos in addition to the Block name, or activate your portal while in debug mode to get a better idea of what exactly is going on.

     

    Do you really need to use the event, though? Why not use Block#onBlockActivated instead? It's your block, after all, right?

  5. There are 2 components to this question: one is the block as seen when placed, and the other is the block as seen when in your inventory / held.

     

    The first is the simplest: you make your block as normal, give it a TileEntity that can store a Block and meta value pair, then in your ISimpleBlockModel you fetch the extended state of your block to get the IBlockState to render. It would look something like this:

    @Override
    public IBakedModel handleBlockState(IBlockState state) {
    if (state instanceof IExtendedBlockState) {
    	IBlockState renderState = ((IExtendedBlockState) state).getValue(BlockDungeonStone.RENDER_BLOCK);
    	if (renderState != null) {
    		IBakedModel renderModel = mc.getBlockRendererDispatcher().getBlockModelShapes().getModelForState(renderState);
    		if (renderModel instanceof ISmartBlockModel) {
    			renderModel = ((ISmartBlockModel) renderModel).handleBlockState(renderState);
    		}
    		return renderModel;
    	}
    }
    return defaultModel;
    }
    

     

    For the block as an item, you need an ISmartItemModel along with your custom ItemBlock - the ItemBlock should be able to store whatever BlockState is necessary to recreate the Block + TileEntity you place in the world, and should also have a way to switch textures such as sneak+right-clicking on a block with it in your hand, depending of course on how you want your block to work.

     

    To register your block with a custom model, you need to use the ModelBakeEvent. TheGreyGhost's MinecraftByExample project has some examples that should prove helpful.

  6. You are making the code way more convoluted than you need to: why use a List at all, when you are already iterating over positions? Make your iteration logic do the work.

     

    Another thing - if you are going to use the position above the current one, use pos.up() once as an assignment, like so:

    // or however you want to check if it's a log, perhaps there's a Forge method
    while (world.getBlockState(pos).getBlock() instanceof BlockLog) {
       // destroy the block
       world.destroyBlock(pos, true);
    
       // this is also where you should check the surrounding blocks
       // but those can also be long branches, so you should probably come up with a better system than this
       // which only goes up and possibly one block to each side (I'm not writing that, though)
    
       // finally move up one position
       pos = pos.up();
    }
    

     

    Also, check your code for errors - you surely meant to use == here:

    if(stop = false)
    

    And be careful using .equals - that's usually not what you want.

  7. If you set the block hardness to -1, then no one, even with tools, will ever be able to harvest ANY of that kind of block. This is because blocks are singletons, so if you change a value for one, you've changed the value for all.

     

    As for events like BreakSpeed - these do not of themselves slow performance by any noticeable amount, but if you subscribe to one and put it resource-intensive code, such as many nested for loops or recursion over a large area, then yes, you might cause some performance issues. If you keep your code lean, however, you likely won't notice at all.

     

    BreakSpeed has to be called basically every tick because things may change - the player's tool may change, the block may change, the player may gain a potion effect or other change, etc. - and all of these may affect the break speed. If you just calculated it once, you wouldn't always have an accurate speed.

     

    As TGG mentioned, LEFT_CLICK_BLOCK in the PlayerInteractEvent is a good bet, but the trouble with it is that it is only called on the server, so you may still get some glitches on the client.

     

    To fix that, you'd need to subscribe to MouseEvent and KeyInputEvent (in case player changes the use-item key to non-mouse) - these both fire on the client; when they do, if it's the use-item key, check if the current mouseover object is a log block, check the player's current held item, and cancel the event if they don't match. This will prevent the player from clicking the block and starting to break it at all, which unfortunately will also prevent the animation.

     

    Honestly, using BreakEvent, while it does give you that visual glitch where the block disappears briefly, may not be that bad. Annoyingly imperfect, but it gets the job done.

  8. The Skeleton's ranged attack doesn't use the attribute system:

    entityarrow.setDamage((double)(p_82196_2_ * 2.0F) + this.rand.nextGaussian() * 0.25D + (double)((float)this.worldObj.getDifficulty().getDifficultyId() * 0.11F));
    

    Way to make the code consistent, Mojang -.-

     

    So yeah, all (?) melee mobs should work fine, but ranged ones you may have to use the LivingHurtEvent, and that could get messy.

  9. That looks correct... and you are sure the method is getting called, i.e. you registered the event listener to the Forge EVENT_BUS ?

     

    Have you been printing out the damage inflicted from LivingHurtEvent? Best to do so only for players, otherwise your console will get spammed, but that will let you verify whether the damage is increasing or not. If not, how do you know it's not working?

     

    Just for reference, attribute modifier operations are:

    0: simply adds a flat amount to the total

    1: adds (amount * current total) to the total

    2: multiplies current total * (1 + amount)

  10. Instead of making all of those static methods in Registry, move them into your ClientProxy and make them non-static, at least all of the ones that access client-only classes such as the one registering custom state mappers.

     

    The way you have it now, even if you only access those methods from the client side, the Registry class still tries to load all of the classes on the server because it thinks it will need them.

  11. The simplest solution would probably be to use a recursive method. Assuming your blocks store their orientation (e.g. UP = next block is up), this would be trivial, but you'll need a wrapper for the coordinates to make it simpler (I'll use BlockPos from 1.8, but it's easy to make your own or use e.g. Vec3i):

    /**
    * Assume that you know the beginning block, and x/y/z are the coordinates of that block
    * @return wrapped x/y/z coordinates of the final block
    */
    public BlockPos findEnd(World world, int x, int y, int z, BlockPos last) {
        Block block = world.getBlock(x, y, z);
        if (block != this) { // important to have a condition to end the recursion 
            // return new BlockPos(x, y, z); // this is the position that the player should come out at
            return last; // this way you still have the orientation information
        }
        int facing = world.getBlockMetadata(x, y, z); // or ForgeDirection - use EnumFacing in 1.8
        switch (facing) { // I'm using names for the cases, but you'd probably be using 0, 1, etc. in 1.7.10
        case UP: return findEnd(world, x, y + 1, z, new BlockPos(x, y, z));
        case DOWN: return findEnd(world, x, y - 1, z, new BlockPos(x, y, z));
        // etc.
        }
    }
    

    Those may not be accurate method names - I'm just writing from memory - but that's the idea. Pretty straightforward, and you can even have side-by-side tubes and they won't get mixed up.

     

    Then once you've found the ending position (which isn't actually one of your blocks), you need to figure out if it is suitable to teleport there (i.e. there are air blocks) and whether to move the player up or down one more block - this may be easiest if you return the last block position containing your block so that you can still have the orientation information.

  12. It still works fine, you just have to supply all of the parameters.

    public static final ArmorMaterial NEW_MATERIAL = EnumHelper.addArmorMaterial("NewMaterial", "FakeTexture", 5, new int[] {1,3,2,1}, 5);
    

    Why are you making a (poorly named) getter method for your material when it is already public and static?

     

    As for the rest of the classes, if you had it working in 1.7.10 and you know how the 1.8 modeling system works, it shouldn't be that difficult to update.

  13. That's what I was getting at earlier - you can't access the server from the client side. Single player you can fudge around this, but you shouldn't even be trying to access the integrated server from the logical client side, such as from a GUI.

     

    To access other players on the server, you have to have code running on the server, and send a packet from you to the server, then from the server to the other player. Or have the server send your GUI a list of players in the world to select from, and then you have a reference to that player.

     

    You might be able to get away with trying to fetch the player instance by username (let the player type it into the GUI or something) via mc.theWorld.getPlayerEntityByName. I have never tried using that client side, though, but I'd imagine it must work otherwise you couldn't see other players' names and the like.

×
×
  • Create New...

Important Information

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