diff --git a/fml/client/cpw/mods/fml/client/GuiIdMismatchScreen.java b/fml/client/cpw/mods/fml/client/GuiIdMismatchScreen.java index e4a3fcbe2..f625faeab 100644 --- a/fml/client/cpw/mods/fml/client/GuiIdMismatchScreen.java +++ b/fml/client/cpw/mods/fml/client/GuiIdMismatchScreen.java @@ -25,13 +25,13 @@ public class GuiIdMismatchScreen extends GuiYesNo { field_73942_a = this; for (Entry entry : idDifferences.entriesOnlyOnLeft().entrySet()) { - missingIds.add(String.format("ID %d (ModID: %s, type %s) is missing", entry.getValue().itemId, entry.getValue().modId, entry.getValue().itemType)); + missingIds.add(String.format("ID %d (ModID: %s, type %s) is missing", entry.getValue().getItemId(), entry.getValue().getModId(), entry.getValue().getItemType())); } for (Entry> entry : idDifferences.entriesDiffering().entrySet()) { ItemData world = entry.getValue().leftValue(); ItemData game = entry.getValue().rightValue(); - mismatchedIds.add(String.format("ID %d is mismatched. World: (ModID: %s, type %s, ordinal %d) Game (ModID: %s, type %s, ordinal %d)", world.itemId, world.modId, world.itemType, world.ordinal, game.modId, game.itemType, game.ordinal)); + mismatchedIds.add(String.format("ID %d is mismatched. World: (ModID: %s, type %s, ordinal %d) Game (ModID: %s, type %s, ordinal %d)", world.getItemId(), world.getModId(), world.getItemType(), world.getOrdinal(), game.getModId(), game.getItemType(), game.getOrdinal())); } this.allowContinue = allowContinue; } diff --git a/fml/common/cpw/mods/fml/common/registry/GameData.java b/fml/common/cpw/mods/fml/common/registry/GameData.java index a52cbd1b7..b2bf9432a 100644 --- a/fml/common/cpw/mods/fml/common/registry/GameData.java +++ b/fml/common/cpw/mods/fml/common/registry/GameData.java @@ -42,7 +42,7 @@ public class GameData { if (idMap.containsKey(item.field_77779_bT)) { ItemData id = idMap.get(item.field_77779_bT); - FMLLog.warning("[ItemTracker] The mod %s is attempting to overwrite existing item at %d (%s from %s) with %s", mc.getModId(), id.itemId, id.itemType, id.modId, itemType); + FMLLog.warning("[ItemTracker] The mod %s is attempting to overwrite existing item at %d (%s from %s) with %s", mc.getModId(), id.getItemId(), id.getItemType(), id.getModId(), itemType); } idMap.put(item.field_77779_bT, itemData); FMLLog.fine("[ItemTracker] Adding item %s(%d) owned by %s", item.getClass().getName(), item.field_77779_bT, mc.getModId()); @@ -68,7 +68,7 @@ public class GameData { Function idMapFunction = new Function() { public Integer apply(ItemData input) { - return input.itemId; + return input.getItemId(); }; }; @@ -156,6 +156,13 @@ public class GameData { return worldSaveItems; } + static void setName(Item item, String name, String modId) + { + int id = item.field_77779_bT; + ItemData itemData = idMap.get(id); + itemData.setName(name,modId); + } + } diff --git a/fml/common/cpw/mods/fml/common/registry/GameRegistry.java b/fml/common/cpw/mods/fml/common/registry/GameRegistry.java index c34f42b5e..6a6934c0a 100644 --- a/fml/common/cpw/mods/fml/common/registry/GameRegistry.java +++ b/fml/common/cpw/mods/fml/common/registry/GameRegistry.java @@ -152,22 +152,81 @@ public class GameRegistry return BlockTracker.nextBlockId(); } + /** + * Register an item with the item registry with a custom name : this allows for easier server->client resolution + * + * @param item The item to register + * @param name The mod-unique name of the item + */ + public static void registerItem(net.minecraft.item.Item item, String name) + { + registerItem(item, name, null); + } + + /** + * Register the specified Item with a mod specific name : overrides the standard type based name + * @param item The item to register + * @param name The mod-unique name to register it as - null will remove a custom name + * @param modId An optional modId that will "own" this block - generally used by multi-mod systems + * where one mod should "own" all the blocks of all the mods, null defaults to the active mod + */ + public static void registerItem(net.minecraft.item.Item item, String name, String modId) + { + GameData.setName(item, name, modId); + } + /** * Register a block with the world * */ + @Deprecated public static void registerBlock(net.minecraft.block.Block block) { registerBlock(block, ItemBlock.class); } + + /** + * Register a block with the specified mod specific name : overrides the standard type based name + * @param block The block to register + * @param name The mod-unique name to register it as + */ + public static void registerBlock(net.minecraft.block.Block block, String name) + { + registerBlock(block, ItemBlock.class, name); + } + /** * Register a block with the world, with the specified item class * - * @param block - * @param itemclass + * Deprecated in favour of named versions + * + * @param block The block to register + * @param itemclass The item type to register with it */ + @Deprecated public static void registerBlock(net.minecraft.block.Block block, Class itemclass) + { + registerBlock(block, itemclass, null); + } + /** + * Register a block with the world, with the specified item class and block name + * @param block The block to register + * @param itemclass The item type to register with it + * @param name The mod-unique name to register it with + */ + public static void registerBlock(net.minecraft.block.Block block, Class itemclass, String name) + { + registerBlock(block, itemclass, name, null); + } + /** + * Register a block with the world, with the specified item class, block name and owning modId + * @param block The block to register + * @param itemclass The iterm type to register with it + * @param name The mod-unique name to register it with + * @param modId The modId that will own the block name. null defaults to the active modId + */ + public static void registerBlock(net.minecraft.block.Block block, Class itemclass, String name, String modId) { if (Loader.instance().isInState(LoaderState.CONSTRUCTING)) { @@ -178,7 +237,8 @@ public class GameRegistry assert block != null : "registerBlock: block cannot be null"; assert itemclass != null : "registerBlock: itemclass cannot be null"; int blockItemId = block.field_71990_ca - 256; - itemclass.getConstructor(int.class).newInstance(blockItemId); + Item i = itemclass.getConstructor(int.class).newInstance(blockItemId); + GameRegistry.registerItem(i,name, modId); } catch (Exception e) { diff --git a/fml/common/cpw/mods/fml/common/registry/ItemData.java b/fml/common/cpw/mods/fml/common/registry/ItemData.java index f284196e7..cc73b2866 100644 --- a/fml/common/cpw/mods/fml/common/registry/ItemData.java +++ b/fml/common/cpw/mods/fml/common/registry/ItemData.java @@ -12,22 +12,27 @@ import com.google.common.collect.HashMultiset; import com.google.common.collect.Maps; import com.google.common.collect.Multiset; +import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.LoaderException; import cpw.mods.fml.common.ModContainer; public class ItemData { private static Map> modOrdinals = Maps.newHashMap(); - public final String modId; - public final String itemType; - public final int itemId; - public final int ordinal; + private final String modId; + private final String itemType; + private final int itemId; + private final int ordinal; + private String forcedModId; + private String forcedName; public ItemData(Item item, ModContainer mc) { this.itemId = item.field_77779_bT; if (item.getClass().equals(ItemBlock.class)) { - this.itemType = Block.field_71973_m[this.itemId].getClass().getName(); + this.itemType = Block.field_71973_m[this.getItemId()].getClass().getName(); } else { @@ -47,6 +52,28 @@ public class ItemData { this.itemType = tag.func_74779_i("ItemType"); this.itemId = tag.func_74762_e("ItemId"); this.ordinal = tag.func_74762_e("ordinal"); + this.forcedModId = tag.func_74764_b("ForcedModId") ? tag.func_74779_i("ForcedModId") : null; + this.forcedName = tag.func_74764_b("ForcedName") ? tag.func_74779_i("ForcedName") : null; + } + + public String getItemType() + { + return this.forcedName !=null ? forcedName : itemType; + } + + public String getModId() + { + return this.forcedModId != null ? forcedModId : modId; + } + + public int getOrdinal() + { + return ordinal; + } + + public int getItemId() + { + return itemId; } public NBTTagCompound toNBT() @@ -56,13 +83,21 @@ public class ItemData { tag.func_74778_a("ItemType", itemType); tag.func_74768_a("ItemId", itemId); tag.func_74768_a("ordinal", ordinal); + if (forcedModId != null) + { + tag.func_74778_a("ForcedModId", forcedModId); + } + if (forcedName != null) + { + tag.func_74778_a("ForcedName", forcedName); + } return tag; } @Override public int hashCode() { - return Objects.hashCode(modId, itemType, itemId, ordinal); + return Objects.hashCode(itemId, ordinal); } @Override @@ -71,7 +106,7 @@ public class ItemData { try { ItemData other = (ItemData) obj; - return Objects.equal(modId, other.modId) && Objects.equal(itemType, other.itemType) && Objects.equal(itemId, other.itemId) && Objects.equal(ordinal, other.ordinal); + return Objects.equal(getModId(), other.getModId()) && Objects.equal(getItemType(), other.getItemType()) && Objects.equal(itemId, other.itemId) && ( isOveridden() || Objects.equal(ordinal, other.ordinal)); } catch (ClassCastException cce) { @@ -82,11 +117,33 @@ public class ItemData { @Override public String toString() { - return String.format("Item %d, Type %s, owned by %s, ordinal %d", itemId, itemType, modId, ordinal); + return String.format("Item %d, Type %s, owned by %s, ordinal %d, name %s, claimedModId %s", itemId, itemType, modId, ordinal, forcedName, forcedModId); } public boolean mayDifferByOrdinal(ItemData rightValue) { - return Objects.equal(itemType, rightValue.itemType) && Objects.equal(modId, rightValue.modId); + return Objects.equal(getItemType(), rightValue.getItemType()) && Objects.equal(getModId(), rightValue.getModId()); + } + + public boolean isOveridden() + { + return forcedName != null; + } + + public void setName(String name, String modId) + { + String localModId = modId; + if (modId == null) + { + localModId = Loader.instance().activeModContainer().getModId(); + } + if (modOrdinals.get(localModId).count(name)>0) + { + FMLLog.severe("The mod %s is attempting to redefine the item at id %d with a non-unique name (%s.%s)", Loader.instance().activeModContainer(), itemId, localModId, name); + throw new LoaderException(); + } + modOrdinals.get(localModId).add(name); + this.forcedModId = modId; + this.forcedName = name; } }