Lab 4: Crystals and Infections

Objective

In lab 4, you will continue to create custom blocks. You will be creating a block and item that generate crystal towers of random height, and an "infection" block that infects the Minecraft world whenever a player draws near.

Notes

Test to see if a block is dirt

if (someBlock.equals(Blocks.dirt)) { ... }

Get block at location x, y, z.

Use Block block = world.getBlock(x, y, z).

Set block at location x, y, z.

Use world.setBlock(x, y, z, blockType).

Block types used in this lab:

  • Blocks.air
  • Blocks.gold_block
  • Blocks.coal_block
  • Blocks.leaves
  • Blocks.log

Set block step sound

This is the sound the block makes when you step on it: setStepSound(Block.soundTypeXXX).

Tasks

Part 1 — Create a crystal-growing block

For part 1, you will create a block that grows a crystal of random height, from 10 to 20 blocks above the base block.

  1. Create a new class that extends Block called CrystalGrowingBlock. The public constructor should accept a Material parameter that is passed to the super class. Set the creative tab CreativeTabs.tabBlock, and set the hardness to 40.0.
  2. In your BlocksModule class, register the new CrystalGrowingBlock with texture name "crystal_growing_block", using a new CrystalGrowingBlock instance with material Material.glass, with display name "Crystal Growing Block".
  3. Create a new class CrystalGrowingItem that extends Item. The public constructor takes no parameters, and just sets the creative tab to CreativeTab.tabTools.
  4. In ItemsModule.java, add an entry for CrystalGrowingItem, using texture name "crystal_growing_item", and display name "Crystal Growing Item".
  5. Implement the onItemUse(...) method of the new CrystalGrowingItem class. Here's the method signature: public boolean onItemUse ( ItemStack item, // Items in the player's inventory EntityPlayer player, World world, int x, int y, int z, // Location of block (can be air) the player clicked int side, // Cube face the player clicked float px, float py, float pz // Player's location in the world )

    In this method, get the block at the item use location. If it's a CrystalGrowingBlock, and if the block above is air, then pick a random crystal height from 10 to 20 above the CrystalGrowingBlock. Replace the blocks above the CrystalGrowingBlock with gold blocks, and replace the original CrystalGrowingBlock with coal.

  6. Always return true from the onItemUse function.

Part 2 — Quick Change to BlocksModule and ItemsModule

At this point, you have four custom block types (amethyst ore, battery block, checkered block, and crystal growing block) and two custom item types (rock sifter and crystal growing item). You can reference standard blocks like Blocks.coal_block or Blocks.air, but you cannot easily reference our own custom blocks. To help make this easier, you're going to refactor our code a bit. Code refactoring is the process of cleaning up, simplifying, or otherwise improving existing code without changing any functionality. For this change, you'll make it easier to reference our custom blocks and items.

  1. Open up ItemsModule.java in the editor. Add the following two declarations above the onLoad() method: public static final RockSifter rockSifter = new RockSifter(); public static final CrystalGrowingItem crystalGrowingItem = new CrystalGrowingItem();
  2. Now change the onLoad() method to use the new instance variables, like so: public void onLoad() { parentMod.itemRegistry.newInstance ( "rock_sifter", rockSifter, "Rock Sifter"); parentMod.itemRegistry.newInstance( "crystal_growing_item", crystalGrowingItem, "Crystal Growing Item"); }

  3. Now you're going to do the same for the BlocksModule class, which you'll find in src/tealsmc.mods/blocks. Use the same pattern as for the ItemsModule, where you declare an instance variable for each block instance, and refer to that instance variable in the newInstance call.
  4. At this point, you should be able to set a given world block to a BatteryBlock like so: world.setBlock(x,y,z, BlocksModule.batteryBlock);

Part 3 — Create an infection block

For part 3, you will create a block that spreads and infects neighboring blocks.

  1. For this new block, you'll need another new texture: infected_block.png. Get this image file from your instructor, and add it to src/main/java/resources/assets.tealsmodloader.textures/blocks.
  2. Create a new block InfectedBlock that extends Block. Just like for CrystalGrowingBlock, the InfectedBlock public constructor takes a Material parameter and passes it to the super class. When constructing the block object, set the material to Material.glass. The CreativeTab is CreativeTabs.tabBlock. For this block set the step sound (see the notes above) to Block.soundTypeCloth.
  3. Now add the new InfectedBlock to the BlocksModule class, using the new style of instance variables you converted to in part 2 of this lab. This will come in handy below when you may want to set a neighboring block to another infected block. The texture name for the infected block is "infected_block".
  4. You want the infected block to infect other blocks at random intervals in time. To do this, you will override the randomDisplayTick() method, which has the following signature: public void randomDisplayTick(World world, int x, int y, int z, Random random)

    For our purposes, you'll only use the world, x, y and z parameters.

  5. In the randomDisplayTick() method, select a random neighbor to the block: up to one unit away in X, Y or Z, or any combination (that is, any one of the 26 neighboring blocks).
  6. Don't infect air.
  7. Only infect blocks with a hardness less than 10.
  8. If you are ok to infect the neighboring block, change it to an InfectedBlock using the world.setBlock method and our BlocksModule.infectedBlock instance variable.
  9. Fire up Minecraft and test out the infected block. You should see the infection spread when you are in the area, and stop infecting once you're far enough away.