From cb383c824c3f799e678fb98f29661d79b5a13836 Mon Sep 17 00:00:00 2001 From: Jakub <53441451+kuba6000@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:53:16 +0200 Subject: Use mixins accessors + some misc fixes (#77) * Change reflections to mixins * Wrap witchery checking * Remove more repeating code * hmm * test generation * test * client sided * Update CommandCustomDrops.java * Update MobRecipeLoader.java * Save to static variable * Imports * Log message * Convert InfernalHelper to mixin accessors * Update build.gradle * One more * Return class nodes to optimize * Translations mixin * Automatically add commands * Fixes * Fix https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/12021 * Update kubatech.java * Update CommonProxy.java * Unnecessary qualified reference * Simplify ItemUtils * Check if single player diffrently * Remove accessor for infernal-mobs --- src/main/java/kubatech/CommonProxy.java | 8 - .../java/kubatech/api/helpers/InfernalHelper.java | 231 ------ .../kubatech/api/helpers/ReflectionHelper.java | 63 ++ .../api/network/CustomTileEntityPacket.java | 2 +- src/main/java/kubatech/api/utils/ItemUtils.java | 26 + src/main/java/kubatech/api/utils/MobUtils.java | 16 +- src/main/java/kubatech/api/utils/ModUtils.java | 14 + src/main/java/kubatech/commands/CommandBees.java | 6 +- src/main/java/kubatech/commands/CommandConfig.java | 1 + .../java/kubatech/commands/CommandCustomDrops.java | 67 ++ .../java/kubatech/commands/CommandHandler.java | 30 +- src/main/java/kubatech/commands/CommandHelp.java | 1 + src/main/java/kubatech/commands/CommandTea.java | 1 + src/main/java/kubatech/kubatech.java | 19 +- .../java/kubatech/loaders/MobRecipeLoader.java | 922 +++++++++++---------- src/main/java/kubatech/mixin/Mixin.java | 12 +- .../java/kubatech/mixin/MixinsVariablesHelper.java | 6 + src/main/java/kubatech/mixin/TargetedMod.java | 4 +- .../mixin/mixins/minecraft/EntityAccessor.java | 15 + .../mixins/minecraft/EntityLivingAccessor.java | 16 + .../mixins/minecraft/EntityLivingBaseAccessor.java | 16 + .../mixins/minecraft/EntitySlimeAccessor.java | 13 + .../mixins/minecraft/LanguageRegistryMixin.java | 27 + .../mixin/mixins/minecraft/LocaleMixin.java | 47 ++ .../minecraft/RendererLivingEntityAccessor.java | 15 + .../mixins/minecraft/StringTranslateMixin.java | 33 + .../mixin/mixins/minecraft/WorldMixin.java | 12 +- src/main/java/kubatech/nei/Mob_Handler.java | 25 +- src/main/java/kubatech/standalone.java | 15 + ...MetaTileEntity_ExtremeIndustrialGreenhouse.java | 34 +- .../GT_MetaTileEntity_MegaIndustrialApiary.java | 10 +- 31 files changed, 943 insertions(+), 764 deletions(-) delete mode 100644 src/main/java/kubatech/api/helpers/InfernalHelper.java create mode 100644 src/main/java/kubatech/api/utils/ItemUtils.java create mode 100644 src/main/java/kubatech/commands/CommandCustomDrops.java create mode 100644 src/main/java/kubatech/mixin/MixinsVariablesHelper.java create mode 100644 src/main/java/kubatech/mixin/mixins/minecraft/EntityAccessor.java create mode 100644 src/main/java/kubatech/mixin/mixins/minecraft/EntityLivingAccessor.java create mode 100644 src/main/java/kubatech/mixin/mixins/minecraft/EntityLivingBaseAccessor.java create mode 100644 src/main/java/kubatech/mixin/mixins/minecraft/EntitySlimeAccessor.java create mode 100644 src/main/java/kubatech/mixin/mixins/minecraft/LanguageRegistryMixin.java create mode 100644 src/main/java/kubatech/mixin/mixins/minecraft/LocaleMixin.java create mode 100644 src/main/java/kubatech/mixin/mixins/minecraft/RendererLivingEntityAccessor.java create mode 100644 src/main/java/kubatech/mixin/mixins/minecraft/StringTranslateMixin.java create mode 100644 src/main/java/kubatech/standalone.java (limited to 'src/main/java') diff --git a/src/main/java/kubatech/CommonProxy.java b/src/main/java/kubatech/CommonProxy.java index b0d8446211..267efdab21 100644 --- a/src/main/java/kubatech/CommonProxy.java +++ b/src/main/java/kubatech/CommonProxy.java @@ -36,11 +36,7 @@ import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.event.FMLServerStoppedEvent; import cpw.mods.fml.common.event.FMLServerStoppingEvent; import kubatech.api.LoaderReference; -import kubatech.commands.CommandBees; -import kubatech.commands.CommandConfig; import kubatech.commands.CommandHandler; -import kubatech.commands.CommandHelp; -import kubatech.commands.CommandTea; import kubatech.config.Config; import kubatech.loaders.MTLoader; import kubatech.loaders.RecipeLoader; @@ -76,10 +72,6 @@ public class CommonProxy { public void serverStarting(FMLServerStartingEvent event) { RecipeLoader.addRecipesLate(); CommandHandler cmd = new CommandHandler(); - cmd.addCommand(new CommandHelp()); - cmd.addCommand(new CommandConfig()); - cmd.addCommand(new CommandBees()); - cmd.addCommand(new CommandTea()); event.registerServerCommand(cmd); } diff --git a/src/main/java/kubatech/api/helpers/InfernalHelper.java b/src/main/java/kubatech/api/helpers/InfernalHelper.java deleted file mode 100644 index e3c0db456b..0000000000 --- a/src/main/java/kubatech/api/helpers/InfernalHelper.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * spotless:off - * KubaTech - Gregtech Addon - * Copyright (C) 2022 - 2023 kuba6000 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - * spotless:on - */ - -package kubatech.api.helpers; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; - -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.item.ItemStack; - -import atomicstryker.infernalmobs.common.InfernalMobsCore; -import atomicstryker.infernalmobs.common.mods.api.ModifierLoader; - -@SuppressWarnings("unchecked") -public class InfernalHelper { - - private static Method isClassAllowed = null; - - public static boolean isClassAllowed(EntityLivingBase e) { - try { - if (isClassAllowed == null) { - isClassAllowed = InfernalMobsCore.class.getDeclaredMethod("isClassAllowed", EntityLivingBase.class); - isClassAllowed.setAccessible(true); - } - return (boolean) isClassAllowed.invoke(InfernalMobsCore.instance(), e); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return false; - } - - private static Method checkEntityClassForced = null; - - public static boolean checkEntityClassForced(EntityLivingBase e) { - try { - if (checkEntityClassForced == null) { - checkEntityClassForced = InfernalMobsCore.class - .getDeclaredMethod("checkEntityClassForced", EntityLivingBase.class); - checkEntityClassForced.setAccessible(true); - } - return (boolean) checkEntityClassForced.invoke(InfernalMobsCore.instance(), e); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return false; - } - - private static Field modifierLoaders = null; - - public static ArrayList> getModifierLoaders() { - try { - if (modifierLoaders == null) { - modifierLoaders = InfernalMobsCore.class.getDeclaredField("modifierLoaders"); - modifierLoaders.setAccessible(true); - } - return (ArrayList>) modifierLoaders.get(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return new ArrayList<>(); - } - - private static Field eliteRarity; - - public static int getEliteRarity() { - try { - if (eliteRarity == null) { - eliteRarity = InfernalMobsCore.class.getDeclaredField("eliteRarity"); - eliteRarity.setAccessible(true); - } - return eliteRarity.getInt(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return 15; - } - - private static Field ultraRarity; - - public static int getUltraRarity() { - try { - if (ultraRarity == null) { - ultraRarity = InfernalMobsCore.class.getDeclaredField("ultraRarity"); - ultraRarity.setAccessible(true); - } - return ultraRarity.getInt(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return 15; - } - - private static Field infernoRarity; - - public static int getInfernoRarity() { - try { - if (infernoRarity == null) { - infernoRarity = InfernalMobsCore.class.getDeclaredField("infernoRarity"); - infernoRarity.setAccessible(true); - } - return infernoRarity.getInt(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return 15; - } - - private static Field minEliteModifiers; - - public static int getMinEliteModifiers() { - try { - if (minEliteModifiers == null) { - minEliteModifiers = InfernalMobsCore.class.getDeclaredField("minEliteModifiers"); - minEliteModifiers.setAccessible(true); - } - return minEliteModifiers.getInt(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return 15; - } - - private static Field minUltraModifiers; - - public static int getMinUltraModifiers() { - try { - if (minUltraModifiers == null) { - minUltraModifiers = InfernalMobsCore.class.getDeclaredField("minUltraModifiers"); - minUltraModifiers.setAccessible(true); - } - return minUltraModifiers.getInt(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return 15; - } - - private static Field minInfernoModifiers; - - public static int getMinInfernoModifiers() { - try { - if (minInfernoModifiers == null) { - minInfernoModifiers = InfernalMobsCore.class.getDeclaredField("minInfernoModifiers"); - minInfernoModifiers.setAccessible(true); - } - return minInfernoModifiers.getInt(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return 15; - } - - private static Field dimensionBlackList; - - public static ArrayList getDimensionBlackList() { - try { - if (dimensionBlackList == null) { - dimensionBlackList = InfernalMobsCore.class.getDeclaredField("dimensionBlackList"); - dimensionBlackList.setAccessible(true); - } - return (ArrayList) dimensionBlackList.get(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return new ArrayList<>(); - } - - private static Field dropIdListElite; - - public static ArrayList getDropIdListElite() { - try { - if (dropIdListElite == null) { - dropIdListElite = InfernalMobsCore.class.getDeclaredField("dropIdListElite"); - dropIdListElite.setAccessible(true); - } - return (ArrayList) dropIdListElite.get(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return new ArrayList<>(); - } - - private static Field dropIdListUltra; - - public static ArrayList getDropIdListUltra() { - try { - if (dropIdListUltra == null) { - dropIdListUltra = InfernalMobsCore.class.getDeclaredField("dropIdListUltra"); - dropIdListUltra.setAccessible(true); - } - return (ArrayList) dropIdListUltra.get(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return new ArrayList<>(); - } - - private static Field dropIdListInfernal; - - public static ArrayList getDropIdListInfernal() { - try { - if (dropIdListInfernal == null) { - dropIdListInfernal = InfernalMobsCore.class.getDeclaredField("dropIdListInfernal"); - dropIdListInfernal.setAccessible(true); - } - return (ArrayList) dropIdListInfernal.get(InfernalMobsCore.instance()); - } catch (Throwable exception) { - exception.printStackTrace(); - } - return new ArrayList<>(); - } -} diff --git a/src/main/java/kubatech/api/helpers/ReflectionHelper.java b/src/main/java/kubatech/api/helpers/ReflectionHelper.java index 63fd6bd633..8f2234f052 100644 --- a/src/main/java/kubatech/api/helpers/ReflectionHelper.java +++ b/src/main/java/kubatech/api/helpers/ReflectionHelper.java @@ -20,9 +20,23 @@ package kubatech.api.helpers; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.net.URL; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; +import java.util.Objects; +import java.util.jar.JarFile; +import java.util.stream.Collectors; + +import net.minecraft.launchwrapper.Launch; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.tree.ClassNode; public class ReflectionHelper { @@ -140,4 +154,53 @@ public class ReflectionHelper { return defaultValue; } } + + /** + * Gets all classes in a specific package path, works only for jar files. + * + * @param packageName The package name + * @return The class nodes + */ + public static Collection getClasses(String packageName) throws IOException, SecurityException { + ClassLoader classLoader = Thread.currentThread() + .getContextClassLoader(); + assert classLoader != null; + String packagePath = packageName.replace('.', '/'); + URL resource = classLoader.getResource(packagePath); + if (resource == null) throw new FileNotFoundException(); + if (!resource.getProtocol() + .equals("jar")) return Collections.emptySet(); + String jarPath = resource.getPath(); + + try (JarFile jar = new JarFile(jarPath.substring(5, jarPath.indexOf('!')))) { + return jar.stream() + .filter( + j -> !j.isDirectory() && j.getName() + .startsWith(packagePath) + && j.getName() + .endsWith(".class")) + .map(j -> { + try { + String name = j.getName(); + URL jarResource = Launch.classLoader.getResource(name); + if (jarResource == null) return null; + byte[] bytes; + try (InputStream is = jarResource.openStream()) { + bytes = new byte[(int) j.getSize()]; + if (is.read(bytes) != bytes.length) return null; + if (is.available() > 0) return null; + } + + ClassNode cn = new ClassNode(); + ClassReader cr = new ClassReader(bytes); + cr.accept(cn, 0); + + return cn; + } catch (IOException ignored) {} + return null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } + } } diff --git a/src/main/java/kubatech/api/network/CustomTileEntityPacket.java b/src/main/java/kubatech/api/network/CustomTileEntityPacket.java index cd65d08d57..67a310ecf5 100644 --- a/src/main/java/kubatech/api/network/CustomTileEntityPacket.java +++ b/src/main/java/kubatech/api/network/CustomTileEntityPacket.java @@ -132,7 +132,7 @@ public class CustomTileEntityPacket implements IMessage { @Override public IMessage onMessage(CustomTileEntityPacket message, MessageContext ctx) { - if (!ModUtils.isClientSided) return null; + if (!ModUtils.isClientThreaded()) return null; Minecraft mc = Minecraft.getMinecraft(); if (mc == null) return null; if (mc.thePlayer == null) return null; diff --git a/src/main/java/kubatech/api/utils/ItemUtils.java b/src/main/java/kubatech/api/utils/ItemUtils.java new file mode 100644 index 0000000000..2fc34057c3 --- /dev/null +++ b/src/main/java/kubatech/api/utils/ItemUtils.java @@ -0,0 +1,26 @@ +package kubatech.api.utils; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +public class ItemUtils { + + public static NBTTagCompound writeItemStackToNBT(ItemStack stack) { + NBTTagCompound compound = new NBTTagCompound(); + + stack.writeToNBT(compound); + compound.setInteger("IntCount", stack.stackSize); + + return compound; + } + + public static ItemStack readItemStackFromNBT(NBTTagCompound compound) { + ItemStack stack = ItemStack.loadItemStackFromNBT(compound); + + if (stack == null) return null; + + if (compound.hasKey("IntCount")) stack.stackSize = compound.getInteger("IntCount"); + + return stack; + } +} diff --git a/src/main/java/kubatech/api/utils/MobUtils.java b/src/main/java/kubatech/api/utils/MobUtils.java index ad48c51cbf..d3ec59757a 100644 --- a/src/main/java/kubatech/api/utils/MobUtils.java +++ b/src/main/java/kubatech/api/utils/MobUtils.java @@ -20,8 +20,6 @@ package kubatech.api.utils; -import java.lang.reflect.Field; - import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelBox; import net.minecraft.client.model.ModelRenderer; @@ -32,11 +30,10 @@ import net.minecraft.entity.EntityLiving; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import kubatech.mixin.mixins.minecraft.RendererLivingEntityAccessor; public class MobUtils { - private static Field mainmodelfield = null; - @SideOnly(Side.CLIENT) public static float getDesiredScale(EntityLiving e, float desiredHeight) { return getDesiredScale(getMobHeight(e), desiredHeight); @@ -50,17 +47,12 @@ public class MobUtils { @SideOnly(Side.CLIENT) public static float getMobHeight(EntityLiving e) { try { - if (mainmodelfield == null) { - mainmodelfield = RendererLivingEntity.class - .getDeclaredField(ModUtils.isDeobfuscatedEnvironment ? "mainModel" : "field_77045_g"); - mainmodelfield.setAccessible(true); - } float eheight = e.height; float ewidth = e.width; Render r = RenderManager.instance.getEntityRenderObject(e); - if (r instanceof RendererLivingEntity && mainmodelfield != null) { - ModelBase mainmodel = (ModelBase) mainmodelfield.get(r); - for (Object box : mainmodel.boxList) { + if (r instanceof RendererLivingEntity) { + ModelBase mainModel = ((RendererLivingEntityAccessor) r).getMainModel(); + for (Object box : mainModel.boxList) { if (box instanceof ModelRenderer) { float minY = 999f; float minX = 999f; diff --git a/src/main/java/kubatech/api/utils/ModUtils.java b/src/main/java/kubatech/api/utils/ModUtils.java index cd02d28dba..61352cce9d 100644 --- a/src/main/java/kubatech/api/utils/ModUtils.java +++ b/src/main/java/kubatech/api/utils/ModUtils.java @@ -32,6 +32,7 @@ import javax.xml.bind.DatatypeConverter; import net.minecraft.launchwrapper.Launch; +import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; import kubatech.kubatech; @@ -41,6 +42,19 @@ public class ModUtils { public static final boolean isDeobfuscatedEnvironment = (boolean) Launch.blackboard .get("fml.deobfuscatedEnvironment"); public static boolean isClientSided = false; + + public static boolean isClientThreaded() { + return FMLCommonHandler.instance() + .getEffectiveSide() + .isClient(); + } + + @FunctionalInterface + public interface TriConsumer { + + void accept(T t, U u, V v); + } + private static final HashMap classNamesToModIDs = new HashMap<>(); private static final Map.Entry emptyEntry = new AbstractMap.SimpleEntry<>("", ""); diff --git a/src/main/java/kubatech/commands/CommandBees.java b/src/main/java/kubatech/commands/CommandBees.java index 8d01080500..edf3b04ce6 100644 --- a/src/main/java/kubatech/commands/CommandBees.java +++ b/src/main/java/kubatech/commands/CommandBees.java @@ -28,7 +28,6 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.List; -import net.minecraft.client.Minecraft; import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; import net.minecraft.item.ItemStack; @@ -40,7 +39,9 @@ import com.google.common.io.Files; import forestry.api.apiculture.IAlleleBeeSpecies; import forestry.api.apiculture.IBee; import forestry.api.apiculture.IBeeGenome; +import kubatech.api.utils.ModUtils; +@CommandHandler.ChildCommand public class CommandBees extends CommandBase { @Override @@ -62,8 +63,7 @@ public class CommandBees extends CommandBase { @Override public void processCommand(ICommandSender p_71515_1_, String[] p_71515_2_) { - if (!Minecraft.getMinecraft() - .isSingleplayer()) { + if (!ModUtils.isClientSided) { p_71515_1_ .addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "This command is single-player only!")); return; diff --git a/src/main/java/kubatech/commands/CommandConfig.java b/src/main/java/kubatech/commands/CommandConfig.java index e4ffe9753d..cf43bc88ba 100644 --- a/src/main/java/kubatech/commands/CommandConfig.java +++ b/src/main/java/kubatech/commands/CommandConfig.java @@ -36,6 +36,7 @@ import kubatech.config.Config; import kubatech.kubatech; import kubatech.loaders.MobRecipeLoader; +@CommandHandler.ChildCommand public class CommandConfig extends CommandBase { enum Translations { diff --git a/src/main/java/kubatech/commands/CommandCustomDrops.java b/src/main/java/kubatech/commands/CommandCustomDrops.java new file mode 100644 index 0000000000..80148eb796 --- /dev/null +++ b/src/main/java/kubatech/commands/CommandCustomDrops.java @@ -0,0 +1,67 @@ +/* + * spotless:off + * KubaTech - Gregtech Addon + * Copyright (C) 2022 - 2023 kuba6000 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * spotless:on + */ + +package kubatech.commands; + +import java.io.File; + +import net.minecraft.command.CommandBase; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; + +import kubatech.api.utils.ModUtils; +import kubatech.loaders.MobRecipeLoader; + +@CommandHandler.ChildCommand +public class CommandCustomDrops extends CommandBase { + + @Override + public String getCommandName() { + return "customdrops"; + } + + @Override + public String getCommandUsage(ICommandSender p_71518_1_) { + return "customdrops"; + } + + @Override + public int getRequiredPermissionLevel() { + return 4; + } + + @Override + public void processCommand(ICommandSender p_71515_1_, String[] p_71515_2_) { + + if (!ModUtils.isClientSided) { + p_71515_1_ + .addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "This command is single-player only!")); + return; + } + + File f = MobRecipeLoader.makeCustomDrops(); + + if (f == null) { + p_71515_1_.addChatMessage( + new ChatComponentText(EnumChatFormatting.RED + "There was an error! Look in the console")); + } else p_71515_1_.addChatMessage(new ChatComponentText(f.getAbsolutePath())); + } +} diff --git a/src/main/java/kubatech/commands/CommandHandler.java b/src/main/java/kubatech/commands/CommandHandler.java index 0daea862ca..89f1db7429 100644 --- a/src/main/java/kubatech/commands/CommandHandler.java +++ b/src/main/java/kubatech/commands/CommandHandler.java @@ -25,6 +25,10 @@ import static kubatech.commands.CommandHandler.Translations.GENERIC_HELP; import static kubatech.commands.CommandHandler.Translations.INVALID; import static kubatech.commands.CommandHandler.Translations.USAGE; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -38,6 +42,8 @@ import net.minecraft.util.ChatComponentTranslation; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.StatCollector; +import kubatech.kubatech; + public class CommandHandler extends CommandBase { enum Translations { @@ -121,7 +127,29 @@ public class CommandHandler extends CommandBase { return true; } - public void addCommand(ICommand command) { + public static void addCommand(ICommand command) { commands.put(command.getCommandName(), command); } + + static { + String ChildCommandDesc = "L" + ChildCommand.class.getName() + .replace(".", "/") + ";"; + kubatech.myClasses.stream() + .filter( + clazz -> clazz.invisibleAnnotations != null && clazz.invisibleAnnotations.stream() + .anyMatch(ann -> ann.desc.equals(ChildCommandDesc))) + .forEach(clazz -> { + try { + addCommand( + (ICommand) Class.forName(clazz.name.replace("/", ".")) + .newInstance()); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + }); + } + + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.CLASS) + public @interface ChildCommand {} } diff --git a/src/main/java/kubatech/commands/CommandHelp.java b/src/main/java/kubatech/commands/CommandHelp.java index 47a448afe1..d7e9fbee59 100644 --- a/src/main/java/kubatech/commands/CommandHelp.java +++ b/src/main/java/kubatech/commands/CommandHelp.java @@ -28,6 +28,7 @@ import net.minecraft.command.ICommandSender; import net.minecraft.util.ChatComponentText; import net.minecraft.util.StatCollector; +@CommandHandler.ChildCommand public class CommandHelp extends CommandBase { enum Translations { diff --git a/src/main/java/kubatech/commands/CommandTea.java b/src/main/java/kubatech/commands/CommandTea.java index 70a924d9c7..64412f8ef3 100644 --- a/src/main/java/kubatech/commands/CommandTea.java +++ b/src/main/java/kubatech/commands/CommandTea.java @@ -38,6 +38,7 @@ import net.minecraft.util.StatCollector; import kubatech.api.helpers.UUIDFinder; import kubatech.api.tea.TeaNetwork; +@CommandHandler.ChildCommand public class CommandTea extends CommandBase { enum Translations { diff --git a/src/main/java/kubatech/kubatech.java b/src/main/java/kubatech/kubatech.java index e13f1c36e0..6cb6bd299c 100644 --- a/src/main/java/kubatech/kubatech.java +++ b/src/main/java/kubatech/kubatech.java @@ -22,6 +22,8 @@ package kubatech; import static kubatech.api.enums.ItemList.LegendaryRedTea; +import java.io.IOException; +import java.util.Collection; import java.util.List; import net.minecraft.creativetab.CreativeTabs; @@ -30,6 +32,7 @@ import net.minecraft.item.ItemStack; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.objectweb.asm.tree.ClassNode; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.SidedProxy; @@ -45,6 +48,7 @@ import cpw.mods.fml.common.event.FMLServerStoppingEvent; import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.relauncher.Side; import kubatech.api.enums.ItemList; +import kubatech.api.helpers.ReflectionHelper; import kubatech.api.network.CustomTileEntityPacket; import kubatech.api.network.LoadConfigPacket; @@ -67,7 +71,7 @@ import kubatech.api.network.LoadConfigPacket; + "after: Forestry; " + "after: DraconicEvolution; " + "after: Avaritia; " - + " after: dreamcraft; ") + + "after: dreamcraft; ") public class kubatech { public static kubatech instance = null; @@ -112,9 +116,22 @@ public class kubatech { @SidedProxy(clientSide = Tags.MODID + ".ClientProxy", serverSide = Tags.MODID + ".CommonProxy") public static CommonProxy proxy; + public static Collection myClasses; + @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { instance = this; + final long timeStart = System.currentTimeMillis(); + try { + myClasses = ReflectionHelper.getClasses( + this.getClass() + .getPackage() + .getName()); + } catch (IOException e) { + throw new RuntimeException(e); + } + final long timeToLoad = System.currentTimeMillis() - timeStart; + info("Class discovery took " + timeToLoad + "ms ! Found " + myClasses.size() + " classes."); proxy.preInit(event); } diff --git a/src/main/java/kubatech/loaders/MobRecipeLoader.java b/src/main/java/kubatech/loaders/MobRecipeLoader.java index ebb1a2a906..da54d44117 100644 --- a/src/main/java/kubatech/loaders/MobRecipeLoader.java +++ b/src/main/java/kubatech/loaders/MobRecipeLoader.java @@ -29,8 +29,6 @@ import static kubatech.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeE import java.io.File; import java.io.Reader; import java.io.Writer; -import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -41,6 +39,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.UUID; +import java.util.function.Supplier; import java.util.stream.Collectors; import net.minecraft.block.Block; @@ -49,7 +49,6 @@ import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.monster.EntitySlime; @@ -59,18 +58,23 @@ import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; import net.minecraft.util.StatCollector; import net.minecraft.world.World; +import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.common.util.FakePlayer; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.google.common.io.Files; import com.google.gson.Gson; +import com.mojang.authlib.GameProfile; import atomicstryker.infernalmobs.common.InfernalMobsCore; import atomicstryker.infernalmobs.common.MobModifier; import atomicstryker.infernalmobs.common.mods.api.ModifierLoader; +import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import gregtech.api.util.GT_Utility; @@ -78,14 +82,19 @@ import gregtech.common.GT_DummyWorld; import kubatech.Tags; import kubatech.api.LoaderReference; import kubatech.api.helpers.EnderIOHelper; -import kubatech.api.helpers.InfernalHelper; import kubatech.api.helpers.ProgressBarWrapper; import kubatech.api.mobhandler.MobDrop; import kubatech.api.network.LoadConfigPacket; +import kubatech.api.utils.FastRandom; import kubatech.api.utils.GSONUtils; import kubatech.api.utils.ModUtils; +import kubatech.api.utils.ModUtils.TriConsumer; import kubatech.config.Config; import kubatech.config.OverridesConfig; +import kubatech.mixin.mixins.minecraft.EntityAccessor; +import kubatech.mixin.mixins.minecraft.EntityLivingAccessor; +import kubatech.mixin.mixins.minecraft.EntityLivingBaseAccessor; +import kubatech.mixin.mixins.minecraft.EntitySlimeAccessor; import kubatech.nei.Mob_Handler; import kubatech.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber; import minetweaker.MineTweakerAPI; @@ -99,12 +108,8 @@ public class MobRecipeLoader { private static final Logger LOG = LogManager.getLogger(Tags.MODID + "[Mob Recipe Loader]"); - private static final String dropFewItemsName = isDeobfuscatedEnvironment ? "dropFewItems" : "func_70628_a"; - private static final String dropRareDropName = isDeobfuscatedEnvironment ? "dropRareDrop" : "func_70600_l"; - private static final String setSlimeSizeName = isDeobfuscatedEnvironment ? "setSlimeSize" : "func_70799_a"; private static final String addRandomArmorName = isDeobfuscatedEnvironment ? "addRandomArmor" : "func_82164_bB"; private static final String enchantEquipmentName = isDeobfuscatedEnvironment ? "enchantEquipment" : "func_82162_bC"; - private static final String randName = isDeobfuscatedEnvironment ? "rand" : "field_70146_Z"; private static boolean alreadyGenerated = false; public static boolean isInGenerationProcess = false; @@ -158,57 +163,65 @@ public class MobRecipeLoader { @SuppressWarnings("unchecked") private MobRecipe(EntityLiving e, String entityID, ArrayList outputs) { - if (infernaldrops == null && LoaderReference.InfernalMobs) { - infernaldrops = new droplist(); - LOG.info("Generating Infernal drops"); - ArrayList> modifierLoaders = (ArrayList>) InfernalHelper - .getModifierLoaders() - .clone(); - int i = 0; - for (ModifierLoader modifierLoader : modifierLoaders) { - MobModifier nextMod = modifierLoader.make(null); - if (nextMod.getBlackListMobClasses() != null) - for (Class cl : nextMod.getBlackListMobClasses()) if (e.getClass() - .isAssignableFrom(cl)) break; - i++; - } - if (i > 0) { - double chance = InfernalHelper.checkEntityClassForced(e) ? 1d - : (1d / InfernalHelper.getEliteRarity()); - ArrayList elitelist = InfernalHelper.getDropIdListElite(); - for (ItemStack stack : elitelist) { - dropinstance instance = infernaldrops - .add(new dropinstance(stack.copy(), infernaldrops), chance / elitelist.size()); - instance.isEnchatmentRandomized = true; - // noinspection ConstantConditions - instance.enchantmentLevel = stack.getItem() - .getItemEnchantability(); - } - ArrayList ultralist = InfernalHelper.getDropIdListUltra(); - chance *= 1d / InfernalHelper.getUltraRarity(); - for (ItemStack stack : ultralist) { - dropinstance instance = infernaldrops - .add(new dropinstance(stack.copy(), infernaldrops), chance / ultralist.size()); - instance.isEnchatmentRandomized = true; - // noinspection ConstantConditions - instance.enchantmentLevel = stack.getItem() - .getItemEnchantability(); + if (LoaderReference.InfernalMobs) { + InfernalMobsCore infernalMobsCore = InfernalMobsCore.instance(); + if (infernaldrops == null) { + infernaldrops = new droplist(); + LOG.info("Generating Infernal drops"); + ArrayList> modifierLoaders = (ArrayList>) infernalMobsCore + .getModifierLoaders() + .clone(); + int i = 0; + for (ModifierLoader modifierLoader : modifierLoaders) { + MobModifier nextMod = modifierLoader.make(null); + if (nextMod.getBlackListMobClasses() != null) + for (Class cl : nextMod.getBlackListMobClasses()) if (e.getClass() + .isAssignableFrom(cl)) break; + i++; } - ArrayList infernallist = InfernalHelper.getDropIdListInfernal(); - chance *= 1d / InfernalHelper.getInfernoRarity(); - for (ItemStack stack : infernallist) { - dropinstance instance = infernaldrops - .add(new dropinstance(stack.copy(), infernaldrops), chance / infernallist.size()); - instance.isEnchatmentRandomized = true; - // noinspection ConstantConditions - instance.enchantmentLevel = stack.getItem() - .getItemEnchantability(); + if (i > 0) { + double chance = infernalMobsCore.checkEntityClassForced(e) ? 1d + : (1d / infernalMobsCore.getEliteRarity()); + ArrayList elitelist = infernalMobsCore.getDropIdListElite(); + for (ItemStack stack : elitelist) { + dropinstance instance = infernaldrops + .add(new dropinstance(stack.copy(), infernaldrops), chance / elitelist.size()); + instance.isEnchatmentRandomized = true; + // noinspection ConstantConditions + instance.enchantmentLevel = stack.getItem() + .getItemEnchantability(); + } + ArrayList ultralist = infernalMobsCore.getDropIdListUltra(); + chance *= 1d / infernalMobsCore.getUltraRarity(); + for (ItemStack stack : ultralist) { + dropinstance instance = infernaldrops + .add(new dropinstance(stack.copy(), infernaldrops), chance / ultralist.size()); + instance.isEnchatmentRandomized = true; + // noinspection ConstantConditions + instance.enchantmentLevel = stack.getItem() + .getItemEnchantability(); + } + ArrayList infernallist = infernalMobsCore.getDropIdListInfernal(); + chance *= 1d / infernalMobsCore.getInfernoRarity(); + for (ItemStack stack : infernallist) { + dropinstance instance = infernaldrops + .add(new dropinstance(stack.copy(), infernaldrops), chance / infernallist.size()); + instance.isEnchatmentRandomized = true; + // noinspection ConstantConditions + instance.enchantmentLevel = stack.getItem() + .getItemEnchantability(); + } } } - } else if (infernaldrops == null) infernaldrops = new droplist(); + infernalityAllowed = infernalMobsCore.isClassAllowed(e); + alwaysinfernal = infernalMobsCore.checkEntityClassForced(e); + } else { + infernalityAllowed = false; + alwaysinfernal = false; + } + + if (infernaldrops == null) infernaldrops = new droplist(); - infernalityAllowed = InfernalHelper.isClassAllowed(e); - alwaysinfernal = InfernalHelper.checkEntityClassForced(e); isPeacefulAllowed = !(e instanceof IMob); mOutputs = (ArrayList) outputs.clone(); @@ -266,44 +279,48 @@ public class MobRecipeLoader { } } - if (infernalityAllowed && mEUt * 8 < MTE.getMaxInputVoltage() - && !InfernalHelper.getDimensionBlackList() - .contains( - MTE.getBaseMetaTileEntity() - .getWorld().provider.dimensionId)) { - int p = 0; - int mods = 0; - if (alwaysinfernal || (preferInfernalDrops && rnd.nextInt(InfernalHelper.getEliteRarity()) == 0)) { - p = 1; - if (rnd.nextInt(InfernalHelper.getUltraRarity()) == 0) { - p = 2; - if (rnd.nextInt(InfernalHelper.getInfernoRarity()) == 0) p = 3; + if (LoaderReference.InfernalMobs) { + InfernalMobsCore infernalMobsCore = InfernalMobsCore.instance(); + if (infernalityAllowed && mEUt * 8 < MTE.getMaxInputVoltage() + && !infernalMobsCore.getDimensionBlackList() + .contains( + MTE.getBaseMetaTileEntity() + .getWorld().provider.dimensionId)) { + int p = 0; + int mods = 0; + if (alwaysinfernal + || (preferInfernalDrops && rnd.nextInt(infernalMobsCore.getEliteRarity()) == 0)) { + p = 1; + if (rnd.nextInt(infernalMobsCore.getUltraRarity()) == 0) { + p = 2; + if (rnd.nextInt(infernalMobsCore.getInfernoRarity()) == 0) p = 3; + } + } + ArrayList infernalstacks = null; + if (p > 0) if (p == 1) { + infernalstacks = infernalMobsCore.getDropIdListElite(); + mods = infernalMobsCore.getMinEliteModifiers(); + } else if (p == 2) { + infernalstacks = infernalMobsCore.getDropIdListUltra(); + mods = infernalMobsCore.getMinUltraModifiers(); + } else { + infernalstacks = infernalMobsCore.getDropIdListInfernal(); + mods = infernalMobsCore.getMinInfernoModifiers(); + } + if (infernalstacks != null) { + ItemStack infernalstack = infernalstacks.get(rnd.nextInt(infernalstacks.size())) + .copy(); + // noinspection ConstantConditions + EnchantmentHelper.addRandomEnchantment( + rnd, + infernalstack, + infernalstack.getItem() + .getItemEnchantability()); + stacks.add(infernalstack); + MTE.lEUt *= 8L; + MTE.mMaxProgresstime *= mods * InfernalMobsCore.instance() + .getMobModHealthFactor(); } - } - ArrayList infernalstacks = null; - if (p > 0) if (p == 1) { - infernalstacks = InfernalHelper.getDropIdListElite(); - mods = InfernalHelper.getMinEliteModifiers(); - } else if (p == 2) { - infernalstacks = InfernalHelper.getDropIdListUltra(); - mods = InfernalHelper.getMinUltraModifiers(); - } else { - infernalstacks = InfernalHelper.getDropIdListInfernal(); - mods = InfernalHelper.getMinInfernoModifiers(); - } - if (infernalstacks != null) { - ItemStack infernalstack = infernalstacks.get(rnd.nextInt(infernalstacks.size())) - .copy(); - // noinspection ConstantConditions - EnchantmentHelper.addRandomEnchantment( - rnd, - infernalstack, - infernalstack.getItem() - .getItemEnchantability()); - stacks.add(infernalstack); - MTE.lEUt *= 8L; - MTE.mMaxProgresstime *= mods * InfernalMobsCore.instance() - .getMobModHealthFactor(); } } @@ -685,32 +702,6 @@ public class MobRecipeLoader { long time = System.currentTimeMillis(); - Method setSlimeSize; - Method dropFewItems; - Method dropRareDrop; - Method addRandomArmor; - Method enchantEquipment; - Field rand; - - try { - setSlimeSize = EntitySlime.class.getDeclaredMethod(setSlimeSizeName, int.class); - setSlimeSize.setAccessible(true); - dropFewItems = EntityLivingBase.class.getDeclaredMethod(dropFewItemsName, boolean.class, int.class); - dropFewItems.setAccessible(true); - dropRareDrop = EntityLivingBase.class.getDeclaredMethod(dropRareDropName, int.class); - dropRareDrop.setAccessible(true); - addRandomArmor = EntityLiving.class.getDeclaredMethod(addRandomArmorName); - addRandomArmor.setAccessible(true); - enchantEquipment = EntityLiving.class.getDeclaredMethod(enchantEquipmentName); - enchantEquipment.setAccessible(true); - rand = Entity.class.getDeclaredField(randName); - rand.setAccessible(true); - } catch (Exception ex) { - LOG.error("Failed to obtain methods"); - isInGenerationProcess = false; - return; - } - dropCollector collector = new dropCollector(); // Stupid MC code, I need to cast myself @@ -758,372 +749,299 @@ public class MobRecipeLoader { // POWERFULL GENERATION - e.captureDrops = true; - - if (e instanceof EntitySlime) try { - setSlimeSize.invoke(e, 1); - } catch (Exception ex) { - ex.printStackTrace(); - return; - } - try { - rand.set(e, frand); - } catch (Exception ex) { - ex.printStackTrace(); - return; - } - droplist drops = new droplist(); - droplist raredrops = new droplist(); - droplist superraredrops = new droplist(); - droplist additionaldrops = new droplist(); - droplist dropslooting = new droplist(); + e.captureDrops = true; - frand.newRound(); - collector.newRound(); + if (e instanceof EntitySlime) ((EntitySlimeAccessor) e).callSetSlimeSize(1); - if (v.getName() - .startsWith("com.emoniph.witchery")) { - try { - dropFewItems.invoke(e, true, 0); - } catch (Exception ex) { - ex.printStackTrace(); - return; - } - frand.newRound(); - frand.exceptionOnEnchantTry = true; - boolean enchantmentDetected = false; - try { - dropFewItems.invoke(e, true, 0); - } catch (Exception ex) { - enchantmentDetected = true; - } - int w = frand.walkCounter; - frand.newRound(); - if (enchantmentDetected) { - frand.maxWalkCount = w; - collector.booksAlwaysRandomlyEnchanted = true; - } - e.capturedDrops.clear(); - } + ((EntityAccessor) e).setRand(frand); - boolean second = false; - do { - try { - dropFewItems.invoke(e, true, 0); - } catch (Exception ex) { - ex.printStackTrace(); - return; - } - collector.addDrop(drops, e.capturedDrops, frand.chance); - - if (second && frand.chance < 0.0000001d) { - LOG.warn("Skipping " + k + " normal dropmap because it's too randomized"); - break; - } - second = true; + droplist drops = new droplist(); + droplist raredrops = new droplist(); + droplist superraredrops = new droplist(); + droplist additionaldrops = new droplist(); + droplist dropslooting = new droplist(); + droplist dropscustom = new droplist(); - } while (frand.nextRound()); - - frand.newRound(); - collector.newRound(); - - if (v.getName() - .startsWith("com.emoniph.witchery")) { - try { - dropFewItems.invoke(e, true, 0); - } catch (Exception ex) { - ex.printStackTrace(); - return; - } frand.newRound(); - frand.exceptionOnEnchantTry = true; - boolean enchantmentDetected = false; - try { - dropFewItems.invoke(e, true, 0); - } catch (Exception ex) { - enchantmentDetected = true; - } - int w = frand.walkCounter; - frand.newRound(); - if (enchantmentDetected) { - frand.maxWalkCount = w; - collector.booksAlwaysRandomlyEnchanted = true; - } - e.capturedDrops.clear(); - } - - second = false; - do { - try { - dropFewItems.invoke(e, true, 1); - } catch (Exception ex) { - ex.printStackTrace(); - return; - } - collector.addDrop(dropslooting, e.capturedDrops, frand.chance); - - if (second && frand.chance < 0.0000001d) { - LOG.warn("Skipping " + k + " normal dropmap because it's too randomized"); - break; - } - second = true; + collector.newRound(); + + Runnable checkForWitchery = () -> { + if (v.getName() + .startsWith("com.emoniph.witchery")) { + ((EntityLivingBaseAccessor) e).callDropFewItems(true, 0); + frand.newRound(); + frand.exceptionOnEnchantTry = true; + boolean enchantmentDetected = false; + try { + ((EntityLivingBaseAccessor) e).callDropFewItems(true, 0); + } catch (Exception ex) { + enchantmentDetected = true; + } + int w = frand.walkCounter; + frand.newRound(); + if (enchantmentDetected) { + frand.maxWalkCount = w; + collector.booksAlwaysRandomlyEnchanted = true; + } + e.capturedDrops.clear(); + } + }; - } while (frand.nextRound()); + TriConsumer, droplist, String> doTheDrop = (callerCanceller, dList, dListName) -> { + boolean second = false; + do { + if (!callerCanceller.get()) break; - frand.newRound(); - collector.newRound(); + collector.addDrop(dList, e.capturedDrops, frand.chance); - second = false; - do { - try { - dropRareDrop.invoke(e, 0); - } catch (Exception ex) { - ex.printStackTrace(); - return; - } - collector.addDrop(raredrops, e.capturedDrops, frand.chance); + if (second && frand.chance < 0.0000001d) { + LOG.warn("Skipping " + k + " " + dListName + " dropmap because it's too randomized"); + break; + } + second = true; + + } while (frand.nextRound()); + + frand.newRound(); + collector.newRound(); + }; + + checkForWitchery.run(); + + doTheDrop.accept(() -> { + ((EntityLivingBaseAccessor) e).callDropFewItems(true, 0); + return true; + }, drops, "normal"); + + checkForWitchery.run(); + + doTheDrop.accept(() -> { + ((EntityLivingBaseAccessor) e).callDropFewItems(true, 1); + return true; + }, dropslooting, "normal"); + + doTheDrop.accept(() -> { + ((EntityLivingBaseAccessor) e).callDropRareDrop(0); + return true; + }, raredrops, "rare"); + + doTheDrop.accept(() -> { + ((EntityLivingBaseAccessor) e).callDropRareDrop(1); + return true; + }, superraredrops, "rare"); + + if (registeringWitherSkeleton && e instanceof EntitySkeleton && k.equals("witherSkeleton")) { + dropinstance i = new dropinstance(new ItemStack(Items.stone_sword), additionaldrops); + i.isDamageRandomized = true; + int maxdamage = i.stack.getMaxDamage(); + int max = Math.max(maxdamage - 25, 1); + for (int d = Math.min(max, 25); d <= max; d++) i.damagesPossible.put(d, 1); + additionaldrops.add(i, 1d); + } else try { + Class cl = e.getClass(); + boolean detectedException; + do { + detectedException = false; + try { + cl.getDeclaredMethod(addRandomArmorName); + } catch (Exception ex) { + detectedException = true; + cl = cl.getSuperclass(); + } + } while (detectedException && !cl.equals(Entity.class)); + if (cl.equals(EntityLiving.class) || cl.equals(Entity.class)) throw new Exception(); + cl = e.getClass(); + do { + detectedException = false; + try { + cl.getDeclaredMethod(enchantEquipmentName); + } catch (Exception ex) { + detectedException = true; + cl = cl.getSuperclass(); + } + } while (detectedException && !cl.equals(EntityLiving.class)); + boolean usingVanillaEnchantingMethod = cl.equals(EntityLiving.class); + double chanceModifierLocal = 1f; + if (v.getName() + .startsWith("twilightforest.entity")) { + frand.forceFloatValue = 0f; + chanceModifierLocal = 0.25f; + } + boolean second = false; + do { + ((EntityLivingAccessor) e).callAddRandomArmor(); + if (!usingVanillaEnchantingMethod) ((EntityLivingAccessor) e).callEnchantEquipment(); + ItemStack[] lastActiveItems = e.getLastActiveItems(); + for (int j = 0, lastActiveItemsLength = lastActiveItems.length; j + < lastActiveItemsLength; j++) { + ItemStack stack = lastActiveItems[j]; + if (stack != null) { + if (LoaderReference.Thaumcraft) + if (stack.getItem() instanceof ItemWandCasting) continue; // crashes the game when + // rendering in GUI + + int randomenchant = -1; + if (stack.hasTagCompound() + && stack.stackTagCompound.hasKey(randomEnchantmentDetectedString)) { + randomenchant = stack.stackTagCompound.getInteger(randomEnchantmentDetectedString); + stack.stackTagCompound.removeTag("ench"); + } + dropinstance i = additionaldrops.add( + new dropinstance(stack.copy(), additionaldrops), + frand.chance * chanceModifierLocal + * (usingVanillaEnchantingMethod ? (j == 0 ? 0.75d : 0.5d) : 1d)); + if (!i.isDamageRandomized && i.stack.isItemStackDamageable()) { + i.isDamageRandomized = true; + int maxdamage = i.stack.getMaxDamage(); + int max = Math.max(maxdamage - 25, 1); + for (int d = Math.min(max, 25); d <= max; d++) i.damagesPossible.put(d, 1); + } + if (!i.isEnchatmentRandomized && randomenchant != -1) { + i.isEnchatmentRandomized = true; + i.enchantmentLevel = randomenchant; + } + if (usingVanillaEnchantingMethod) { + if (!stack.hasTagCompound()) stack.stackTagCompound = new NBTTagCompound(); + stack.stackTagCompound.setInteger(randomEnchantmentDetectedString, 14); + dropinstance newdrop = additionaldrops.add( + new dropinstance(stack.copy(), additionaldrops), + frand.chance * chanceModifierLocal * (j == 0 ? 0.25d : 0.5d)); + newdrop.isEnchatmentRandomized = true; + newdrop.enchantmentLevel = 14; + newdrop.isDamageRandomized = i.isDamageRandomized; + newdrop.damagesPossible = (HashMap) i.damagesPossible.clone(); + } + } + } + Arrays.fill(e.getLastActiveItems(), null); - if (second && frand.chance < 0.0000001d) { - LOG.warn("Skipping " + k + " rare dropmap because it's too randomized"); - break; - } - second = true; + if (second && frand.chance < 0.0000001d) { + LOG.warn("Skipping " + k + " additional dropmap because it's too randomized"); + break; + } + second = true; - } while (frand.nextRound()); + } while (frand.nextRound()); + } catch (Exception ignored) {} - frand.newRound(); - collector.newRound(); + frand.newRound(); + collector.newRound(); - second = false; - do { - try { - dropRareDrop.invoke(e, 1); - } catch (Exception ex) { - ex.printStackTrace(); + if (drops.isEmpty() && raredrops.isEmpty() && additionaldrops.isEmpty()) { + ArrayList arr = new ArrayList<>(); + GeneralMobList.put(k, new GeneralMappedMob(e, MobRecipe.generateMobRecipe(e, k, arr), arr)); + LOG.info("Mapped " + k); return; } - collector.addDrop(superraredrops, e.capturedDrops, frand.chance); - - if (second && frand.chance < 0.0000001d) { - LOG.warn("Skipping " + k + " rare dropmap because it's too randomized"); - break; - } - second = true; - - } while (frand.nextRound()); - frand.newRound(); - collector.newRound(); + ArrayList moboutputs = new ArrayList<>( + drops.size() + raredrops.size() + additionaldrops.size()); - if (registeringWitherSkeleton && e instanceof EntitySkeleton && k.equals("witherSkeleton")) { - dropinstance i = new dropinstance(new ItemStack(Items.stone_sword), additionaldrops); - i.isDamageRandomized = true; - int maxdamage = i.stack.getMaxDamage(); - int max = Math.max(maxdamage - 25, 1); - for (int d = Math.min(max, 25); d <= max; d++) i.damagesPossible.put(d, 1); - additionaldrops.add(i, 1d); - } else try { - Class cl = e.getClass(); - boolean detectedException; - do { - detectedException = false; - try { - cl.getDeclaredMethod(addRandomArmorName); - } catch (Exception ex) { - detectedException = true; - cl = cl.getSuperclass(); + for (dropinstance drop : drops.drops) { + ItemStack stack = drop.stack; + if (stack.hasTagCompound()) stack.stackTagCompound.removeTag(randomEnchantmentDetectedString); + int chance = drop.getchance(10000); + if (chance > 10000) { + int div = (int) Math.ceil(c