First attempt at making FMLControlledRegistry something a bit more generic than just blocks/items.

It probably doesn't work yet though.
This commit is contained in:
cpw 2015-03-15 16:22:28 -04:00
parent 418b7794d2
commit d81fd22792
3 changed files with 114 additions and 8 deletions

View file

@ -93,6 +93,11 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
}
}
@SuppressWarnings("unchecked")
void setFrom(FMLControlledNamespacedRegistry<?> registry) {
set((FMLControlledNamespacedRegistry<I>) registry);
}
void set(FMLControlledNamespacedRegistry<I> registry)
{
if (this.superType != registry.superType) throw new IllegalArgumentException("incompatible registry");
@ -520,4 +525,9 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
if (this.optionalDefaultKey != null)
Validate.notNull(this.optionalDefaultObject);
}
FMLControlledNamespacedRegistry<I> makeShallowCopy() {
return new FMLControlledNamespacedRegistry<I>(optionalDefaultKey, maxId, minId, superType);
}
}

View file

@ -142,6 +142,9 @@ public class GameData {
GameDataSnapshot snap = new GameDataSnapshot();
snap.entries.put("fml:blocks", new GameDataSnapshot.Entry(getMain().getBlockRegistry()));
snap.entries.put("fml:items", new GameDataSnapshot.Entry(getMain().getItemRegistry()));
for (Map.Entry<String, FMLControlledNamespacedRegistry<?>> e : getMain().genericRegistries.entrySet()) {
snap.entries.put("fmlgr:"+e.getKey(), new GameDataSnapshot.Entry(e.getValue()));
}
return snap;
}
@ -445,6 +448,11 @@ public class GameData {
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);
@ -665,6 +673,7 @@ public class GameData {
iItemRegistry = new FMLControlledNamespacedRegistry<Item>(null, MAX_ITEM_ID, MIN_ITEM_ID, Item.class);
availabilityMap = new BitSet(MAX_ITEM_ID + 1);
blockedIds = new HashSet<Integer>();
genericRegistries = new HashMap<String,FMLControlledNamespacedRegistry<?>>();
}
private GameData(GameData data)
@ -681,6 +690,17 @@ public class GameData {
availabilityMap.or(data.availabilityMap);
blockedIds.clear();
blockedIds.addAll(data.blockedIds);
copyGenericRegistries(data);
}
private void copyGenericRegistries(GameData data) {
for (Map.Entry<String, FMLControlledNamespacedRegistry<?>> e : data.genericRegistries.entrySet()) {
FMLControlledNamespacedRegistry<?> orig = e.getValue();
FMLControlledNamespacedRegistry<?> copy = orig.makeShallowCopy();
// UGLY AS FUCK
copy.setFrom(orig);
genericRegistries.put(e.getKey(), copy);
}
}
int register(Object obj, String name, int idHint) // from FMLControlledNamespacedRegistry.addObject
@ -966,4 +986,65 @@ public class GameData {
this.objectList.clear();
}
}
private Map<String,FMLControlledNamespacedRegistry<?>> genericRegistries;
@SuppressWarnings("unchecked")
private <T> FMLControlledNamespacedRegistry<T> getGenericRegistry(String registryName, Class<T> type) {
FMLControlledNamespacedRegistry<?> fmlControlledNamespacedRegistry = genericRegistries.get(registryName);
return (FMLControlledNamespacedRegistry<T>) fmlControlledNamespacedRegistry;
}
@SuppressWarnings("unchecked")
private <T> FMLControlledNamespacedRegistry<T> createGenericRegistry(String registryName, Class<T> type, int minId, int maxId) {
FMLControlledNamespacedRegistry<?> fmlControlledNamespacedRegistry = new FMLControlledNamespacedRegistry<T>(null, maxId, minId, type);
return (FMLControlledNamespacedRegistry<T>) fmlControlledNamespacedRegistry;
}
public static <T> FMLControlledNamespacedRegistry<T> createRegistry(String registryName, Class<T> type, int minId, int maxId) {
return getMain().createGenericRegistry(registryName, type, minId, maxId);
}
private List<String> loadGenericRegistries(GameDataSnapshot snapshot, GameData existing) {
List<String> result = Lists.newArrayList();
for (Map.Entry<String, FMLControlledNamespacedRegistry<?>> e : existing.genericRegistries.entrySet())
{
String regName = e.getKey();
FMLControlledNamespacedRegistry<?> registry = e.getValue();
FMLControlledNamespacedRegistry<?> newRegistry = genericRegistries.get(regName);
GameDataSnapshot.Entry regSnap = snapshot.entries.get("fmlgr:"+regName);
if (regSnap == null) {
FMLLog.info("Weird, there was no registry data for registry %s found in the snapshot", regName);
continue;
}
for (Entry<String, Integer> entry : regSnap.ids.entrySet())
{
String entryName = entry.getKey();
int entryId = entry.getValue();
int currId = registry.getId(entryName);
if (currId == -1)
{
FMLLog.info("Found a missing id in registry %s from the world %s", regName, entryName);
result.add(regName+"{"+entryName+"}="+entryId);
continue; // no block/item -> nothing to add
}
else if (currId != entryId)
{
FMLLog.fine("Fixed registry %s id mismatch %s: %d (init) -> %d (map).", regName, entryName, currId, entryId);
}
newRegistry.register(entryId, entryName, registry.getRaw(entryName));
}
}
return result;
}
public static <T> FMLControlledNamespacedRegistry<T> getRegistry(String registryName, Class<T> type) {
return getMain().getGenericRegistry(registryName, type);
}
}

View file

@ -20,9 +20,11 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import org.apache.commons.lang3.Validate;
import net.minecraft.block.Block;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.passive.EntityVillager.*;
import net.minecraft.init.Blocks;
@ -31,6 +33,8 @@ import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ObjectIntIdentityMap;
import net.minecraft.util.RegistryNamespacedDefaultedByKey;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Tuple;
import net.minecraft.village.MerchantRecipeList;
@ -112,6 +116,7 @@ public class VillagerRegistry
* Register your villager id
* @param id
*/
@Deprecated // Doesn't work at all.
public void registerVillagerId(int id)
{
if (newVillagerIds.contains(id))
@ -128,6 +133,7 @@ public class VillagerRegistry
* @param villagerSkin
*/
@SideOnly(Side.CLIENT)
@Deprecated // Doesn't work at all.
public void registerVillagerSkin(int villagerId, ResourceLocation villagerSkin)
{
if (newVillagers == null)
@ -154,6 +160,7 @@ public class VillagerRegistry
* @param defaultSkin
*/
@SideOnly(Side.CLIENT)
@Deprecated // Doesn't work at all.
public static ResourceLocation getVillagerSkin(int villagerType, ResourceLocation defaultSkin)
{
if (instance().newVillagers != null && instance().newVillagers.containsKey(villagerType))
@ -168,6 +175,7 @@ public class VillagerRegistry
*
* @return newVillagerIds
*/
@Deprecated // Doesn't work at all.
public static Collection<Integer> getRegisteredVillagers()
{
return Collections.unmodifiableCollection(instance().newVillagerIds);
@ -191,12 +199,15 @@ public class VillagerRegistry
public void register(VillagerProfession prof)
{
//blah
register(prof, -1);
}
private void register(VillagerProfession prof, int id)
{
professions.register(id, prof.name, prof);
}
private boolean hasInit = false;
private List<VillagerProfession> professions = Lists.newArrayList();
private FMLControlledNamespacedRegistry<VillagerProfession> professions = GameData.createRegistry("villagerprofessions", VillagerProfession.class, 0, 1024);
private void init()
@ -206,7 +217,7 @@ public class VillagerRegistry
VillagerProfession prof = new VillagerProfession("minecraft:farmer", "minecraft:textures/entity/villager/farmer.png");
{
register(prof);
register(prof, 0);
(new VillagerCareer(prof, "farmer" )).init(VanillaTrades.trades[0][0]);
(new VillagerCareer(prof, "fisherman" )).init(VanillaTrades.trades[0][1]);
(new VillagerCareer(prof, "shepherd" )).init(VanillaTrades.trades[0][2]);
@ -214,24 +225,24 @@ public class VillagerRegistry
}
prof = new VillagerProfession("minecraft:librarian", "minecraft:textures/entity/villager/librarian.png");
{
register(prof);
register(prof, 1);
(new VillagerCareer(prof, "librarian")).init(VanillaTrades.trades[1][0]);
}
prof = new VillagerProfession("minecraft:priest", "minecraft:textures/entity/villager/priest.png");
{
register(prof);
register(prof, 2);
(new VillagerCareer(prof, "cleric")).init(VanillaTrades.trades[2][0]);
}
prof = new VillagerProfession("minecraft:smith", "minecraft:textures/entity/villager/smith.png");
{
register(prof);
register(prof, 3);
(new VillagerCareer(prof, "armor" )).init(VanillaTrades.trades[3][0]);
(new VillagerCareer(prof, "weapon")).init(VanillaTrades.trades[3][1]);
(new VillagerCareer(prof, "tool" )).init(VanillaTrades.trades[3][2]);
}
prof = new VillagerProfession("minecraft:butcher", "minecraft:textures/entity/villager/butcher.png");
{
register(prof);
register(prof, 4);
(new VillagerCareer(prof, "butcher")).init(VanillaTrades.trades[4][0]);
(new VillagerCareer(prof, "leather")).init(VanillaTrades.trades[4][1]);
}
@ -242,11 +253,13 @@ public class VillagerRegistry
private ResourceLocation name;
private ResourceLocation texture;
private List<VillagerCareer> careers = Lists.newArrayList();
private RegistryDelegate<VillagerProfession> delegate = GameData.getRegistry("villagerprofessions", VillagerProfession.class).getDelegate(this, VillagerProfession.class);
public VillagerProfession(String name, String texture)
{
this.name = new ResourceLocation(name);
this.texture = new ResourceLocation(texture);
((RegistryDelegate.Delegate<VillagerProfession>)delegate).setName(name);
}
private void register(VillagerCareer career)
@ -293,6 +306,8 @@ public class VillagerRegistry
*/
public static void setRandomProfession(EntityVillager entity, Random rand)
{
Set<String> entries = INSTANCE.professions.getKeys();
int prof = rand.nextInt(entries.size());
//TODO: Grab id range from internal registry
entity.setProfession(rand.nextInt(5));
}