[Tutorial] Adding dispenser functionality

Discussion in 'Resources' started by epicfacecreeper, Dec 19, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    epicfacecreeper

    While trying to change how bonemeal works in dispensers, I came upon this semi-simple way to add/change what happens when items are dispensed. Semi-simple because it requires NMS.

    First of all, why not use BlockDispenseEvent? I found that this event does not give accurate information on the ItemStack when it is dispensed. (Custom name/lore, as well as metadata is lost). As this is probably a bug, this tutorial may become invalid when this is fixed.

    To add a behavior to a Dispenser, you must add an object to the BlockDispenser's registry, which is currently BlockDispenser.a. To add a mapping, you must call 'a' on this registry, which takes an NMS Item and an IDispenserBehavior. The method that is called in IDispenserBehavior is, unsurprisingly, 'a'. This takes an ISourceBlock, which is the dispenser, and an ItemStack, which is the item that is dispensed.

    To finish up, here is my code that changes how Bonemeal works in dispensers.
    Code:java
    1. BlockDispenser.a.a(net.minecraft.server.v1_7_R1.Item.d(351), new IDispenseBehavior() {
    2. @Override
    3. public net.minecraft.server.v1_7_R1.ItemStack a(ISourceBlock par1IBlockSource, net.minecraft.server.v1_7_R1.ItemStack par2ItemStack) {
    4. if (par2ItemStack.j() == 15) {
    5. EnumFacing var3 = BlockDispenser.b(par1IBlockSource.h());
    6. World var4 = par1IBlockSource.getTileEntity().getWorld();
    7. int var5 = par1IBlockSource.getBlockX() + var3.c();
    8. int var6 = par1IBlockSource.getBlockY() + var3.d();
    9. int var7 = par1IBlockSource.getBlockZ() + var3.e();
    10.  
    11.  
    12. if (par2ItemStack.hasName() && par2ItemStack.getName().equals(FERTILIZER_NAME)) {
    13. if (fertilize(par1IBlockSource.getTileEntity().getWorld().getWorld().getBlockAt(var5, var6, var7))) {
    14. par2ItemStack.count--;
    15. }
    16.  
    17. }
    18. else if (ItemDye.a(par2ItemStack, var4, var5, var6, var7)) {
    19. if (!var4.isStatic) {
    20. var4.triggerEffect(2005, var5, var6, var7, 0);
    21. }
    22. } else {
    23. //this.field_150838_b = false;
    24. //? Cannot grow
    25. }
    26.  
    27. return par2ItemStack;
    28. } else {
    29. return new DispenseBehaviorItem().a(par1IBlockSource, par2ItemStack);
    30. }
    31. }
    32. });


    Note: If you add a mapping for an item that is already in the registry, you will get a message on startup. AFAIK there is no other side effects.
     
  2. Offline

    Necrodoom

    Removed offtopic.
     
    epicfacecreeper likes this.
Thread Status:
Not open for further replies.

Share This Page