Some tweaks to item identification. The GameRegistry methods are deprecated

to encourage you to use the new named ones instead. These will force a
name on the item/block, allowing for stronger matching than "sequential guessing"
This commit is contained in:
Christian 2012-12-16 22:57:11 -05:00
parent 3369976c05
commit e6c71bb148
4 changed files with 140 additions and 16 deletions

View file

@ -25,13 +25,13 @@ public class GuiIdMismatchScreen extends GuiYesNo {
field_73942_a = this; field_73942_a = this;
for (Entry<Integer, ItemData> entry : idDifferences.entriesOnlyOnLeft().entrySet()) for (Entry<Integer, ItemData> 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<Integer, ValueDifference<ItemData>> entry : idDifferences.entriesDiffering().entrySet()) for (Entry<Integer, ValueDifference<ItemData>> entry : idDifferences.entriesDiffering().entrySet())
{ {
ItemData world = entry.getValue().leftValue(); ItemData world = entry.getValue().leftValue();
ItemData game = entry.getValue().rightValue(); 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; this.allowContinue = allowContinue;
} }

View file

@ -42,7 +42,7 @@ public class GameData {
if (idMap.containsKey(item.field_77779_bT)) if (idMap.containsKey(item.field_77779_bT))
{ {
ItemData id = idMap.get(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); 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()); 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<? super ItemData, Integer> idMapFunction = new Function<ItemData, Integer>() { Function<? super ItemData, Integer> idMapFunction = new Function<ItemData, Integer>() {
public Integer apply(ItemData input) { public Integer apply(ItemData input) {
return input.itemId; return input.getItemId();
}; };
}; };
@ -156,6 +156,13 @@ public class GameData {
return worldSaveItems; 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);
}
} }

View file

@ -152,22 +152,81 @@ public class GameRegistry
return BlockTracker.nextBlockId(); 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 * Register a block with the world
* *
*/ */
@Deprecated
public static void registerBlock(net.minecraft.block.Block block) public static void registerBlock(net.minecraft.block.Block block)
{ {
registerBlock(block, ItemBlock.class); 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 * Register a block with the world, with the specified item class
* *
* @param block * Deprecated in favour of named versions
* @param itemclass *
* @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<? extends ItemBlock> itemclass) public static void registerBlock(net.minecraft.block.Block block, Class<? extends ItemBlock> 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<? extends ItemBlock> 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<? extends ItemBlock> itemclass, String name, String modId)
{ {
if (Loader.instance().isInState(LoaderState.CONSTRUCTING)) if (Loader.instance().isInState(LoaderState.CONSTRUCTING))
{ {
@ -178,7 +237,8 @@ public class GameRegistry
assert block != null : "registerBlock: block cannot be null"; assert block != null : "registerBlock: block cannot be null";
assert itemclass != null : "registerBlock: itemclass cannot be null"; assert itemclass != null : "registerBlock: itemclass cannot be null";
int blockItemId = block.field_71990_ca - 256; 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) catch (Exception e)
{ {

View file

@ -12,22 +12,27 @@ import com.google.common.collect.HashMultiset;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Multiset; 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; import cpw.mods.fml.common.ModContainer;
public class ItemData { public class ItemData {
private static Map<String, Multiset<String>> modOrdinals = Maps.newHashMap(); private static Map<String, Multiset<String>> modOrdinals = Maps.newHashMap();
public final String modId; private final String modId;
public final String itemType; private final String itemType;
public final int itemId; private final int itemId;
public final int ordinal; private final int ordinal;
private String forcedModId;
private String forcedName;
public ItemData(Item item, ModContainer mc) public ItemData(Item item, ModContainer mc)
{ {
this.itemId = item.field_77779_bT; this.itemId = item.field_77779_bT;
if (item.getClass().equals(ItemBlock.class)) 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 else
{ {
@ -47,6 +52,28 @@ public class ItemData {
this.itemType = tag.func_74779_i("ItemType"); this.itemType = tag.func_74779_i("ItemType");
this.itemId = tag.func_74762_e("ItemId"); this.itemId = tag.func_74762_e("ItemId");
this.ordinal = tag.func_74762_e("ordinal"); 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() public NBTTagCompound toNBT()
@ -56,13 +83,21 @@ public class ItemData {
tag.func_74778_a("ItemType", itemType); tag.func_74778_a("ItemType", itemType);
tag.func_74768_a("ItemId", itemId); tag.func_74768_a("ItemId", itemId);
tag.func_74768_a("ordinal", ordinal); 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; return tag;
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
return Objects.hashCode(modId, itemType, itemId, ordinal); return Objects.hashCode(itemId, ordinal);
} }
@Override @Override
@ -71,7 +106,7 @@ public class ItemData {
try try
{ {
ItemData other = (ItemData) obj; 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) catch (ClassCastException cce)
{ {
@ -82,11 +117,33 @@ public class ItemData {
@Override @Override
public String toString() 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) 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;
} }
} }