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
---
src/main/java/kubatech/ClientProxy.java | 8 +
src/main/java/kubatech/CommonProxy.java | 20 +-
src/main/java/kubatech/Config.java | 54 +-
src/main/java/kubatech/FMLEventHandler.java | 16 +
src/main/java/kubatech/api/LoaderReference.java | 12 +
src/main/java/kubatech/api/Variables.java | 26 +
src/main/java/kubatech/api/enums/ItemList.java | 167 ++++
src/main/java/kubatech/api/utils/FastRandom.java | 27 +
.../java/kubatech/api/utils/InfernalHelper.java | 226 +++++
src/main/java/kubatech/api/utils/ModUtils.java | 50 ++
.../java/kubatech/api/utils/ReflectionHelper.java | 62 ++
src/main/java/kubatech/commands/CommandConfig.java | 96 ++
.../java/kubatech/commands/CommandHandler.java | 115 +++
src/main/java/kubatech/commands/CommandHelp.java | 80 ++
...MetaTileEntity_ExtremeExterminationChamber.java | 394 +++++++++
src/main/java/kubatech/kubatech.java | 26 +-
.../java/kubatech/loaders/MobRecipeLoader.java | 973 +++++++++++++++++++++
src/main/java/kubatech/loaders/RecipeLoader.java | 77 ++
src/main/java/kubatech/mixin/Mixin.java | 42 +
src/main/java/kubatech/mixin/MixinPlugin.java | 110 +++
src/main/java/kubatech/mixin/TargetedMod.java | 35 +
.../mixins/minecraft/EnchantmentHelperMixin.java | 40 +
src/main/java/kubatech/nei/IMCForNEI.java | 76 ++
src/main/java/kubatech/nei/Mob_Handler.java | 592 +++++++++++++
src/main/java/kubatech/nei/NEI_Config.java | 44 +
.../java/kubatech/network/LoadConfigHandler.java | 36 +
.../java/kubatech/network/LoadConfigPacket.java | 61 ++
27 files changed, 3458 insertions(+), 7 deletions(-)
create mode 100644 src/main/java/kubatech/FMLEventHandler.java
create mode 100644 src/main/java/kubatech/api/LoaderReference.java
create mode 100644 src/main/java/kubatech/api/Variables.java
create mode 100644 src/main/java/kubatech/api/enums/ItemList.java
create mode 100644 src/main/java/kubatech/api/utils/FastRandom.java
create mode 100644 src/main/java/kubatech/api/utils/InfernalHelper.java
create mode 100644 src/main/java/kubatech/api/utils/ModUtils.java
create mode 100644 src/main/java/kubatech/api/utils/ReflectionHelper.java
create mode 100644 src/main/java/kubatech/commands/CommandConfig.java
create mode 100644 src/main/java/kubatech/commands/CommandHandler.java
create mode 100644 src/main/java/kubatech/commands/CommandHelp.java
create mode 100644 src/main/java/kubatech/common/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeExterminationChamber.java
create mode 100644 src/main/java/kubatech/loaders/MobRecipeLoader.java
create mode 100644 src/main/java/kubatech/loaders/RecipeLoader.java
create mode 100644 src/main/java/kubatech/mixin/Mixin.java
create mode 100644 src/main/java/kubatech/mixin/MixinPlugin.java
create mode 100644 src/main/java/kubatech/mixin/TargetedMod.java
create mode 100644 src/main/java/kubatech/mixin/mixins/minecraft/EnchantmentHelperMixin.java
create mode 100644 src/main/java/kubatech/nei/IMCForNEI.java
create mode 100644 src/main/java/kubatech/nei/Mob_Handler.java
create mode 100644 src/main/java/kubatech/nei/NEI_Config.java
create mode 100644 src/main/java/kubatech/network/LoadConfigHandler.java
create mode 100644 src/main/java/kubatech/network/LoadConfigPacket.java
(limited to 'src/main/java/kubatech')
diff --git a/src/main/java/kubatech/ClientProxy.java b/src/main/java/kubatech/ClientProxy.java
index 8d676b30ec..f25f41ee2c 100644
--- a/src/main/java/kubatech/ClientProxy.java
+++ b/src/main/java/kubatech/ClientProxy.java
@@ -20,15 +20,23 @@
package kubatech;
import cpw.mods.fml.common.event.*;
+import kubatech.api.utils.ModUtils;
+import kubatech.loaders.MobRecipeLoader;
+import kubatech.nei.IMCForNEI;
+import net.minecraftforge.common.MinecraftForge;
+@SuppressWarnings("unused")
public class ClientProxy extends CommonProxy {
public void preInit(FMLPreInitializationEvent event) {
+ ModUtils.isClientSided = true;
super.preInit(event);
}
public void init(FMLInitializationEvent event) {
super.init(event);
+ IMCForNEI.IMCSender();
+ MinecraftForge.EVENT_BUS.register(MobRecipeLoader.instance);
}
public void postInit(FMLPostInitializationEvent event) {
diff --git a/src/main/java/kubatech/CommonProxy.java b/src/main/java/kubatech/CommonProxy.java
index b058dc96e7..e844cd19d0 100644
--- a/src/main/java/kubatech/CommonProxy.java
+++ b/src/main/java/kubatech/CommonProxy.java
@@ -19,14 +19,22 @@
package kubatech;
+import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.event.*;
+import kubatech.commands.CommandConfig;
+import kubatech.commands.CommandHandler;
+import kubatech.commands.CommandHelp;
+import kubatech.loaders.RecipeLoader;
public class CommonProxy {
public void preInit(FMLPreInitializationEvent event) {
- Config.syncronizeConfiguration(event.getSuggestedConfigurationFile());
+ kubatech.info("Initializing ! Version: " + Tags.VERSION);
- kubatech.info("I am " + Tags.MODNAME + " at version " + Tags.VERSION);
+ Config.init(event.getSuggestedConfigurationFile());
+ Config.synchronizeConfiguration();
+ RecipeLoader.addRecipes();
+ FMLCommonHandler.instance().bus().register(new FMLEventHandler());
}
public void init(FMLInitializationEvent event) {}
@@ -35,7 +43,13 @@ public class CommonProxy {
public void serverAboutToStart(FMLServerAboutToStartEvent event) {}
- public void serverStarting(FMLServerStartingEvent event) {}
+ public void serverStarting(FMLServerStartingEvent event) {
+ RecipeLoader.addRecipesLate();
+ CommandHandler cmd = new CommandHandler();
+ cmd.addCommand(new CommandHelp());
+ cmd.addCommand(new CommandConfig());
+ event.registerServerCommand(cmd);
+ }
public void serverStarted(FMLServerStartedEvent event) {}
diff --git a/src/main/java/kubatech/Config.java b/src/main/java/kubatech/Config.java
index b3af0fe9bc..439557d9a0 100644
--- a/src/main/java/kubatech/Config.java
+++ b/src/main/java/kubatech/Config.java
@@ -24,10 +24,62 @@ import net.minecraftforge.common.config.Configuration;
public class Config {
- public static void syncronizeConfiguration(File configFile) {
+ private static class Categories {
+ public static final String mobHandler = "MobHandler";
+ }
+
+ public static boolean mobHandlerEnabled = true;
+ public static boolean includeEmptyMobs = true;
+ public static String[] mobBlacklist;
+ public static File configFile;
+
+ public static void init(File configFile) {
+ Config.configFile = configFile;
+ }
+
+ public static void synchronizeConfiguration() {
Configuration configuration = new Configuration(configFile);
configuration.load();
+ mobHandlerEnabled = configuration
+ .get(
+ Categories.mobHandler,
+ "Enabled",
+ true,
+ "Enable \"Mob Drops\" NEI page and Extreme Extermination Chamber")
+ .getBoolean();
+ includeEmptyMobs = configuration
+ .get(Categories.mobHandler, "IncludeEmptyMobs", true, "Include mobs that have no drops in NEI")
+ .getBoolean();
+ mobBlacklist = configuration
+ .get(
+ Categories.mobHandler,
+ "MobBlacklist",
+ new String[] {
+ "Giant",
+ "Thaumcraft.TravelingTrunk",
+ "chisel.snowman",
+ "OpenBlocks.Luggage",
+ "OpenBlocks.MiniMe",
+ "SpecialMobs.SpecialCreeper",
+ "SpecialMobs.SpecialZombie",
+ "SpecialMobs.SpecialPigZombie",
+ "SpecialMobs.SpecialSlime",
+ "SpecialMobs.SpecialSkeleton",
+ "SpecialMobs.SpecialEnderman",
+ "SpecialMobs.SpecialCaveSpider",
+ "SpecialMobs.SpecialGhast",
+ "SpecialMobs.SpecialWitch",
+ "SpecialMobs.SpecialSpider",
+ "TwilightForest.HydraHead",
+ "TwilightForest.RovingCube",
+ "TwilightForest.Harbinger Cube",
+ "TwilightForest.Adherent",
+ "SpecialMobs.SpecialSilverfish",
+ },
+ "These mobs will be skipped when generating recipe map")
+ .getStringList();
+
if (configuration.hasChanged()) {
configuration.save();
}
diff --git a/src/main/java/kubatech/FMLEventHandler.java b/src/main/java/kubatech/FMLEventHandler.java
new file mode 100644
index 0000000000..e5acd58a36
--- /dev/null
+++ b/src/main/java/kubatech/FMLEventHandler.java
@@ -0,0 +1,16 @@
+package kubatech;
+
+import cpw.mods.fml.common.eventhandler.SubscribeEvent;
+import cpw.mods.fml.common.gameevent.PlayerEvent;
+import kubatech.network.LoadConfigPacket;
+import net.minecraft.entity.player.EntityPlayerMP;
+
+public class FMLEventHandler {
+ // Gets fired only server-sided
+ @SubscribeEvent
+ public void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
+ if (!(event.player instanceof EntityPlayerMP)) return;
+ kubatech.info("Sending config to " + event.player.getDisplayName());
+ kubatech.NETWORK.sendTo(LoadConfigPacket.instance, (EntityPlayerMP) event.player);
+ }
+}
diff --git a/src/main/java/kubatech/api/LoaderReference.java b/src/main/java/kubatech/api/LoaderReference.java
new file mode 100644
index 0000000000..aef8930905
--- /dev/null
+++ b/src/main/java/kubatech/api/LoaderReference.java
@@ -0,0 +1,12 @@
+package kubatech.api;
+
+import cpw.mods.fml.common.Loader;
+
+public class LoaderReference {
+ public static final boolean BloodMagic = Loader.isModLoaded("AWWayofTime");
+ public static final boolean EnderIO = Loader.isModLoaded("EnderIO");
+ public static final boolean ExtraUtilities = Loader.isModLoaded("ExtraUtilities");
+ public static final boolean InfernalMobs = Loader.isModLoaded("InfernalMobs");
+ public static final boolean Thaumcraft = Loader.isModLoaded("Thaumcraft");
+ public static final boolean MineTweaker = Loader.isModLoaded("MineTweaker3");
+}
diff --git a/src/main/java/kubatech/api/Variables.java b/src/main/java/kubatech/api/Variables.java
new file mode 100644
index 0000000000..c989b45f6f
--- /dev/null
+++ b/src/main/java/kubatech/api/Variables.java
@@ -0,0 +1,26 @@
+/*
+ * 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.api;
+
+import net.minecraft.util.EnumChatFormatting;
+
+public class Variables {
+ public static final String Author = "Author: " + EnumChatFormatting.GOLD + "kuba6000";
+}
diff --git a/src/main/java/kubatech/api/enums/ItemList.java b/src/main/java/kubatech/api/enums/ItemList.java
new file mode 100644
index 0000000000..b0cf3289b6
--- /dev/null
+++ b/src/main/java/kubatech/api/enums/ItemList.java
@@ -0,0 +1,167 @@
+package kubatech.api.enums;
+
+import static gregtech.api.enums.GT_Values.NI;
+import static gregtech.api.enums.GT_Values.W;
+
+import gregtech.api.interfaces.IItemContainer;
+import gregtech.api.util.GT_LanguageManager;
+import gregtech.api.util.GT_ModHandler;
+import gregtech.api.util.GT_OreDictUnificator;
+import gregtech.api.util.GT_Utility;
+import java.util.Locale;
+import net.minecraft.block.Block;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+
+public enum ItemList implements IItemContainer {
+ ExtremeExterminationChamber;
+
+ private ItemStack mStack;
+ private boolean mHasNotBeenSet = true;
+
+ @Override
+ public IItemContainer set(Item aItem) {
+ mHasNotBeenSet = false;
+ if (aItem == null) return this;
+ ItemStack aStack = new ItemStack(aItem, 1, 0);
+ mStack = GT_Utility.copyAmount(1, aStack);
+ return this;
+ }
+
+ @Override
+ public IItemContainer set(ItemStack aStack) {
+ mHasNotBeenSet = false;
+ mStack = GT_Utility.copyAmount(1, aStack);
+ return this;
+ }
+
+ @Override
+ public Item getItem() {
+ if (mHasNotBeenSet)
+ throw new IllegalAccessError("The Enum '" + name() + "' has not been set to an Item at this time!");
+ if (GT_Utility.isStackInvalid(mStack)) return null;
+ return mStack.getItem();
+ }
+
+ @Override
+ public Block getBlock() {
+ if (mHasNotBeenSet)
+ throw new IllegalAccessError("The Enum '" + name() + "' has not been set to an Item at this time!");
+ return GT_Utility.getBlockFromItem(getItem());
+ }
+
+ @Override
+ public final boolean hasBeenSet() {
+ return !mHasNotBeenSet;
+ }
+
+ @Override
+ public boolean isStackEqual(Object aStack) {
+ return isStackEqual(aStack, false, false);
+ }
+
+ @Override
+ public boolean isStackEqual(Object aStack, boolean aWildcard, boolean aIgnoreNBT) {
+ if (GT_Utility.isStackInvalid(aStack)) return false;
+ return GT_Utility.areUnificationsEqual((ItemStack) aStack, aWildcard ? getWildcard(1) : get(1), aIgnoreNBT);
+ }
+
+ @Override
+ public ItemStack get(long aAmount, Object... aReplacements) {
+ if (mHasNotBeenSet)
+ throw new IllegalAccessError("The Enum '" + name() + "' has not been set to an Item at this time!");
+ if (GT_Utility.isStackInvalid(mStack)) return GT_Utility.copyAmount(aAmount, aReplacements);
+ return GT_Utility.copyAmount(aAmount, GT_OreDictUnificator.get(mStack));
+ }
+
+ @Override
+ public ItemStack getWildcard(long aAmount, Object... aReplacements) {
+ if (mHasNotBeenSet)
+ throw new IllegalAccessError("The Enum '" + name() + "' has not been set to an Item at this time!");
+ if (GT_Utility.isStackInvalid(mStack)) return GT_Utility.copyAmount(aAmount, aReplacements);
+ return GT_Utility.copyAmountAndMetaData(aAmount, W, GT_OreDictUnificator.get(mStack));
+ }
+
+ @Override
+ public ItemStack getUndamaged(long aAmount, Object... aReplacements) {
+ if (mHasNotBeenSet)
+ throw new IllegalAccessError("The Enum '" + name() + "' has not been set to an Item at this time!");
+ if (GT_Utility.isStackInvalid(mStack)) return GT_Utility.copyAmount(aAmount, aReplacements);
+ return GT_Utility.copyAmountAndMetaData(aAmount, 0, GT_OreDictUnificator.get(mStack));
+ }
+
+ @Override
+ public ItemStack getAlmostBroken(long aAmount, Object... aReplacements) {
+ if (mHasNotBeenSet)
+ throw new IllegalAccessError("The Enum '" + name() + "' has not been set to an Item at this time!");
+ if (GT_Utility.isStackInvalid(mStack)) return GT_Utility.copyAmount(aAmount, aReplacements);
+ return GT_Utility.copyAmountAndMetaData(aAmount, mStack.getMaxDamage() - 1, GT_OreDictUnificator.get(mStack));
+ }
+
+ @Override
+ public ItemStack getWithName(long aAmount, String aDisplayName, Object... aReplacements) {
+ ItemStack rStack = get(1, aReplacements);
+ if (GT_Utility.isStackInvalid(rStack)) return NI;
+
+ // CamelCase alphanumeric words from aDisplayName
+ StringBuilder tCamelCasedDisplayNameBuilder = new StringBuilder();
+ final String[] tDisplayNameWords = aDisplayName.split("\\W");
+ for (String tWord : tDisplayNameWords) {
+ if (tWord.length() > 0)
+ tCamelCasedDisplayNameBuilder.append(tWord.substring(0, 1).toUpperCase(Locale.US));
+ if (tWord.length() > 1)
+ tCamelCasedDisplayNameBuilder.append(tWord.substring(1).toLowerCase(Locale.US));
+ }
+ if (tCamelCasedDisplayNameBuilder.length() == 0) {
+ // CamelCased DisplayName is empty, so use hash of aDisplayName
+ tCamelCasedDisplayNameBuilder.append(((Long) (long) aDisplayName.hashCode()));
+ }
+
+ // Construct a translation key from UnlocalizedName and CamelCased DisplayName
+ final String tKey = rStack.getUnlocalizedName() + ".with." + tCamelCasedDisplayNameBuilder + ".name";
+
+ rStack.setStackDisplayName(GT_LanguageManager.addStringLocalization(tKey, aDisplayName));
+ return GT_Utility.copyAmount(aAmount, rStack);
+ }
+
+ @Override
+ public ItemStack getWithCharge(long aAmount, int aEnergy, Object... aReplacements) {
+ ItemStack rStack = get(1, aReplacements);
+ if (GT_Utility.isStackInvalid(rStack)) return null;
+ GT_ModHandler.chargeElectricItem(rStack, aEnergy, Integer.MAX_VALUE, true, false);
+ return GT_Utility.copyAmount(aAmount, rStack);
+ }
+
+ @Override
+ public ItemStack getWithDamage(long aAmount, long aMetaValue, Object... aReplacements) {
+ if (mHasNotBeenSet)
+ throw new IllegalAccessError("The Enum '" + name() + "' has not been set to an Item at this time!");
+ if (GT_Utility.isStackInvalid(mStack)) return GT_Utility.copyAmount(aAmount, aReplacements);
+ return GT_Utility.copyAmountAndMetaData(aAmount, aMetaValue, GT_OreDictUnificator.get(mStack));
+ }
+
+ @Override
+ public IItemContainer registerOre(Object... aOreNames) {
+ if (mHasNotBeenSet)
+ throw new IllegalAccessError("The Enum '" + name() + "' has not been set to an Item at this time!");
+ for (Object tOreName : aOreNames) GT_OreDictUnificator.registerOre(tOreName, get(1));
+ return this;
+ }
+
+ @Override
+ public IItemContainer registerWildcardAsOre(Object... aOreNames) {
+ if (mHasNotBeenSet)
+ throw new IllegalAccessError("The Enum '" + name() + "' has not been set to an Item at this time!");
+ for (Object tOreName : aOreNames) GT_OreDictUnificator.registerOre(tOreName, getWildcard(1));
+ return this;
+ }
+
+ /**
+ * Returns the internal stack.
+ * This method is unsafe. It's here only for quick operations.
+ * DON'T CHANGE THE RETURNED VALUE!
+ */
+ public ItemStack getInternalStack_unsafe() {
+ return mStack;
+ }
+}
diff --git a/src/main/java/kubatech/api/utils/FastRandom.java b/src/main/java/kubatech/api/utils/FastRandom.java
new file mode 100644
index 0000000000..c0fb1ec9d5
--- /dev/null
+++ b/src/main/java/kubatech/api/utils/FastRandom.java
@@ -0,0 +1,27 @@
+package kubatech.api.utils;
+
+import java.util.Random;
+import java.util.SplittableRandom;
+
+public class FastRandom extends Random {
+
+ private SplittableRandom realRandom;
+
+ public FastRandom() {
+ realRandom = new SplittableRandom();
+ }
+
+ public FastRandom(long seed) {
+ realRandom = new SplittableRandom(seed);
+ }
+
+ @Override
+ public synchronized void setSeed(long seed) {
+ realRandom = new SplittableRandom(seed);
+ }
+
+ @Override
+ protected int next(int bits) {
+ return (realRandom.nextInt() >>> (32 - bits));
+ }
+}
diff --git a/src/main/java/kubatech/api/utils/InfernalHelper.java b/src/main/java/kubatech/api/utils/InfernalHelper.java
new file mode 100644
index 0000000000..d4e416e9a5
--- /dev/null
+++ b/src/main/java/kubatech/api/utils/InfernalHelper.java
@@ -0,0 +1,226 @@
+/*
+ * 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.api.utils;
+
+import atomicstryker.infernalmobs.common.InfernalMobsCore;
+import atomicstryker.infernalmobs.common.mods.api.ModifierLoader;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.item.ItemStack;
+
+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/utils/ModUtils.java b/src/main/java/kubatech/api/utils/ModUtils.java
new file mode 100644
index 0000000000..0802294974
--- /dev/null
+++ b/src/main/java/kubatech/api/utils/ModUtils.java
@@ -0,0 +1,50 @@
+/*
+ * 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.api.utils;
+
+import cpw.mods.fml.common.Loader;
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.Map;
+import net.minecraft.launchwrapper.Launch;
+
+public class ModUtils {
+ public static final boolean isDeobfuscatedEnvironment =
+ (boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
+ public static boolean isClientSided = false;
+ private static final HashMap classNamesToModIDs = new HashMap<>();
+ private static final Map.Entry emptyEntry = new AbstractMap.SimpleEntry<>("", "");
+
+ public static String getModNameFromClassName(String classname) {
+ if (classNamesToModIDs.size() == 0) {
+ classNamesToModIDs.put("net.minecraft", "Minecraft");
+ Loader.instance().getActiveModList().forEach(m -> {
+ Object Mod = m.getMod();
+ if (Mod != null)
+ classNamesToModIDs.put(Mod.getClass().getPackage().getName(), m.getName());
+ });
+ }
+ return classNamesToModIDs.entrySet().stream()
+ .filter(e -> classname.startsWith(e.getKey()))
+ .findAny()
+ .orElse(emptyEntry)
+ .getValue();
+ }
+}
diff --git a/src/main/java/kubatech/api/utils/ReflectionHelper.java b/src/main/java/kubatech/api/utils/ReflectionHelper.java
new file mode 100644
index 0000000000..0e5d40e245
--- /dev/null
+++ b/src/main/java/kubatech/api/utils/ReflectionHelper.java
@@ -0,0 +1,62 @@
+/*
+ * 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.api.utils;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+
+public class ReflectionHelper {
+ private static final HashMap> fields = new HashMap<>();
+
+ public static T getField(Object obj, String fieldName, boolean useBasicTypes, T defaultvalue) {
+ Class> cl = obj.getClass();
+ String clName = cl.getName();
+ HashMap classmap = fields.computeIfAbsent(clName, s -> new HashMap<>());
+ try {
+ if (classmap.containsKey(fieldName)) {
+ return (T) classmap.get(fieldName).get(obj);
+ }
+ boolean exceptionDetected = false;
+ Field f = null;
+ do {
+ try {
+ f = cl.getDeclaredField(fieldName);
+ f.setAccessible(true);
+ } catch (Exception ex) {
+ exceptionDetected = true;
+ cl = cl.getSuperclass();
+ }
+ } while (exceptionDetected && !cl.equals(Object.class));
+ if (f == null) return defaultvalue;
+ classmap.put(fieldName, f);
+ return (T) f.get(obj);
+ } catch (Exception ex) {
+ return defaultvalue;
+ }
+ }
+
+ public static T getField(Object obj, String fieldName, boolean useBasicTypes) {
+ return getField(obj, fieldName, useBasicTypes, null);
+ }
+
+ public static T getField(Object obj, String fieldName) {
+ return getField(obj, fieldName, true, null);
+ }
+}
diff --git a/src/main/java/kubatech/commands/CommandConfig.java b/src/main/java/kubatech/commands/CommandConfig.java
new file mode 100644
index 0000000000..f3bcbb7754
--- /dev/null
+++ b/src/main/java/kubatech/commands/CommandConfig.java
@@ -0,0 +1,96 @@
+/*
+ * 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.commands;
+
+import static kubatech.commands.CommandConfig.Translations.*;
+
+import kubatech.Config;
+import kubatech.kubatech;
+import kubatech.loaders.MobRecipeLoader;
+import kubatech.network.LoadConfigPacket;
+import net.minecraft.command.CommandBase;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.StatCollector;
+
+public class CommandConfig extends CommandBase {
+ enum Translations {
+ INVALID_OPTION,
+ SUCCESS,
+ USAGE,
+ ;
+ final String key;
+
+ Translations() {
+ key = "command.config." + this.name().toLowerCase();
+ }
+
+ public String get() {
+ return StatCollector.translateToLocal(key);
+ }
+
+ public String get(Object... args) {
+ return StatCollector.translateToLocalFormatted(key, args);
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public String toString() {
+ return get();
+ }
+ }
+
+ @Override
+ public String getCommandName() {
+ return "config";
+ }
+
+ @Override
+ public String getCommandUsage(ICommandSender p_71518_1_) {
+ return "config " + USAGE.get();
+ }
+
+ @Override
+ public int getRequiredPermissionLevel() {
+ return 4;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void processCommand(ICommandSender p_71515_1_, String[] p_71515_2_) {
+ if (p_71515_2_.length == 0 || !p_71515_2_[0].equals("reload")) {
+ p_71515_1_.addChatMessage(new ChatComponentText(INVALID_OPTION.get()));
+ return;
+ }
+ Config.synchronizeConfiguration();
+ MobRecipeLoader.processMobRecipeMap();
+ MinecraftServer.getServer().getConfigurationManager().playerEntityList.forEach(p -> {
+ if (!(p instanceof EntityPlayerMP)) return;
+ kubatech.info("Sending config to " + ((EntityPlayerMP) p).getDisplayName());
+ kubatech.NETWORK.sendTo(LoadConfigPacket.instance, (EntityPlayerMP) p);
+ });
+ p_71515_1_.addChatMessage(new ChatComponentText(SUCCESS.get()));
+ }
+}
diff --git a/src/main/java/kubatech/commands/CommandHandler.java b/src/main/java/kubatech/commands/CommandHandler.java
new file mode 100644
index 0000000000..6f32839472
--- /dev/null
+++ b/src/main/java/kubatech/commands/CommandHandler.java
@@ -0,0 +1,115 @@
+/*
+ * 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.commands;
+
+import static kubatech.commands.CommandHandler.Translations.*;
+
+import java.util.*;
+import net.minecraft.command.CommandBase;
+import net.minecraft.command.ICommand;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.ChatComponentTranslation;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+
+public class CommandHandler extends CommandBase {
+ enum Translations {
+ INVALID,
+ CANT_FIND,
+ GENERIC_HELP,
+ USAGE,
+ ;
+ final String key;
+
+ Translations() {
+ key = "commandhandler." + this.name().toLowerCase();
+ }
+
+ public String get() {
+ return StatCollector.translateToLocal(key);
+ }
+
+ public String get(Object... args) {
+ return StatCollector.translateToLocalFormatted(key, args);
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public String toString() {
+ return get();
+ }
+ }
+
+ private static final ArrayList aliases = new ArrayList<>(Collections.singleton("kt"));
+ public static final HashMap commands = new HashMap<>();
+
+ @Override
+ public String getCommandName() {
+ return "kubatech";
+ }
+
+ @Override
+ public String getCommandUsage(ICommandSender p_71518_1_) {
+ return "kubatech " + USAGE.get();
+ }
+
+ @Override
+ public List getCommandAliases() {
+ return aliases;
+ }
+
+ @Override
+ public void processCommand(ICommandSender p_71515_1_, String[] p_71515_2_) {
+ if (p_71515_1_.getEntityWorld().isRemote) return;
+ if (p_71515_2_.length == 0) {
+ p_71515_1_.addChatMessage(new ChatComponentText(INVALID.get(getCommandUsage(p_71515_1_))));
+ p_71515_1_.addChatMessage(new ChatComponentText(GENERIC_HELP.get()));
+ return;
+ }
+ if (!commands.containsKey(p_71515_2_[0])) {
+ p_71515_1_.addChatMessage(new ChatComponentText(CANT_FIND.get(p_71515_2_[0])));
+ p_71515_1_.addChatMessage(new ChatComponentText(GENERIC_HELP.get()));
+ return;
+ }
+ ICommand cmd = commands.get(p_71515_2_[0]);
+ if (!cmd.canCommandSenderUseCommand(p_71515_1_)) {
+ ChatComponentTranslation chatcomponenttranslation2 =
+ new ChatComponentTranslation("commands.generic.permission");
+ chatcomponenttranslation2.getChatStyle().setColor(EnumChatFormatting.RED);
+ p_71515_1_.addChatMessage(chatcomponenttranslation2);
+ } else
+ cmd.processCommand(
+ p_71515_1_,
+ p_71515_2_.length > 1 ? Arrays.copyOfRange(p_71515_2_, 1, p_71515_2_.length) : new String[0]);
+ }
+
+ @Override
+ public boolean canCommandSenderUseCommand(ICommandSender p_71519_1_) {
+ return true;
+ }
+
+ public void addCommand(ICommand command) {
+ commands.put(command.getCommandName(), command);
+ }
+}
diff --git a/src/main/java/kubatech/commands/CommandHelp.java b/src/main/java/kubatech/commands/CommandHelp.java
new file mode 100644
index 0000000000..0165e67c80
--- /dev/null
+++ b/src/main/java/kubatech/commands/CommandHelp.java
@@ -0,0 +1,80 @@
+/*
+ * 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.commands;
+
+import static kubatech.commands.CommandHelp.Translations.*;
+
+import net.minecraft.command.CommandBase;
+import net.minecraft.command.ICommandSender;
+import net.minecraft.util.ChatComponentText;
+import net.minecraft.util.StatCollector;
+
+public class CommandHelp extends CommandBase {
+ enum Translations {
+ POSSIBLE_COMMANDS,
+ USAGE,
+ ;
+ final String key;
+
+ Translations() {
+ key = "command.help." + this.name().toLowerCase();
+ }
+
+ public String get() {
+ return StatCollector.translateToLocal(key);
+ }
+
+ public String get(Object... args) {
+ return StatCollector.translateToLocalFormatted(key, args);
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ @Override
+ public String toString() {
+ return get();
+ }
+ }
+
+ @Override
+ public String getCommandName() {
+ return "help";
+ }
+
+ @Override
+ public String getCommandUsage(ICommandSender p_71518_1_) {
+ return "help " + USAGE.get();
+ }
+
+ @Override
+ public boolean canCommandSenderUseCommand(ICommandSender p_71519_1_) {
+ return true;
+ }
+
+ @Override
+ public void processCommand(ICommandSender p_71515_1_, String[] p_71515_2_) {
+ p_71515_1_.addChatMessage(new ChatComponentText(POSSIBLE_COMMANDS.get()));
+ CommandHandler.commands.values().forEach(c -> {
+ p_71515_1_.addChatMessage(new ChatComponentText("/kubatech " + c.getCommandUsage(p_71515_1_)));
+ });
+ }
+}
diff --git a/src/main/java/kubatech/common/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeExterminationChamber.java b/src/main/java/kubatech/common/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeExterminationChamber.java
new file mode 100644
index 0000000000..f02599f37f
--- /dev/null
+++ b/src/main/java/kubatech/common/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeExterminationChamber.java
@@ -0,0 +1,394 @@
+/*
+ * 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.common.tileentity.gregtech.multiblock;
+
+import static com.gtnewhorizon.structurelib.structure.StructureUtility.*;
+import static gregtech.api.enums.Textures.BlockIcons.*;
+import static gregtech.api.util.GT_StructureUtility.ofHatchAdder;
+import static kubatech.api.Variables.Author;
+
+import WayofTime.alchemicalWizardry.api.alchemy.energy.ReagentRegistry;
+import WayofTime.alchemicalWizardry.api.event.RitualRunEvent;
+import WayofTime.alchemicalWizardry.api.rituals.Rituals;
+import WayofTime.alchemicalWizardry.api.soulNetwork.SoulNetworkHandler;
+import WayofTime.alchemicalWizardry.api.tile.IBloodAltar;
+import WayofTime.alchemicalWizardry.common.rituals.RitualEffectWellOfSuffering;
+import WayofTime.alchemicalWizardry.common.tileEntity.TEMasterStone;
+import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
+import com.gtnewhorizon.structurelib.structure.StructureDefinition;
+import cpw.mods.fml.common.eventhandler.EventPriority;
+import cpw.mods.fml.common.eventhandler.SubscribeEvent;
+import crazypants.enderio.EnderIO;
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.Textures;
+import gregtech.api.interfaces.ITexture;
+import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_EnhancedMultiBlockBase;
+import gregtech.api.render.TextureFactory;
+import gregtech.api.util.GT_Multiblock_Tooltip_Builder;
+import gregtech.api.util.GT_Utility;
+import java.util.HashMap;
+import java.util.Random;
+import kubatech.Tags;
+import kubatech.api.LoaderReference;
+import kubatech.api.utils.FastRandom;
+import kubatech.api.utils.ReflectionHelper;
+import kubatech.loaders.MobRecipeLoader;
+import net.minecraft.block.Block;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.ChunkCoordinates;
+import net.minecraft.world.EnumDifficulty;
+import net.minecraft.world.World;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.fluids.FluidRegistry;
+import net.minecraftforge.fluids.FluidStack;
+
+public class GT_MetaTileEntity_ExtremeExterminationChamber
+ extends GT_MetaTileEntity_EnhancedMultiBlockBase {
+
+ public static final HashMap MobNameToRecipeMap = new HashMap<>();
+ public final Random rand = new FastRandom();
+
+ public GT_MetaTileEntity_ExtremeExterminationChamber(int aID, String aName, String aNameRegional) {
+ super(aID, aName, aNameRegional);
+ }
+
+ public GT_MetaTileEntity_ExtremeExterminationChamber(String aName) {
+ super(aName);
+ if (LoaderReference.BloodMagic) MinecraftForge.EVENT_BUS.register(this);
+ }
+
+ @Override
+ public void onRemoval() {
+ if (LoaderReference.BloodMagic) MinecraftForge.EVENT_BUS.unregister(this);
+ }
+
+ private static final String WellOfSufferingRitualName = "AW013Suffering";
+
+ private static final Item poweredSpawnerItem = Item.getItemFromBlock(EnderIO.blockPoweredSpawner);
+ private static final int CASING_INDEX = 16;
+ private static final String STRUCTURE_PIECE_MAIN = "main";
+ private static final IStructureDefinition STRUCTURE_DEFINITION =
+ StructureDefinition.builder()
+ .addShape(STRUCTURE_PIECE_MAIN, transpose(new String[][] {
+ {"ccccc", "ccccc", "ccccc", "ccccc", "ccccc"},
+ {"ccccc", "c---c", "c---c", "c---c", "ccccc"},
+ {"ccccc", "c---c", "c---c", "c---c", "ccccc"},
+ {"ccccc", "c---c", "c---c", "c---c", "ccccc"},
+ {"ccccc", "c---c", "c---c", "c---c", "ccccc"},
+ {"ccccc", "csssc", "csssc", "csssc", "ccccc"},
+ {"CC~CC", "CCCCC", "CCCCC", "CCCCC", "CCCCC"},
+ }))
+ .addElement('c', onElementPass(t -> t.mCasing++, ofBlock(GregTech_API.sBlockCasings2, 0)))
+ .addElement(
+ 'C',
+ ofChain(
+ onElementPass(t -> t.mCasing++, ofBlock(GregTech_API.sBlockCasings2, 0)),
+ ofHatchAdder(
+ GT_MetaTileEntity_ExtremeExterminationChamber::addOutputToMachineList,
+ CASING_INDEX,
+ 1),
+ ofHatchAdder(
+ GT_MetaTileEntity_ExtremeExterminationChamber::addEnergyInputToMachineList,
+ CASING_INDEX,
+ 1),
+ ofHatchAdder(
+ GT_MetaTileEntity_ExtremeExterminationChamber::addMaintenanceToMachineList,
+ CASING_INDEX,
+ 1)))
+ .addElement(
+ 's',
+ LoaderReference.ExtraUtilities
+ ? ofBlock(Block.getBlockFromName("ExtraUtilities:spike_base_diamond"), 0)
+ : isAir())
+ .build();
+
+ private TileEntity masterStoneRitual = null;
+ private TileEntity tileAltar = null;
+ private boolean isInRitualMode = false;
+ private int mCasing = 0;
+
+ @Override
+ public void saveNBTData(NBTTagCompound aNBT) {
+ super.saveNBTData(aNBT);
+ aNBT.setBoolean("isInRitualMode", isInRitualMode);
+ }
+
+ @Override
+ public void loadNBTData(NBTTagCompound aNBT) {
+ super.loadNBTData(aNBT);
+ isInRitualMode = aNBT.getBoolean("isInRitualMode");
+ }
+
+ @Override
+ public IStructureDefinition getStructureDefinition() {
+ return STRUCTURE_DEFINITION;
+ }
+
+ @Override
+ protected GT_Multiblock_Tooltip_Builder createTooltip() {
+ GT_Multiblock_Tooltip_Builder tt = new GT_Multiblock_Tooltip_Builder();
+ tt.addMachineType("Powered Spawner")
+ .addInfo("Controller block for Extreme Extermination Chamber")
+ .addInfo("Spawns and Exterminates monsters for you")
+ .addInfo("Base energy usage: 2,000 EU/t")
+ .addInfo("Recipe time is based on mob health")
+ .addInfo("Also produces 120 Liquid XP per operation")
+ .addInfo("If the mob spawns infernal")
+ .addInfo("it will drain 8 times more power")
+ .addInfo("You can enable ritual mode with a screwdriver")
+ .addInfo("When in ritual mode and Well Of Suffering ritual is built directly on the machine in center")
+ .addInfo("The mobs will start to buffer and die very slowly by a ritual")
+ .addInfo(Author)
+ .addSeparator()
+ .beginStructureBlock(5, 7, 5, true)
+ .addController("Front Bottom Center")
+ .addCasingInfo("Solid Steel Machine Casing", 10)
+ .addOutputBus("Any casing", 1)
+ .addOutputHatch("Any casing", 1)
+ .addEnergyHatch("Any casing", 1)
+ .addMaintenanceHatch("Any casing", 1)
+ .toolTipFinisher(Tags.MODNAME);
+ return tt;
+ }
+
+ @Override
+ public void construct(ItemStack itemStack, boolean b) {
+ buildPiece(STRUCTURE_PIECE_MAIN, itemStack, b, 2, 6, 0);
+ }
+
+ @Override
+ public IMetaTileEntity newMetaEntity(IGregTechTileEntity aTileEntity) {
+ return new GT_MetaTileEntity_ExtremeExterminationChamber(this.mName);
+ }
+
+ @Override
+ public ITexture[] getTexture(
+ IGregTechTileEntity aBaseMetaTileEntity,
+ byte aSide,
+ byte aFacing,
+ byte aColorIndex,
+ boolean aActive,
+ boolean aRedstone) {
+ if (aSide == aFacing) {
+ if (aActive)
+ return new ITexture[] {
+ Textures.BlockIcons.getCasingTextureForId(CASING_INDEX),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE_GLOW)
+ .extFacing()
+ .glow()
+ .build()
+ };
+ return new ITexture[] {
+ Textures.BlockIcons.getCasingTextureForId(CASING_INDEX),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER)
+ .extFacing()
+ .build(),
+ TextureFactory.builder()
+ .addIcon(OVERLAY_FRONT_DISTILLATION_TOWER_GLOW)
+ .extFacing()
+ .glow()
+ .build()
+ };
+ }
+ return new ITexture[] {Textures.BlockIcons.getCasingTextureForId(CASING_INDEX)};
+ }
+
+ @Override
+ public boolean isCorrectMachinePart(ItemStack aStack) {
+ return true;
+ }
+
+ @Override
+ public void onFirstTick(IGregTechTileEntity aBaseMetaTileEntity) {
+ super.onFirstTick(aBaseMetaTileEntity);
+ }
+
+ @Override
+ public void onScrewdriverRightClick(byte aSide, EntityPlayer aPlayer, float aX, float aY, float aZ) {
+ if (!LoaderReference.BloodMagic) return;
+ if (this.mMaxProgresstime > 0) {
+ GT_Utility.sendChatToPlayer(aPlayer, "Can't change mode when running !");
+ return;
+ }
+ isInRitualMode = !isInRitualMode;
+ if (!isInRitualMode) {
+ GT_Utility.sendChatToPlayer(aPlayer, "Ritual mode disabled");
+ } else {
+ GT_Utility.sendChatToPlayer(aPlayer, "Ritual mode enabled");
+ if (connectToRitual()) GT_Utility.sendChatToPlayer(aPlayer, "Successfully connected to the ritual");
+ else GT_Utility.sendChatToPlayer(aPlayer, "Can't connect to the ritual");
+ }
+ }
+
+ @SuppressWarnings("unused")
+ @SubscribeEvent(priority = EventPriority.LOWEST)
+ public void onRitualPerform(RitualRunEvent event) {
+ if (!isInRitualMode) return;
+ if (masterStoneRitual == null) return;
+ if (this.mMaxProgresstime == 0) return;
+ if (event.mrs.equals(masterStoneRitual) && event.ritualKey.equals(WellOfSufferingRitualName)) {
+ Rituals ritual = Rituals.ritualMap.get(WellOfSufferingRitualName);
+ if (ritual != null && ritual.effect instanceof RitualEffectWellOfSuffering) {
+ RitualEffectWellOfSuffering effect = (RitualEffectWellOfSuffering) ritual.effect;
+ event.setCanceled(true); // we will handle that
+ String owner = event.mrs.getOwner();
+ int currentEssence = SoulNetworkHandler.getCurrentEssence(owner);
+ World world = event.mrs.getWorld();
+ int x = event.mrs.getXCoord();
+ int y = event.mrs.getYCoord();
+ int z = event.mrs.getZCoord();
+
+ if (world.getWorldTime() % RitualEffectWellOfSuffering.timeDelay != 0) return;
+
+ if (tileAltar == null || tileAltar.isInvalid()) {
+ tileAltar = null;
+ for (int i = -5; i <= 5; i++)
+ for (int j = -5; j <= 5; j++)
+ for (int k = -10; k <= 10; k++)
+ if (world.getTileEntity(x + i, y + k, z + j) instanceof IBloodAltar)
+ tileAltar = world.getTileEntity(x + i, y + k, z + j);
+ }
+ if (tileAltar == null) return;
+
+ if (currentEssence < effect.getCostPerRefresh() * 100) SoulNetworkHandler.causeNauseaToPlayer(owner);
+
+ ((IBloodAltar) tileAltar)
+ .sacrificialDaggerCall(
+ 100
+ * RitualEffectWellOfSuffering.amount
+ * (effect.canDrainReagent(
+ event.mrs,
+ ReagentRegistry.offensaReagent,
+ ReflectionHelper.getField(effect, "offensaDrain", true, 3),
+ true)
+ ? 2
+ : 1)
+ * (effect.canDrainReagent(
+ event.mrs,
+ ReagentRegistry.tenebraeReagent,
+ ReflectionHelper.getField(effect, "tennebraeDrain", true, 5),
+ true)
+ ? 2
+ : 1),
+ true);
+
+ SoulNetworkHandler.syphonFromNetwork(owner, effect.getCostPerRefresh() * 100);
+ }
+ }
+ }
+
+ @Override
+ public boolean checkRecipe(ItemStack aStack) {
+ if (aStack == null) return false;
+
+ if (aStack.getItem() != poweredSpawnerItem) return false;
+
+ if (aStack.getTagCompound() == null) return false;
+ String mobType = aStack.getTagCompound().getString("mobType");
+ if (mobType.isEmpty()) return false;
+
+ MobRecipeLoader.MobRecipe recipe = MobNameToRecipeMap.get(mobType);
+
+ if (recipe == null) return false;
+ if (!recipe.isPeacefulAllowed
+ && this.getBaseMetaTileEntity().getWorld().difficultySetting == EnumDifficulty.PEACEFUL) return false;
+
+ this.mOutputItems = recipe.generateOutputs(rand, this);
+
+ if (isInRitualMode && isRitualValid()) {
+ this.mMaxProgresstime = 400;
+ this.mEUt /= 4;
+ this.mOutputFluids = new FluidStack[] {FluidRegistry.getFluidStack("xpjuice", 5000)};
+ } else {
+ calculateOverclockedNessMulti(this.mEUt, this.mMaxProgresstime, 2, getMaxInputVoltage());
+ this.mOutputFluids = new FluidStack[] {FluidRegistry.getFluidStack("xpjuice", 120)};
+ }
+ if (this.mEUt > 0) this.mEUt = -this.mEUt;
+ this.mEfficiency = (10000 - (getIdealStatus() - getRepairStatus()) * 1000);
+ this.mEfficiencyIncrease = 10000;
+
+ return true;
+ }
+
+ private boolean isRitualValid() {
+ if (!isInRitualMode) return false;
+ if (masterStoneRitual == null) return false;
+ if (masterStoneRitual.isInvalid()
+ || !(((TEMasterStone) masterStoneRitual).getCurrentRitual().equals(WellOfSufferingRitualName))) {
+ masterStoneRitual = null;
+ return false;
+ }
+ return true;
+ }
+
+ private boolean connectToRitual() {
+ if (!LoaderReference.BloodMagic) return false;
+ ChunkCoordinates coords = this.getBaseMetaTileEntity().getCoords();
+ int[] abc = new int[] {0, -8, 2};
+ int[] xyz = new int[] {0, 0, 0};
+ this.getExtendedFacing().getWorldOffset(abc, xyz);
+ xyz[0] += coords.posX;
+ xyz[1] += coords.posY;
+ xyz[2] += coords.posZ;
+ TileEntity te = this.getBaseMetaTileEntity().getTileEntity(xyz[0], xyz[1], xyz[2]);
+ if (te instanceof TEMasterStone) {
+ if (((TEMasterStone) te).getCurrentRitual().equals(WellOfSufferingRitualName)) {
+ masterStoneRitual = te;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) {
+ if (!checkPiece(STRUCTURE_PIECE_MAIN, 2, 6, 0)) return false;
+ if (mCasing < 10 || mMaintenanceHatches.size() != 1 || mEnergyHatches.size() == 0) return false;
+ if (isInRitualMode) connectToRitual();
+ return true;
+ }
+
+ @Override
+ public int getMaxEfficiency(ItemStack aStack) {
+ return 10000;
+ }
+
+ @Override
+ public int getDamageToComponent(ItemStack aStack) {
+ return 0;
+ }
+
+ @Override
+ public boolean explodesOnComponentBreak(ItemStack aStack) {
+ return false;
+ }
+}
diff --git a/src/main/java/kubatech/kubatech.java b/src/main/java/kubatech/kubatech.java
index 187fa255b6..893928ea60 100644
--- a/src/main/java/kubatech/kubatech.java
+++ b/src/main/java/kubatech/kubatech.java
@@ -1,5 +1,5 @@
/*
- * kubatech - Gregtech Addon
+ * KubaTech - Gregtech Addon
* Copyright (C) 2022 kuba6000
*
* This program is free software: you can redistribute it and/or modify
@@ -22,19 +22,39 @@ package kubatech;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.*;
+import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
+import cpw.mods.fml.relauncher.Side;
+import kubatech.network.LoadConfigHandler;
+import kubatech.network.LoadConfigPacket;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-@Mod(modid = Tags.MODID, version = Tags.VERSION, name = Tags.MODNAME, acceptedMinecraftVersions = "[1.7.10]")
+@SuppressWarnings("unused")
+@Mod(
+ modid = Tags.MODID,
+ version = Tags.VERSION,
+ name = Tags.MODNAME,
+ acceptedMinecraftVersions = "[1.7.10]",
+ dependencies = "required-after:gregtech; " + "required-after:spongemixins@[1.4.0,); " + "after:EnderIO; "
+ + "after:AWWayofTime; " + "after:ExtraUtilities; " + "after: InfernalMobs; " + "after: Thaumcraft; "
+ + "after: MineTweaker3; ")
public class kubatech {
- private static Logger LOG = LogManager.getLogger(Tags.MODID);
+ public static kubatech instance = null;
+ public static final SimpleNetworkWrapper NETWORK = new SimpleNetworkWrapper(Tags.MODID);
+
+ static {
+ NETWORK.registerMessage(new LoadConfigHandler(), LoadConfigPacket.class, 0, Side.CLIENT);
+ }
+
+ private static final Logger LOG = LogManager.getLogger(Tags.MODID);
@SidedProxy(clientSide = Tags.MODID + ".ClientProxy", serverSide = Tags.MODID + ".CommonProxy")
public static CommonProxy proxy;
@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
+ instance = this;
proxy.preInit(event);
}
diff --git a/src/main/java/kubatech/loaders/MobRecipeLoader.java b/src/main/java/kubatech/loaders/MobRecipeLoader.java
new file mode 100644
index 000000000