コード例 #1
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
 private Block[] readFluidsFromNBT(NBTTagCompound tagCompound, String name) {
   List<Block> fluids = new ArrayList<Block>();
   for (int a : getIntArraySafe(tagCompound, name)) {
     fluids.add((Block) Block.blockRegistry.getObjectById(a));
   }
   return fluids.toArray(new Block[fluids.size()]);
 }
コード例 #2
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
 private static <T extends Enum> int[] toIntArray(Collection<T> collection) {
   List<Integer> c = new ArrayList<Integer>(collection.size());
   for (T t : collection) {
     c.add(t.ordinal());
   }
   return ArrayUtils.toPrimitive(c.toArray(new Integer[c.size()]));
 }
コード例 #3
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
  public Block getFeatureLiquid(
      Random random,
      Map<FeatureType, List<DimletKey>> modifiersForFeature,
      FeatureType featureType) {
    Block block;
    if (featureTypes.contains(featureType)) {
      List<BlockMeta> blocks = new ArrayList<BlockMeta>();
      List<Block> fluids = new ArrayList<Block>();
      getMaterialAndFluidModifiers(modifiersForFeature.get(featureType), blocks, fluids);

      if (!fluids.isEmpty()) {
        block = fluids.get(random.nextInt(fluids.size()));
        if (block == null) {
          block = Blocks.water; // This is the default in case None was specified.
        }
      } else {
        // Nothing was specified. With a relatively big chance we use stone. But there is also a
        // chance that the material will be something else.
        if (random.nextFloat() < DimletConfiguration.randomOrbFluidChance) {
          DimletKey key = DimletRandomizer.getRandomFluidBlock(random, true);
          actualRfCost += calculateCostFactor(key);
          block = DimletObjectMapping.idToFluid.get(key);
        } else {
          block = Blocks.water;
        }
      }
    } else {
      block = Blocks.water;
    }
    return block;
  }
コード例 #4
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
 private static Block[] readFluidArrayFromBuf(ByteBuf buf) {
   List<Block> blocks = new ArrayList<Block>();
   int size = buf.readInt();
   for (int i = 0; i < size; i++) {
     blocks.add((Block) Block.blockRegistry.getObjectById(buf.readInt()));
   }
   return blocks.toArray(new Block[blocks.size()]);
 }
コード例 #5
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
 private static void writeFluidsToNBT(NBTTagCompound tagCompound, Block[] fluids, String name) {
   List<Integer> c;
   c = new ArrayList<Integer>(fluids.length);
   for (Block t : fluids) {
     c.add(Block.blockRegistry.getIDForObject(t));
   }
   tagCompound.setIntArray(name, ArrayUtils.toPrimitive(c.toArray(new Integer[c.size()])));
 }
コード例 #6
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
 private static BlockMeta[] readBlockArrayFromBuf(ByteBuf buf) {
   int size = buf.readInt();
   List<BlockMeta> blocksMeta = new ArrayList<BlockMeta>();
   for (int i = 0; i < size; i++) {
     Block b = (Block) Block.blockRegistry.getObjectById(buf.readInt());
     int m = buf.readInt();
     blocksMeta.add(new BlockMeta(b, m));
   }
   return blocksMeta.toArray(new BlockMeta[blocksMeta.size()]);
 }
コード例 #7
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
 public static void getMaterialAndFluidModifiers(
     List<DimletKey> modifiers, List<BlockMeta> blocks, List<Block> fluids) {
   if (modifiers != null) {
     for (DimletKey modifier : modifiers) {
       if (modifier.getType() == DimletType.DIMLET_MATERIAL) {
         BlockMeta block = DimletObjectMapping.idToBlock.get(modifier);
         blocks.add(block);
       } else if (modifier.getType() == DimletType.DIMLET_LIQUID) {
         Block fluid = DimletObjectMapping.idToFluid.get(modifier);
         fluids.add(fluid);
       }
     }
   }
 }
コード例 #8
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
 private static BlockMeta[] readBlockArrayFromNBT(NBTTagCompound tagCompound, String name) {
   List<BlockMeta> blocks = new ArrayList<BlockMeta>();
   int[] blockIds = getIntArraySafe(tagCompound, name);
   int[] metas = getIntArraySafe(tagCompound, name + "_meta");
   for (int i = 0; i < blockIds.length; i++) {
     int id = blockIds[i];
     Block block = (Block) Block.blockRegistry.getObjectById(id);
     int meta = 0;
     if (i < metas.length) {
       meta = metas[i];
     }
     blocks.add(new BlockMeta(block, meta));
   }
   return blocks.toArray(new BlockMeta[blocks.size()]);
 }
コード例 #9
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
 private static void writeBlocksToNBT(
     NBTTagCompound tagCompound, BlockMeta[] blocks, String name) {
   List<Integer> ids = new ArrayList<Integer>(blocks.length);
   List<Integer> meta = new ArrayList<Integer>(blocks.length);
   for (BlockMeta t : blocks) {
     ids.add(Block.blockRegistry.getIDForObject(t.getBlock()));
     meta.add((int) t.getMeta());
   }
   tagCompound.setIntArray(name, ArrayUtils.toPrimitive(ids.toArray(new Integer[ids.size()])));
   tagCompound.setIntArray(
       name + "_meta", ArrayUtils.toPrimitive(meta.toArray(new Integer[meta.size()])));
 }
コード例 #10
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
  private void calculateCelestialBodyDescriptors() {
    List<CelestialBodyType> celestialBodies = skyDescriptor.getCelestialBodies();
    // Find the most suitable sun and moon. This is typically the largest sun in the list of
    // celestial bodies.
    int sunidx = -1;
    int bestsun = 0;
    int moonidx = -1;
    int bestmoon = 0;
    for (int i = 0; i < celestialBodies.size(); i++) {
      CelestialBodyType type = celestialBodies.get(i);
      if (type.getGoodSunFactor() > bestsun) {
        bestsun = type.getGoodSunFactor();
        sunidx = i;
      }
      if (type.getGoodMoonFactor() > bestmoon) {
        bestmoon = type.getGoodMoonFactor();
        moonidx = i;
      }
    }

    // Always the same random series.
    Random random = new Random(123);
    random.nextFloat();
    celestialBodyDescriptors = new ArrayList<CelestialBodyDescriptor>();
    for (int i = 0; i < celestialBodies.size(); i++) {
      CelestialBodyType type = celestialBodies.get(i);
      celestialBodyDescriptors.add(new CelestialBodyDescriptor(type, i == sunidx || i == moonidx));
    }
  }
コード例 #11
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
  public DimensionInformation(String name, DimensionDescriptor descriptor, ByteBuf buf) {
    this.name = name;
    this.descriptor = descriptor;

    terrainType = NetworkTools.readEnum(buf, TerrainType.values());
    NetworkTools.readEnumCollection(buf, featureTypes, FeatureType.values());
    NetworkTools.readEnumCollection(buf, structureTypes, StructureType.values());
    NetworkTools.readEnumCollection(buf, effectTypes, EffectType.values());

    biomes.clear();
    int size = buf.readInt();
    for (int i = 0; i < size; i++) {
      BiomeGenBase biome = BiomeGenBase.getBiome(buf.readInt());
      if (biome != null) {
        biomes.add(biome);
      } else {
        biomes.add(BiomeGenBase.plains);
      }
    }
    controllerType = NetworkTools.readEnum(buf, ControllerType.values());
    digitString = NetworkTools.readString(buf);

    forcedDimensionSeed = buf.readLong();
    baseSeed = buf.readLong();
    worldVersion = buf.readInt();

    Block block = (Block) Block.blockRegistry.getObjectById(buf.readInt());
    int meta = buf.readInt();
    baseBlockForTerrain = new BlockMeta(block, meta);
    block = (Block) Block.blockRegistry.getObjectById(buf.readInt());
    meta = buf.readInt();
    tendrilBlock = new BlockMeta(block, meta);

    pyramidBlocks = readBlockArrayFromBuf(buf);
    sphereBlocks = readBlockArrayFromBuf(buf);
    hugeSphereBlocks = readBlockArrayFromBuf(buf);
    liquidSphereBlocks = readBlockArrayFromBuf(buf);
    liquidSphereFluids = readFluidArrayFromBuf(buf);
    hugeLiquidSphereBlocks = readBlockArrayFromBuf(buf);
    hugeLiquidSphereFluids = readFluidArrayFromBuf(buf);

    block = (Block) Block.blockRegistry.getObjectById(buf.readInt());
    meta = buf.readInt();
    canyonBlock = new BlockMeta(block, meta);
    fluidForTerrain = (Block) Block.blockRegistry.getObjectById(buf.readInt());

    extraOregen = readBlockArrayFromBuf(buf);

    fluidsForLakes = readFluidArrayFromBuf(buf);

    peaceful = buf.readBoolean();
    noanimals = buf.readBoolean();
    shelter = buf.readBoolean();
    respawnHere = buf.readBoolean();

    celestialAngle = NetworkTools.readFloat(buf);
    timeSpeed = NetworkTools.readFloat(buf);

    probeCounter = buf.readInt();
    actualRfCost = buf.readInt();

    skyDescriptor = new SkyDescriptor.Builder().fromBytes(buf).build();
    calculateCelestialBodyDescriptors();

    weatherDescriptor = new WeatherDescriptor.Builder().fromBytes(buf).build();

    patreon1 = buf.readLong();

    extraMobs.clear();
    size = buf.readInt();
    for (int i = 0; i < size; i++) {
      String className = NetworkTools.readString(buf);
      try {
        Class<? extends EntityLiving> c = (Class<? extends EntityLiving>) Class.forName(className);
        int chance = buf.readInt();
        int minGroup = buf.readInt();
        int maxGroup = buf.readInt();
        int maxLoaded = buf.readInt();
        MobDescriptor mob = new MobDescriptor(null, c, chance, minGroup, maxGroup, maxLoaded);
        extraMobs.add(mob);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      }
    }

    size = buf.readInt();
    dimensionTypes = new String[size];
    for (int i = 0; i < size; i++) {
      dimensionTypes[i] = NetworkTools.readString(buf);
    }

    setupBiomeMapping();
  }
コード例 #12
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
  public void toBytes(ByteBuf buf) {
    NetworkTools.writeEnum(buf, terrainType, TerrainType.TERRAIN_VOID);
    NetworkTools.writeEnumCollection(buf, featureTypes);
    NetworkTools.writeEnumCollection(buf, structureTypes);
    NetworkTools.writeEnumCollection(buf, effectTypes);

    buf.writeInt(biomes.size());
    for (BiomeGenBase entry : biomes) {
      if (entry != null) {
        buf.writeInt(entry.biomeID);
      } else {
        buf.writeInt(BiomeGenBase.plains.biomeID);
      }
    }
    NetworkTools.writeEnum(buf, controllerType, ControllerType.CONTROLLER_DEFAULT);

    NetworkTools.writeString(buf, digitString);
    buf.writeLong(forcedDimensionSeed);
    buf.writeLong(baseSeed);
    buf.writeInt(worldVersion);

    buf.writeInt(Block.blockRegistry.getIDForObject(baseBlockForTerrain.getBlock()));
    buf.writeInt(baseBlockForTerrain.getMeta());
    buf.writeInt(Block.blockRegistry.getIDForObject(tendrilBlock.getBlock()));
    buf.writeInt(tendrilBlock.getMeta());

    writeBlockArrayToBuf(buf, pyramidBlocks);
    writeBlockArrayToBuf(buf, sphereBlocks);
    writeBlockArrayToBuf(buf, hugeSphereBlocks);
    writeBlockArrayToBuf(buf, liquidSphereBlocks);
    writeFluidArrayToBuf(buf, liquidSphereFluids);
    writeBlockArrayToBuf(buf, hugeLiquidSphereBlocks);
    writeFluidArrayToBuf(buf, hugeLiquidSphereFluids);

    buf.writeInt(Block.blockRegistry.getIDForObject(canyonBlock.getBlock()));
    buf.writeInt(canyonBlock.getMeta());
    buf.writeInt(Block.blockRegistry.getIDForObject(fluidForTerrain));

    writeBlockArrayToBuf(buf, extraOregen);

    writeFluidArrayToBuf(buf, fluidsForLakes);

    buf.writeBoolean(peaceful);
    buf.writeBoolean(noanimals);
    buf.writeBoolean(shelter);
    buf.writeBoolean(respawnHere);
    NetworkTools.writeFloat(buf, celestialAngle);
    NetworkTools.writeFloat(buf, timeSpeed);

    buf.writeInt(probeCounter);
    buf.writeInt(actualRfCost);

    skyDescriptor.toBytes(buf);
    weatherDescriptor.toBytes(buf);

    buf.writeLong(patreon1);

    buf.writeInt(extraMobs.size());
    for (MobDescriptor mob : extraMobs) {
      if (mob != null) {
        if (mob.getEntityClass() != null) {
          NetworkTools.writeString(buf, mob.getEntityClass().getName());
          buf.writeInt(mob.getSpawnChance());
          buf.writeInt(mob.getMinGroup());
          buf.writeInt(mob.getMaxGroup());
          buf.writeInt(mob.getMaxLoaded());
        }
      }
    }

    buf.writeInt(dimensionTypes.length);
    for (String type : dimensionTypes) {
      NetworkTools.writeString(buf, type);
    }
  }
コード例 #13
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
  public void writeToNBT(NBTTagCompound tagCompound) {
    tagCompound.setString("name", getName());
    Coordinate spawnPoint = getSpawnPoint();
    if (spawnPoint != null) {
      Coordinate.writeToNBT(tagCompound, "spawnPoint", spawnPoint);
    }
    tagCompound.setInteger("probeCounter", getProbeCounter());
    tagCompound.setInteger(
        "version",
        1); // Version number so that we can detect incompatible changes in persisted dimension
    // information objects.

    tagCompound.setInteger(
        "terrain",
        terrainType == null ? TerrainType.TERRAIN_VOID.ordinal() : terrainType.ordinal());
    tagCompound.setIntArray("features", toIntArray(featureTypes));
    tagCompound.setIntArray("structures", toIntArray(structureTypes));
    tagCompound.setIntArray("effects", toIntArray(effectTypes));

    List<Integer> c = new ArrayList<Integer>(biomes.size());
    for (BiomeGenBase t : biomes) {
      if (t != null) {
        c.add(t.biomeID);
      } else {
        c.add(BiomeGenBase.plains.biomeID);
      }
    }
    tagCompound.setIntArray("biomes", ArrayUtils.toPrimitive(c.toArray(new Integer[c.size()])));
    tagCompound.setInteger(
        "controller",
        controllerType == null
            ? ControllerType.CONTROLLER_DEFAULT.ordinal()
            : controllerType.ordinal());
    tagCompound.setString("digits", digitString);

    tagCompound.setLong("forcedSeed", forcedDimensionSeed);
    tagCompound.setLong("baseSeed", baseSeed);
    tagCompound.setInteger("worldVersion", worldVersion);

    setBlockMeta(tagCompound, baseBlockForTerrain, "baseBlock");
    setBlockMeta(tagCompound, tendrilBlock, "tendrilBlock");

    writeBlocksToNBT(tagCompound, pyramidBlocks, "pyramidBlocks");

    writeBlocksToNBT(tagCompound, sphereBlocks, "sphereBlocks");
    if (sphereBlocks.length > 0) {
      // Write out a single sphere block for compatibility with older RFTools.
      setBlockMeta(tagCompound, sphereBlocks[0], "sphereBlock");
    }

    writeBlocksToNBT(tagCompound, hugeSphereBlocks, "hugeSphereBlocks");
    writeBlocksToNBT(tagCompound, hugeLiquidSphereBlocks, "hugeLiquidSphereBlocks");
    writeFluidsToNBT(tagCompound, hugeLiquidSphereFluids, "hugeLiquidSphereFluids");

    writeBlocksToNBT(tagCompound, liquidSphereBlocks, "liquidSphereBlocks");
    if (liquidSphereBlocks.length > 0) {
      // Write out a single sphere block for compatibility with older RFTools.
      setBlockMeta(tagCompound, liquidSphereBlocks[0], "liquidSphereBlock");
    }

    writeFluidsToNBT(tagCompound, liquidSphereFluids, "liquidSphereFluids");
    if (liquidSphereFluids.length > 0) {
      tagCompound.setInteger(
          "liquidSphereFluid", Block.blockRegistry.getIDForObject(liquidSphereFluids[0]));
    }

    setBlockMeta(tagCompound, canyonBlock, "canyonBlock");
    tagCompound.setInteger("fluidBlock", Block.blockRegistry.getIDForObject(fluidForTerrain));

    writeBlocksToNBT(tagCompound, extraOregen, "extraOregen");
    writeFluidsToNBT(tagCompound, fluidsForLakes, "lakeFluids");

    tagCompound.setBoolean("peaceful", peaceful);
    tagCompound.setBoolean("noanimals", noanimals);
    tagCompound.setBoolean("shelter", shelter);
    tagCompound.setBoolean("respawnHere", respawnHere);
    if (celestialAngle != null) {
      tagCompound.setFloat("celestialAngle", celestialAngle);
    }
    if (timeSpeed != null) {
      tagCompound.setFloat("timeSpeed", timeSpeed);
    }
    tagCompound.setInteger("probes", probeCounter);
    tagCompound.setInteger("actualCost", actualRfCost);

    skyDescriptor.writeToNBT(tagCompound);
    weatherDescriptor.writeToNBT(tagCompound);

    tagCompound.setLong("patreon1", patreon1);

    NBTTagList list = new NBTTagList();
    for (MobDescriptor mob : extraMobs) {
      NBTTagCompound tc = new NBTTagCompound();

      if (mob != null) {
        if (mob.getEntityClass() != null) {
          tc.setString("class", mob.getEntityClass().getName());
          tc.setInteger("chance", mob.getSpawnChance());
          tc.setInteger("minGroup", mob.getMinGroup());
          tc.setInteger("maxGroup", mob.getMaxGroup());
          tc.setInteger("maxLoaded", mob.getMaxLoaded());
          list.appendTag(tc);
        }
      }
    }

    tagCompound.setTag("mobs", list);
    tagCompound.setString("dimensionTypes", StringUtils.join(dimensionTypes, ","));
  }
コード例 #14
0
ファイル: DimensionInformation.java プロジェクト: ntf/RFTools
  private void setupFromNBT(NBTTagCompound tagCompound) {
    terrainType = TerrainType.values()[tagCompound.getInteger("terrain")];
    featureTypes = toEnumSet(getIntArraySafe(tagCompound, "features"), FeatureType.values());
    structureTypes = toEnumSet(getIntArraySafe(tagCompound, "structures"), StructureType.values());
    effectTypes = toEnumSet(getIntArraySafe(tagCompound, "effects"), EffectType.values());

    biomes.clear();
    for (int a : getIntArraySafe(tagCompound, "biomes")) {
      BiomeGenBase biome = BiomeGenBase.getBiome(a);
      if (biome != null) {
        biomes.add(biome);
      } else {
        // Protect against deleted biomes (i.e. a mod with biomes gets removed and this dimension
        // still uses it).
        // We will pick a replacement biome here.
        biomes.add(BiomeGenBase.plains);
      }
    }
    if (tagCompound.hasKey("controller")) {
      controllerType = ControllerType.values()[tagCompound.getInteger("controller")];
    } else {
      // Support for old type.
      if (biomes.isEmpty()) {
        controllerType = ControllerType.CONTROLLER_DEFAULT;
      } else {
        controllerType = ControllerType.CONTROLLER_SINGLE;
      }
    }

    digitString = tagCompound.getString("digits");

    forcedDimensionSeed = tagCompound.getLong("forcedSeed");
    baseSeed = tagCompound.getLong("baseSeed");
    worldVersion = tagCompound.getInteger("worldVersion");

    baseBlockForTerrain = getBlockMeta(tagCompound, "baseBlock");
    tendrilBlock = getBlockMeta(tagCompound, "tendrilBlock");
    canyonBlock = getBlockMeta(tagCompound, "canyonBlock");
    fluidForTerrain =
        (Block) Block.blockRegistry.getObjectById(tagCompound.getInteger("fluidBlock"));

    hugeLiquidSphereFluids = readFluidsFromNBT(tagCompound, "hugeLiquidSphereFluids");
    hugeLiquidSphereBlocks = readBlockArrayFromNBT(tagCompound, "hugeLiquidSphereBlocks");

    // Support for the old format with only one liquid block.
    Block oldLiquidSphereFluid =
        (Block) Block.blockRegistry.getObjectById(tagCompound.getInteger("liquidSphereFluid"));
    liquidSphereFluids = readFluidsFromNBT(tagCompound, "liquidSphereFluids");
    if (liquidSphereFluids.length == 0) {
      liquidSphereFluids = new Block[] {oldLiquidSphereFluid};
    }

    // Support for the old format with only one sphere block.
    BlockMeta oldLiquidSphereBlock = getBlockMeta(tagCompound, "liquidSphereBlock");
    liquidSphereBlocks = readBlockArrayFromNBT(tagCompound, "liquidSphereBlocks");
    if (liquidSphereBlocks.length == 0) {
      liquidSphereBlocks = new BlockMeta[] {oldLiquidSphereBlock};
    }

    pyramidBlocks = readBlockArrayFromNBT(tagCompound, "pyramidBlocks");
    if (pyramidBlocks.length == 0) {
      pyramidBlocks = new BlockMeta[] {BlockMeta.STONE};
    }

    // Support for the old format with only one sphere block.
    BlockMeta oldSphereBlock = getBlockMeta(tagCompound, "sphereBlock");
    sphereBlocks = readBlockArrayFromNBT(tagCompound, "sphereBlocks");
    if (sphereBlocks.length == 0) {
      sphereBlocks = new BlockMeta[] {oldSphereBlock};
    }

    hugeSphereBlocks = readBlockArrayFromNBT(tagCompound, "hugeSphereBlocks");

    extraOregen = readBlockArrayFromNBT(tagCompound, "extraOregen");
    fluidsForLakes = readFluidsFromNBT(tagCompound, "lakeFluids");

    peaceful = tagCompound.getBoolean("peaceful");
    noanimals = tagCompound.getBoolean("noanimals");
    shelter = tagCompound.getBoolean("shelter");
    respawnHere = tagCompound.getBoolean("respawnHere");
    if (tagCompound.hasKey("celestialAngle")) {
      celestialAngle = tagCompound.getFloat("celestialAngle");
    } else {
      celestialAngle = null;
    }
    if (tagCompound.hasKey("timeSpeed")) {
      timeSpeed = tagCompound.getFloat("timeSpeed");
    } else {
      timeSpeed = null;
    }
    probeCounter = tagCompound.getInteger("probes");
    actualRfCost = tagCompound.getInteger("actualCost");

    skyDescriptor = new SkyDescriptor.Builder().fromNBT(tagCompound).build();
    calculateCelestialBodyDescriptors();

    patreon1 = tagCompound.getLong("patreon1");

    weatherDescriptor = new WeatherDescriptor.Builder().fromNBT(tagCompound).build();

    extraMobs.clear();
    NBTTagList list = tagCompound.getTagList("mobs", Constants.NBT.TAG_COMPOUND);
    for (int i = 0; i < list.tagCount(); i++) {
      NBTTagCompound tc = list.getCompoundTagAt(i);
      String className = tc.getString("class");
      int chance = tc.getInteger("chance");
      int minGroup = tc.getInteger("minGroup");
      int maxGroup = tc.getInteger("maxGroup");
      int maxLoaded = tc.getInteger("maxLoaded");
      Class<? extends EntityLiving> c = null;
      try {
        c = (Class<? extends EntityLiving>) Class.forName(className);
      } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
      }
      MobDescriptor mob = new MobDescriptor(null, c, chance, minGroup, maxGroup, maxLoaded);
      extraMobs.add(mob);
    }

    String ds = tagCompound.getString("dimensionTypes");
    dimensionTypes = StringUtils.split(ds, ",");
    if (dimensionTypes == null) {
      dimensionTypes = new String[0];
    }
  }