Example #1
0
      public Entry(FMLControlledNamespacedRegistry registry) {
        this.ids = Maps.newHashMap();
        this.substitutions = Sets.newHashSet();
        this.aliases = Maps.newHashMap();
        this.blocked = Sets.newHashSet();

        registry.serializeInto(this.ids);
        registry.serializeSubstitutions(this.substitutions);
        registry.serializeAliases(this.aliases);

        if (GameData.getBlockRegistry() == registry || GameData.getItemRegistry() == registry) {
          this.blocked.addAll(GameData.getMain().blockedIds);
        }
      }
Example #2
0
  public static void freezeData() {
    FMLLog.fine("Freezing block and item id maps");

    getMain().testConsistency();
    frozen = new GameData(getMain());
    frozen.testConsistency();
  }
  @Override
  public ItemStack deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    JsonHelper helper = new JsonHelper(json);

    String name = helper.getString("name");
    int amount = helper.getNullableInteger("amount", 1);
    int meta = helper.getNullableInteger("meta", 0);

    return new ItemStack(
        GameData.getItemRegistry().containsKey(new ResourceLocation(name))
            ? GameData.getItemRegistry().getObject(new ResourceLocation(name))
            : null,
        amount,
        meta);
  }
 public static void rebakeMap() {
   // System.out.println("Baking OreDictionary:");
   stackToId.clear();
   for (int id = 0; id < idToStack.size(); id++) {
     List<ItemStack> ores = idToStack.get(id);
     if (ores == null) continue;
     for (ItemStack ore : ores) {
       // HACK: use the registry name's ID. It is unique and it knows about substitutions
       ResourceLocation name = ore.getItem().delegate.name();
       int hash;
       if (name == null) {
         FMLLog.log(
             Level.DEBUG,
             "Defaulting unregistered ore dictionary entry for ore dictionary %s: type %s to -1",
             getOreName(id),
             ore.getItem().getClass());
         hash = -1;
       } else {
         hash = GameData.getItemRegistry().getId(name);
       }
       if (ore.getItemDamage() != WILDCARD_VALUE) {
         hash |= ((ore.getItemDamage() + 1) << 16); // +1 so meta 0 is significant
       }
       List<Integer> ids = stackToId.get(hash);
       if (ids == null) {
         ids = Lists.newArrayList();
         stackToId.put(hash, ids);
       }
       ids.add(id);
       // System.out.println(id + " " + getOreName(id) + " " + Integer.toHexString(hash) + " " +
       // ore);
     }
   }
 }
  /**
   * Gets all the integer ID for the ores that the specified item stack is registered to. If the
   * item stack is not linked to any ore, this will return an empty array and no new entry will be
   * created.
   *
   * @param stack The item stack of the ore.
   * @return An array of ids that this ore is registered as.
   */
  public static int[] getOreIDs(ItemStack stack) {
    if (stack == null || stack.getItem() == null)
      throw new IllegalArgumentException("Stack can not be null!");

    Set<Integer> set = new HashSet<Integer>();

    // HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to
    // a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not
    // aware of the item yet
    // IT should be noted that -1 will fail the gate further down, if an entry already exists with
    // value -1 for this name. This is what is broken and being warned about.
    // APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes
    // - you can't make them properly until you've registered with the game.
    ResourceLocation registryName = stack.getItem().delegate.name();
    int id;
    if (registryName == null) {
      FMLLog.log(
          Level.DEBUG,
          "Attempted to find the oreIDs for an unregistered object (%s). This won't work very well.",
          stack);
      return new int[0];
    } else {
      id = GameData.getItemRegistry().getId(registryName);
    }
    List<Integer> ids = stackToId.get(id);
    if (ids != null) set.addAll(ids);
    ids = stackToId.get(id | ((stack.getItemDamage() + 1) << 16));
    if (ids != null) set.addAll(ids);

    Integer[] tmp = set.toArray(new Integer[set.size()]);
    int[] ret = new int[tmp.length];
    for (int x = 0; x < tmp.length; x++) ret[x] = tmp[x];
    return ret;
  }
  @Override
  public JsonElement serialize(ItemStack src, Type typeOfSrc, JsonSerializationContext context) {
    JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty(
        "name", GameData.getItemRegistry().getNameForObject(src.getItem()).toString());
    jsonObject.addProperty("amount", src.stackSize);
    jsonObject.addProperty("meta", src.getItemDamage());

    return jsonObject;
  }
  /**
   * Registers a ore item into the dictionary. Raises the registerOre function in all registered
   * handlers.
   *
   * @param name The name of the ore
   * @param ore The ore's ItemStack
   */
  private static void registerOreImpl(String name, ItemStack ore) {
    if ("Unknown".equals(name)) return; // prevent bad IDs.
    if (ore == null || ore.getItem() == null) {
      FMLLog.bigWarning(
          "Invalid registration attempt for an Ore Dictionary item with name %s has occurred. The registration has been denied to prevent crashes. The mod responsible for the registration needs to correct this.",
          name);
      return; // prevent bad ItemStacks.
    }

    int oreID = getOreID(name);
    // HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to
    // a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not
    // aware of the item yet
    // IT should be noted that -1 will fail the gate further down, if an entry already exists with
    // value -1 for this name. This is what is broken and being warned about.
    // APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes
    // - you can't make them properly until you've registered with the game.
    ResourceLocation registryName = ore.getItem().delegate.name();
    int hash;
    if (registryName == null) {
      FMLLog.bigWarning(
          "A broken ore dictionary registration with name %s has occurred. It adds an item (type: %s) which is currently unknown to the game registry. This dictionary item can only support a single value when"
              + " registered with ores like this, and NO I am not going to turn this spam off. Just register your ore dictionary entries after the GameRegistry.\n"
              + "TO USERS: YES this is a BUG in the mod "
              + Loader.instance().activeModContainer().getName()
              + " report it to them!",
          name,
          ore.getItem().getClass());
      hash = -1;
    } else {
      hash = GameData.getItemRegistry().getId(registryName);
    }
    if (ore.getItemDamage() != WILDCARD_VALUE) {
      hash |= ((ore.getItemDamage() + 1) << 16); // +1 so 0 is significant
    }

    // Add things to the baked version, and prevent duplicates
    List<Integer> ids = stackToId.get(hash);
    if (ids != null && ids.contains(oreID)) return;
    if (ids == null) {
      ids = Lists.newArrayList();
      stackToId.put(hash, ids);
    }
    ids.add(oreID);

    // Add to the unbaked version
    ore = ore.copy();
    idToStack.get(oreID).add(ore);
    MinecraftForge.EVENT_BUS.post(new OreRegisterEvent(name, ore));
  }
Example #8
0
 public void initializeMods() {
   progressBar.step("Initializing mods Phase 2");
   // Mod controller should be in the initialization state here
   modController.distributeStateMessage(LoaderState.INITIALIZATION);
   progressBar.step("Initializing mods Phase 3");
   modController.transition(LoaderState.POSTINITIALIZATION, false);
   modController.distributeStateMessage(FMLInterModComms.IMCEvent.class);
   ItemStackHolderInjector.INSTANCE.inject();
   modController.distributeStateMessage(LoaderState.POSTINITIALIZATION);
   progressBar.step("Finishing up");
   modController.transition(LoaderState.AVAILABLE, false);
   modController.distributeStateMessage(LoaderState.AVAILABLE);
   GameData.freezeData();
   FMLLog.info(
       "Forge Mod Loader has successfully loaded %d mod%s",
       mods.size(), mods.size() == 1 ? "" : "s");
   progressBar.step("Completing Minecraft initialization");
 }
Example #9
0
  public static List<String> processIdRematches(
      Iterable<MissingMapping> missedMappings,
      boolean isLocalWorld,
      GameData gameData,
      Map<String, Integer[]> remapBlocks,
      Map<String, Integer[]> remapItems) {
    List<String> failed = Lists.newArrayList();
    List<String> ignored = Lists.newArrayList();
    List<String> warned = Lists.newArrayList();
    List<String> defaulted = Lists.newArrayList();

    for (MissingMapping remap : missedMappings) {
      FMLMissingMappingsEvent.Action action = remap.getAction();

      if (action == FMLMissingMappingsEvent.Action.REMAP) {
        // block/item re-mapped, finish the registration with the new name/object, but the old id
        int currId, newId;
        String newName;

        if (remap.type == Type.BLOCK) {
          currId = getMain().iBlockRegistry.getId((Block) remap.getTarget());
          newName = getMain().iBlockRegistry.getNameForObject(remap.getTarget()).toString();
          FMLLog.fine("The Block %s is being remapped to %s.", remap.name, newName);

          newId = gameData.registerBlock((Block) remap.getTarget(), newName, remap.id);
          gameData.iBlockRegistry.addAlias(remap.name, newName);
        } else {
          currId = getMain().iItemRegistry.getId((Item) remap.getTarget());
          newName = getMain().iItemRegistry.getNameForObject(remap.getTarget()).toString();
          FMLLog.fine("The Item %s is being remapped to %s.", remap.name, newName);

          newId = gameData.registerItem((Item) remap.getTarget(), newName, remap.id);
          gameData.iItemRegistry.addAlias(remap.name, newName);
        }

        if (newId != remap.id) throw new IllegalStateException();

        if (currId != newId) {
          FMLLog.info(
              "Fixed %s id mismatch %s: %d (init) -> %d (map).",
              remap.type == Type.BLOCK ? "block" : "item", newName, currId, newId);
          (remap.type == Type.BLOCK ? remapBlocks : remapItems)
              .put(newName, new Integer[] {currId, newId});
        }
      } else if (action == FMLMissingMappingsEvent.Action.BLOCKONLY) {
        // Pulled out specifically so the block doesn't get reassigned a new ID just because it's
        // Item block has gone away
        FMLLog.fine(
            "The ItemBlock %s is no longer present in the game. The residual block will remain",
            remap.name);
      } else {
        // block item missing, warn as requested and block the id
        if (action == FMLMissingMappingsEvent.Action.DEFAULT) {
          defaulted.add(remap.name);
        } else if (action == FMLMissingMappingsEvent.Action.IGNORE) {
          ignored.add(remap.name);
        } else if (action == FMLMissingMappingsEvent.Action.FAIL) {
          failed.add(remap.name);
        } else if (action == FMLMissingMappingsEvent.Action.WARN) {
          warned.add(remap.name);
        }

        gameData.block(remap.id); // prevent the id from being reused later
      }
    }

    if (!defaulted.isEmpty()) {
      String text =
          "Forge Mod Loader detected missing blocks/items.\n\n"
              + "There are "
              + defaulted.size()
              + " missing blocks and items in this save.\n"
              + "If you continue the missing blocks/items will get removed.\n"
              + "A world backup will be automatically created in your saves directory.\n\n"
              + "Missing Blocks/Items:\n";

      for (String s : defaulted) text += s + "\n";

      boolean confirmed = StartupQuery.confirm(text);
      if (!confirmed) StartupQuery.abort();

      try {
        String skip = System.getProperty("fml.doNotBackup");
        if (skip == null || !"true".equals(skip)) {
          ZipperUtil.backupWorld();
        } else {
          for (int x = 0; x < 10; x++)
            FMLLog.severe("!!!!!!!!!! UPDATING WORLD WITHOUT DOING BACKUP !!!!!!!!!!!!!!!!");
        }
      } catch (IOException e) {
        StartupQuery.notify("The world backup couldn't be created.\n\n" + e);
        StartupQuery.abort();
      }

      warned.addAll(defaulted);
    }
    if (!failed.isEmpty()) {
      FMLLog.severe(
          "This world contains blocks and items that refuse to be remapped. The world will not be loaded");
      return failed;
    }
    if (!warned.isEmpty()) {
      FMLLog.severe("This world contains block and item mappings that may cause world breakage");
      return failed;
    } else if (!ignored.isEmpty()) {
      FMLLog.fine("There were %d missing mappings that have been ignored", ignored.size());
    }
    return failed;
  }
Example #10
0
  public static List<String> injectSnapshot(
      GameDataSnapshot snapshot, boolean injectFrozenData, boolean isLocalWorld) {
    FMLLog.info(
        "Injecting existing block and item data into this %s instance",
        FMLCommonHandler.instance().getEffectiveSide().isServer() ? "server" : "client");
    Map<String, Integer[]> remapBlocks = Maps.newHashMap();
    Map<String, Integer[]> remapItems = Maps.newHashMap();
    LinkedHashMap<String, Integer> missingBlocks = new LinkedHashMap<String, Integer>();
    LinkedHashMap<String, Integer> missingItems = new LinkedHashMap<String, Integer>();
    getMain().testConsistency();
    getMain().iBlockRegistry.dump();
    getMain().iItemRegistry.dump();

    getMain().iItemRegistry.resetSubstitutionDelegates();

    GameDataSnapshot.Entry blocks = snapshot.entries.get("fml:blocks");
    GameDataSnapshot.Entry items = snapshot.entries.get("fml:items");

    GameData newData = new GameData();

    for (int id : blocks.blocked) {
      newData.block(id);
    }

    for (Map.Entry<String, String> entry : blocks.aliases.entrySet()) {
      newData.iBlockRegistry.addAlias(entry.getKey(), entry.getValue());
    }

    for (Map.Entry<String, String> entry : items.aliases.entrySet()) {
      newData.iItemRegistry.addAlias(entry.getKey(), entry.getValue());
    }

    for (String entry : blocks.substitutions) {
      newData.iBlockRegistry.activateSubstitution(entry);
    }
    for (String entry : items.substitutions) {
      newData.iItemRegistry.activateSubstitution(entry);
    }
    if (injectFrozenData) {
      for (String newBlockSubstitution : getMain().blockSubstitutions.keySet()) {
        if (!blocks.substitutions.contains(newBlockSubstitution)) {
          newData.iBlockRegistry.activateSubstitution(newBlockSubstitution);
        }
      }
      for (String newItemSubstitution : getMain().itemSubstitutions.keySet()) {
        if (!items.substitutions.contains(newItemSubstitution)) {
          newData.iItemRegistry.activateSubstitution(newItemSubstitution);
        }
      }
    }

    // Clear State map for it's ready for us to register below.
    GameData.BLOCKSTATE_TO_ID.clear();

    // process blocks and items in the world, blocks in the first pass, items in the second
    // blocks need to be added first for proper ItemBlock handling
    for (int pass = 0; pass < 2; pass++) {
      boolean isBlock = (pass == 0);
      Map<String, Integer> ids = (isBlock ? blocks.ids : items.ids);

      for (Entry<String, Integer> entry : ids.entrySet()) {
        String itemName = entry.getKey();
        int newId = entry.getValue();
        int currId =
            isBlock
                ? getMain().iBlockRegistry.getId(itemName)
                : getMain().iItemRegistry.getId(itemName);

        if (currId == -1) {
          FMLLog.info("Found a missing id from the world %s", itemName);
          (isBlock ? missingBlocks : missingItems).put(entry.getKey(), newId);
          continue; // no block/item -> nothing to add
        } else if (currId != newId) {
          FMLLog.fine(
              "Fixed %s id mismatch %s: %d (init) -> %d (map).",
              isBlock ? "block" : "item", itemName, currId, newId);
          (isBlock ? remapBlocks : remapItems).put(itemName, new Integer[] {currId, newId});
        }

        // register
        if (isBlock) {
          currId =
              newData.registerBlock(getMain().iBlockRegistry.getRaw(itemName), itemName, newId);
        } else {
          currId = newData.registerItem(getMain().iItemRegistry.getRaw(itemName), itemName, newId);
        }

        if (currId != newId) {
          throw new IllegalStateException(
              String.format(
                  "Can't map %s %s to id %d (seen at: %d), already occupied by %s, blocked %b, ItemBlock %b",
                  isBlock ? "block" : "item",
                  itemName,
                  newId,
                  currId,
                  isBlock
                      ? newData.iBlockRegistry.getRaw(newId)
                      : newData.iItemRegistry.getRaw(newId),
                  newData.blockedIds.contains(newId),
                  isBlock ? false : (getMain().iItemRegistry.getRaw(currId) instanceof ItemBlock)));
        }
      }
    }

    List<String> missedMappings =
        Loader.instance()
            .fireMissingMappingEvent(
                missingBlocks, missingItems, isLocalWorld, newData, remapBlocks, remapItems);
    if (!missedMappings.isEmpty()) return missedMappings;

    // If we got here - the load was accepted. We'll load generic repositories here.
    // Generic registries can fail by returning a missing mapping.
    missedMappings = newData.loadGenericRegistries(snapshot, getMain());
    if (!missedMappings.isEmpty()) return missedMappings;

    if (injectFrozenData) // add blocks + items missing from the map
    {
      Map<String, Integer> newBlocks =
          frozen.iBlockRegistry.getEntriesNotIn(newData.iBlockRegistry);
      Map<String, Integer> newItems = frozen.iItemRegistry.getEntriesNotIn(newData.iItemRegistry);

      if (!newBlocks.isEmpty() || !newItems.isEmpty()) {
        FMLLog.info("Injecting new block and item data into this server instance.");

        for (int pass = 0; pass < 2; pass++) {
          boolean isBlock = pass == 0;
          Map<String, Integer> missing = (pass == 0) ? newBlocks : newItems;
          Map<String, Integer[]> remaps = (isBlock ? remapBlocks : remapItems);

          for (Entry<String, Integer> entry : missing.entrySet()) {
            String itemName = entry.getKey();
            int currId = entry.getValue();
            int newId;

            if (isBlock) {
              newId =
                  newData.registerBlock(frozen.iBlockRegistry.getRaw(itemName), itemName, currId);
            } else {
              newId = newData.registerItem(frozen.iItemRegistry.getRaw(itemName), itemName, currId);
            }

            FMLLog.info(
                "Injected new block/item %s: %d (init) -> %d (map).", itemName, currId, newId);

            if (newId != currId) // a new id was assigned
            {
              remaps.put(itemName, new Integer[] {entry.getValue(), newId});
            }
          }
        }
      }
    }

    newData.testConsistency();
    getMain().set(newData);

    getMain().iBlockRegistry.dump();
    getMain().iItemRegistry.dump();
    Loader.instance().fireRemapEvent(remapBlocks, remapItems);
    // The id map changed, ensure we apply object holders
    ObjectHolderRegistry.INSTANCE.applyObjectHolders();
    return ImmutableList.of();
  }
Example #11
0
public class FlipHelper {
  public static final FlipHelper INSTANCE = new FlipHelper();

  private static final FMLControlledNamespacedRegistry<Block> BLOCK_REGISTRY =
      GameData.getBlockRegistry();

  public boolean flip(final SchematicWorld world, final EnumFacing axis, final boolean forced) {
    if (world == null) {
      return false;
    }

    try {
      final ISchematic schematic = world.getSchematic();
      final Schematic schematicFlipped = flip(schematic, axis, forced);

      world.setSchematic(schematicFlipped);

      for (final TileEntity tileEntity : world.getTileEntities()) {
        world.initializeTileEntity(tileEntity);
      }

      return true;
    } catch (final FlipException fe) {
      Reference.logger.error(fe.getMessage());
    } catch (final Exception e) {
      Reference.logger.fatal("Something went wrong!", e);
    }

    return false;
  }

  public Schematic flip(final ISchematic schematic, final EnumFacing axis, boolean forced)
      throws FlipException {
    final Vec3i dimensionsFlipped =
        new Vec3i(schematic.getWidth(), schematic.getHeight(), schematic.getLength());
    final Schematic schematicFlipped =
        new Schematic(
            schematic.getIcon(),
            dimensionsFlipped.getX(),
            dimensionsFlipped.getY(),
            dimensionsFlipped.getZ());
    final MBlockPos tmp = new MBlockPos();

    for (final MBlockPos pos :
        BlockPosHelper.getAllInBox(
            0,
            0,
            0,
            schematic.getWidth() - 1,
            schematic.getHeight() - 1,
            schematic.getLength() - 1)) {
      final IBlockState blockState = schematic.getBlockState(pos);
      final IBlockState blockStateFlipped = flipBlock(blockState, axis, forced);
      schematicFlipped.setBlockState(flipPos(pos, axis, dimensionsFlipped, tmp), blockStateFlipped);
    }

    final List<TileEntity> tileEntities = schematic.getTileEntities();
    for (final TileEntity tileEntity : tileEntities) {
      final BlockPos pos = tileEntity.getPos();
      tileEntity.setPos(new BlockPos(flipPos(pos, axis, dimensionsFlipped, tmp)));
      schematicFlipped.setTileEntity(tileEntity.getPos(), tileEntity);
    }

    return schematicFlipped;
  }

  private BlockPos flipPos(
      final BlockPos pos, final EnumFacing axis, final Vec3i dimensions, final MBlockPos flipped)
      throws FlipException {
    switch (axis) {
      case DOWN:
      case UP:
        return flipped.set(pos.getX(), dimensions.getY() - 1 - pos.getY(), pos.getZ());

      case NORTH:
      case SOUTH:
        return flipped.set(pos.getX(), pos.getY(), dimensions.getZ() - 1 - pos.getZ());

      case WEST:
      case EAST:
        return flipped.set(dimensions.getX() - 1 - pos.getX(), pos.getY(), pos.getZ());
    }

    throw new FlipException("'%s' is not a valid axis!", axis.getName());
  }

  private IBlockState flipBlock(final IBlockState blockState, final EnumFacing axis, boolean forced)
      throws FlipException {
    final IProperty propertyFacing = getProperty(blockState, "facing");
    if (propertyFacing instanceof PropertyDirection) {
      final Comparable value = blockState.getValue(propertyFacing);
      if (value instanceof EnumFacing) {
        final EnumFacing facing = getFlippedFacing(axis, (EnumFacing) value);
        if (propertyFacing.getAllowedValues().contains(facing)) {
          return blockState.withProperty(propertyFacing, facing);
        }
      }
    } else if (propertyFacing instanceof PropertyEnum) {
      if (BlockLever.EnumOrientation.class.isAssignableFrom(propertyFacing.getValueClass())) {
        final BlockLever.EnumOrientation orientation =
            (BlockLever.EnumOrientation) blockState.getValue(propertyFacing);
        final BlockLever.EnumOrientation orientationRotated =
            getFlippedLeverFacing(axis, orientation);
        if (propertyFacing.getAllowedValues().contains(orientationRotated)) {
          return blockState.withProperty(propertyFacing, orientationRotated);
        }
      }
    } else if (propertyFacing != null) {
      Reference.logger.error(
          "'{}': found 'facing' property with unknown type {}",
          BLOCK_REGISTRY.getNameForObject(blockState.getBlock()),
          propertyFacing.getClass().getSimpleName());
    }

    if (!forced && propertyFacing != null) {
      throw new FlipException(
          "'%s' cannot be flipped across '%s'",
          BLOCK_REGISTRY.getNameForObject(blockState.getBlock()), axis);
    }

    return blockState;
  }

  private IProperty getProperty(final IBlockState blockState, final String name) {
    for (final IProperty prop : (Set<IProperty>) blockState.getProperties().keySet()) {
      if (prop.getName().equals(name)) {
        return prop;
      }
    }

    return null;
  }

  private static EnumFacing getFlippedFacing(final EnumFacing axis, final EnumFacing side) {
    if (axis.getAxis() == side.getAxis()) {
      return side.getOpposite();
    }

    return side;
  }

  private static BlockLever.EnumOrientation getFlippedLeverFacing(
      final EnumFacing source, final BlockLever.EnumOrientation side) {
    if (source.getAxis() != side.getFacing().getAxis()) {
      return side;
    }

    final EnumFacing facing;
    if (side == BlockLever.EnumOrientation.UP_Z || side == BlockLever.EnumOrientation.DOWN_Z) {
      facing = EnumFacing.NORTH;
    } else if (side == BlockLever.EnumOrientation.UP_X
        || side == BlockLever.EnumOrientation.DOWN_X) {
      facing = EnumFacing.WEST;
    } else {
      facing = side.getFacing();
    }

    final EnumFacing facingFlipped = getFlippedFacing(source, side.getFacing());
    return BlockLever.EnumOrientation.forFacings(facingFlipped, facing);
  }

  public static class FlipException extends Exception {
    public FlipException(String message, Object... args) {
      super(String.format(message, args));
    }
  }
}
  private void loadItems() {
    registerVariantNames();
    int size = 0;
    ImmutableList<Item> items = ImmutableList.copyOf(GameData.getItemRegistry().typeSafeIterable());
    for (Item item : items) {
      size += getVariantNames(item).size();
    }
    itemBar = ProgressManager.push("ModelLoader: items", size);
    for (Item item : items) {
      // default loading
      for (String s : (List<String>) getVariantNames(item)) {
        ResourceLocation file = getItemLocation(s);
        ModelResourceLocation memory = getInventoryVariant(s);
        itemBar.step(memory.toString());
        IModel model = null;
        try {
          model = getModel(file);
        } catch (IOException e) {
          // Handled by our finally block.
        } finally {
          if (model == null || model == getMissingModel()) {
            FMLLog.fine(
                "Item json isn't found for '"
                    + memory
                    + "', trying to load the variant from the blockstate json");
            try {
              registerVariant(getModelBlockDefinition(memory), memory);
            } catch (Exception exception) {
              FMLLog.getLogger().warn("Unable to load definition " + memory, exception);
            }
          } else stateModels.put(memory, model);
        }
      }
    }
    ProgressManager.pop(itemBar);

    // replace vanilla bucket models if desired. done afterwards for performance reasons
    if (ForgeModContainer.replaceVanillaBucketModel) {
      // ensure the bucket model is loaded
      if (!stateModels.containsKey(ModelDynBucket.LOCATION)) {
        // load forges blockstate json for it
        ModelResourceLocation memory = getInventoryVariant("forge:dynbucket");
        registerVariant(getModelBlockDefinition(memory), memory);
      }

      // empty bucket
      for (String s : getVariantNames(Items.bucket)) {
        ModelResourceLocation memory = getInventoryVariant(s);
        try {
          IModel model = getModel(new ResourceLocation("forge", "item/bucket"));
          // only on successful load, otherwise continue using the old model
          stateModels.put(memory, model);
        } catch (IOException e) {
          // use the original vanilla model
        }
      }

      setBucketModel(Items.water_bucket);
      setBucketModel(Items.lava_bucket);
      // milk bucket only replaced if some mod adds milk
      if (FluidRegistry.isFluidRegistered("milk")) {
        // can the milk be put into a bucket?
        Fluid milk = FluidRegistry.getFluid("milk");
        FluidStack milkStack = new FluidStack(milk, FluidContainerRegistry.BUCKET_VOLUME);
        if (FluidContainerRegistry.getContainerCapacity(milkStack, new ItemStack(Items.bucket))
            == FluidContainerRegistry.BUCKET_VOLUME) {
          setBucketModel(Items.milk_bucket);
        }
      } else {
        // milk bucket if no milk fluid is present
        for (String s : getVariantNames(Items.milk_bucket)) {
          ModelResourceLocation memory = getInventoryVariant(s);
          try {
            IModel model = getModel(new ResourceLocation("forge", "item/bucket_milk"));
            // only on successful load, otherwise continue using the old model
            stateModels.put(memory, model);
          } catch (IOException e) {
            // use the original vanilla model
          }
        }
      }
    }
  }
Example #13
0
  /**
   * Fire a FMLMissingMappingsEvent to let mods determine how blocks/items defined in the world
   * save, but missing from the runtime, are to be handled.
   *
   * @param missing Map containing missing names with their associated id, blocks need to come
   *     before items for remapping.
   * @param isLocalWorld Whether this is executing for a world load (local/server) or a client.
   * @param gameData GameData instance where the new map's config is to be loaded into.
   * @return List with the mapping results.
   */
  public List<String> fireMissingMappingEvent(
      LinkedHashMap<String, Integer> missingBlocks,
      LinkedHashMap<String, Integer> missingItems,
      boolean isLocalWorld,
      GameData gameData,
      Map<String, Integer[]> remapBlocks,
      Map<String, Integer[]> remapItems) {
    if (missingBlocks.isEmpty() && missingItems.isEmpty()) // nothing to do
    {
      return ImmutableList.of();
    }

    FMLLog.fine(
        "There are %d mappings missing - attempting a mod remap",
        missingBlocks.size() + missingItems.size());
    ArrayListMultimap<String, MissingMapping> missingMappings = ArrayListMultimap.create();

    for (Map.Entry<String, Integer> mapping : missingBlocks.entrySet()) {
      MissingMapping m =
          new MissingMapping(GameRegistry.Type.BLOCK, mapping.getKey(), mapping.getValue());
      missingMappings.put(m.name.substring(0, m.name.indexOf(':')), m);
    }
    for (Map.Entry<String, Integer> mapping : missingItems.entrySet()) {
      MissingMapping m =
          new MissingMapping(GameRegistry.Type.ITEM, mapping.getKey(), mapping.getValue());
      missingMappings.put(m.name.substring(0, m.name.indexOf(':')), m);
    }

    FMLMissingMappingsEvent missingEvent = new FMLMissingMappingsEvent(missingMappings);
    modController.propogateStateMessage(missingEvent);

    if (isLocalWorld) // local world, warn about entries still being set to the default action
    {
      boolean didWarn = false;

      for (MissingMapping mapping : missingMappings.values()) {
        if (mapping.getAction() == FMLMissingMappingsEvent.Action.DEFAULT) {
          if (!didWarn) {
            FMLLog.severe(
                "There are unidentified mappings in this world - we are going to attempt to process anyway");
            didWarn = true;
          }

          FMLLog.severe(
              "Unidentified %s: %s, id %d",
              mapping.type == Type.BLOCK ? "block" : "item", mapping.name, mapping.id);
        }
      }
    } else // remote world, fail on entries with the default action
    {
      List<String> missedMapping = new ArrayList<String>();

      for (MissingMapping mapping : missingMappings.values()) {
        if (mapping.getAction() == FMLMissingMappingsEvent.Action.DEFAULT) {
          missedMapping.add(mapping.name);
        }
      }

      if (!missedMapping.isEmpty()) {
        return ImmutableList.copyOf(missedMapping);
      }
    }

    return GameData.processIdRematches(
        missingMappings.values(), isLocalWorld, gameData, remapBlocks, remapItems);
  }
Example #14
0
 public void serverStopped() {
   GameData.revertToFrozen();
   modController.distributeStateMessage(LoaderState.SERVER_STOPPED);
   modController.transition(LoaderState.SERVER_STOPPED, true);
   modController.transition(LoaderState.AVAILABLE, true);
 }
public class BlockStateReplacer {
  private static final FMLControlledNamespacedRegistry<Block> BLOCK_REGISTRY =
      GameData.getBlockRegistry();
  private final IBlockState defaultReplacement;

  private BlockStateReplacer(final IBlockState defaultReplacement) {
    this.defaultReplacement = defaultReplacement;
  }

  @SuppressWarnings({"rawtypes"})
  public IBlockState getReplacement(
      final IBlockState original, final Map<IProperty, Comparable> properties) {
    IBlockState replacement = this.defaultReplacement;

    replacement = applyProperties(replacement, original.getProperties());
    replacement = applyProperties(replacement, properties);

    return replacement;
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  private IBlockState applyProperties(
      IBlockState blockState, final Map<IProperty, Comparable> properties) {
    for (final Map.Entry<IProperty, Comparable> entry : properties.entrySet()) {
      try {
        blockState = blockState.withProperty(entry.getKey(), entry.getValue());
      } catch (final IllegalArgumentException ignored) {
      }
    }

    return blockState;
  }

  public static BlockStateReplacer forBlockState(final IBlockState replacement) {
    return new BlockStateReplacer(replacement);
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  public static BlockStateHelper getMatcher(final BlockStateInfo blockStateInfo) {
    final BlockStateHelper matcher = BlockStateHelper.forBlock(blockStateInfo.block);
    for (final Map.Entry<IProperty, Comparable> entry : blockStateInfo.stateData.entrySet()) {
      matcher.where(
          entry.getKey(),
          new Predicate<Comparable>() {
            @Override
            public boolean apply(final Comparable input) {
              return input != null && input.equals(entry.getValue());
            }
          });
    }

    return matcher;
  }

  @SuppressWarnings({"rawtypes"})
  public static BlockStateInfo fromString(final String input) throws LocalizedException {
    final int start = input.indexOf('[');
    final int end = input.indexOf(']');

    final String blockName;
    final String stateData;
    if (start > -1 && end > -1) {
      blockName = input.substring(0, start);
      stateData = input.substring(start + 1, end);
    } else {
      blockName = input;
      stateData = "";
    }

    final ResourceLocation location = new ResourceLocation(blockName);
    if (!BLOCK_REGISTRY.containsKey(location)) {
      throw new LocalizedException(Names.Messages.INVALID_BLOCK, blockName);
    }

    final Block block = BLOCK_REGISTRY.getObject(location);
    final Map<IProperty, Comparable> propertyData =
        parsePropertyData(block.getDefaultState(), stateData, true);
    return new BlockStateInfo(block, propertyData);
  }

  @SuppressWarnings({"rawtypes"})
  public static Map<IProperty, Comparable> parsePropertyData(
      final IBlockState blockState, final String stateData, final boolean strict)
      throws LocalizedException {
    final HashMap<IProperty, Comparable> map = new HashMap<IProperty, Comparable>();
    if (stateData == null || stateData.length() == 0) {
      return map;
    }

    final String[] propertyPairs = stateData.split(",");
    for (final String propertyPair : propertyPairs) {
      final String[] split = propertyPair.split("=");
      if (split.length != 2) {
        throw new LocalizedException(Names.Messages.INVALID_PROPERTY, propertyPair);
      }

      putMatchingProperty(map, blockState, split[0], split[1], strict);
    }

    return map;
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  private static boolean putMatchingProperty(
      final Map<IProperty, Comparable> map,
      final IBlockState blockState,
      final String name,
      final String value,
      final boolean strict)
      throws LocalizedException {
    for (final IProperty property : blockState.getPropertyNames()) {
      if (property.getName().equalsIgnoreCase(name)) {
        final Collection<Comparable> allowedValues = property.getAllowedValues();
        for (final Comparable allowedValue : allowedValues) {
          if (String.valueOf(allowedValue).equalsIgnoreCase(value)) {
            map.put(property, allowedValue);
            return true;
          }
        }
      }
    }

    if (strict) {
      throw new LocalizedException(
          Names.Messages.INVALID_PROPERTY_FOR_BLOCK,
          name + "=" + value,
          BLOCK_REGISTRY.getNameForObject(blockState.getBlock()));
    }

    return false;
  }

  @SuppressWarnings({"rawtypes"})
  public static class BlockStateInfo {
    public final Block block;
    public final Map<IProperty, Comparable> stateData;

    public BlockStateInfo(final Block block, final Map<IProperty, Comparable> stateData) {
      this.block = block;
      this.stateData = stateData;
    }
  }
}
 static {
   blockIDBlacklistDefault = GameData.getBlockRegistry().getNameForObject(Blocks.bedrock) + ";";
   stringOfIdsDefault =
       GameData.getItemRegistry().getNameForObject(Items.arrow)
           + ", 10; "
           + GameData.getItemRegistry().getNameForObject(Items.arrow)
           + ", 16; "
           + GameData.getItemRegistry().getNameForObject(Items.coal)
           + ", 6; "
           + GameData.getItemRegistry().getNameForObject(Items.diamond)
           + ", 1; "
           + GameData.getItemRegistry().getNameForObject(Items.iron_ingot)
           + ", 3; "
           + GameData.getItemRegistry().getNameForObject(Items.gold_ingot)
           + ", 2; "
           + GameData.getItemRegistry().getNameForObject(Items.mushroom_stew)
           + ", 2; "
           + GameData.getItemRegistry().getNameForObject(Items.feather)
           + ", 1; "
           + GameData.getItemRegistry().getNameForObject(Items.chainmail_helmet)
           + ", 1; "
           + GameData.getItemRegistry().getNameForObject(Items.chainmail_chestplate)
           + ", 1; "
           + GameData.getItemRegistry().getNameForObject(Items.chainmail_leggings)
           + ", 1; "
           + GameData.getItemRegistry().getNameForObject(Items.chainmail_boots)
           + ", 1; "
           + GameData.getItemRegistry().getNameForObject(Items.painting)
           + ", 2; "
           + GameData.getItemRegistry().getNameForObject(Items.painting)
           + ", 5; "
           + GameData.getItemRegistry().getNameForObject(Items.golden_apple)
           + ", 1; "
           + GameData.getItemRegistry().getNameForObject(Items.golden_apple)
           + ", 3; "
           + GameData.getItemRegistry().getNameForObject(Items.bucket)
           + ", 2; "
           + GameData.getItemRegistry().getNameForObject(Items.lava_bucket)
           + ", 1; "
           + GameData.getItemRegistry().getNameForObject(Items.milk_bucket)
           + ", 1; "
           + GameData.getItemRegistry().getNameForObject(Items.book)
           + ", 4; "
           + GameData.getItemRegistry().getNameForObject(Items.slime_ball)
           + ", 6; "
           + GameData.getItemRegistry().getNameForObject(Items.egg)
           + ", 4; "
           + GameData.getItemRegistry().getNameForObject(Items.egg)
           + ", 8; "
           + GameData.getItemRegistry().getNameForObject(Items.glowstone_dust)
           + ", 12; "
           + GameData.getItemRegistry().getNameForObject(Items.glowstone_dust)
           + ", 8; "
           + GameData.getItemRegistry().getNameForObject(Items.cooked_fish)
           + ", 3; "
           + GameData.getItemRegistry().getNameForObject(Items.dye)
           + ", 5, 0; "
           + GameData.getItemRegistry().getNameForObject(Items.cake)
           + ", 2; "
           + GameData.getItemRegistry().getNameForObject(Items.blaze_rod)
           + ", 2; "
           + GameData.getItemRegistry().getNameForObject(Items.nether_wart)
           + ", 6; "
           + GameData.getItemRegistry().getNameForObject(Items.emerald)
           + ", 4; "
           + GameData.getItemRegistry().getNameForObject(Items.emerald)
           + ", 6; "
           + GameData.getItemRegistry().getNameForObject(Items.quartz)
           + ", 6; "
           + GameData.getItemRegistry().getNameForObject(Items.map)
           + ", 1; "
           + GameData.getBlockRegistry().getNameForObject(Blocks.obsidian)
           + ", 4; "
           + GameData.getBlockRegistry().getNameForObject(Blocks.ice)
           + ", 3;";
 }