From 6d436a2c6a5d9b51070b8399c4fdb196603a8e82 Mon Sep 17 00:00:00 2001
From: Jakub <53441451+kuba6000@users.noreply.github.com>
Date: Sun, 14 Aug 2022 15:19:13 +0200
Subject: Add "Mob Drops" NEI page + Extreme Extermination Chamber (#1)
* First commit
* Mixins
* Merge the same items with diffrent damage
* Faster random in NEI
* More accuracy ?
* Update ClientProxy.java
* Renaming
* Update buildscript
* Use reserved MTE ID's
* EEC work
* Rework NEI page
* Fix inaccurate chances
* Basic equipment spawn
* Add config options
* Translations
* Add infernal drops
* Witchery fix
* Forestry fixes
* More fixes
* Default blacklist
* NEI sorting
* Comment out testing deps
* Clientsided check
* Blood Magic support
* LoaderReference
* Check if peacefull is allowed
* Add some XP output
* Add recipe
* Send Server config to Client
* Add command to reload config
* Translations
* Process MT additions
---
.../java/kubatech/loaders/MobRecipeLoader.java | 973 +++++++++++++++++++++
src/main/java/kubatech/loaders/RecipeLoader.java | 77 ++
2 files changed, 1050 insertions(+)
create mode 100644 src/main/java/kubatech/loaders/MobRecipeLoader.java
create mode 100644 src/main/java/kubatech/loaders/RecipeLoader.java
(limited to 'src/main/java/kubatech/loaders')
diff --git a/src/main/java/kubatech/loaders/MobRecipeLoader.java b/src/main/java/kubatech/loaders/MobRecipeLoader.java
new file mode 100644
index 0000000000..033beb49fd
--- /dev/null
+++ b/src/main/java/kubatech/loaders/MobRecipeLoader.java
@@ -0,0 +1,973 @@
+/*
+ * KubaTech - Gregtech Addon
+ * Copyright (C) 2022 kuba6000
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package kubatech.loaders;
+
+import static kubatech.api.utils.ModUtils.isClientSided;
+import static kubatech.api.utils.ModUtils.isDeobfuscatedEnvironment;
+import static kubatech.common.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber.MobNameToRecipeMap;
+
+import atomicstryker.infernalmobs.common.InfernalMobsCore;
+import atomicstryker.infernalmobs.common.MobModifier;
+import atomicstryker.infernalmobs.common.mods.api.ModifierLoader;
+import cpw.mods.fml.common.eventhandler.SubscribeEvent;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.util.GT_Utility;
+import gregtech.common.GT_DummyWorld;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.stream.Collectors;
+import kubatech.Config;
+import kubatech.Tags;
+import kubatech.api.LoaderReference;
+import kubatech.api.utils.InfernalHelper;
+import kubatech.common.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber;
+import kubatech.nei.Mob_Handler;
+import kubatech.network.LoadConfigPacket;
+import minetweaker.MineTweakerAPI;
+import minetweaker.api.entity.IEntityDefinition;
+import minetweaker.api.item.IItemStack;
+import minetweaker.mc1710.item.MCItemStack;
+import net.minecraft.enchantment.Enchantment;
+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.EntitySlime;
+import net.minecraft.entity.monster.IMob;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.StatCollector;
+import net.minecraft.world.World;
+import net.minecraftforge.client.event.GuiOpenEvent;
+import net.minecraftforge.common.MinecraftForge;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import stanhebben.zenscript.value.IntRange;
+import thaumcraft.common.items.wands.ItemWandCasting;
+
+public class MobRecipeLoader {
+
+ private static final Logger LOG = LogManager.getLogger(Tags.MODID + "[Mob Handler]");
+
+ public static final MobRecipeLoader instance = new MobRecipeLoader();
+
+ @SuppressWarnings("unused")
+ @SubscribeEvent
+ public void onOpenGui(GuiOpenEvent event) {
+ MobRecipeLoader.generateMobRecipeMap();
+ MinecraftForge.EVENT_BUS.unregister(instance);
+ }
+
+ 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;
+ public static final String randomEnchantmentDetectedString = "RandomEnchantmentDetected";
+
+ public static class MobRecipe {
+ public final ArrayList mOutputs;
+ public final int mEUt = 2000;
+ public final int mDuration;
+ public final int mMaxDamageChance;
+ public final boolean infernalityAllowed;
+ public final boolean alwaysinfernal;
+ public static droplist infernaldrops;
+ public final boolean isPeacefulAllowed;
+
+ @SuppressWarnings("unchecked")
+ public MobRecipe copy() {
+ return new MobRecipe(
+ (ArrayList) mOutputs.clone(),
+ mDuration,
+ mMaxDamageChance,
+ infernalityAllowed,
+ alwaysinfernal,
+ isPeacefulAllowed);
+ }
+
+ private MobRecipe(
+ ArrayList mOutputs,
+ int mDuration,
+ int mMaxDamageChance,
+ boolean infernalityAllowed,
+ boolean alwaysinfernal,
+ boolean isPeacefulAllowed) {
+ this.mOutputs = mOutputs;
+ this.mDuration = mDuration;
+ this.mMaxDamageChance = mMaxDamageChance;
+ this.infernalityAllowed = infernalityAllowed;
+ this.alwaysinfernal = alwaysinfernal;
+ this.isPeacefulAllowed = isPeacefulAllowed;
+ }
+
+ @SuppressWarnings("unchecked")
+ public MobRecipe(EntityLiving e, 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;
+ 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;
+ instance.enchantmentLevel = stack.getItem().getItemEnchantability();
+ }
+ 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;
+ instance.enchantmentLevel = stack.getItem().getItemEnchantability();
+ }
+ }
+ } else if (infernaldrops == null) infernaldrops = new droplist();
+
+ infernalityAllowed = InfernalHelper.isClassAllowed(e);
+ alwaysinfernal = InfernalHelper.checkEntityClassForced(e);
+ isPeacefulAllowed = !(e instanceof IMob);
+
+ mOutputs = outputs;
+ int maxdamagechance = 0;
+ for (MobDrop o : mOutputs) {
+ if (o.damages != null) for (int v : o.damages.values()) maxdamagechance += v;
+ }
+ mMaxDamageChance = maxdamagechance;
+ // Powered spawner with octadic capacitor spawns ~22/min ~= 0.366/sec ~= 2.72s/spawn ~= 54.54t/spawn
+ mDuration = 55 + 10 + (((int) e.getMaxHealth() / 5) * 10);
+ }
+
+ public ItemStack[] generateOutputs(Random rnd, GT_MetaTileEntity_ExtremeExterminationChamber MTE) {
+ MTE.mEUt = mEUt;
+ MTE.mMaxProgresstime = mDuration;
+ ArrayList stacks = new ArrayList<>(mOutputs.size());
+ for (MobDrop o : mOutputs) {
+ if (o.chance == 10000 || rnd.nextInt(10000) < o.chance) {
+ ItemStack s = o.stack.copy();
+ if (o.enchantable != null) EnchantmentHelper.addRandomEnchantment(rnd, s, o.enchantable);
+ if (o.damages != null) {
+ int rChance = rnd.nextInt(mMaxDamageChance);
+ int cChance = 0;
+ for (Map.Entry damage : o.damages.entrySet()) {
+ cChance += damage.getValue();
+ if (rChance <= cChance) {
+ s.setItemDamage(damage.getKey());
+ break;
+ }
+ }
+ }
+ stacks.add(s);
+ }
+ }
+
+ if (infernalityAllowed
+ && mEUt * 8 < MTE.getMaxInputVoltage()
+ && !InfernalHelper.getDimensionBlackList()
+ .contains(MTE.getBaseMetaTileEntity().getWorld().provider.dimensionId)) {
+ int p = 0;
+ int mods = 0;
+ if (alwaysinfernal || rnd.nextInt(InfernalHelper.getEliteRarity()) == 0) {
+ p = 1;
+ if (rnd.nextInt(InfernalHelper.getUltraRarity()) == 0) {
+ p = 2;
+ if (rnd.nextInt(InfernalHelper.getInfernoRarity()) == 0) p = 3;
+ }
+ }
+ 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 if (p == 3) {
+ infernalstacks = InfernalHelper.getDropIdListInfernal();
+ mods = InfernalHelper.getMinInfernoModifiers();
+ }
+ if (infernalstacks != null) {
+ ItemStack infernalstack = infernalstacks
+ .get(rnd.nextInt(infernalstacks.size()))
+ .copy();
+ EnchantmentHelper.addRandomEnchantment(
+ rnd, infernalstack, infernalstack.getItem().getItemEnchantability());
+ stacks.add(infernalstack);
+ MTE.mEUt *= 8;
+ MTE.mMaxProgresstime *= mods * InfernalMobsCore.instance().getMobModHealthFactor();
+ }
+ }
+
+ return stacks.toArray(new ItemStack[0]);
+ }
+ }
+
+ public static class MobDrop {
+ public enum DropType {
+ Normal,
+ Rare,
+ Additional,
+ Infernal
+ }
+
+ public ItemStack stack;
+ public DropType type;
+ public int chance;
+ public Integer enchantable;
+ public HashMap damages;
+
+ public MobDrop(
+ ItemStack stack, DropType type, int chance, Integer enchantable, HashMap damages) {
+ this.stack = stack;
+ this.type = type;
+ this.chance = chance;
+ this.enchantable = enchantable;
+ this.damages = damages;
+ }
+ }
+
+ public static class fakeRand extends Random {
+ private static class nexter {
+ private final int type;
+ private final int bound;
+ private int next;
+
+ public nexter(int type, int bound) {
+ this.next = 0;
+ this.bound = bound;
+ this.type = type;
+ }
+
+ private int getType() {
+ return type;
+ }
+
+ private boolean getBoolean() {
+ return next == 1;
+ }
+
+ private int getInt() {
+ return next;
+ }
+
+ private float getFloat() {
+ return next * 0.1f;
+ }
+
+ private boolean next() {
+ next++;
+ return next >= bound;
+ }
+ }
+
+ private final ArrayList nexts = new ArrayList<>();
+ private int walkCounter = 0;
+ private double chance;
+ private boolean exceptionOnEnchantTry = false;
+ private int maxWalkCount = -1;
+ private float forceFloatValue = -1.f;
+
+ @Override
+ public int nextInt(int bound) {
+ if (exceptionOnEnchantTry && bound == Enchantment.enchantmentsBookList.length) return -1;
+ if (nexts.size() <= walkCounter) { // new call
+ if (maxWalkCount == walkCounter) {
+ return 0;
+ }
+ nexts.add(new nexter(0, bound));
+ walkCounter++;
+ chance /= bound;
+ return 0;
+ }
+ chance /= bound;
+ return nexts.get(walkCounter++).getInt();
+ }
+
+ @Override
+ public float nextFloat() {
+ if (forceFloatValue != -1f) return forceFloatValue;
+ if (nexts.size() <= walkCounter) { // new call
+ if (maxWalkCount == walkCounter) {
+ return 0f;
+ }
+ nexts.add(new nexter(2, 10));
+ walkCounter++;
+ chance /= 10;
+ return 0f;
+ }
+ chance /= 10;
+ return nexts.get(walkCounter++).getFloat();
+ }
+
+ @Override
+ public boolean nextBoolean() {
+ if (nexts.size() <= walkCounter) { // new call
+ if (maxWalkCount == walkCounter) {
+ return false;
+ }
+ nexts.add(new nexter(1, 2));
+ walkCounter++;
+ chance /= 2;
+ return false;
+ }
+ chance /= 2;
+ return nexts.get(walkCounter++).getBoolean();
+ }
+
+ public void newRound() {
+ walkCounter = 0;
+ nexts.clear();
+ chance = 1d;
+ maxWalkCount = -1;
+ exceptionOnEnchantTry = false;
+ forceFloatValue = -1f;
+ }
+
+ public boolean nextRound() {
+ walkCounter = 0;
+ chance = 1d;
+ while (nexts.size() > 0 && nexts.get(nexts.size() - 1).next()) nexts.remove(nexts.size() - 1);
+ return nexts.size() > 0;
+ }
+ }
+
+ private static class dropinstance {
+ public boolean isDamageRandomized = false;
+ public HashMap damagesPossible = new HashMap<>();
+ public boolean isEnchatmentRandomized = false;
+ public int enchantmentLevel = 0;
+ public final ItemStack stack;
+ public final GT_Utility.ItemId itemId;
+ private double dropchance = 0d;
+ private int dropcount = 1;
+ private final droplist owner;
+
+ public dropinstance(ItemStack s, droplist owner) {
+ this.owner = owner;
+ stack = s;
+ itemId = GT_Utility.ItemId.createNoCopy(stack);
+ }
+
+ public int getchance(int chancemodifier) {
+ dropchance = (double) Math.round(dropchance * 100000) / 100000d;
+ return (int) (dropchance * chancemodifier);
+ }
+
+ @Override
+ public int hashCode() {
+ return itemId.hashCode();
+ }
+ }
+
+ public static class droplist {
+ private final ArrayList drops = new ArrayList<>();
+ private final HashMap dropschecker = new HashMap<>();
+
+ public dropinstance add(dropinstance i, double chance) {
+ if (contains(i)) {
+ int ssize = i.stack.stackSize;
+ i = get(dropschecker.get(i.itemId));
+ i.dropchance += chance * ssize;
+ i.dropcount += ssize;
+ return i;
+ }
+ drops.add(i);
+ i.dropchance += chance * i.stack.stackSize;
+ i.dropcount += i.stack.stackSize - 1;
+ i.stack.stackSize = 1;
+ dropschecker.put(i.itemId, drops.size() - 1);
+ return i;
+ }
+
+ public dropinstance get(int index) {
+ return drops.get(index);
+ }
+
+ public dropinstance get(dropinstance i) {
+ if (!contains(i)) return null;
+ return get(dropschecker.get(i.itemId));
+ }
+
+ public boolean contains(dropinstance i) {
+ return dropschecker.containsKey(i.itemId);
+ }
+
+ public boolean contains(ItemStack stack) {
+ return dropschecker.containsKey(GT_Utility.ItemId.createNoCopy(stack));
+ }
+
+ public boolean isEmpty() {
+ return drops.isEmpty();
+ }
+
+ public int size() {
+ return drops.size();
+ }
+
+ public int indexOf(dropinstance i) {
+ if (!contains(i)) return -1;
+ return dropschecker.get(i.itemId);
+ }
+ }
+
+ private static class dropCollector {
+ HashMap damagableChecker = new HashMap<>();
+ private boolean booksAlwaysRandomlyEnchanted = false;
+
+ public void addDrop(droplist fdrops, ArrayList listToParse, double chance) {
+ for (EntityItem entityItem : listToParse) {
+ ItemStack ostack = entityItem.getEntityItem();
+ if (ostack == null) continue;
+ dropinstance drop;
+ boolean randomchomenchantdetected =
+ ostack.hasTagCompound() && ostack.stackTagCompound.hasKey(randomEnchantmentDetectedString);
+ int randomenchantmentlevel = 0;
+ if (randomchomenchantdetected) {
+ randomenchantmentlevel = ostack.stackTagCompound.getInteger(randomEnchantmentDetectedString);
+ ostack.stackTagCompound.removeTag("ench");
+ }
+ if ((booksAlwaysRandomlyEnchanted || randomchomenchantdetected)
+ && Items.enchanted_book == ostack.getItem()) {
+ NBTTagCompound tagCompound = (NBTTagCompound) ostack.stackTagCompound.copy();
+ tagCompound.removeTag("StoredEnchantments");
+ ostack = new ItemStack(Items.book, ostack.stackSize, 0);
+ if (!tagCompound.hasNoTags()) ostack.stackTagCompound = tagCompound;
+ if (randomenchantmentlevel == 0) randomenchantmentlevel = 1;
+ randomchomenchantdetected = true;
+ }
+ boolean randomdamagedetected = false;
+ int newdamage = -1;
+ if (ostack.isItemStackDamageable()) {
+ int odamage = ostack.getItemDamage();
+ ostack.setItemDamage(1);
+ GT_Utility.ItemId id = GT_Utility.ItemId.createNoCopy(ostack);
+ damagableChecker.putIfAbsent(id, odamage);
+ int check = damagableChecker.get(id);
+ if (check != odamage) {
+ randomdamagedetected = true;
+ newdamage = odamage;
+ ostack.setItemDamage(check);
+ } else ostack.setItemDamage(odamage);
+ }
+ drop = fdrops.add(new dropinstance(ostack.copy(), fdrops), chance);
+ if (!drop.isEnchatmentRandomized && randomchomenchantdetected) {
+ drop.isEnchatmentRandomized = true;
+ drop.enchantmentLevel = randomenchantmentlevel;
+ }
+ if (drop.isDamageRandomized && !randomdamagedetected) {
+ drop.damagesPossible.merge(drop.stack.getItemDamage(), 1, Integer::sum);
+ }
+ if (randomdamagedetected) {
+ if (!drop.isDamageRandomized) {
+ drop.isDamageRandomized = true;
+ drop.damagesPossible.merge(drop.stack.getItemDamage(), drop.dropcount - 1, Integer::sum);
+ }
+ if (newdamage == -1) newdamage = drop.stack.getItemDamage();
+ drop.damagesPossible.merge(newdamage, 1, Integer::sum);
+ }
+ }
+
+ listToParse.clear();
+ }
+
+ public void newRound() {
+ damagableChecker.clear();
+ booksAlwaysRandomlyEnchanted = false;
+ }
+ }
+
+ public static class GeneralMappedMob {
+ public final EntityLiving mob;
+ public final MobRecipe recipe;
+ public final ArrayList drops;
+
+ public GeneralMappedMob(EntityLiving mob, MobRecipe recipe, ArrayList drops) {
+ this.mob = mob;
+ this.recipe = recipe;
+ this.drops = drops;
+ }
+ }
+
+ public static final HashMap GeneralMobList = new HashMap<>();
+
+ @SuppressWarnings("unchecked")
+ public static void generateMobRecipeMap() {
+
+ if (alreadyGenerated) return;
+ alreadyGenerated = true;
+ if (!Config.mobHandlerEnabled) return;
+
+ World f = new GT_DummyWorld() {
+ @Override
+ public boolean blockExists(int p_72899_1_, int p_72899_2_, int p_72899_3_) {
+ return false;
+ }
+
+ @Override
+ public List getEntitiesWithinAABB(Class p_72872_1_, AxisAlignedBB p_72872_2_) {
+ return new ArrayList();
+ }
+ };
+ f.isRemote = true; // quick hack to get around achievements
+
+ fakeRand frand = new fakeRand();
+ f.rand = frand;
+
+ isInGenerationProcess = true;
+
+ LOG.info("Generating Recipe Map for Mob Handler and EEC");
+
+ 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
+ ((Map>) EntityList.stringToClassMapping).forEach((k, v) -> {
+ if (v == null) return;
+
+ LOG.info("Generating entry for mob: " + k);
+
+ if (Modifier.isAbstract(v.getModifiers())) {
+ LOG.info("Entity " + k + " is abstract, skipping");
+ return;
+ }
+
+ EntityLiving e;
+ try {
+ e = (EntityLiving) v.getConstructor(new Class[] {World.class}).newInstance(new Object[] {f});
+ } catch (ClassCastException ex) {
+ // not a EntityLiving
+ LOG.info("Entity " + k + " is not a LivingEntity, skipping");
+ return;
+ } catch (NoSuchMethodException ex) {
+ // No constructor ?
+ LOG.info("Entity " + k + " doesn't have constructor, skipping");
+ return;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return;
+ }
+
+ if (StatCollector.translateToLocal("entity." + k + ".name").equals("entity." + k + ".name")) {
+ LOG.info("Entity " + k + " does't have localized name, skipping");
+ return;
+ }
+
+ e.captureDrops = true;
+
+ // POWERFULL GENERATION
+
+ 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 additionaldrops = new droplist();
+
+ LOG.info("Generating normal drops");
+
+ 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();
+ }
+
+ do {
+ try {
+ dropFewItems.invoke(e, true, 0);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return;
+ }
+ collector.addDrop(drops, e.capturedDrops, frand.chance);
+
+ if (frand.chance < 0.0000001d) {
+ LOG.info("Skipping " + k + " normal dropmap because it's too randomized");
+ break;
+ }
+
+ } while (frand.nextRound());
+
+ LOG.info("Generating rare drops");
+
+ frand.newRound();
+ collector.newRound();
+
+ do {
+ try {
+ dropRareDrop.invoke(e, 0);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return;
+ }
+ collector.addDrop(raredrops, e.capturedDrops, frand.chance);
+
+ if (frand.chance < 0.0000001d) {
+ LOG.info("Skipping " + k + " rare dropmap because it's too randomized");
+ break;
+ }
+ } while (frand.nextRound());
+
+ LOG.info("Generating additional drops");
+
+ frand.newRound();
+ collector.newRound();
+
+ try {
+ Class> cl = e.getClass();
+ boolean detectedException = false;
+ 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;
+ }
+ do {
+ addRandomArmor.invoke(e);
+ if (!usingVanillaEnchantingMethod) enchantEquipment.invoke(e);
+ 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 (frand.chance < 0.0000001d) {
+ LOG.info("Skipping " + k + " additional dropmap because it's too randomized");
+ break;
+ }
+
+ } while (frand.nextRound());
+ } catch (Exception ignored) {
+ }
+
+ frand.newRound();
+ collector.newRound();
+
+ if (drops.isEmpty() && raredrops.isEmpty() && additionaldrops.isEmpty()) {
+ GeneralMobList.put(k, new GeneralMappedMob(e, null, new ArrayList<>()));
+ LOG.info("Entity " + k + " doesn't drop any items, skipping EEC Recipe map");
+ return;
+ }
+
+ ArrayList moboutputs = new ArrayList<>(drops.size() + raredrops.size() + additionaldrops.size());
+
+ for (dropinstance drop : drops.drops) {
+ ItemStack stack = drop.stack;
+ if (stack.hasTagCompound()) stack.stackTagCompound.removeTag(randomEnchantmentDetectedString);
+ int chance = drop.getchance(10000);
+ while (chance > 10000) {
+ stack.stackSize *= 2;
+ chance /= 2;
+ }
+ moboutputs.add(new MobDrop(
+ stack,
+ MobDrop.DropType.Normal,
+ chance,
+ drop.isEnchatmentRandomized ? drop.enchantmentLevel : null,
+ drop.isDamageRandomized ? drop.damagesPossible : null));
+ }
+ for (dropinstance drop : raredrops.drops) {
+ ItemStack stack = drop.stack;
+ if (stack.hasTagCompound()) stack.stackTagCompound.removeTag(randomEnchantmentDetectedString);
+ int chance = drop.getchance(250);
+ while (chance > 10000) {
+ stack.stackSize *= 2;
+ chance /= 2;
+ }
+ moboutputs.add(new MobDrop(
+ stack,
+ MobDrop.DropType.Rare,
+ chance,
+ drop.isEnchatmentRandomized ? drop.enchantmentLevel : null,
+ drop.isDamageRandomized ? drop.damagesPossible : null));
+ }
+ for (dropinstance drop : additionaldrops.drops) {
+ ItemStack stack = drop.stack;
+ if (stack.hasTagCompound()) stack.stackTagCompound.removeTag(randomEnchantmentDetectedString);
+ int chance = drop.getchance(850);
+ while (chance > 10000) {
+ stack.stackSize *= 2;
+ chance /= 2;
+ }
+ moboutputs.add(new MobDrop(
+ stack,
+ MobDrop.DropType.Additional,
+ chance,
+ drop.isEnchatmentRandomized ? drop.enchantmentLevel : null,
+ drop.isDamageRandomized ? drop.damagesPossible : null));
+ }
+
+ GeneralMobList.put(k, new GeneralMappedMob(e, new MobRecipe(e, moboutputs), moboutputs));
+
+ LOG.info("Mapped " + k);
+ });
+
+ time -= System.currentTimeMillis();
+ time = -time;
+
+ LOG.info("Recipe map generated ! It took " + time + "ms");
+
+ isInGenerationProcess = false;
+ }
+
+ public static void processMobRecipeMap() {
+ LOG.info("Loading config");
+
+ if (isClientSided) Mob_Handler.clearRecipes();
+ MobNameToRecipeMap.clear();
+ LoadConfigPacket.instance.mobsToLoad.clear();
+ GeneralMobList.forEach((k, v) -> {
+ if (Arrays.asList(Config.mobBlacklist).contains(k)) {
+ LOG.info("Entity " + k + " is blacklisted, skipping");
+ return;
+ }
+
+ MobRecipe recipe = v.recipe;
+ if (recipe != null) recipe = recipe.copy();
+ ArrayList drops = (ArrayList) v.drops.clone();
+
+ // MT Scripts should already be loaded here
+ if (LoaderReference.MineTweaker) {
+ Optionals.parseMTAdditions(k, drops, recipe);
+ }
+
+ if (drops.isEmpty()) {
+ LOG.info("Entity " + k + " doesn't drop any items, skipping EEC map");
+ if (!Config.includeEmptyMobs) return;
+ LoadConfigPacket.instance.mobsToLoad.add(k);
+ LOG.info("Registered " + k);
+ return;
+ }
+ if (v.recipe != null) MobNameToRecipeMap.put(k, recipe);
+ LoadConfigPacket.instance.mobsToLoad.add(k);
+ LOG.info("Registered " + k);
+ });
+ }
+
+ @SideOnly(Side.CLIENT)
+ public static void processMobRecipeMap(HashSet mobs) {
+ if (isClientSided) Mob_Handler.clearRecipes();
+ MobNameToRecipeMap.clear();
+ mobs.forEach(k -> {
+ GeneralMappedMob v = GeneralMobList.get(k);
+ MobRecipe recipe = v.recipe;
+ if (recipe != null) recipe = recipe.copy();
+ ArrayList drops = (ArrayList) v.drops.clone();
+
+ // MT Scripts should already be loaded here
+ if (LoaderReference.MineTweaker) {
+ Optionals.parseMTAdditions(k, drops, recipe);
+ }
+
+ Mob_Handler.addRecipe(v.mob, drops);
+ if (recipe != null) MobNameToRecipeMap.put(k, recipe);
+ LOG.info("Registered " + k);
+ });
+ LOG.info("Sorting NEI map");
+ Mob_Handler.sortCachedRecipes();
+ }
+
+ private static class Optionals {
+ private static void parseMTAdditions(String k, ArrayList drops, MobRecipe recipe) {
+ IEntityDefinition ie = MineTweakerAPI.game.getEntity(k);
+ if (ie != null) {
+ for (Map.Entry entry : ie.getDropsToAdd().entrySet()) {
+ IntRange r = entry.getValue();
+ // Get average chance
+ double chance;
+ if (r.getFrom() == 0 && r.getTo() == 0) chance = 1d;
+ else chance = (((double) r.getTo() - (double) r.getFrom()) / 2d) + (double) r.getFrom();
+ ItemStack stack = ((ItemStack) entry.getKey().getInternal()).copy();
+ MobDrop drop = new MobDrop(stack, MobDrop.DropType.Normal, (int) (chance * 10000), null, null);
+ drops.add(drop);
+ if (recipe != null) recipe.mOutputs.add(drop);
+ }
+ for (Map.Entry entry :
+ ie.getDropsToAddPlayerOnly().entrySet()) {
+ IntRange r = entry.getValue();
+ // Get average chance
+ double chance;
+ if (r.getFrom() == 0 && r.getTo() == 0) chance = 1d;
+ else chance = (((double) r.getTo() - (double) r.getFrom()) / 2d) + (double) r.getFrom();
+ ItemStack stack = ((ItemStack) entry.getKey().getInternal()).copy();
+ MobDrop drop = new MobDrop(stack, MobDrop.DropType.Normal, (int) (chance * 10000), null, null);
+ drops.add(drop);
+ if (recipe != null) recipe.mOutputs.add(drop);
+ }
+ for (IItemStack istack : ie.getDropsToRemove()) {
+ List toRemove = drops.stream()
+ .filter(d -> istack.matches(new MCItemStack(d.stack)))
+ .collect(Collectors.toList());
+ drops.removeAll(toRemove);
+ if (recipe != null) recipe.mOutputs.removeAll(toRemove);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/kubatech/loaders/RecipeLoader.java b/src/main/java/kubatech/loaders/RecipeLoader.java
new file mode 100644
index 0000000000..99908a857f
--- /dev/null
+++ b/src/main/java/kubatech/loaders/RecipeLoader.java
@@ -0,0 +1,77 @@
+/*
+ * KubaTech - Gregtech Addon
+ * Copyright (C) 2022 kuba6000
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package kubatech.loaders;
+
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.OrePrefixes;
+import gregtech.api.util.GT_ModHandler;
+import kubatech.Tags;
+import kubatech.api.LoaderReference;
+import kubatech.api.enums.ItemList;
+import kubatech.common.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class RecipeLoader {
+
+ private static final Logger LOG = LogManager.getLogger(Tags.MODID + "[Recipe Loader]");
+ protected static final long bitsd = GT_ModHandler.RecipeBits.NOT_REMOVABLE
+ | GT_ModHandler.RecipeBits.REVERSIBLE
+ | GT_ModHandler.RecipeBits.BUFFERED
+ | GT_ModHandler.RecipeBits.DISMANTLEABLE;
+
+ private static int MTEID = 14201;
+ private static final int MTEIDMax = 14300;
+
+ public static void addRecipes() {
+ if (LoaderReference.EnderIO) {
+ ItemList.ExtremeExterminationChamber.set(new GT_MetaTileEntity_ExtremeExterminationChamber(
+ MTEID++, "multimachine.exterminationchamber", "Extreme Extermination Chamber")
+ .getStackForm(1L));
+ GT_ModHandler.addCraftingRecipe(ItemList.ExtremeExterminationChamber.get(1), bitsd, new Object[] {
+ "RCR",
+ "CHC",
+ "VVV",
+ 'R',
+ gregtech.api.enums.ItemList.Robot_Arm_EV,
+ 'C',
+ OrePrefixes.circuit.get(Materials.Data),
+ 'H',
+ gregtech.api.enums.ItemList.Hull_EV,
+ 'V',
+ GT_ModHandler.getModItem("OpenBlocks", "vacuumhopper", 1, new ItemStack(Blocks.hopper))
+ });
+ }
+ if (MTEID > MTEIDMax + 1) throw new RuntimeException("MTE ID's");
+ }
+
+ private static boolean lateRecipesInitialized = false;
+
+ public static void addRecipesLate() {
+ // Runs on server start
+ if (lateRecipesInitialized) return;
+ lateRecipesInitialized = true;
+
+ MobRecipeLoader.generateMobRecipeMap();
+ MobRecipeLoader.processMobRecipeMap();
+ }
+}
--
cgit
From f53a666152aa956a097d67fdaa7fb18757839147 Mon Sep 17 00:00:00 2001
From: kuba6000
Date: Sun, 14 Aug 2022 16:23:54 +0200
Subject: Fix server crash from Blood Magic entities
---
src/main/java/kubatech/loaders/MobRecipeLoader.java | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
(limited to 'src/main/java/kubatech/loaders')
diff --git a/src/main/java/kubatech/loaders/MobRecipeLoader.java b/src/main/java/kubatech/loaders/MobRecipeLoader.java
index 033beb49fd..fddfb03137 100644
--- a/src/main/java/kubatech/loaders/MobRecipeLoader.java
+++ b/src/main/java/kubatech/loaders/MobRecipeLoader.java
@@ -618,7 +618,11 @@ public class MobRecipeLoader {
// No constructor ?
LOG.info("Entity " + k + " doesn't have constructor, skipping");
return;
- } catch (Exception ex) {
+ } catch (NoClassDefFoundError ex) {
+ // Its using classes from Client ? Then it's not important to include
+ LOG.info("Entity " + k + " is using undefined classes, skipping");
+ return;
+ } catch (Throwable ex) {
ex.printStackTrace();
return;
}
--
cgit
From 4ad580a05e475a912ff9964cdd09d5ff666b98e8 Mon Sep 17 00:00:00 2001
From: kuba6000
Date: Sun, 14 Aug 2022 21:46:59 +0200
Subject: LGPL 3.0
---
src/main/java/kubatech/loaders/MobRecipeLoader.java | 18 +++++++++---------
src/main/java/kubatech/loaders/RecipeLoader.java | 18 +++++++++---------
2 files changed, 18 insertions(+), 18 deletions(-)
(limited to 'src/main/java/kubatech/loaders')
diff --git a/src/main/java/kubatech/loaders/MobRecipeLoader.java b/src/main/java/kubatech/loaders/MobRecipeLoader.java
index fddfb03137..3c087961d9 100644
--- a/src/main/java/kubatech/loaders/MobRecipeLoader.java
+++ b/src/main/java/kubatech/loaders/MobRecipeLoader.java
@@ -2,18 +2,18 @@
* KubaTech - Gregtech Addon
* Copyright (C) 2022 kuba6000
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see .
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
*
*/
diff --git a/src/main/java/kubatech/loaders/RecipeLoader.java b/src/main/java/kubatech/loaders/RecipeLoader.java
index 99908a857f..ba6cbb7a1f 100644
--- a/src/main/java/kubatech/loaders/RecipeLoader.java
+++ b/src/main/java/kubatech/loaders/RecipeLoader.java
@@ -2,18 +2,18 @@
* KubaTech - Gregtech Addon
* Copyright (C) 2022 kuba6000
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU 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 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 program is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * 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 General Public License
- * along with this program. If not, see .
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
*
*/
--
cgit
From 76a2834cedfa4f3916d07e2893fc54121268489e Mon Sep 17 00:00:00 2001
From: kuba6000
Date: Wed, 17 Aug 2022 05:01:16 +0200
Subject: Structure
---
.../java/kubatech/loaders/MobRecipeLoader.java | 22 +++++++++++++++-------
src/main/java/kubatech/loaders/RecipeLoader.java | 2 +-
2 files changed, 16 insertions(+), 8 deletions(-)
(limited to 'src/main/java/kubatech/loaders')
diff --git a/src/main/java/kubatech/loaders/MobRecipeLoader.java b/src/main/java/kubatech/loaders/MobRecipeLoader.java
index 3c087961d9..21c18897f4 100644
--- a/src/main/java/kubatech/loaders/MobRecipeLoader.java
+++ b/src/main/java/kubatech/loaders/MobRecipeLoader.java
@@ -21,7 +21,7 @@ package kubatech.loaders;
import static kubatech.api.utils.ModUtils.isClientSided;
import static kubatech.api.utils.ModUtils.isDeobfuscatedEnvironment;
-import static kubatech.common.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber.MobNameToRecipeMap;
+import static kubatech.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber.MobNameToRecipeMap;
import atomicstryker.infernalmobs.common.InfernalMobsCore;
import atomicstryker.infernalmobs.common.MobModifier;
@@ -39,10 +39,10 @@ import java.util.stream.Collectors;
import kubatech.Config;
import kubatech.Tags;
import kubatech.api.LoaderReference;
+import kubatech.api.network.LoadConfigPacket;
import kubatech.api.utils.InfernalHelper;
-import kubatech.common.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber;
import kubatech.nei.Mob_Handler;
-import kubatech.network.LoadConfigPacket;
+import kubatech.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber;
import minetweaker.MineTweakerAPI;
import minetweaker.api.entity.IEntityDefinition;
import minetweaker.api.item.IItemStack;
@@ -102,6 +102,7 @@ public class MobRecipeLoader {
public final boolean alwaysinfernal;
public static droplist infernaldrops;
public final boolean isPeacefulAllowed;
+ public final EntityLiving entity;
@SuppressWarnings("unchecked")
public MobRecipe copy() {
@@ -111,7 +112,8 @@ public class MobRecipeLoader {
mMaxDamageChance,
infernalityAllowed,
alwaysinfernal,
- isPeacefulAllowed);
+ isPeacefulAllowed,
+ entity);
}
private MobRecipe(
@@ -120,13 +122,15 @@ public class MobRecipeLoader {
int mMaxDamageChance,
boolean infernalityAllowed,
boolean alwaysinfernal,
- boolean isPeacefulAllowed) {
+ boolean isPeacefulAllowed,
+ EntityLiving entity) {
this.mOutputs = mOutputs;
this.mDuration = mDuration;
this.mMaxDamageChance = mMaxDamageChance;
this.infernalityAllowed = infernalityAllowed;
this.alwaysinfernal = alwaysinfernal;
this.isPeacefulAllowed = isPeacefulAllowed;
+ this.entity = entity;
}
@SuppressWarnings("unchecked")
@@ -185,6 +189,7 @@ public class MobRecipeLoader {
mMaxDamageChance = maxdamagechance;
// Powered spawner with octadic capacitor spawns ~22/min ~= 0.366/sec ~= 2.72s/spawn ~= 54.54t/spawn
mDuration = 55 + 10 + (((int) e.getMaxHealth() / 5) * 10);
+ entity = e;
}
public ItemStack[] generateOutputs(Random rnd, GT_MetaTileEntity_ExtremeExterminationChamber MTE) {
@@ -460,7 +465,7 @@ public class MobRecipeLoader {
}
private static class dropCollector {
- HashMap damagableChecker = new HashMap<>();
+ final HashMap damagableChecker = new HashMap<>();
private boolean booksAlwaysRandomlyEnchanted = false;
public void addDrop(droplist fdrops, ArrayList listToParse, double chance) {
@@ -552,6 +557,7 @@ public class MobRecipeLoader {
return false;
}
+ @SuppressWarnings("rawtypes")
@Override
public List getEntitiesWithinAABB(Class p_72872_1_, AxisAlignedBB p_72872_2_) {
return new ArrayList();
@@ -727,7 +733,7 @@ public class MobRecipeLoader {
try {
Class> cl = e.getClass();
- boolean detectedException = false;
+ boolean detectedException;
do {
detectedException = false;
try {
@@ -894,6 +900,7 @@ public class MobRecipeLoader {
MobRecipe recipe = v.recipe;
if (recipe != null) recipe = recipe.copy();
+ @SuppressWarnings("unchecked")
ArrayList drops = (ArrayList) v.drops.clone();
// MT Scripts should already be loaded here
@@ -922,6 +929,7 @@ public class MobRecipeLoader {
GeneralMappedMob v = GeneralMobList.get(k);
MobRecipe recipe = v.recipe;
if (recipe != null) recipe = recipe.copy();
+ @SuppressWarnings("unchecked")
ArrayList drops = (ArrayList) v.drops.clone();
// MT Scripts should already be loaded here
diff --git a/src/main/java/kubatech/loaders/RecipeLoader.java b/src/main/java/kubatech/loaders/RecipeLoader.java
index ba6cbb7a1f..84c3603225 100644
--- a/src/main/java/kubatech/loaders/RecipeLoader.java
+++ b/src/main/java/kubatech/loaders/RecipeLoader.java
@@ -25,7 +25,7 @@ import gregtech.api.util.GT_ModHandler;
import kubatech.Tags;
import kubatech.api.LoaderReference;
import kubatech.api.enums.ItemList;
-import kubatech.common.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber;
+import kubatech.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import org.apache.logging.log4j.LogManager;
--
cgit
From 01d91c0acd0e8b494578d63683088e6f1d67509f Mon Sep 17 00:00:00 2001
From: kuba6000
Date: Thu, 18 Aug 2022 00:12:14 +0200
Subject: Cache Mob Handler map
---
.../java/kubatech/loaders/MobRecipeLoader.java | 84 +++++++++++++++++++++-
1 file changed, 83 insertions(+), 1 deletion(-)
(limited to 'src/main/java/kubatech/loaders')
diff --git a/src/main/java/kubatech/loaders/MobRecipeLoader.java b/src/main/java/kubatech/loaders/MobRecipeLoader.java
index 3c087961d9..b7c5e9781d 100644
--- a/src/main/java/kubatech/loaders/MobRecipeLoader.java
+++ b/src/main/java/kubatech/loaders/MobRecipeLoader.java
@@ -26,20 +26,28 @@ import static kubatech.common.tileentity.gregtech.multiblock.GT_MetaTileEntity_E
import atomicstryker.infernalmobs.common.InfernalMobsCore;
import atomicstryker.infernalmobs.common.MobModifier;
import atomicstryker.infernalmobs.common.mods.api.ModifierLoader;
+import com.google.common.io.Files;
+import com.google.gson.Gson;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import gregtech.api.util.GT_Utility;
import gregtech.common.GT_DummyWorld;
+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.*;
import java.util.stream.Collectors;
import kubatech.Config;
import kubatech.Tags;
import kubatech.api.LoaderReference;
+import kubatech.api.utils.GSONUtils;
import kubatech.api.utils.InfernalHelper;
+import kubatech.api.utils.ModUtils;
import kubatech.common.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber;
import kubatech.nei.Mob_Handler;
import kubatech.network.LoadConfigPacket;
@@ -259,7 +267,10 @@ public class MobRecipeLoader {
Infernal
}
+ @GSONUtils.SkipGSON
public ItemStack stack;
+
+ public NBTTagCompound reconstructableStack;
public DropType type;
public int chance;
public Integer enchantable;
@@ -268,11 +279,16 @@ public class MobRecipeLoader {
public MobDrop(
ItemStack stack, DropType type, int chance, Integer enchantable, HashMap damages) {
this.stack = stack;
+ this.reconstructableStack = stack.writeToNBT(new NBTTagCompound());
this.type = type;
this.chance = chance;
this.enchantable = enchantable;
this.damages = damages;
}
+
+ public void reconstructStack() {
+ this.stack = ItemStack.loadItemStackFromNBT(this.reconstructableStack);
+ }
}
public static class fakeRand extends Random {
@@ -539,7 +555,12 @@ public class MobRecipeLoader {
public static final HashMap GeneralMobList = new HashMap<>();
- @SuppressWarnings("unchecked")
+ private static class MobRecipeLoaderCacheStructure {
+ String version;
+ Map> moblist;
+ }
+
+ @SuppressWarnings({"unchecked", "UnstableApiUsage"})
public static void generateMobRecipeMap() {
if (alreadyGenerated) return;
@@ -562,6 +583,46 @@ public class MobRecipeLoader {
fakeRand frand = new fakeRand();
f.rand = frand;
+ File cache = Config.getConfigFile("MobRecipeLoader.cache");
+ Gson gson = GSONUtils.GSON_BUILDER.create();
+
+ if (cache.exists()) {
+ LOG.info("Parsing Cached map");
+ Reader reader = null;
+ try {
+ reader = Files.newReader(cache, StandardCharsets.UTF_8);
+ MobRecipeLoaderCacheStructure s = gson.fromJson(reader, MobRecipeLoaderCacheStructure.class);
+ if (s.version.equals(ModUtils.getModListVersion())) {
+ for (Map.Entry> entry : s.moblist.entrySet()) {
+ try {
+ EntityLiving e =
+ (EntityLiving) ((Class>) EntityList.stringToClassMapping.get(entry.getKey()))
+ .getConstructor(new Class[] {World.class})
+ .newInstance(new Object[] {f});
+ ArrayList drops = entry.getValue();
+ drops.forEach(MobDrop::reconstructStack);
+ GeneralMobList.put(entry.getKey(), new GeneralMappedMob(e, new MobRecipe(e, drops), drops));
+ } catch (Exception ignored) {
+ }
+ }
+ LOG.info("Parsed cached map, skipping generation");
+ return;
+ } else {
+ LOG.info("Cached map version mismatch, generating a new one");
+ }
+ } catch (Exception ignored) {
+ LOG.info("There was an exception while parsing cached map, generating a new one");
+ } finally {
+ if (reader != null)
+ try {
+ reader.close();
+ } catch (Exception ignored) {
+ }
+ }
+ } else {
+ LOG.info("Cached map doesn't exist, generating a new one");
+ }
+
isInGenerationProcess = true;
LOG.info("Generating Recipe Map for Mob Handler and EEC");
@@ -878,6 +939,27 @@ public class MobRecipeLoader {
LOG.info("Recipe map generated ! It took " + time + "ms");
isInGenerationProcess = false;
+
+ LOG.info("Saving generated map to file");
+ MobRecipeLoaderCacheStructure s = new MobRecipeLoaderCacheStructure();
+ s.version = ModUtils.getModListVersion();
+ s.moblist = new HashMap<>();
+ GeneralMobList.forEach((k, v) -> s.moblist.put(k, v.drops));
+ Writer writer = null;
+ try {
+ writer = Files.newWriter(cache, StandardCharsets.UTF_8);
+ gson.toJson(s, writer);
+ writer.flush();
+ writer.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (writer != null)
+ try {
+ writer.close();
+ } catch (Exception ignored) {
+ }
+ }
}
public static void processMobRecipeMap() {
--
cgit
From c775b9f97779003c3a2366eff607b1d64b6c8040 Mon Sep 17 00:00:00 2001
From: kuba6000
Date: Thu, 18 Aug 2022 00:45:04 +0200
Subject: Update MobRecipeLoader.java
---
src/main/java/kubatech/loaders/MobRecipeLoader.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
(limited to 'src/main/java/kubatech/loaders')
diff --git a/src/main/java/kubatech/loaders/MobRecipeLoader.java b/src/main/java/kubatech/loaders/MobRecipeLoader.java
index b7c5e9781d..283c75391a 100644
--- a/src/main/java/kubatech/loaders/MobRecipeLoader.java
+++ b/src/main/java/kubatech/loaders/MobRecipeLoader.java
@@ -601,7 +601,9 @@ public class MobRecipeLoader {
.newInstance(new Object[] {f});