mirror of
https://github.com/GTNewHorizons/NotEnoughItems.git
synced 2026-11-15 09:44:44 +00:00
Compare commits
29
Commits
mu
...
2.8.61-GTNH-pre
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83c54ec6c6 | ||
|
|
688c2c1f36 | ||
|
|
22280ea320 | ||
|
|
6df14438c5 | ||
|
|
0b1019bdf0 | ||
|
|
a811d20299 | ||
|
|
4e1835ed12 | ||
|
|
1db5809cde | ||
|
|
fa4411ad2e | ||
|
|
80f7455e7f | ||
|
|
b9cac67ec7 | ||
|
|
41a6cc0711 | ||
|
|
319ed409f1 | ||
|
|
ad153f1c0a | ||
|
|
e340423b28 | ||
|
|
7b0feb16f9 | ||
|
|
e0b34e8b9a | ||
|
|
c533f6f1b5 | ||
|
|
140977be2e | ||
|
|
8a13af1969 | ||
|
|
d6d50a968d | ||
|
|
43459d4b41 | ||
|
|
2a1aff073b | ||
|
|
73eea57d11 | ||
|
|
9b84ea7804 | ||
|
|
de42a43b2c | ||
|
|
b89734f3e6 | ||
|
|
7445d96531 | ||
|
|
dc997626c1 |
@@ -1,8 +1,11 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -26,10 +29,19 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
public class ItemMobSpawner extends ItemBlock {
|
||||
|
||||
private static final Map<Integer, EntityLiving> entityHashMap = new HashMap<>();
|
||||
private static final Map<Integer, String> IDtoNameMap = new HashMap<>();
|
||||
public static int idPig;
|
||||
private static boolean loaded;
|
||||
private static final Map<Integer, EntityLiving> entityHashMap = Collections.synchronizedMap(new WeakHashMap<>());
|
||||
private static final Map<Integer, String> IDtoNameMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static int idPig = 90;
|
||||
private static boolean loaded = false;
|
||||
|
||||
private static final ThreadLocal<PlacementContext> placementContext = ThreadLocal
|
||||
.withInitial(PlacementContext::new);
|
||||
|
||||
private static class PlacementContext {
|
||||
|
||||
int x, y, z;
|
||||
}
|
||||
|
||||
public ItemMobSpawner() {
|
||||
super(Blocks.mob_spawner);
|
||||
@@ -37,99 +49,218 @@ public class ItemMobSpawner extends ItemBlock {
|
||||
MinecraftForgeClient.registerItemRenderer(this, new SpawnerRenderer());
|
||||
}
|
||||
|
||||
/**
|
||||
* These are ASM translated from BlockMobSpawner
|
||||
*/
|
||||
public static int placedX;
|
||||
public static int placedY;
|
||||
public static int placedZ;
|
||||
|
||||
@Override
|
||||
public IIcon getIconFromDamage(int par1) {
|
||||
public IIcon getIconFromDamage(int meta) {
|
||||
return Blocks.mob_spawner.getBlockTextureFromSide(0);
|
||||
}
|
||||
|
||||
public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int x, int y, int z, int par7,
|
||||
float par8, float par9, float par10) {
|
||||
if (super.onItemUse(itemstack, entityplayer, world, x, y, z, par7, par8, par9, par10) && world.isRemote) {
|
||||
TileEntityMobSpawner tileentitymobspawner = (TileEntityMobSpawner) world
|
||||
.getTileEntity(placedX, placedY, placedZ);
|
||||
if (tileentitymobspawner != null) {
|
||||
setDefaultTag(itemstack);
|
||||
String mobtype = IDtoNameMap.get(itemstack.getItemDamage());
|
||||
if (mobtype != null) {
|
||||
NEICPH.sendMobSpawnerID(placedX, placedY, placedZ, mobtype);
|
||||
tileentitymobspawner.func_145881_a().setEntityName(mobtype);
|
||||
public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int x, int y, int z, int side,
|
||||
float hitX, float hitY, float hitZ) {
|
||||
boolean placed = super.onItemUse(itemstack, entityplayer, world, x, y, z, side, hitX, hitY, hitZ);
|
||||
|
||||
if (placed && world.isRemote) {
|
||||
TileEntityMobSpawner spawner = (TileEntityMobSpawner) world.getTileEntity(x, y, z);
|
||||
if (spawner != null) {
|
||||
String mobType = getMobTypeFromItemStack(itemstack);
|
||||
if (mobType != null) {
|
||||
NEICPH.sendMobSpawnerID(x, y, z, mobType);
|
||||
spawner.func_145881_a().setEntityName(mobType);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return placed;
|
||||
}
|
||||
|
||||
private String getMobTypeFromItemStack(ItemStack stack) {
|
||||
int meta = getValidMetaData(stack);
|
||||
return IDtoNameMap.get(meta);
|
||||
}
|
||||
|
||||
private int getValidMetaData(ItemStack stack) {
|
||||
int meta = stack.getItemDamage();
|
||||
if (meta == 0 || !IDtoNameMap.containsKey(meta)) {
|
||||
return idPig;
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void addInformation(ItemStack itemstack, EntityPlayer par2EntityPlayer, List<String> list, boolean par4) {
|
||||
setDefaultTag(itemstack);
|
||||
int meta = itemstack.getItemDamage();
|
||||
if (meta == 0) {
|
||||
meta = idPig;
|
||||
public void addInformation(ItemStack itemstack, EntityPlayer player, List<String> tooltip, boolean advanced) {
|
||||
int meta = getValidMetaData(itemstack);
|
||||
EntityLiving entity = getEntity(meta);
|
||||
String mobName = IDtoNameMap.get(meta);
|
||||
|
||||
if (entity != null && mobName != null) {
|
||||
EnumChatFormatting color = (entity instanceof IMob) ? EnumChatFormatting.DARK_RED
|
||||
: EnumChatFormatting.DARK_AQUA;
|
||||
tooltip.add(color + mobName);
|
||||
}
|
||||
Entity e = getEntity(meta);
|
||||
list.add(
|
||||
(e instanceof IMob ? EnumChatFormatting.DARK_RED : EnumChatFormatting.DARK_AQUA)
|
||||
+ IDtoNameMap.get(meta));
|
||||
}
|
||||
|
||||
public static EntityLiving getEntity(int ID) {
|
||||
EntityLiving e = entityHashMap.get(ID);
|
||||
if (e == null) {
|
||||
loadSpawners();
|
||||
Class<?> clazz = EntityList.IDtoClassMapping.get(ID);
|
||||
World world = NEIClientUtils.mc().theWorld;
|
||||
try {
|
||||
e = (EntityLiving) clazz.getConstructor(new Class[] { World.class }).newInstance(world);
|
||||
} catch (Throwable t) {
|
||||
if (clazz == null)
|
||||
NEIClientConfig.logger.error("Null class for entity (" + ID + ", " + IDtoNameMap.get(ID));
|
||||
else NEIClientConfig.logger.error("Error creating instance of entity: " + clazz.getName(), t);
|
||||
e = getEntity(idPig);
|
||||
}
|
||||
entityHashMap.put(ID, e);
|
||||
public static EntityLiving getEntity(int id) {
|
||||
EntityLiving cached = entityHashMap.get(id);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
return e;
|
||||
|
||||
loadSpawners();
|
||||
|
||||
Class<?> entityClass = (Class<?>) EntityList.IDtoClassMapping.get(id);
|
||||
World world = NEIClientUtils.mc() != null ? NEIClientUtils.mc().theWorld : null;
|
||||
|
||||
if (isInvalidEntityClass(entityClass)) {
|
||||
return cacheFallback(id);
|
||||
}
|
||||
|
||||
EntityLiving entity = createEntityInstance(entityClass, world, id);
|
||||
if (entity != null) {
|
||||
entityHashMap.put(id, entity);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private static boolean isInvalidEntityClass(Class<?> entityClass) {
|
||||
if (entityClass == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int modifiers = entityClass.getModifiers();
|
||||
if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers)) {
|
||||
NEIClientConfig.logger.warn("Skipping abstract entity class: " + entityClass.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static EntityLiving createEntityInstance(Class<?> entityClass, World world, int id) {
|
||||
if (entityClass == null || world == null) {
|
||||
return getFallbackEntity(id);
|
||||
}
|
||||
|
||||
try {
|
||||
return (EntityLiving) entityClass.getConstructor(World.class).newInstance(world);
|
||||
} catch (Throwable t) {
|
||||
logEntityCreationError(entityClass, id, t);
|
||||
return getFallbackEntity(id);
|
||||
}
|
||||
}
|
||||
|
||||
private static void logEntityCreationError(Class<?> entityClass, int id, Throwable t) {
|
||||
if (entityClass == null) {
|
||||
NEIClientConfig.logger
|
||||
.error("Null class for entity (ID: {}, Name: {})", id, IDtoNameMap.getOrDefault(id, "unknown"));
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Error creating instance of entity: " + entityClass.getName(), t);
|
||||
}
|
||||
}
|
||||
|
||||
private static EntityLiving cacheFallback(int id) {
|
||||
EntityLiving fallback = getFallbackEntity(id);
|
||||
if (fallback != null) {
|
||||
entityHashMap.put(id, fallback);
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
private static EntityLiving getFallbackEntity(int originalId) {
|
||||
EntityLiving pig = entityHashMap.get(idPig);
|
||||
if (pig == null) {
|
||||
World world = NEIClientUtils.mc() != null ? NEIClientUtils.mc().theWorld : null;
|
||||
|
||||
if (world != null) {
|
||||
try {
|
||||
pig = new EntityPig(world);
|
||||
entityHashMap.put(idPig, pig);
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Failed to create fallback pig entity", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pig == null && originalId != idPig) {
|
||||
NEIClientConfig.logger
|
||||
.warn("Using null fallback for entity ID: {}, original fallback ID: {}", originalId, idPig);
|
||||
}
|
||||
|
||||
return pig;
|
||||
}
|
||||
|
||||
public static void clearEntityReferences() {
|
||||
entityHashMap.clear();
|
||||
}
|
||||
|
||||
private void setDefaultTag(ItemStack itemstack) {
|
||||
if (!IDtoNameMap.containsKey(itemstack.getItemDamage())) itemstack.setItemDamage(idPig);
|
||||
}
|
||||
|
||||
public static void loadSpawners() {
|
||||
if (loaded) return;
|
||||
loaded = true;
|
||||
for (Map.Entry<Class<? extends Entity>, String> entry : EntityList.classToStringMapping.entrySet()) {
|
||||
final Class<? extends Entity> clazz = entry.getKey();
|
||||
if (EntityLiving.class.isAssignableFrom(clazz)) {
|
||||
Integer id = (Integer) EntityList.classToIDMapping.get(clazz);
|
||||
if (id == null) continue;
|
||||
String name = entry.getValue();
|
||||
if (name == null) continue;
|
||||
if (name.equals("EnderDragon")) continue;
|
||||
if (name.equals("Pig")) idPig = id;
|
||||
if (clazz != EntityPig.class || name.equals("Pig")) {
|
||||
IDtoNameMap.put(id, name);
|
||||
if (loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (ItemMobSpawner.class) {
|
||||
if (loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for (Object entry : EntityList.classToStringMapping.entrySet()) {
|
||||
Map.Entry<Class<? extends Entity>, String> mapEntry = (Map.Entry<Class<? extends Entity>, String>) entry;
|
||||
|
||||
Class<? extends Entity> clazz = mapEntry.getKey();
|
||||
String name = mapEntry.getValue();
|
||||
|
||||
if (shouldRegisterEntity(clazz, name)) {
|
||||
Integer id = (Integer) EntityList.classToIDMapping.get(clazz);
|
||||
if (id != null) {
|
||||
IDtoNameMap.put(id, name);
|
||||
if ("Pig".equals(name)) {
|
||||
idPig = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loaded = true;
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Error loading spawners", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldRegisterEntity(Class<? extends Entity> clazz, String name) {
|
||||
if (clazz == null || name == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!EntityLiving.class.isAssignableFrom(clazz)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ("EnderDragon".equals(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems(Item item, CreativeTabs tab, List<ItemStack> list) {
|
||||
if (!NEIClientConfig.hasSMPCounterPart()) list.add(new ItemStack(item));
|
||||
else for (int i : IDtoNameMap.keySet()) list.add(new ItemStack(item, 1, i));
|
||||
if (!NEIClientConfig.hasSMPCounterPart()) {
|
||||
list.add(new ItemStack(item));
|
||||
} else {
|
||||
for (int id : IDtoNameMap.keySet()) {
|
||||
list.add(new ItemStack(item, 1, id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getEntityNameForMeta(int meta) {
|
||||
loadSpawners();
|
||||
return IDtoNameMap.getOrDefault(meta, IDtoNameMap.getOrDefault(idPig, "Pig"));
|
||||
}
|
||||
|
||||
public static boolean isValidEntityMeta(int meta) {
|
||||
loadSpawners();
|
||||
return IDtoNameMap.containsKey(meta) || meta == 0;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user