Jump to content

[1.8.9] Re: Arrays of Blocks, Items, etc


kramlat

Recommended Posts

I am planning a very unique mod, called Customcraft (allows you to create custom blocks, biomes, items, entities, etc from inside minecraft while loaded by commands, textures and locale would use a resource pack to apply if the names are totally custom) and I have a question.  What is the max number within reason that one could have of blocks, items, biomes, entities, and dimensions loaded by a mod without a crash?

 

 

This will help with construction of an array to avoid pointers.

Link to comment
Share on other sites

4096 is the limit on blocks, from vanilla plus all loaded mods.

I think the item limit is 32,000ish.

Biomes are limited to 255, IIRC.

Mobs are limited to 255 per mod.

Dimensions are effectively unlimited (Mystcraft and RF Tools both allow players to create dimensions).  The dimension ID is a signed integer.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

thanks, that is exactly what I asked for.  I guess it is time to make the array structures (will declare static final so that preinit() can do the work of defining all that stuff and load() can do the saved registrations, and also I can use an index to push new blocks into the array and register them at runtime.

 

Mobs are limited to 255 per mod.

Not true. Mod entities can use the complete integer range.

char, short, or long?
Link to comment
Share on other sites

Not true. Mod entities can use the complete integer range.

 

Huh.  Never looked into it, I guess.

 

char, short, or long?

 

Integer, which is 32 bits.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Block ids are from 256 (below is minecraft) to 4096, so 3840 in total.

Item ids are from 4096 to 32767, so 28671 in total.

 

Side note: some of these limits can be raised, but require hell lot of bytecode manipultions and frequently cause severe compatibility problems.

Link to comment
Share on other sites

Save the config to a static variable in your main class.

Access it from anywhere.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Save the config to a static variable in your main class.

Access it from anywhere.

Already did that, just how do you write to it.  There is an overloaded get() function, but not an overloaded set() method. I also indexed all of Materials and SoundTypes with ints the main class. by indexed with ints I mean I used an int value and a switch / case structure that assigns existing Materials and SoundTypes to variables that we used to build the block to be registered.

 

main class:

package org.CyberneticStudios.CustomBlocks;

import java.io.File;

import org.CyberneticStudios.CustomBlocks.Block.BlockCustom;
import org.CyberneticStudios.CustomBlocks.common.CommonProxy;

import net.minecraft.block.Block;
import net.minecraft.block.Block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

@Mod(modid=CustomBlocks.MODID, name=CustomBlocks.MODNAME, version=CustomBlocks.MODVER) //Tell forge "Oh hey, there's a new mod here to load."
public class CustomBlocks //Start the class Declaration
{
    //Set the ID of the mod (Should be lower case).
    public static final String MODID = "customBlocks";
    //Set the "Name" of the mod.
    public static final String MODNAME = "Custom Blocks";
    //Set the version of the mod.
    public static final String MODVER = "0.0.0";

    @Instance(value = CustomBlocks.MODID) //Tell Forge what instance to use.
    public static CustomBlocks instance;
    @SidedProxy(clientSide="org.CyberneticStudios.CustomBlocks.client.ClientProxy", serverSide="org.CyberneticStudios.CustomBlocks.common.CommonProxy")
    public static CommonProxy proxy;
    
    //Used for creative tab
    public final static Block customBlock = new BlockCustom(Material.ground)
            .setHardness(0.5F).setStepSound(Block.soundTypeGravel)
            .setUnlocalizedName("custom_block");
    
    public static final CreativeTabs customBlocks= new CreativeTabs("custom_blocks") {
        @Override
        @SideOnly(Side.CLIENT)
        public Item getTabIconItem(){
            ItemStack iStack = new ItemStack(customBlock);
            return iStack.getItem();
        }
    };
    
    //empty stack of allocated blocks
    public static Block[] emptyBlocks = new Block[3839];
    
    //now we need an index
    public static int blockIndex;
    
    //set up configuration
    public static File configFile;
    public static Configuration config;

    @EventHandler
    public void preInit(FMLPreInitializationEvent event)
    {
        // you will be able to find the config file in .minecraft/config/ and it will be named Dummy.cfg
        // here our Configuration has been instantiated, and saved under the name "config"
       configFile = event.getSuggestedConfigurationFile();
        config = new Configuration(event.getSuggestedConfigurationFile());

        // loading the configuration from its file
        config.load();
        
        blockIndex = config.getInt("BlockCount", "B", 0, 0, 3839, "The number of custom blocks");
        int currentIndex = 0;
        while (currentIndex < blockIndex){
           Material blkMaterial;
           switch (config.getInt("Material", "B:Block" + Integer.toString(currentIndex), 0, 0, 34, "The current block's material.")) {
           case 0:
              blkMaterial = Material.air;
              break;
           case 1:
              blkMaterial = Material.grass;
              break;
           case 2:
              blkMaterial = Material.ground;
              break;
           case 3:
              blkMaterial = Material.wood;
              break;
           case 4:
              blkMaterial = Material.rock;
              break;
           case 5:
              blkMaterial = Material.iron;
              break;
           case 6:
              blkMaterial = Material.anvil;
              break;
           case 7:
              blkMaterial = Material.water;
              break;
           case 8:
              blkMaterial = Material.lava;
              break;
           case 9:
              blkMaterial = Material.leaves;
              break;
           case 10:
              blkMaterial = Material.plants;
              break;
           case 11:
              blkMaterial = Material.vine;
              break;
           case 12:
              blkMaterial = Material.sponge;
              break;
           case 13:
              blkMaterial = Material.cloth;
              break;
           case 14:
              blkMaterial = Material.fire;
              break;
           case 15:
              blkMaterial = Material.sand;
              break;
           case 16:
              blkMaterial = Material.circuits;
              break;
           case 17:
              blkMaterial = Material.carpet;
              break;
           case 18:
              blkMaterial = Material.glass;
              break;
           case 19:
              blkMaterial = Material.redstoneLight;
              break;
           case 20:
              blkMaterial = Material.tnt;
              break;
           case 21:
              blkMaterial = Material.coral;
              break;
           case 22:
              blkMaterial = Material.ice;
              break;
           case 23:
              blkMaterial = Material.packedIce;
              break;
           case 24:
              blkMaterial = Material.snow;
              break;
           case 25:
              blkMaterial = Material.craftedSnow;
              break;
           case 26:
              blkMaterial = Material.cactus;
              break;
           case 27:
              blkMaterial = Material.clay;
              break;
           case 28:
              blkMaterial = Material.gourd;
              break;
           case 29:
              blkMaterial = Material.dragonEgg;
              break;
           case 30:
              blkMaterial = Material.portal;
              break;
           case 31:
              blkMaterial = Material.cake;
              break;
           case 32:
              blkMaterial = Material.web;
              break;
           case 33:
              blkMaterial = Material.piston;
              break;
           case 34:
              blkMaterial = Material.barrier;
              break;
           default:
              blkMaterial = Material.air;
           }
           float hardness = config.getFloat("Hardness", "B:Block" + Integer.toString(currentIndex), 0.5F, 3.4e-038F, 3.4e+038F, "Sets how many hits it takes to break a block.");
           SoundType stepSound;
           switch(config.getInt("StepSound", "B:Block" + Integer.toString(currentIndex), 0, 0, 12, "the sound that plays when walking on our block")) {
           case 0:
              stepSound = Block.soundTypeStone;
              break;
           case 1:
              stepSound = Block.soundTypeWood;
              break;
           case 2:
              stepSound = Block.soundTypeGravel;
              break;
           case 3:
              stepSound = Block.soundTypeGrass;
              break;
           case 4:
              stepSound = Block.soundTypePiston;
              break;
           case 5:
              stepSound = Block.soundTypeMetal;
              break;
           case 6:
              stepSound = Block.soundTypeGlass;
              break;
           case 7:
              stepSound = Block.soundTypeCloth;
              break;
           case 8:
              stepSound = Block.soundTypeSand;
              break;
           case 9:
              stepSound = Block.soundTypeSnow;
              break;
           case 10:
              stepSound = Block.soundTypeLadder;
              break;
           case 11:
              stepSound = Block.soundTypeAnvil;
              break;
           case 12:
              stepSound = Block.SLIME_SOUND;
              break;
           default:
              stepSound = Block.soundTypeStone;
           }
           int lightOpacity = config.getInt("LightOpacity", "B:Block" + Integer.toString(currentIndex), 0, -2147483647, 2147483647, "Sets how much light is blocked going through this block.");
           float lightLevel = config.getFloat("LightLevel", "B:Block" + Integer.toString(currentIndex), 1.0F, 3.4e-038F, 3.4e+038F, "Sets the light value that the block emits.");
           float resistance = config.getFloat("Resistance", "B:Block" + Integer.toString(currentIndex), 1.0F, 3.4e-038F, 3.4e+038F, "Sets the the blocks resistance to explosions.");
           String unlocalizedName = config.getString("UnlocalizedName", "B:Block" + Integer.toString(currentIndex), "generic_block", "the name of the block");
           boolean tickRandomly=config.getBoolean("TickRandomly", "B:Block" + Integer.toString(currentIndex), false, "Sets whether this block type will receive random update ticks");
           boolean unbreakable=config.getBoolean("Unbreakable", "B:Block" + Integer.toString(currentIndex), false, "Sets whether this block type will receive random update ticks");
           if (unbreakable == true){
              emptyBlocks[currentIndex] = new BlockCustom(blkMaterial)
                 .setHardness(hardness)
                 .setStepSound(stepSound)
                 .setUnlocalizedName(unlocalizedName)
                 .setLightOpacity(lightOpacity)
                 .setLightLevel(lightLevel)
                 .setResistance(resistance)
                 .setTickRandomly(tickRandomly)
                 .setBlockUnbreakable()
                 .setCreativeTab(customBlocks);
           }else{
              emptyBlocks[currentIndex] = new BlockCustom(blkMaterial)
                  .setHardness(hardness)
                  .setStepSound(stepSound)
                  .setUnlocalizedName(unlocalizedName)
                  .setLightOpacity(lightOpacity)
                  .setLightLevel(lightLevel)
                  .setResistance(resistance)
                  .setTickRandomly(tickRandomly)
                  .setCreativeTab(customBlocks);
               }

           currentIndex++;
        }

        // saving the configuration to its file
        config.save();
   }
        
    @EventHandler
    public void load(FMLInitializationEvent event)
    {
       //register a generic custom block icon for the mod's creative tab
       GameRegistry.registerBlock(customBlock, "custom_block");
       int currentIndex = 0;
       while (currentIndex < blockIndex){
          GameRegistry.registerBlock(emptyBlocks[currentIndex], emptyBlocks[currentIndex].getUnlocalizedName());
          Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(Item.getItemFromBlock(emptyBlocks[currentIndex]), 0, new ModelResourceLocation("custom:" + emptyBlocks[currentIndex].getUnlocalizedName(), "inventory"));
          currentIndex++;
       }
    }
        
    @EventHandler
    public void postInit(FMLPostInitializationEvent event)
    {
    }
}

 

command class:

package org.CyberneticStudios.CustomBlocks.Commands;

import java.util.ArrayList;
import java.util.List;

import org.CyberneticStudios.CustomBlocks.CustomBlocks;
import org.CyberneticStudios.CustomBlocks.Block.BlockCustom;

import net.minecraft.block.Block;
import net.minecraft.block.Block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ChatComponentText;
import net.minecraftforge.fml.common.registry.GameRegistry;

public class CommandCreateBlock implements ICommand {
   
   private final List aliases;

   public CommandCreateBlock() {
      aliases = new ArrayList();
      aliases.add("cb");
      aliases.add("mkblock");
   }

   @Override
   public int compareTo(ICommand arg0) {
      return 0;
   }

   @Override
   public String getCommandName() {
      return "create block";
   }

   @Override
   public String getCommandUsage(ICommandSender sender) {
      return "create block <block_name> <material> <step sound> <hardness> <light opacity> <light level> <resistance> <needs random ticks?> <unbreakable>";
   }

   @Override
   public List<String> getCommandAliases() {
      return aliases;
   }

   @Override
   public void processCommand(ICommandSender sender, String[] args) throws CommandException {
      if (CustomBlocks.blockIndex < 3840){
         String name = args[0];
         int material = Integer.valueOf(args[1]);
         int stepSound = Integer.valueOf(args[2]);
         float hardness = Float.valueOf(args[3]);
           int lightOpacity = Integer.valueOf(args[4]);
           float lightLevel = Float.valueOf(args[5]);
           float resistance = Float.valueOf(args[6]);
           boolean tickRandomly=Boolean.valueOf(args[7]);
           boolean unbreakable=Boolean.valueOf(args[8]);

         Material blkMaterial;
         SoundType stepSound_;
         if (CustomBlocks.blockIndex < 3839) CustomBlocks.blockIndex++;
         switch (material) {
         case 0:
            blkMaterial = Material.air;
            break;
         case 1:
            blkMaterial = Material.grass;
            break;
         case 2:
            blkMaterial = Material.ground;
            break;
         case 3:
            blkMaterial = Material.wood;
            break;
         case 4:
            blkMaterial = Material.rock;
            break;
         case 5:
            blkMaterial = Material.iron;
            break;
         case 6:
            blkMaterial = Material.anvil;
            break;
         case 7:
            blkMaterial = Material.water;
            break;
         case 8:
            blkMaterial = Material.lava;
            break;
         case 9:
            blkMaterial = Material.leaves;
            break;
         case 10:
            blkMaterial = Material.plants;
            break;
         case 11:
            blkMaterial = Material.vine;
            break;
         case 12:
            blkMaterial = Material.sponge;
            break;
         case 13:
            blkMaterial = Material.cloth;
            break;
         case 14:
            blkMaterial = Material.fire;
            break;
         case 15:
            blkMaterial = Material.sand;
            break;
         case 16:
            blkMaterial = Material.circuits;
            break;
         case 17:
            blkMaterial = Material.carpet;
            break;
         case 18:
            blkMaterial = Material.glass;
            break;
         case 19:
            blkMaterial = Material.redstoneLight;
            break;
         case 20:
            blkMaterial = Material.tnt;
            break;
         case 21:
            blkMaterial = Material.coral;
            break;
         case 22:
            blkMaterial = Material.ice;
            break;
         case 23:
            blkMaterial = Material.packedIce;
            break;
         case 24:
            blkMaterial = Material.snow;
            break;
         case 25:
            blkMaterial = Material.craftedSnow;
            break;
         case 26:
            blkMaterial = Material.cactus;
            break;
         case 27:
            blkMaterial = Material.clay;
            break;
         case 28:
            blkMaterial = Material.gourd;
            break;
         case 29:
            blkMaterial = Material.dragonEgg;
            break;
         case 30:
            blkMaterial = Material.portal;
            break;
         case 31:
            blkMaterial = Material.cake;
            break;
         case 32:
            blkMaterial = Material.web;
            break;
         case 33:
            blkMaterial = Material.piston;
            break;
         case 34:
            blkMaterial = Material.barrier;
            break;
         default:
            blkMaterial = Material.air;
         }
         switch(stepSound) {
         case 0:
            stepSound_ = Block.soundTypeStone;
            break;
         case 1:
            stepSound_ = Block.soundTypeWood;
            break;
         case 2:
            stepSound_ = Block.soundTypeGravel;
            break;
         case 3:
            stepSound_ = Block.soundTypeGrass;
            break;
         case 4:
            stepSound_ = Block.soundTypePiston;
            break;
         case 5:
            stepSound_ = Block.soundTypeMetal;
            break;
         case 6:
            stepSound_ = Block.soundTypeGlass;
            break;
         case 7:
            stepSound_ = Block.soundTypeCloth;
            break;
         case 8:
            stepSound_ = Block.soundTypeSand;
            break;
         case 9:
            stepSound_ = Block.soundTypeSnow;
            break;
         case 10:
            stepSound_ = Block.soundTypeLadder;
            break;
         case 11:
            stepSound_ = Block.soundTypeAnvil;
            break;
         case 12:
            stepSound_ = Block.SLIME_SOUND;
            break;
         default:
            stepSound_ = Block.soundTypeStone;
         }
         if(unbreakable == true){
            CustomBlocks.emptyBlocks[CustomBlocks.blockIndex] = new BlockCustom(blkMaterial)
                 .setHardness(hardness)
                 .setStepSound(stepSound_)
                 .setUnlocalizedName(name)
                 .setLightOpacity(lightOpacity)
                 .setLightLevel(lightLevel)
                 .setResistance(resistance)
                 .setTickRandomly(tickRandomly)
                 .setBlockUnbreakable()
                 .setCreativeTab(CustomBlocks.customBlocks);
         }else{
            CustomBlocks.emptyBlocks[CustomBlocks.blockIndex] = new BlockCustom(blkMaterial)
                 .setHardness(hardness)
                 .setStepSound(stepSound_)
                 .setUnlocalizedName(name)
                  .setLightOpacity(lightOpacity)
                  .setLightLevel(lightLevel)
                  .setResistance(resistance)
                  .setTickRandomly(tickRandomly)
                  .setCreativeTab(CustomBlocks.customBlocks);
         }
         GameRegistry.registerBlock(CustomBlocks.emptyBlocks[CustomBlocks.blockIndex], CustomBlocks.emptyBlocks[CustomBlocks.blockIndex].getUnlocalizedName());
         sender.addChatMessage(new ChatComponentText("Created new custom block: custom:" + name));
         
         // what do I put here to write the config settings?
         CustomBlocks.config.save();
      } else sender.addChatMessage(new ChatComponentText("Too many custom blocks exist in the game."));
   }

   @Override
   public boolean canCommandSenderUseCommand(ICommandSender sender) {
      return true;
   }

   @Override
   public List<String> addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) {
      return null;
   }

   @Override
   public boolean isUsernameIndex(String[] args, int index) {
      return false;
   }

}

I know that the code isn't perfect, this is what I came up with in a short time and thus very messy.  I have yet to merge some of the preinit and init code together as well as move to a custom SoundTypes and custom materials model, the custom block class needs more code so that the new blocks can be tweaked as well, but that will be done while I wait.

Link to comment
Share on other sites

Here is what I ended up using:


        Property p = CustomBlocks.config.get("B", "BlockCount", "0", "The number of custom blocks")
              .setValue(CustomBlocks.blockIndex);
        p = CustomBlocks.config.get("Material", "B:Block" + Integer.toString(CustomBlocks.blockIndex), "0", "The current block's material.")
              .setValue(material);
        p = CustomBlocks.config.get("Hardness", "B:Block" + Integer.toString(CustomBlocks.blockIndex), "0.5F", "Sets how many hits it takes to break a block.")
              .setValue(hardness);
        p = CustomBlocks.config.get("StepSound", "B:Block" + Integer.toString(CustomBlocks.blockIndex), "0", "the sound that plays when walking on our block")
              .setValue(stepSound);
        p = CustomBlocks.config.get("LightOpacity", "B:Block" + Integer.toString(CustomBlocks.blockIndex), "0", "Sets how much light is blocked going through this block.")
              .setValue(lightOpacity);
        p = CustomBlocks.config.get("LightLevel", "B:Block" + Integer.toString(CustomBlocks.blockIndex), "1.0F", "Sets the light value that the block emits.")
              .setValue(lightLevel);
        p = CustomBlocks.config.get("Resistance", "B:Block" + Integer.toString(CustomBlocks.blockIndex), "1.0F", "Sets the the blocks resistance to explosions.")
              .setValue(resistance);
        p = CustomBlocks.config.get("UnlocalizedName", "B:Block" + Integer.toString(CustomBlocks.blockIndex), "generic_block", "the name of the block")
              .setValue(name);
        p = CustomBlocks.config.get("TickRandomly", "B:Block" + Integer.toString(CustomBlocks.blockIndex), "false", "Sets whether this block type will receive random update ticks")
              .setValue(tickRandomly);
        p = CustomBlocks.config.get("Unbreakable", "B:Block" + Integer.toString(CustomBlocks.blockIndex), "false", "The block can't be broken.")
              .setValue(unbreakable);
[/Code]

Link to comment
Share on other sites

I could do that in a future release, but what would you recommend for scripting events via resource pack that forge already has? or are my only options invent something, use a lua module that is in an external jar, or another language jar?

 

 

Also the word is dynamically and I intend to do more than one mod in a jar. I will do the same with materials and Block.SoundTypes next, then items, then biomes, then entities(yes I mean mobs), then dimensions. The jar won't be called Customcraft for nothing.  Besides, the end user will be able to add new blocks, items, etc, from console commands.  If you read the dated code above, you would have figured that one out. The creative tab that the end user gets to use will have for an icon, an untextured version of what is stored in it, i.e. custom blocks will use an untextured block for the tab's icon. I am doing that on purpose, the untextured block represents something brand new.

Link to comment
Share on other sites

I could do that in a future release, but what would you recommend for scripting events via resource pack that forge already has? or are my only options invent something, use a lua module that is in an external jar, or another language jar?

 

 

Also the word is dynamically and I intend to do more than one mod in a jar. I will do the same with materials and Block.SoundTypes next, then items, then biomes, then entities(yes I mean mobs), then dimensions. The jar won't be called Customcraft for nothing.  Besides, the end user will be able to add new blocks, items, etc, from console commands.  If you read the dated code above, you would have figured that one out. The creative tab that the end user gets to use will have for an icon, an untextured version of what is stored in it, i.e. custom blocks will use an untextured block for the tab's icon. I am doing that on purpose, the untextured block represents something brand new.

Using standart config files will be a pain to do all this.

Seriously, go learn json and GSON, and trust me, your life will be over 9000 times easier.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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