Registry: Implement support for remapping blocks/items to a new name.
This commit is contained in:
parent
180c605570
commit
ac44af863b
5 changed files with 330 additions and 113 deletions
|
@ -15,6 +15,7 @@ package cpw.mods.fml.common;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -101,6 +102,7 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
||||||
list.func_74742_a(mod);
|
list.func_74742_a(mod);
|
||||||
}
|
}
|
||||||
fmlData.func_74782_a("ModList", list);
|
fmlData.func_74782_a("ModList", list);
|
||||||
|
// name <-> id mappings
|
||||||
NBTTagList dataList = new NBTTagList();
|
NBTTagList dataList = new NBTTagList();
|
||||||
FMLLog.fine("Gathering id map for writing to world save %s", info.func_76065_j());
|
FMLLog.fine("Gathering id map for writing to world save %s", info.func_76065_j());
|
||||||
Map<String,Integer> itemList = GameData.buildItemDataList();
|
Map<String,Integer> itemList = GameData.buildItemDataList();
|
||||||
|
@ -112,7 +114,29 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
||||||
dataList.func_74742_a(tag);
|
dataList.func_74742_a(tag);
|
||||||
}
|
}
|
||||||
fmlData.func_74782_a("ItemData", dataList);
|
fmlData.func_74782_a("ItemData", dataList);
|
||||||
fmlData.func_74783_a("BlockedIds", GameData.getBlockedIds());
|
// blocked ids
|
||||||
|
fmlData.func_74783_a("BlockedItemIds", GameData.getBlockedIds());
|
||||||
|
// block aliases
|
||||||
|
NBTTagList blockAliasList = new NBTTagList();
|
||||||
|
for (Entry<String, String> entry : GameData.getBlockRegistry().getAliases().entrySet())
|
||||||
|
{
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
tag.func_74778_a("K", entry.getKey());
|
||||||
|
tag.func_74778_a("V", entry.getValue());
|
||||||
|
blockAliasList.func_74742_a(tag);
|
||||||
|
}
|
||||||
|
fmlData.func_74782_a("BlockAliases", blockAliasList);
|
||||||
|
// item aliases
|
||||||
|
NBTTagList itemAliasList = new NBTTagList();
|
||||||
|
for (Entry<String, String> entry : GameData.getItemRegistry().getAliases().entrySet())
|
||||||
|
{
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
tag.func_74778_a("K", entry.getKey());
|
||||||
|
tag.func_74778_a("V", entry.getValue());
|
||||||
|
itemAliasList.func_74742_a(tag);
|
||||||
|
}
|
||||||
|
fmlData.func_74782_a("ItemAliases", itemAliasList);
|
||||||
|
|
||||||
return fmlData;
|
return fmlData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,18 +211,34 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
||||||
}
|
}
|
||||||
else if (tag.func_74764_b("ItemData"))
|
else if (tag.func_74764_b("ItemData"))
|
||||||
{
|
{
|
||||||
// read name <-> id mappings
|
// name <-> id mappings
|
||||||
NBTTagList list = tag.func_150295_c("ItemData", (byte)10);
|
NBTTagList list = tag.func_150295_c("ItemData", 10);
|
||||||
Map<String,Integer> dataList = Maps.newLinkedHashMap();
|
Map<String,Integer> dataList = Maps.newLinkedHashMap();
|
||||||
for (int i = 0; i < list.func_74745_c(); i++)
|
for (int i = 0; i < list.func_74745_c(); i++)
|
||||||
{
|
{
|
||||||
NBTTagCompound dataTag = list.func_150305_b(i);
|
NBTTagCompound dataTag = list.func_150305_b(i);
|
||||||
dataList.put(dataTag.func_74779_i("K"), dataTag.func_74762_e("V"));
|
dataList.put(dataTag.func_74779_i("K"), dataTag.func_74762_e("V"));
|
||||||
}
|
}
|
||||||
// read blocked ids
|
// blocked ids
|
||||||
int[] blockedIds = tag.func_74759_k("BlockedIds");
|
int[] blockedIds = tag.func_74759_k("BlockedItemIds");
|
||||||
|
// block aliases
|
||||||
|
Map<String, String> blockAliases = new HashMap<String, String>();
|
||||||
|
list = tag.func_150295_c("BlockAliases", 10);
|
||||||
|
for (int i = 0; i < list.func_74745_c(); i++)
|
||||||
|
{
|
||||||
|
NBTTagCompound dataTag = list.func_150305_b(i);
|
||||||
|
blockAliases.put(dataTag.func_74779_i("K"), dataTag.func_74779_i("V"));
|
||||||
|
}
|
||||||
|
// item aliases
|
||||||
|
Map<String, String> itemAliases = new HashMap<String, String>();
|
||||||
|
list = tag.func_150295_c("ItemAliases", 10);
|
||||||
|
for (int i = 0; i < list.func_74745_c(); i++)
|
||||||
|
{
|
||||||
|
NBTTagCompound dataTag = list.func_150305_b(i);
|
||||||
|
itemAliases.put(dataTag.func_74779_i("K"), dataTag.func_74779_i("V"));
|
||||||
|
}
|
||||||
|
|
||||||
List<String> failedElements = GameData.injectWorldIDMap(dataList, blockedIds, true, true);
|
List<String> failedElements = GameData.injectWorldIDMap(dataList, blockedIds, blockAliases, itemAliases, true, true);
|
||||||
if (!failedElements.isEmpty())
|
if (!failedElements.isEmpty())
|
||||||
{
|
{
|
||||||
throw new GameRegistryException("Failed to load the world - there are fatal block and item id issues", failedElements);
|
throw new GameRegistryException("Failed to load the world - there are fatal block and item id issues", failedElements);
|
||||||
|
|
|
@ -856,7 +856,7 @@ public class Loader
|
||||||
* @param gameData GameData instance where the new map's config is to be loaded into.
|
* @param gameData GameData instance where the new map's config is to be loaded into.
|
||||||
* @return List with the mapping results.
|
* @return List with the mapping results.
|
||||||
*/
|
*/
|
||||||
public List<String> fireMissingMappingEvent(LinkedHashMap<String, Integer> missing, boolean isLocalWorld, GameData gameData)
|
public List<String> fireMissingMappingEvent(LinkedHashMap<String, Integer> missing, boolean isLocalWorld, GameData gameData, Map<String, Integer[]> remaps)
|
||||||
{
|
{
|
||||||
if (missing.isEmpty()) // nothing to do
|
if (missing.isEmpty()) // nothing to do
|
||||||
{
|
{
|
||||||
|
@ -868,10 +868,9 @@ public class Loader
|
||||||
|
|
||||||
for (Map.Entry<String, Integer> mapping : missing.entrySet())
|
for (Map.Entry<String, Integer> mapping : missing.entrySet())
|
||||||
{
|
{
|
||||||
String itemName = mapping.getKey();
|
|
||||||
int id = mapping.getValue();
|
int id = mapping.getValue();
|
||||||
MissingMapping m = new MissingMapping(itemName, id);
|
MissingMapping m = new MissingMapping(mapping.getKey(), id);
|
||||||
missingMappings.put(itemName.substring(0, itemName.indexOf(':')), m);
|
missingMappings.put(m.name.substring(0, m.name.indexOf(':')), m);
|
||||||
}
|
}
|
||||||
|
|
||||||
FMLMissingMappingsEvent missingEvent = new FMLMissingMappingsEvent(missingMappings);
|
FMLMissingMappingsEvent missingEvent = new FMLMissingMappingsEvent(missingMappings);
|
||||||
|
@ -913,7 +912,7 @@ public class Loader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GameData.processIdRematches(missingMappings.values(), isLocalWorld, gameData);
|
return GameData.processIdRematches(missingMappings.values(), isLocalWorld, gameData, remaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fireRemapEvent(Map<String, Integer[]> remaps)
|
public void fireRemapEvent(Map<String, Integer[]> remaps)
|
||||||
|
|
|
@ -2,11 +2,14 @@ package cpw.mods.fml.common.event;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ListMultimap;
|
import com.google.common.collect.ListMultimap;
|
||||||
|
|
||||||
import cpw.mods.fml.common.FMLCommonHandler;
|
|
||||||
import cpw.mods.fml.common.ModContainer;
|
import cpw.mods.fml.common.ModContainer;
|
||||||
|
import cpw.mods.fml.common.registry.GameData;
|
||||||
import cpw.mods.fml.common.registry.GameRegistry;
|
import cpw.mods.fml.common.registry.GameRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,49 +31,102 @@ public class FMLMissingMappingsEvent extends FMLEvent {
|
||||||
* @author cpw
|
* @author cpw
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static enum Action { DEFAULT, IGNORE, WARN, FAIL }
|
public static enum Action { DEFAULT, IGNORE, WARN, FAIL, REMAP }
|
||||||
public static class MissingMapping {
|
public static class MissingMapping {
|
||||||
public final GameRegistry.Type type;
|
public final GameRegistry.Type type;
|
||||||
public final String name;
|
public final String name;
|
||||||
public final int id;
|
public final int id;
|
||||||
private Action action = Action.DEFAULT;
|
private Action action = Action.DEFAULT;
|
||||||
|
private Object target;
|
||||||
|
|
||||||
public MissingMapping(String name, int id)
|
public MissingMapping(String name, int id)
|
||||||
{
|
{
|
||||||
this.type = name.charAt(0) == '\u0001' ? GameRegistry.Type.BLOCK : GameRegistry.Type.ITEM;
|
this.type = name.charAt(0) == '\u0001' ? GameRegistry.Type.BLOCK : GameRegistry.Type.ITEM;
|
||||||
this.name = name;
|
this.name = name.substring(1);
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @deprecated use ignore(), warn() or fail() instead
|
* @deprecated use ignore(), warn(), fail() or remap() instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void setAction(Action target)
|
public void setAction(Action target)
|
||||||
{
|
{
|
||||||
if (target == Action.DEFAULT) throw new IllegalArgumentException();
|
if (target == Action.DEFAULT || target == Action.REMAP) throw new IllegalArgumentException();
|
||||||
|
|
||||||
this.action = target;
|
this.action = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignore the missing item.
|
||||||
|
*/
|
||||||
public void ignore()
|
public void ignore()
|
||||||
{
|
{
|
||||||
this.action = Action.IGNORE;
|
action = Action.IGNORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warn the user about the missing item.
|
||||||
|
*/
|
||||||
public void warn()
|
public void warn()
|
||||||
{
|
{
|
||||||
this.action = Action.WARN;
|
action = Action.WARN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent the world from loading due to the missing item.
|
||||||
|
*/
|
||||||
public void fail()
|
public void fail()
|
||||||
{
|
{
|
||||||
this.action = Action.FAIL;
|
action = Action.FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remap the missing item to the specified Block.
|
||||||
|
*
|
||||||
|
* Use this if you have renamed a Block, don't forget to handle the ItemBlock.
|
||||||
|
* Existing references using the old name will point to the new one.
|
||||||
|
*
|
||||||
|
* @param target Block to remap to.
|
||||||
|
*/
|
||||||
|
public void remap(Block target)
|
||||||
|
{
|
||||||
|
if (type != GameRegistry.Type.BLOCK) throw new IllegalArgumentException("Can't remap an item to a block.");
|
||||||
|
if (target == null) throw new NullPointerException("remap target is null");
|
||||||
|
if (GameData.getBlockRegistry().getId(target) < 0) throw new IllegalArgumentException(String.format("The specified block %s hasn't been registered at startup.", target));
|
||||||
|
|
||||||
|
action = Action.REMAP;
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remap the missing item to the specified Item.
|
||||||
|
*
|
||||||
|
* Use this if you have renamed an Item.
|
||||||
|
* Existing references using the old name will point to the new one.
|
||||||
|
*
|
||||||
|
* @param target Item to remap to.
|
||||||
|
*/
|
||||||
|
public void remap(Item target)
|
||||||
|
{
|
||||||
|
if (type != GameRegistry.Type.ITEM) throw new IllegalArgumentException("Can't remap a block to an item.");
|
||||||
|
if (target == null) throw new NullPointerException("remap target is null");
|
||||||
|
if (GameData.getItemRegistry().getId(target) < 0) throw new IllegalArgumentException(String.format("The specified item %s hasn't been registered at startup.", target));
|
||||||
|
|
||||||
|
action = Action.REMAP;
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal
|
||||||
|
|
||||||
public Action getAction()
|
public Action getAction()
|
||||||
{
|
{
|
||||||
return this.action;
|
return this.action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object getTarget()
|
||||||
|
{
|
||||||
|
return target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private ListMultimap<String,MissingMapping> missing;
|
private ListMultimap<String,MissingMapping> missing;
|
||||||
private ModContainer activeContainer;
|
private ModContainer activeContainer;
|
||||||
|
|
|
@ -15,6 +15,7 @@ import net.minecraft.util.RegistryNamespaced;
|
||||||
|
|
||||||
import com.google.common.collect.BiMap;
|
import com.google.common.collect.BiMap;
|
||||||
import com.google.common.collect.HashBiMap;
|
import com.google.common.collect.HashBiMap;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import cpw.mods.fml.common.FMLLog;
|
import cpw.mods.fml.common.FMLLog;
|
||||||
|
@ -25,10 +26,11 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||||
private final Class<I> superType;
|
private final Class<I> superType;
|
||||||
private String optionalDefaultName;
|
private String optionalDefaultName;
|
||||||
private I optionalDefaultObject;
|
private I optionalDefaultObject;
|
||||||
|
private int maxId;
|
||||||
int maxId;
|
|
||||||
private int minId;
|
private int minId;
|
||||||
private char discriminator;
|
private char discriminator;
|
||||||
|
// aliases redirecting legacy names to the actual name, may need recursive application to find the final name
|
||||||
|
private final Map<String, String> aliases = new HashMap<String, String>();
|
||||||
|
|
||||||
FMLControlledNamespacedRegistry(String optionalDefault, int maxIdValue, int minIdValue, Class<I> type, char discriminator)
|
FMLControlledNamespacedRegistry(String optionalDefault, int maxIdValue, int minIdValue, Class<I> type, char discriminator)
|
||||||
{
|
{
|
||||||
|
@ -47,6 +49,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||||
this.optionalDefaultName = registry.optionalDefaultName;
|
this.optionalDefaultName = registry.optionalDefaultName;
|
||||||
this.maxId = registry.maxId;
|
this.maxId = registry.maxId;
|
||||||
this.minId = registry.minId;
|
this.minId = registry.minId;
|
||||||
|
this.aliases.putAll(registry.aliases);
|
||||||
field_148759_a = new ObjectIntIdentityMap();
|
field_148759_a = new ObjectIntIdentityMap();
|
||||||
field_82596_a.clear();
|
field_82596_a.clear();
|
||||||
|
|
||||||
|
@ -58,6 +61,8 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public api
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an object to the registry, trying to use the specified id.
|
* Add an object to the registry, trying to use the specified id.
|
||||||
*
|
*
|
||||||
|
@ -70,6 +75,137 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||||
GameData.getMain().register(thing, name, id);
|
GameData.getMain().register(thing, name, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public I func_82594_a(String name)
|
||||||
|
{
|
||||||
|
I object = getRaw(name);
|
||||||
|
return object == null ? this.optionalDefaultObject : object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public I func_148754_a(int id)
|
||||||
|
{
|
||||||
|
I object = getRaw(id);
|
||||||
|
return object == null ? this.optionalDefaultObject : object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the object identified by the specified id.
|
||||||
|
*
|
||||||
|
* The default object is the air block for the block registry or null for the item registry.
|
||||||
|
*
|
||||||
|
* @param id Block/Item id.
|
||||||
|
* @return Block/Item object or the default object if it wasn't found.
|
||||||
|
*/
|
||||||
|
public I get(int id)
|
||||||
|
{
|
||||||
|
return func_148754_a(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the object identified by the specified name.
|
||||||
|
*
|
||||||
|
* The default object is the air block for the block registry or null for the item registry.
|
||||||
|
*
|
||||||
|
* @param name Block/Item name.
|
||||||
|
* @return Block/Item object or the default object if it wasn't found.
|
||||||
|
*/
|
||||||
|
public I get(String name)
|
||||||
|
{
|
||||||
|
return func_82594_a(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the id for the specified object.
|
||||||
|
*
|
||||||
|
* Don't hold onto the id across the world, it's being dynamically re-mapped as needed.
|
||||||
|
*
|
||||||
|
* Usually the name should be used instead of the id, if using the Block/Item object itself is
|
||||||
|
* not suitable for the task.
|
||||||
|
*
|
||||||
|
* @param think Block/Item object.
|
||||||
|
* @return Block/Item id or -1 if it wasn't found.
|
||||||
|
*/
|
||||||
|
public int getId(I thing)
|
||||||
|
{
|
||||||
|
return func_148757_b(thing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the object identified by the specified id.
|
||||||
|
*
|
||||||
|
* @param id Block/Item id.
|
||||||
|
* @return Block/Item object or null if it wasn't found.
|
||||||
|
*/
|
||||||
|
public I getRaw(int id)
|
||||||
|
{
|
||||||
|
return superType.cast(super.func_148754_a(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the object identified by the specified name.
|
||||||
|
*
|
||||||
|
* @param name Block/Item name.
|
||||||
|
* @return Block/Item object or null if it wasn't found.
|
||||||
|
*/
|
||||||
|
public I getRaw(String name)
|
||||||
|
{
|
||||||
|
I ret = superType.cast(super.func_82594_a(name));
|
||||||
|
|
||||||
|
if (ret == null) // no match, try aliases recursively
|
||||||
|
{
|
||||||
|
name = aliases.get(name);
|
||||||
|
|
||||||
|
if (name != null) return getRaw(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean func_148741_d(String name)
|
||||||
|
{
|
||||||
|
boolean ret = super.func_148741_d(name);
|
||||||
|
|
||||||
|
if (!ret) // no match, try aliases recursively
|
||||||
|
{
|
||||||
|
name = aliases.get(name);
|
||||||
|
|
||||||
|
if (name != null) return func_148741_d(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId(String itemName)
|
||||||
|
{
|
||||||
|
I obj = getRaw(itemName);
|
||||||
|
if (obj == null) return -1;
|
||||||
|
|
||||||
|
return getId(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(String itemName)
|
||||||
|
{
|
||||||
|
return func_148741_d(itemName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal
|
||||||
|
|
||||||
|
public void serializeInto(Map<String, Integer> idMapping)
|
||||||
|
{
|
||||||
|
for (Iterator<Object> it = iterator(); it.hasNext(); )
|
||||||
|
{
|
||||||
|
I thing = (I) it.next();
|
||||||
|
idMapping.put(discriminator+func_148750_c(thing), getId(thing));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getAliases()
|
||||||
|
{
|
||||||
|
return ImmutableMap.copyOf(aliases);
|
||||||
|
}
|
||||||
|
|
||||||
int add(int id, String name, I thing, BitSet availabilityMap)
|
int add(int id, String name, I thing, BitSet availabilityMap)
|
||||||
{
|
{
|
||||||
if (name.equals(optionalDefaultName))
|
if (name.equals(optionalDefaultName))
|
||||||
|
@ -98,30 +234,9 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||||
return idToUse;
|
return idToUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
void addAlias(String from, String to)
|
||||||
public I func_82594_a(String name)
|
|
||||||
{
|
{
|
||||||
I object = superType.cast(super.func_82594_a(name));
|
aliases.put(from, to);
|
||||||
return object == null ? this.optionalDefaultObject : object;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public I func_148754_a(int id)
|
|
||||||
{
|
|
||||||
I object = superType.cast(super.func_148754_a(id));
|
|
||||||
return object == null ? this.optionalDefaultObject : object;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private ObjectIntIdentityMap idMap()
|
|
||||||
{
|
|
||||||
return field_148759_a;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private BiMap<String,I> nameMap()
|
|
||||||
{
|
|
||||||
return (BiMap<String,I>) field_82596_a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String,Integer> getEntriesNotIn(FMLControlledNamespacedRegistry<I> registry)
|
Map<String,Integer> getEntriesNotIn(FMLControlledNamespacedRegistry<I> registry)
|
||||||
|
@ -137,53 +252,6 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public I get(int id)
|
|
||||||
{
|
|
||||||
return func_148754_a(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public I get(String name)
|
|
||||||
{
|
|
||||||
return func_82594_a(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId(I thing)
|
|
||||||
{
|
|
||||||
return func_148757_b(thing);
|
|
||||||
}
|
|
||||||
|
|
||||||
public I getRaw(int id)
|
|
||||||
{
|
|
||||||
return superType.cast(super.func_148754_a(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
public I getRaw(String name)
|
|
||||||
{
|
|
||||||
return superType.cast(super.func_82594_a(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void serializeInto(Map<String, Integer> idMapping)
|
|
||||||
{
|
|
||||||
for (Iterator<Object> it = iterator(); it.hasNext(); )
|
|
||||||
{
|
|
||||||
I thing = (I) it.next();
|
|
||||||
idMapping.put(discriminator+func_148750_c(thing), getId(thing));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId(String itemName)
|
|
||||||
{
|
|
||||||
I obj = getRaw(itemName);
|
|
||||||
if (obj == null) return -1;
|
|
||||||
|
|
||||||
return getId(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(String itemName)
|
|
||||||
{
|
|
||||||
return field_82596_a.containsKey(itemName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump()
|
void dump()
|
||||||
{
|
{
|
||||||
List<Integer> ids = new ArrayList<Integer>();
|
List<Integer> ids = new ArrayList<Integer>();
|
||||||
|
|
|
@ -15,6 +15,7 @@ package cpw.mods.fml.common.registry;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -47,6 +48,7 @@ import cpw.mods.fml.common.Loader;
|
||||||
import cpw.mods.fml.common.ModContainer;
|
import cpw.mods.fml.common.ModContainer;
|
||||||
import cpw.mods.fml.common.event.FMLMissingMappingsEvent;
|
import cpw.mods.fml.common.event.FMLMissingMappingsEvent;
|
||||||
import cpw.mods.fml.common.event.FMLMissingMappingsEvent.MissingMapping;
|
import cpw.mods.fml.common.event.FMLMissingMappingsEvent.MissingMapping;
|
||||||
|
import cpw.mods.fml.common.registry.GameRegistry.Type;
|
||||||
import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier;
|
import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier;
|
||||||
|
|
||||||
public class GameData {
|
public class GameData {
|
||||||
|
@ -205,10 +207,10 @@ public class GameData {
|
||||||
|
|
||||||
public static List<String> injectWorldIDMap(Map<String, Integer> dataList, boolean injectFrozenData, boolean isLocalWorld)
|
public static List<String> injectWorldIDMap(Map<String, Integer> dataList, boolean injectFrozenData, boolean isLocalWorld)
|
||||||
{
|
{
|
||||||
return injectWorldIDMap(dataList, new int[0], injectFrozenData, isLocalWorld);
|
return injectWorldIDMap(dataList, new int[0], new HashMap<String, String>(), new HashMap<String, String>(), injectFrozenData, isLocalWorld);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> injectWorldIDMap(Map<String, Integer> dataList, int[] blockedIds, boolean injectFrozenData, boolean isLocalWorld)
|
public static List<String> injectWorldIDMap(Map<String, Integer> dataList, int[] blockedIds, Map<String, String> blockAliases, Map<String, String> itemAliases, boolean injectFrozenData, boolean isLocalWorld)
|
||||||
{
|
{
|
||||||
FMLLog.info("Injecting existing block and item data into this %s instance", FMLCommonHandler.instance().getEffectiveSide().isServer() ? "server" : "client");
|
FMLLog.info("Injecting existing block and item data into this %s instance", FMLCommonHandler.instance().getEffectiveSide().isServer() ? "server" : "client");
|
||||||
Map<String, Integer[]> remaps = Maps.newHashMap();
|
Map<String, Integer[]> remaps = Maps.newHashMap();
|
||||||
|
@ -224,6 +226,16 @@ public class GameData {
|
||||||
newData.block(id);
|
newData.block(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> entry : blockAliases.entrySet())
|
||||||
|
{
|
||||||
|
newData.iBlockRegistry.addAlias(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> entry : itemAliases.entrySet())
|
||||||
|
{
|
||||||
|
newData.iItemRegistry.addAlias(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
// process blocks and items in the world, blocks in the first pass, items in the second
|
// 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
|
// blocks need to be added first for proper ItemBlock handling
|
||||||
for (int pass = 0; pass < 2; pass++)
|
for (int pass = 0; pass < 2; pass++)
|
||||||
|
@ -244,7 +256,7 @@ public class GameData {
|
||||||
if (currId == -1)
|
if (currId == -1)
|
||||||
{
|
{
|
||||||
FMLLog.info("Found a missing id from the world %s", itemName);
|
FMLLog.info("Found a missing id from the world %s", itemName);
|
||||||
missingMappings.put(itemName, newId);
|
missingMappings.put(entry.getKey(), newId);
|
||||||
continue; // no block/item -> nothing to add
|
continue; // no block/item -> nothing to add
|
||||||
}
|
}
|
||||||
else if (currId != newId)
|
else if (currId != newId)
|
||||||
|
@ -279,7 +291,7 @@ public class GameData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> missedMappings = Loader.instance().fireMissingMappingEvent(missingMappings, isLocalWorld, newData);
|
List<String> missedMappings = Loader.instance().fireMissingMappingEvent(missingMappings, isLocalWorld, newData, remaps);
|
||||||
if (!missedMappings.isEmpty()) return missedMappings;
|
if (!missedMappings.isEmpty()) return missedMappings;
|
||||||
|
|
||||||
if (injectFrozenData) // add blocks + items missing from the map
|
if (injectFrozenData) // add blocks + items missing from the map
|
||||||
|
@ -327,15 +339,52 @@ public class GameData {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> processIdRematches(Iterable<MissingMapping> remaps, boolean isLocalWorld, GameData gameData)
|
public static List<String> processIdRematches(Iterable<MissingMapping> missedMappings, boolean isLocalWorld, GameData gameData, Map<String, Integer[]> remaps)
|
||||||
{
|
{
|
||||||
List<String> failed = Lists.newArrayList();
|
List<String> failed = Lists.newArrayList();
|
||||||
List<String> ignored = Lists.newArrayList();
|
List<String> ignored = Lists.newArrayList();
|
||||||
List<String> warned = Lists.newArrayList();
|
List<String> warned = Lists.newArrayList();
|
||||||
|
|
||||||
for (MissingMapping remap : remaps)
|
for (MissingMapping remap : missedMappings)
|
||||||
{
|
{
|
||||||
FMLMissingMappingsEvent.Action action = remap.getAction();
|
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.func_148750_c(remap.getTarget());
|
||||||
|
FMLLog.fine("The Block %s is being remapped to %s.", remap.name, newName);
|
||||||
|
|
||||||
|
newId = gameData.registerBlock((Block) remap.getTarget(), newName, null, remap.id);
|
||||||
|
gameData.iBlockRegistry.addAlias(remap.name, newName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currId = getMain().iItemRegistry.getId((Item) remap.getTarget());
|
||||||
|
newName = getMain().iItemRegistry.func_148750_c(remap.getTarget());
|
||||||
|
FMLLog.fine("The Item %s is being remapped to %s.", remap.name, newName);
|
||||||
|
|
||||||
|
newId = gameData.registerItem((Item) remap.getTarget(), newName, null, remap.id);
|
||||||
|
gameData.iItemRegistry.addAlias(remap.name, newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newId != remap.id) throw new IllegalStateException();
|
||||||
|
|
||||||
|
if (currId != newId)
|
||||||
|
{
|
||||||
|
FMLLog.info("Found %s id mismatch %s : %d (was %d)", remap.type == Type.BLOCK ? "block" : "item", newName, currId, newId);
|
||||||
|
remaps.put(newName, new Integer[] { currId, newId });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// block item missing, warn as requested and block the id
|
||||||
if (action == FMLMissingMappingsEvent.Action.DEFAULT)
|
if (action == FMLMissingMappingsEvent.Action.DEFAULT)
|
||||||
{
|
{
|
||||||
action = FMLCommonHandler.instance().getDefaultMissingAction();
|
action = FMLCommonHandler.instance().getDefaultMissingAction();
|
||||||
|
@ -353,9 +402,14 @@ public class GameData {
|
||||||
{
|
{
|
||||||
warned.add(remap.name);
|
warned.add(remap.name);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new RuntimeException(String.format("Invalid default missing id action specified: %s", action.name()));
|
||||||
|
}
|
||||||
|
|
||||||
gameData.block(remap.id); // prevent the id from being reused later
|
gameData.block(remap.id); // prevent the id from being reused later
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!failed.isEmpty())
|
if (!failed.isEmpty())
|
||||||
{
|
{
|
||||||
FMLLog.severe("This world contains blocks and items that refuse to be remapped. The world will not be loaded");
|
FMLLog.severe("This world contains blocks and items that refuse to be remapped. The world will not be loaded");
|
||||||
|
|
Loading…
Reference in a new issue