Minecraftmodcustomstuff Wiki
Advertisement

Simple Flower (CS2)?[]

2012-11-22 22.34

flowerBlock.js

id = config.getBlockId("newFlowerID");
name = "BlueFlower";
displayName[0] = "Blue Flower";
material = "plants";
stepSound = "grass";
hardness[0] = 0;
opacity[0] = 0;
drop[0] = "5002 1";
pick[0] = 5002;
hasCollision[0] = false;
addToCreative[0] = false;
textureFile = "textures.png"; 
textureIndexXP[0] = 3;
textureIndexXN[0] = 3;
textureIndexYP[0] = 3;
textureIndexYN[0] = 3;
textureIndexZP[0] = 3;
textureIndexZN[0] = 3;
onNeighborChange[0] = "position.y--;if(world.getBlockId(position) != 3 && world.getBlockId(position) != 2 && world.getBlockId(position) != 60){position.y++;world.harvestBlock(position);};";

flowerItem.js

name = "flowerItem";
displayName = "Blue Flower";
id = config.getItemIdProperty("blueFlowerItemID");
textureFile = "textures.png";
textureIndex = 3;
addToCreative = true;
creativeTab = "decorations";
maxStack = 64;
onUse = "if(side == 1 && (world.getBlockId(position) == 2 || world.getBlockId(position) == 3 || world.getBlockId(position) == 60)){position.y++;if(world.getBlockId(position) == 0){position.y--;player.placeBlock(position, side, config.getBlockId('newFlowerID'), 0, false);player.swingItem();if(player.isInCreative() == false){player.removeFromSlot(player.getCurrentSlot(), 1);}}";

mod.js

config.addBlockIdProperty("newFlowerID", 201);
config.addItemIdProperty("blueFlowerItemID", 5002);

mod.addBlock("flowerBlock.js", "crossTexture");
mod.addItem("flowerItem.js", "normal");


A similar approach to the 'Altered Wheat' example below would be as follows for CS2 (There are other ways of handling the block, I just prefer scripts for their flexibility):

cropMeat.js

name = "cropMeat";
id = config.getBlockId("cropMeat");
material = "grass";
stepSound = "grass";
creativeTab = "Testing Tab";
tickrate = 600;
displayName[0] = "Baby Meat Crop";
hardness[0] = 0.3;
resistance[0] = 15;
toolClass[0] = "pickaxe";
harvestLevel[0] = 0;
textureFileYP[0] = "cropMeat1.png";
textureFileYN[0] = "cropMeat1.png";
addToCreative[0] = false;
hasCollision[0] = false;
drop[0] = config.getItemId("seedMeat") + ":0 0-1"
onUpdate[0] = "mod.loadScript('cropGrow.js');"; 

displayName[1] = "Baby Meat Crop";
hardness[1] = 0.3;
resistance[1] = 15;
toolClass[1] = "pickaxe";
harvestLevel[1] = 0;
textureFileYP[1] = "cropMeat2.png";
textureFileYN[1] = "cropMeat2.png";
addToCreative[1] = false;
hasCollision[1] = false;
drop[1] = config.getItemId("seedMeat") + ":0 0-1"
onUpdate[1] = "mod.loadScript('cropGrow.js');"; 

displayName[2] = "Baby Meat Crop";
hardness[2] = 0.3;
resistance[2] = 15;
toolClass[2] = "pickaxe";
harvestLevel[2] = 0;
textureFileYP[2] = "cropMeat8.png";
textureFileYN[2] = "cropMeat8.png";
addToCreative[2] = false;
hasCollision[2] = false;
drop[2] = config.getItemId("seedMeat") + ":0 1-3"
onBreak[2] = "mod.loadScript('dropMeat.js');";

mod.js

config.addBlockIdProperty("cropMeat", 600);
mod.addBlock("cropMeat.js", "wheat");

You can have as many metadata entries as you please, I've shortened my example to 3 from my original 8 for the sake of space. Now, for this example, two additional files are being called. One is the script to grow the plant to the next stage, and one is to tell the block what it will drop when it breaks: cropGrow.js

if(Math.floor(Math.random()*10) < 2)
{
     world.setBlockMetadata(position, world.getBlockMetadata(position) + 1)
}

Because this does not at any point reference the original block, this script can be called by any number of blocks simultaneously.

In layman's terms, cropGrow.js says the block has a 20% (2 in 10) chance of triggering per block update. The block calling this script has a tickrate of 600, meaning it updates every 600 ticks, or every 30 seconds.


dropMeat.js

if(Math.floor(Math.random()*100) < 75)
{
     world.spawnItem(position, 363, 1, 0);
}
if(Math.floor(Math.random()*100) < 75)
{
     world.spawnItem(position, 319, 1, 0);
}
if(Math.floor(Math.random()*100) < 75)
{
     world.spawnItem(position, 365, 1, 0);
}

Each item in this list (raw beef, porkchop, and chicken) has an independant 75% (75 in 100) chance of dropping 1 item where the block was.

In addition to the wheat, here is an updated (albeit slightly modified) version of the 'Modified Seed' from the CS1 tutorials below:


meatSeed.js

name = "seedMeat";
displayName[0] = "Meat Seed";
id = config.getItemId("seedMeat");
textureFile[0] = "seedMeat.png";
addToCreative[0] = true;
creativeTab = "Materials";
full3d = true;
onRightClick[0] = "player.setItemInUse();";
onRightClick[0] = "player.swingItem();";
onUse[0] = "if(side == 1 && (world.getBlockId(position) == 2 || world.getBlockId(position) == 3)) {position.y++;if(world.getBlockId(position) == 0){world.setBlockId(position, config.getBlockId('cropMeat'));player.removeFromSlot(player.getCurrentSlot(), 1);}}";

mod.js

config.addItemIdProperty("seedMeat", 10000);
mod.addItem("seedMeat.js", "normal");

The first onRightClick calls the onUse function, the second onRightClick simply makes the player swing the item like it would for a normal seed (Thanks to Flamarow for pointing this function out). The onUse line does a few things. It checks the top surface of the block you are trying to plant the crop on, as well as the block above it, to make sure you're placing it on dirt or grass with an empty space above for the plant. It then places the cropMeat block (in metadata 0 form) on the block, and removes one seed from your inventory.


CS1 Custom Stuff 1

Information presented below this line is outdated syntax or information used for Custom Stuff 1. It will not work with Custom Stuff 2.

Single Block Plants[]

This is a block such as wheat or netherwart that can be grow within one block. Unfortunately, at the time of writing, the closest block type for plants is the crosstexture block type. Another problem is that almost every block that is placed on farmland (tilled dirt) causes the farmland to instantly turn back into regular dirt, regardless of how hydrated the block is. Also, any crops made in game will look more like tall grass rather than be square like wheat.

Warning: Some users might not see the plant's growth without placing a block next to the plant. This may be caused by optifine or any number of other reasons.

Code for Altered Wheat item[]

First I will start out simple by showing you the code for the grown harvested item form of altered wheat. Vanilla wheat could be used instead of making your own custom wheat, but this will be included in the example to show an example for how to make loot for other custom plants.

name = "Altered Wheat";
id = 447;
iconfile = "gui/items.png";
iconindex = 25;
type = "food";
maxstack = 64;
healamount = 1;
saturation = 1;

There should not be anything that needs too much explaining. I made the item as a food type so the player could, in an emergency, eat the raw wheat for half a heart of hunger and saturation. You could also make a recipe using the altered wheat to make vanilla bread or any other item.

Code for Altered Wheat Seeds[]

Next will be the code for the actual seeds for planting the altered wheat. Although it doesn't need to be a seperate item from the fully grown form of the plant, this example will include it so that it can show how to include multiple drops from fully grown plants.

name = "Altered Wheat Seeds";
id = 446;
iconfile = "gui/items.png";
iconindex = 9;
type = "normal";
maxstack = 64;
rightclick = "if(side == 1 && (world.getBlockId(origin) == 2 || world.getBlockId(origin) == 3)) {origin.y++;if(world.getBlockId(origin) == 0){world.setBlockId(origin, 173);player.removeFromInventory(446, 1, 0);}}";

The most important part here is the rightclick event. It first checks if the top of the block was right clicked and if the block right clicked was either dirt or grass. If both are true, it will check for space to place the block form, then place the wheat block, removing 1 seed from your inventory.

Code for Altered Wheat block[]

Most of the code in this section is basic information, but takes a fairly large amount of room. The more difficult parts in the code will be individually explained in the sections below. If you want to see the full version, click show to see the full altered wheat block.

Now to explain the various difficult parts of the code. I will start by explaining the update event. There are actually two different sets of update events in this code. I will start with the one for damage value 0 through 6 for the growth cycle.

update = "customstuff.loadScript('singleplant.script');";

This one is the easiest to understand. It simply calls a script file to execute code within it. If you want more information about the script, it will have its own section farther down.

Next is the update event for damage value 7, the fully grown version.

update7 = "origin.y--;if(world.getBlockId(origin) != 2 && world.getBlockId(origin) != 3){origin.y++;world.harvestBlock(origin);world.spawnItem(origin, 447, Math.floor(Math.random()*3+1), 0);}else{origin.y++;}";

This is a mixture of some code from the singleplant.script and from the final destroyed event, covered later. This event causes the block to be broken if it is ever found floating or on any block other than dirt or grass, giving both the seeds asked for by iddropped as well as the item version of wheat dropped by the destroyed event.

Since I just methoned the destroyed event, we might as well cover it next.

destroyed7 = "world.spawnItem(origin, 447, Math.floor(Math.random()*3+1), 0)"

This event only affects the block with damage value of 7 because only one item can be dropped using iddropped attribute. This code makes the fully grown wheat block randomly drop between 1 and 3 of the custom wheat. You could just replace 447 with blockID.WHEAT if you just wanted to have it drop vanilla wheat, but this code could easily be used for any other plant type, so an example for custom wheat was included.

Next up is the code for the rightclicked event. This event is only used for damage values 0 to 6.

rightclicked = "if(player.getItemId(player.getCurrentSlot()) == 351 && player.getItemDamage(player.getCurrentSlot()) == 15){world.setBlockMetadata(origin, 7);}";

This event checks if the player just right clicked the plant with bonemeal in hand and if so, takes the bone meal and makes the plant instantly grow to mature form, just like in vanilla.

Next up is the neighbor changed event. This is used for all 7 damage values, each specified individually as usual.

neighborchanged = "customstuff.loadScript('floodcheck.script');"

Again, this script just calls a script, this time for checking for nearby liquids. The script needs some improvement but for now it works well enough. For now, you can find the code later on in the Flood Detection section.

And that appears to be all for the events. Next will be the code for the two scripts metioned earlier.

Code for singleplant.script[]

var singleplantid = world.getBlockId(origin);
var plantAge = world.getBlockDamage(origin);

origin.y--;
if(world.getBlockId(origin) != 2 && world.getBlockId(origin) != 3)
{
	origin.y++;
	world.harvestBlock(origin);
}
else
{
	origin.y++;
	if(Math.floor(Math.random()*100) < 20)
	{
		plantAge++;
		world.setBlockMetadata(origin, plantAge);
	}
}

This code is simple enough, but I will break it down anyways to explain various parts. First will be the variables.

var singleplantid = world.getBlockId(origin);
var plantAge = world.getBlockDamage(origin);

These detect what the plant is, and what stage of growth it is in. This allows the code to work for multiple different plants. The code even works for any number of growth stages, as long as the fully grown version does not call the event.

Next code to detect if the block is somehow floating or on the wrong block.

origin.y--;
if(world.getBlockId(origin) != 2 && world.getBlockId(origin) != 3)
{
     origin.y++;
     world.harvestBlock(origin);
}

This causes the code to check the block under the plant to see if it is dirt or grass, if it is neither of these then the plant will be broken, dropping whatever is defined in iddropped.

Next is the actual code for plant growth.

else
{
     origin.y++;
     if(Math.floor(Math.random()*100) < 20)
     {
          plantAge++;
          world.setBlockMetadata(origin, plantAge);
     }
}

Because of the else, it will only activate if the previous code in the if statement was activated, this block of code will be ignored. The origin.y++ is just to get the origin back to targeting the plant. It then has a 20% chance to make the plant grow to the next stage of the plant's growth cycle.

Code for Flood Detection[]

This script makes the plant break if water is directly next to, below, or above the plant. It will, unfortunately, not detect if the water actually would flow into the block the plant occupies, but until another method is found, this is the method that will be used in this guide. Also, this can also be used for the other types of plants on this page.

First, we need to add the following lines to the .block file to call the script.

neighborchanged = "customstuff.loadScript('floodcheck.script');"
neighborchanged1 = "customstuff.loadScript('floodcheck.script');"
neighborchanged2 = "customstuff.loadScript('floodcheck.script');"
neighborchanged3 = "customstuff.loadScript('floodcheck.script');"
neighborchanged4 = "customstuff.loadScript('floodcheck.script');"
neighborchanged5 = "customstuff.loadScript('floodcheck.script');"
neighborchanged6 = "customstuff.loadScript('floodcheck.script');"
neighborchanged7 = "customstuff.loadScript('floodcheck.script');"

If your plant uses more than 8 states, just continue adding additional. If it has less stages, then remove the unneeded events. Next, we want the code for the actual floodcheck.script which is shown below.

var checkedBlockId;
for(var sideCheck = 0;sideCheck < 6;sideCheck++)
{
   switch(sideCheck)
   {
   case 0:
       origin.y--;
       checkedBlockId = world.getBlockId(origin);
       origin.y++;
       break;
   case 1:
       origin.y++;
       checkedBlockId = world.getBlockId(origin);
       origin.y--;
       break;
   case 2:
       origin.z--;
       checkedBlockId = world.getBlockId(origin);
       origin.z++;
       break;
   case 3:
       origin.z++;
       checkedBlockId = world.getBlockId(origin);
       origin.z--;
       break;
   case 4:
       origin.x--;
       checkedBlockId = world.getBlockId(origin);
       origin.x++;
       break;
   case 5:
       origin.x++;
       checkedBlockId = world.getBlockId(origin);
       origin.x--;
       break;
   }
   if(checkedBlockId == 9 || checkedBlockId == 8 || checkedBlockId == 10 || checkedBlockId == 11)
   {
       world.harvestBlock(origin);
       break;
   }
}

The for loop increments the variable sideCheck by 1 until it is 6 or bigger. This same variable is used to decide which side of the block to check using the switch function. The case # activates when sideCheck is equal to the # of the case.

The block ID is then checked and stored in the variable 'checkedBlockId' to be tested later in the for loop. If checkedBlockId is equal to any of the liquids in the if conditions, then the plant will be harvested (without setting off destroyed event) and the loop will stop without continuing the checks.

Three Block Tall Plants[]

SugarCane

Sugar Cane, and a lot of it.

This is a plant like cactus and sugar cane that will grow to a height of 3 meters by stacking on itself. To make sure that this item can only be placed on certain blocks such as grass, dirt, and itself, an item form is required with a rightclick option.

Code for SugarCane.item[]

name = "Sugar Cane";
id = 448;
iconfile = "gui/items.png";
iconindex = 27;
type = "normal";
maxstack = 64;
rightclick = "if(world.getBlockId(origin) == 2 || world.getBlockId(origin) == 3 || world.getBlockId(origin) == 171){origin.y++;if(world.getBlockId(origin) == 0){world.setBlockId(origin, 171);player.removeFromInventory(448, 1, 0)}}";

Most of this except for the rightclick event should be fairly self-explanatory by now, but if not, check out the normal item type page. The rightclick event first uses an if statement to determine if you have right clicked on grass, dirt, or the plant that the item represents. An odd functionality of bit of script is that the block form will appear on top of the valid block, even if the side of the block was clicked. If clicked block is valid, the block form of the item (171 in this example) will be placed on top of the block and one of the item will be removed from the player's inventory.

Code for SugarCane.block[]

​name = "Sugar Cane";
id = 171;
damagevalues = 15;
texturefile = "terrain.png";
textureindex = 73;
type = "crosstexture";
material = "cloth"
stepsound = "grass"
hardness = 0.1;
opacity = 0;
iddropped = 448;
damagedropped = 0;
quantitydropped = 1;
collision = "false";
addtocreative = false;
tickrate = 20;
update = "customstuff.loadScript('threetallplant.script');";

name1 = "Sugar Cane";
textureindex1 = 73;
iddropped1 = 448;
damagedropped1 = 0;
quantitydropped1 = 1;
hardness1 = 0.1;
addtocreative1 = false;
update1 = "customstuff.loadScript('threetallplant.script');";

[removed for space all same as damage value 1 and 15]

name15 = "Sugar Cane";
textureindex15 = 73;
iddropped15 = 448;
damagedropped15 = 0;
quantitydropped15 = 1;
hardness15 = 0.1;
addtocreative15 = false;
update15 = "customstuff.loadScript('threetallplant.script');";

The whole block file can be found in the hidden text below. Press show to see the full thing.

If you do not know what any of these properties other than tickrate and update is, then please refer to the Normal block type page for now. Not all of the attributes above are required but it is a good idea to set them anyways. The iddropped attribute is especially important if you are using an item to place the block. Tickrate is an attribute that determines how often the block is updated. When set to 20 ticks like in this example, it will updated about once ever second. Changing this to be longer might decrease lag if this plant is used in large amounts, but it will also slow down its growth unless you change the chance to grow in the script below.

The script accessed by the update events is used to check if the block is in a valid location, and to give a random chance to age. The script will also make test if the plant is allowed to grow upward based on how tall the plant currently is, and if anything is above it.

Code for threetallplant.script[]

var tallplantid = world.getBlockId(origin);
var plantAge = world.getBlockDamage(origin);

origin.y--;
if(world.getBlockId(origin) != 2 && world.getBlockId(origin) != 3 && world.getBlockId(origin) != tallplantid)
{
   origin.y++;
   world.harvestBlock(origin);
}
else
{
   origin.y += 2;
   if(world.getBlockId(origin) != 0)
   {
      origin.y--;
   }

   else if(Math.floor(Math.random()*100 + 1) > 95)
   {
      origin.y--;
      plantAge++;
      world.setBlockMetadata(origin, plantAge);
	
      if(plantAge == 15)
      {
         world.setBlockMetadata(origin, 0);
         origin.y--;
         if(world.getBlockId(origin) == tallplantid)
         {
            origin.y--;
	    if(world.getBlockId(origin) != tallplantid)
            {
               origin.y += 3;
               if(world.getBlockId(origin) == 0)
               {
               world.setBlockId(origin, tallplantid);
               }
            }
         }
         else
         {
            origin.y += 2;
            if(world.getBlockId(origin) == 0)
            {
               world.setBlockId(origin, tallplantid);
            }
         }
      }
   }
}

This is where things start to get a bit tricky so I will try to break the script down into parts. Some of this information will be repeats from the one block plants section when it is finished, but I will leave the full explaination here anyways in case some people skip to this section.

var tallplantid = world.getBlockId(origin);
var plantAge = world.getBlockDamage(origin);

Let us first start with this part of code. We are declaring two variables, tallplantid and plantAge, and immediately setting a value to them using the getBlockId and getBlockDamage functions. Tallplantid is used in the function to determine which plant is calling the script, making the same script file work for several three tall plants. The plantAge is used in the script to make changing the damage values similar to how vanilla sugar cane works.

origin.y--;
if(world.getBlockId(origin) != 2 && world.getBlockId(origin) != 3 && world.getBlockId(origin) != tallplantid)
{
   origin.y++;
   world.harvestBlock(origin);
}

Now on to the part of the script that makes sure you do not end up with sugar cane on netherrack from being moved somehow or floating in midair after harvesting. the if() statement will check the block below the plant that called the script. If the block is not grass(2), dirt(3), or another plant(tallplantid), then it will harvest the plant that called the script and drop whatever id value the block file says to drop. It is interesting to note that if the check for tallplantid is not included, the second level plant will automatically harvest shortly after being created, making an automatic farm. After this is a larger chunk of code, but I will try to split it up as best as I can.

​else
{
   origin.y += 2;
   if(world.getBlockId(origin) != 0)
   {
      origin.y--;
   }

   else if(Math.floor(Math.random()*100 + 1) > 95)
   {
      origin.y--;
      plantAge++;
      world.setBlockMetadata(origin, plantAge);

This else statement will activate if the earlier if determined that the plant is still on a valid block (the if statement did not harvest). The origin is then moved above the plant that called the script and check if there is something directly above it. This statement also keeps the plant ready to start the cycle again if the block above it is broken. If no block is above the plant, it will continue to the else if() statement. The code inside the parentheses generates a random number between 1 and 100 and checks if it is greater than 95, giving a 5% chance for the else if() statement to activate. If it successfully activates, the plant that called the script will increase its damage value by 1, effectively "aging" the plant. To show that the next part is still in the same else statement, the else if() statement will be included again.

   else if(Math.floor(Math.random()*100 + 1) > 95)
   {
      origin.y--;
      plantAge++;
      world.setBlockMetadata(origin, plantAge);
	
      if(plantAge == 15)
      {
         world.setBlockMetadata(origin, 0);
         origin.y--;
         if(world.getBlockId(origin) == tallplantid)
         {
            origin.y--;
	    if(world.getBlockId(origin) != tallplantid)
            {
               origin.y += 3;
               if(world.getBlockId(origin) == 0)
               {
               world.setBlockId(origin, tallplantid);
               }
            }
         }
         else
         {
            origin.y += 2;
            if(world.getBlockId(origin) == 0)
            {
               world.setBlockId(origin, tallplantid);
            }
         }
      }
   }
}

After the plant is aged, an if() statement is used to check if the plant now has a damage value of 15. If this is true, the plant's damage value will be reset to 0 so that it is simpler to start the cycle again after the new growth is harvested. After that, the If() statements all check blocks above and below the plant that called the script to determine if it is allowed to grow. It is allowed to grow only if it does not have two of itself below it AND has room to grow above it. Currently the code will constantly cycle the top plant block's damage value from 0 to 15 if there is no block above it but the total plant height is 3 meters.

Tall Flowering Plant[]

The following is designed based on a request for a "sunflower" style of plant that grows two blocks tall. The bottom block being a "stem" and the top block being a "flower". Most of the script is based on the single tall plant script, so minimal explainations will be provided.

To begin with, the only changes to the block file is to add more damage values to be used for the "flower" version of the plant. For this example, 8 stages (damage values) are used for the stem, and 4 are used for the flower, making 12 total stages (damagevalues = 11;).

The update events for these 12 stages will look like this:

update = "customstuff.loadScript('floweringtallplant.script');";
update1 = "customstuff.loadScript('floweringtallplant.script');";
update2 = "customstuff.loadScript('floweringtallplant.script');";
update3 = "customstuff.loadScript('floweringtallplant.script');";
update4 = "customstuff.loadScript('floweringtallplant.script');";
update5 = "customstuff.loadScript('floweringtallplant.script');";
update6 = "customstuff.loadScript('floweringtallplant.script');";
update7 = "origin.y--;if(world.getBlockId(origin) != 2 && world.getBlockId(origin) != 3){origin.y++;world.harvestBlock(origin);world.spawnItem(origin, 447, Math.floor(Math.random()*3+1), 0);}else{origin.y++;}";
update8 = "customstuff.loadScript('floweringtallplant.script');";
update9 = "customstuff.loadScript('floweringtallplant.script');";
update10 = "customstuff.loadScript('floweringtallplant.script');";
update11 = "var plantid = world.getBlockId(origin);origin.y--;if(world.getBlockId(origin) != 2 && world.getBlockId(origin) != 3 && world.getBlockId(origin) != planttid){origin.y++;world.harvestBlock(origin);world.spawnItem(origin, 447, Math.floor(Math.random()*3+1), 0);}else{origin.y++;}";

Refer to the single tall plant section for more information about the rest of the block properties and other related items.

Note that if the script fails to place the flower form upon reaching damage value of 8, then it will not make the flower at all.

Code for floweringtallplant.script[]

var plantid = world.getBlockId(origin);
var plantAge = world.getBlockDamage(origin);
var flowerstage = 8;

origin.y--;
if(world.getBlockId(origin) != 2 && world.getBlockId(origin) != 3 && world.getBlockId(origin) != planttid)
{
    origin.y++;
    world.harvestBlock(origin);
}
else
{
    origin.y++;
    if(Math.floor(Math.random()*100) < 20)
    {
        plantAge++;
        world.setBlockMetadata(origin, plantAge);
        if(plantAge == (plantstage - 1) && world.getBlockId(origin) == plantid)
        {
            origin.y++;
            if(world.getBlockId(origin) != 0)
            {
                world.setBlockIdAndMetadata(origin, plantid, flowerstage);
            }
        }
    }
}

More scripts related to plants can be found in other sections. More information might be added later once I have more time.

Vine Grown Plants[]

This type of plant is similar to how a pumpkin grows from a vine. Currently, I have not figured out a way to make the stem lean to only the blocks that are adjacent to it. More testing, and maybe a new feature, will be needed before the stem can be made visually correct. For now, just make a crosstexture stem that reaches to all 4 blocks regardless of if there is anything there.

As for the code, I will just list script related stuff. Follow the code for single block plant exactly EXCEPT for the following parts.

The only real change to the single block plant's block file is the last update event. If you have 8 stages of growth (damagevalues = 7), then your update events will look like this.

update = "customstuff.loadScript('singleplant.script');";
update1 = "customstuff.loadScript('singleplant.script');";
update2 = "customstuff.loadScript('singleplant.script');";
update3 = "customstuff.loadScript('singleplant.script');";
update4 = "customstuff.loadScript('singleplant.script');";
update5 = "customstuff.loadScript('singleplant.script');";
update6 = "customstuff.loadScript('singleplant.script');";
update7 = "var placechance=5;var fruitid=103;var fruitdamage=0;customstuff.loadScript('stemfruit.script');";

Notice that you can set the chance to bear fruit (or whatever your stem places) as well as the id and damage values for your fruit block. This is currently set to vanilla melons but it can be changed to whatever you want it to be.

Code for stemfruit.script[]

origin.y--;
if(world.getBlockId(origin) != 2 && world.getBlockId(origin) != 3)
{
    origin.y++;
    world.harvestBlock(origin);
}
else if(Math.floor(Math.random()*100 < placechance))
{
    origin.y++;
    randomside = Math.floor(Math.random()*4+2);
    
    switch(randomside)
    {
    case 2:
        origin.z--;
        placeFruit();
        origin.z++;
    case 3:
        origin.z++;
        placeFruit();
        origin.z--;
    case 4:
        origin.x--;
        placeFruit();
        origin.x++;
    case 5:
        origin.x++;
        placeFruit();
        origin.x--;
    }
}

function placeFruit()
{
    if(world.getBlockId(origin) == 0)
    {
        lowerblock = world.getBlockId(origin.x, origin.y-1, origin.z);
        if(lowerblock == 2 || lowerblock == 2)
        {
            world.setBlockIdAndMetadata(origin, fruitid, fruitdamage);
        }
    }
}

You should not have to change anything inside of this script. This will allow you to use this script for multiple pumpkin and melon style plants. Just make sure to set the values shown in the update values section.


Ice dragon (Shrunken)
Flamarow The flames of tomorrow consume everything. — 20:51, February 8, 2012 (UTC)
Thank you for reading this article, if you have any questions or comments about this page, please feel free to leave a comment. If you find a better way to go about the code above or even just a better way of explaining it, feel free to make changes to the page.
Advertisement