aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/kubatech/api/utils/ItemID.java81
-rw-r--r--src/main/java/kubatech/loaders/MobRecipeLoader.java29
-rw-r--r--src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeExterminationChamber.java115
3 files changed, 211 insertions, 14 deletions
diff --git a/src/main/java/kubatech/api/utils/ItemID.java b/src/main/java/kubatech/api/utils/ItemID.java
new file mode 100644
index 0000000000..932c45a0f9
--- /dev/null
+++ b/src/main/java/kubatech/api/utils/ItemID.java
@@ -0,0 +1,81 @@
+package kubatech.api.utils;
+
+import java.util.Objects;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+
+public class ItemID {
+ private final Item item;
+ private final int count;
+ private final int meta;
+ private final NBTTagCompound tag;
+ private final boolean ignorecount;
+ private final boolean ignoremeta;
+ private final boolean ignorenbt;
+
+ public static ItemID create(ItemStack stack) {
+ return new ItemID(stack, true, true, true, true); // ignore count by default
+ }
+
+ public static ItemID create(ItemStack stack, boolean ignorecount) {
+ return new ItemID(stack, ignorecount, false, false, true);
+ }
+
+ public static ItemID create(ItemStack stack, boolean ignorecount, boolean ignoremeta) {
+ return new ItemID(stack, ignorecount, ignoremeta, false, true);
+ }
+
+ public static ItemID create(ItemStack stack, boolean ignorecount, boolean ignoremeta, boolean ignorenbt) {
+ return new ItemID(stack, ignorecount, ignoremeta, ignorenbt, true);
+ }
+
+ public static ItemID create_NoCopy(ItemStack stack) {
+ return new ItemID(stack, true, false, false, false); // ignore count by default
+ }
+
+ public static ItemID create_NoCopy(ItemStack stack, boolean ignorecount) {
+ return new ItemID(stack, ignorecount, false, false, false);
+ }
+
+ public static ItemID create_NoCopy(ItemStack stack, boolean ignorecount, boolean ignoremeta) {
+ return new ItemID(stack, ignorecount, ignoremeta, false, false);
+ }
+
+ public static ItemID create_NoCopy(ItemStack stack, boolean ignorecount, boolean ignoremeta, boolean ignorenbt) {
+ return new ItemID(stack, ignorecount, ignoremeta, ignorenbt, false);
+ }
+
+ private ItemID(ItemStack stack, boolean ignorecount, boolean ignoremeta, boolean ignorenbt, boolean createcopy) {
+ this.ignorecount = ignorecount;
+ this.ignoremeta = ignoremeta;
+ this.ignorenbt = ignorenbt;
+ item = stack.getItem();
+ count = ignorecount ? 0 : stack.stackSize;
+ meta = ignoremeta ? 0 : stack.getItemDamage();
+ tag = ignorenbt ? null : (createcopy ? (NBTTagCompound) stack.stackTagCompound.copy() : stack.stackTagCompound);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(item, count, meta, tag);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) return false;
+ if (obj == this) return true;
+ if (obj instanceof ItemID) return obj.hashCode() == this.hashCode();
+ if (obj instanceof ItemStack) {
+ if (!item.equals(((ItemStack) obj).getItem())) return false;
+ if (!ignorecount) if (count != ((ItemStack) obj).stackSize) return false;
+ if (!ignoremeta) if (meta != ((ItemStack) obj).getItemDamage()) return false;
+ if (!ignorenbt) {
+ if (tag == null) return ((ItemStack) obj).stackTagCompound == null;
+ if (!tag.equals(((ItemStack) obj).stackTagCompound)) return false;
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/kubatech/loaders/MobRecipeLoader.java b/src/main/java/kubatech/loaders/MobRecipeLoader.java
index 1374c94d75..adece13f23 100644
--- a/src/main/java/kubatech/loaders/MobRecipeLoader.java
+++ b/src/main/java/kubatech/loaders/MobRecipeLoader.java
@@ -113,6 +113,7 @@ public class MobRecipeLoader {
public static droplist infernaldrops;
public final boolean isPeacefulAllowed;
public final EntityLiving entity;
+ public final float maxEntityHealth;
@SuppressWarnings("unchecked")
public MobRecipe copy() {
@@ -123,7 +124,8 @@ public class MobRecipeLoader {
infernalityAllowed,
alwaysinfernal,
isPeacefulAllowed,
- entity);
+ entity,
+ maxEntityHealth);
}
private MobRecipe(
@@ -133,7 +135,8 @@ public class MobRecipeLoader {
boolean infernalityAllowed,
boolean alwaysinfernal,
boolean isPeacefulAllowed,
- EntityLiving entity) {
+ EntityLiving entity,
+ float maxEntityHealth) {
this.mOutputs = mOutputs;
this.mDuration = mDuration;
this.mMaxDamageChance = mMaxDamageChance;
@@ -141,6 +144,7 @@ public class MobRecipeLoader {
this.alwaysinfernal = alwaysinfernal;
this.isPeacefulAllowed = isPeacefulAllowed;
this.entity = entity;
+ this.maxEntityHealth = maxEntityHealth;
}
@SuppressWarnings("unchecked")
@@ -203,17 +207,30 @@ 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);
+ maxEntityHealth = e.getMaxHealth();
+ mDuration = 55 + (int) (maxEntityHealth * 10);
entity = e;
}
- public ItemStack[] generateOutputs(Random rnd, GT_MetaTileEntity_ExtremeExterminationChamber MTE) {
+ public ItemStack[] generateOutputs(
+ Random rnd, GT_MetaTileEntity_ExtremeExterminationChamber MTE, double attackDamage, int lootinglevel) {
MTE.mEUt = mEUt;
- MTE.mMaxProgresstime = mDuration;
+ MTE.mMaxProgresstime = Math.max(55, (int) ((maxEntityHealth / attackDamage) * 10d));
ArrayList<ItemStack> stacks = new ArrayList<>(mOutputs.size());
for (MobDrop o : mOutputs) {
- if (o.chance == 10000 || rnd.nextInt(10000) < o.chance) {
+ int chance = o.chance;
+ int amount = o.stack.stackSize;
+ if (o.lootable && lootinglevel > 0) {
+ chance += lootinglevel * 5000;
+ if (chance > 10000) {
+ int div = (int) Math.ceil(chance / 10000d);
+ amount *= div;
+ chance /= div;
+ }
+ }
+ if (chance == 10000 || rnd.nextInt(10000) < chance) {
ItemStack s = o.stack.copy();
+ s.stackSize = amount;
if (o.enchantable != null) EnchantmentHelper.addRandomEnchantment(rnd, s, o.enchantable);
if (o.damages != null) {
int rChance = rnd.nextInt(mMaxDamageChance);
diff --git a/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeExterminationChamber.java b/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeExterminationChamber.java
index 1d6bfd15e5..270fd7ff9e 100644
--- a/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeExterminationChamber.java
+++ b/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeExterminationChamber.java
@@ -34,6 +34,7 @@ import WayofTime.alchemicalWizardry.api.tile.IBloodAltar;
import WayofTime.alchemicalWizardry.common.rituals.RitualEffectWellOfSuffering;
import WayofTime.alchemicalWizardry.common.tileEntity.TEMasterStone;
import com.github.bartimaeusnek.bartworks.API.BorosilicateGlass;
+import com.google.common.collect.Multimap;
import com.gtnewhorizon.structurelib.structure.IStructureDefinition;
import com.gtnewhorizon.structurelib.structure.StructureDefinition;
import cpw.mods.fml.common.eventhandler.EventPriority;
@@ -49,9 +50,12 @@ import gregtech.api.interfaces.metatileentity.IMetaTileEntity;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_EnhancedMultiBlockBase;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energy;
+import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_InputBus;
import gregtech.api.render.TextureFactory;
import gregtech.api.util.GT_Multiblock_Tooltip_Builder;
import gregtech.api.util.GT_Utility;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Random;
import kubatech.Tags;
@@ -59,11 +63,17 @@ import kubatech.api.LoaderReference;
import kubatech.api.network.CustomTileEntityPacket;
import kubatech.api.tileentity.CustomTileEntityPacketHandler;
import kubatech.api.utils.FastRandom;
+import kubatech.api.utils.ItemID;
import kubatech.api.utils.ReflectionHelper;
import kubatech.client.effect.EntityRenderer;
import kubatech.loaders.MobRecipeLoader;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
+import net.minecraft.enchantment.Enchantment;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.entity.EnumCreatureAttribute;
+import net.minecraft.entity.SharedMonsterAttributes;
+import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
@@ -71,6 +81,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChunkCoordinates;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
@@ -127,6 +139,10 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
CASING_INDEX,
1),
ofHatchAdder(
+ GT_MetaTileEntity_ExtremeExterminationChamber::addInputToMachineList,
+ CASING_INDEX,
+ 1),
+ ofHatchAdder(
GT_MetaTileEntity_ExtremeExterminationChamber::addEnergyInputToMachineList,
CASING_INDEX,
1),
@@ -153,7 +169,7 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
private boolean isInRitualMode = false;
private int mCasing = 0;
private byte mGlassTier = 0;
- private boolean mAnimationEnabled = false;
+ private boolean mAnimationEnabled = true;
private EntityRenderer entityRenderer = null;
private boolean renderEntity = false;
@@ -170,7 +186,7 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
public void loadNBTData(NBTTagCompound aNBT) {
super.loadNBTData(aNBT);
isInRitualMode = aNBT.getBoolean("isInRitualMode");
- mAnimationEnabled = aNBT.getBoolean("mAnimationEnabled");
+ mAnimationEnabled = !aNBT.hasKey("mAnimationEnabled") || aNBT.getBoolean("mAnimationEnabled");
mGlassTier = aNBT.getByte("mGlassTier");
}
@@ -187,7 +203,8 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
.addInfo(Author)
.addInfo("Spawns and Exterminates monsters for you")
.addInfo("Base energy usage: 2,000 EU/t")
- .addInfo("Recipe time is based on mob health")
+ .addInfo("Recipe time is based on mob health and the weapon")
+ .addInfo("You have to put a weapon in ULV Input Bus (optional)")
.addInfo("Also produces 120 Liquid XP per operation")
.addInfo("If the mob spawns infernal")
.addInfo("it will drain 8 times more power")
@@ -203,7 +220,10 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
.addOtherStructurePart("Borosilicate Glass", "All walls without corners")
.addStructureInfo("The glass tier limits the Energy Input tier")
.addOtherStructurePart("Steel Frame Box", "All vertical corners (except top and bottom)")
+ .addOtherStructurePart("Diamond spikes", "Inside second layer")
.addOutputBus("Any casing", 1)
+ .addOtherStructurePart(
+ "1x ULV " + StatCollector.translateToLocal("GT5U.MBTT.InputBus"), "Any casing", 1)
.addOutputHatch("Any casing", 1)
.addEnergyHatch("Any casing", 1)
.addMaintenanceHatch("Any casing", 1)
@@ -368,7 +388,10 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
}
if (tileAltar == null) return;
- if (currentEssence < effect.getCostPerRefresh() * 100) SoulNetworkHandler.causeNauseaToPlayer(owner);
+ if (currentEssence < effect.getCostPerRefresh() * 100) {
+ SoulNetworkHandler.causeNauseaToPlayer(owner);
+ return;
+ }
((IBloodAltar) tileAltar)
.sacrificialDaggerCall(
@@ -397,6 +420,15 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
private CustomTileEntityPacket mobPacket = null;
+ private static class WeaponCache {
+ boolean isValid = false;
+ ItemID id = null;
+ int looting = 0;
+ double attackdamage = 0;
+ }
+
+ private final WeaponCache weaponCache = new WeaponCache();
+
@Override
public boolean checkRecipe(ItemStack aStack) {
if (getBaseMetaTileEntity().isClientSide()) return false;
@@ -414,14 +446,57 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
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)};
+ this.mOutputItems = recipe.generateOutputs(rand, this, 3, 0);
} else {
- calculateOverclockedNessMulti(this.mEUt, this.mMaxProgresstime, 2, getMaxInputVoltage());
+ double attackDamage = 9d; // damage from spikes
+ GT_MetaTileEntity_Hatch_InputBus inputbus = this.mInputBusses.size() == 0 ? null : this.mInputBusses.get(0);
+ if (inputbus == null || !isValidMetaTileEntity(inputbus)) {
+ weaponCache.isValid = false;
+ return false;
+ }
+ ItemStack lootingholder = inputbus.getStackInSlot(0);
+ weaponCheck:
+ {
+ if (weaponCache.isValid && weaponCache.id.equals(lootingholder)) break weaponCheck;
+ if (lootingholder == null || !Enchantment.looting.canApply(lootingholder)) {
+ weaponCache.isValid = false;
+ break weaponCheck;
+ }
+ try {
+ //noinspection unchecked
+ weaponCache.attackdamage = ((Multimap<String, AttributeModifier>)
+ lootingholder.getAttributeModifiers())
+ .get(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName()).stream()
+ .mapToDouble(attr -> attr.getAmount()
+ + (double) EnchantmentHelper.func_152377_a(
+ lootingholder, EnumCreatureAttribute.UNDEFINED))
+ .sum();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ weaponCache.isValid = true;
+ weaponCache.looting =
+ EnchantmentHelper.getEnchantmentLevel(Enchantment.looting.effectId, lootingholder);
+ weaponCache.id = ItemID.create_NoCopy(lootingholder, true, true);
+ }
+ if (weaponCache.isValid) attackDamage += weaponCache.attackdamage;
+
+ this.mOutputItems =
+ recipe.generateOutputs(rand, this, attackDamage, weaponCache.isValid ? weaponCache.looting : 0);
+ int eut = this.mEUt;
+ calculatePerfectOverclockedNessMulti(this.mEUt, this.mMaxProgresstime, 2, getMaxInputVoltage());
+ if (weaponCache.isValid && lootingholder.isItemStackDamageable()) {
+ do {
+ if (lootingholder.attemptDamageItem(1, rand)) {
+ inputbus.setInventorySlotContents(0, null);
+ break;
+ }
+ } while ((eut <<= 2) < this.mEUt);
+ }
this.mOutputFluids = new FluidStack[] {FluidRegistry.getFluidStack("xpjuice", 120)};
}
if (this.mEUt > 0) this.mEUt = -this.mEUt;
@@ -434,6 +509,7 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
if (mAnimationEnabled) mobPacket.addData(mobType);
mobPacket.sendToAllAround(16);
+ this.updateSlots();
return true;
}
@@ -471,7 +547,11 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
public boolean checkMachine(IGregTechTileEntity aBaseMetaTileEntity, ItemStack aStack) {
mGlassTier = 0;
if (!checkPiece(STRUCTURE_PIECE_MAIN, 2, 6, 0)) return false;
- if (mCasing < 10 || mMaintenanceHatches.size() != 1 || mEnergyHatches.size() == 0) return false;
+ if (mCasing < 10
+ || mMaintenanceHatches.size() != 1
+ || mEnergyHatches.size() == 0
+ || !(mInputBusses.size() == 0 || (mInputBusses.size() == 1 && mInputBusses.get(0).mTier == 0)))
+ return false;
if (mGlassTier < 8)
for (GT_MetaTileEntity_Hatch_Energy hatch : mEnergyHatches) if (hatch.mTier > mGlassTier) return false;
if (isInRitualMode) connectToRitual();
@@ -479,6 +559,25 @@ public class GT_MetaTileEntity_ExtremeExterminationChamber
}
@Override
+ public String[] getInfoData() {
+ ArrayList<String> info = new ArrayList<>(Arrays.asList(super.getInfoData()));
+ info.add("Animations: " + EnumChatFormatting.YELLOW + (mAnimationEnabled ? "Enabled" : "Disabled"));
+ info.add("Is in ritual mode: " + EnumChatFormatting.YELLOW + (isInRitualMode ? "Yes" : "No"));
+ if (isInRitualMode)
+ info.add("Is connected to ritual: "
+ + (isRitualValid() ? EnumChatFormatting.GREEN + "Yes" : EnumChatFormatting.RED + "No"));
+ else {
+ info.add("Inserted weapon: " + EnumChatFormatting.YELLOW + (weaponCache.isValid ? "Yes" : "No"));
+ if (weaponCache.isValid) {
+ info.add("Weapon attack damage: " + EnumChatFormatting.YELLOW + weaponCache.attackdamage);
+ info.add("Weapon looting level: " + EnumChatFormatting.YELLOW + weaponCache.looting);
+ info.add("Total attack damage: " + EnumChatFormatting.YELLOW + (9 + weaponCache.attackdamage));
+ } else info.add("Total attack damage: " + EnumChatFormatting.YELLOW + 9);
+ }
+ return info.toArray(new String[0]);
+ }
+
+ @Override
public int getMaxEfficiency(ItemStack aStack) {
return 10000;
}