aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gtPlusPlus/xmod/gregtech/api/items
diff options
context:
space:
mode:
authorRaven Szewczyk <git@eigenraven.me>2024-05-24 19:50:35 +0100
committerRaven Szewczyk <git@eigenraven.me>2024-05-24 19:50:35 +0100
commit6d1b2216464d4dad449ac6fcfec476832224a55e (patch)
tree526a0c15f7056313c80e6c0386e025e9b3f61781 /src/main/java/gtPlusPlus/xmod/gregtech/api/items
parentb5d35f40afa606ed1b07061dad82e0521a59c186 (diff)
downloadGT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.tar.gz
GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.tar.bz2
GT5-Unofficial-6d1b2216464d4dad449ac6fcfec476832224a55e.zip
Merge addon sources
Diffstat (limited to 'src/main/java/gtPlusPlus/xmod/gregtech/api/items')
-rw-r--r--src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_Generic_Item.java204
-rw-r--r--src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem.java357
-rw-r--r--src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem_Base.java745
-rw-r--r--src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem_X32.java266
-rw-r--r--src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaTool.java692
5 files changed, 2264 insertions, 0 deletions
diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_Generic_Item.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_Generic_Item.java
new file mode 100644
index 0000000000..3ad04ab014
--- /dev/null
+++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_Generic_Item.java
@@ -0,0 +1,204 @@
+package gtPlusPlus.xmod.gregtech.api.items;
+
+import static gregtech.api.enums.Mods.GTPlusPlus;
+
+import java.util.List;
+
+import net.minecraft.block.BlockDispenser;
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
+import net.minecraft.dispenser.BehaviorProjectileDispense;
+import net.minecraft.dispenser.IBlockSource;
+import net.minecraft.dispenser.IPosition;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.IProjectile;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.projectile.EntityArrow;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.IIcon;
+import net.minecraft.world.World;
+
+import cpw.mods.fml.common.registry.GameRegistry;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.enums.SubTag;
+import gregtech.api.interfaces.IProjectileItem;
+import gregtech.api.util.GT_LanguageManager;
+import gregtech.api.util.GT_ModHandler;
+import gregtech.api.util.GT_Utility;
+import gtPlusPlus.core.creative.AddToCreativeTab;
+import gtPlusPlus.core.util.Utils;
+
+/**
+ * Extended by most Items, also used as a fallback Item, to prevent the accidental deletion when Errors occur.
+ */
+public class Gregtech_Generic_Item extends Item implements IProjectileItem {
+
+ private final String mName, mTooltip;
+ protected IIcon mIcon;
+
+ public Gregtech_Generic_Item(final String aUnlocalized, final String aEnglish, final String aEnglishTooltip) {
+ this(aUnlocalized, aEnglish, aEnglishTooltip, true);
+ }
+
+ public Gregtech_Generic_Item(final String aUnlocalized, final String aEnglish, final String aEnglishTooltip,
+ final boolean aWriteToolTipIntoLangFile) {
+ super();
+ this.mName = aUnlocalized;
+ GT_LanguageManager.addStringLocalization(this.mName + ".name", aEnglish);
+ if (GT_Utility.isStringValid(aEnglishTooltip)) {
+ GT_LanguageManager.addStringLocalization(
+ this.mTooltip = this.mName + ".tooltip_main",
+ aEnglishTooltip,
+ aWriteToolTipIntoLangFile);
+ } else {
+ this.mTooltip = null;
+ }
+ this.setCreativeTab(AddToCreativeTab.tabMachines);
+ GameRegistry.registerItem(this, this.mName, GTPlusPlus.ID);
+ BlockDispenser.dispenseBehaviorRegistry.putObject(this, new GT_Item_Dispense());
+ }
+
+ @Override
+ public final Item setUnlocalizedName(final String aName) {
+ return this;
+ }
+
+ @Override
+ public final String getUnlocalizedName() {
+ return this.mName;
+ }
+
+ @Override
+ public String getUnlocalizedName(final ItemStack aStack) {
+ return this.getHasSubtypes() ? this.mName + "." + this.getDamage(aStack) : this.mName;
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void registerIcons(final IIconRegister aIconRegister) {
+ this.mIcon = aIconRegister.registerIcon(GTPlusPlus.ID + ":" + this.mName);
+ }
+
+ @Override
+ public boolean doesSneakBypassUse(final World aWorld, final int aX, final int aY, final int aZ,
+ final EntityPlayer aPlayer) {
+ return true;
+ }
+
+ @Override
+ public IIcon getIconFromDamage(final int par1) {
+ return this.mIcon;
+ }
+
+ public int getTier(final ItemStack aStack) {
+ return 0;
+ }
+
+ @Override
+ public void addInformation(final ItemStack aStack, final EntityPlayer aPlayer, final List aList,
+ final boolean aF3_H) {
+ if ((this.getMaxDamage() > 0) && !this.getHasSubtypes()) {
+ aList.add((aStack.getMaxDamage() - this.getDamage(aStack)) + " / " + aStack.getMaxDamage());
+ }
+ if (this.mTooltip != null) {
+ aList.add(GT_LanguageManager.getTranslation(this.mTooltip));
+ }
+ if (GT_ModHandler.isElectricItem(aStack)) {
+ aList.add("Tier: " + this.getTier(aStack));
+ }
+ this.addAdditionalToolTips(aList, aStack);
+ }
+
+ protected void addAdditionalToolTips(final List aList, final ItemStack aStack) {
+ //
+ }
+
+ @Override
+ public void onCreated(final ItemStack aStack, final World aWorld, final EntityPlayer aPlayer) {
+ this.isItemStackUsable(aStack);
+ }
+
+ public boolean isItemStackUsable(final ItemStack aStack) {
+ return true;
+ }
+
+ public ItemStack onDispense(final IBlockSource aSource, final ItemStack aStack) {
+ final EnumFacing enumfacing = BlockDispenser.func_149937_b(aSource.getBlockMetadata());
+ final IPosition iposition = BlockDispenser.func_149939_a(aSource);
+ final ItemStack itemstack1 = aStack.splitStack(1);
+ BehaviorDefaultDispenseItem.doDispense(aSource.getWorld(), itemstack1, 6, enumfacing, iposition);
+ return aStack;
+ }
+
+ @Override
+ public EntityArrow getProjectile(final SubTag aProjectileType, final ItemStack aStack, final World aWorld,
+ final double aX, final double aY, final double aZ) {
+ return null;
+ }
+
+ @Override
+ public EntityArrow getProjectile(final SubTag aProjectileType, final ItemStack aStack, final World aWorld,
+ final EntityLivingBase aEntity, final float aSpeed) {
+ return null;
+ }
+
+ @Override
+ public boolean hasProjectile(final SubTag aProjectileType, final ItemStack aStack) {
+ return false;
+ }
+
+ @Override
+ public ItemStack getContainerItem(final ItemStack aStack) {
+ return null;
+ }
+
+ @Override
+ public boolean hasContainerItem(final ItemStack aStack) {
+ return this.getContainerItem(aStack) != null;
+ }
+
+ public static class GT_Item_Dispense extends BehaviorProjectileDispense {
+
+ @Override
+ public ItemStack dispenseStack(final IBlockSource aSource, final ItemStack aStack) {
+ return ((Gregtech_Generic_Item) aStack.getItem()).onDispense(aSource, aStack);
+ }
+
+ @Override
+ protected IProjectile getProjectileEntity(final World aWorld, final IPosition aPosition) {
+ return null;
+ }
+ }
+
+ @Override
+ public int getColorFromItemStack(final ItemStack stack, int HEX_OxFFFFFF) {
+ if (stack.getDisplayName()
+ .contains("LuV")) {
+ HEX_OxFFFFFF = 0xffffcc;
+ } else if (stack.getDisplayName()
+ .contains("ZPM")) {
+ HEX_OxFFFFFF = 0xace600;
+ } else if (stack.getDisplayName()
+ .contains("UV")) {
+ HEX_OxFFFFFF = 0xffff00;
+ } else if (stack.getDisplayName()
+ .contains("MAX")) {
+ HEX_OxFFFFFF = 0xff0000;
+ } else if (stack.getDisplayName()
+ .contains("Sodium")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(0, 0, 150);
+ } else if (stack.getDisplayName()
+ .contains("Cadmium")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(50, 50, 60);
+ } else if (stack.getDisplayName()
+ .contains("Lithium")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(225, 220, 255);
+ } else {
+ HEX_OxFFFFFF = 0xffffff;
+ }
+ return HEX_OxFFFFFF;
+ }
+}
diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem.java
new file mode 100644
index 0000000000..015ba9d716
--- /dev/null
+++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem.java
@@ -0,0 +1,357 @@
+package gtPlusPlus.xmod.gregtech.api.items;
+
+import static gregtech.api.enums.GT_Values.D1;
+import static gregtech.api.enums.Mods.GTPlusPlus;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.List;
+
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.EnumAction;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+import net.minecraft.world.World;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.SubTag;
+import gregtech.api.enums.TC_Aspects.TC_AspectStack;
+import gregtech.api.interfaces.IFoodStat;
+import gregtech.api.interfaces.IIconContainer;
+import gregtech.api.interfaces.IItemContainer;
+import gregtech.api.objects.ItemData;
+import gregtech.api.util.GT_LanguageManager;
+import gregtech.api.util.GT_OreDictUnificator;
+import gregtech.api.util.GT_Utility;
+import gtPlusPlus.core.creative.AddToCreativeTab;
+import gtPlusPlus.xmod.gregtech.api.interfaces.internal.Interface_ItemBehaviour;
+
+public abstract class Gregtech_MetaItem extends Gregtech_MetaItem_Base {
+
+ /**
+ * All instances of this Item Class are listed here. This gets used to register the Renderer to all Items of this
+ * Type, if useStandardMetaItemRenderer() returns true.
+ * <p/>
+ * You can also use the unlocalized Name gotten from getUnlocalizedName() as Key if you want to get a specific Item.
+ */
+ public static final HashMap<String, Gregtech_MetaItem> sInstances = new HashMap<>();
+
+ /* ---------- CONSTRUCTOR AND MEMBER VARIABLES ---------- */
+
+ public final short mOffset, mItemAmount;
+ public final BitSet mEnabledItems;
+ public final BitSet mVisibleItems;
+ public final IIcon[][] mIconList;
+
+ public final HashMap<Short, IFoodStat> mFoodStats = new HashMap<>();
+ public final HashMap<Short, Long[]> mElectricStats = new HashMap<>();
+ public final HashMap<Short, Long[]> mFluidContainerStats = new HashMap<>();
+ public final HashMap<Short, Short> mBurnValues = new HashMap<>();
+
+ /**
+ * Creates the Item using these Parameters.
+ *
+ * @param aUnlocalized The Unlocalized Name of this Item.
+ */
+ public Gregtech_MetaItem(final String aUnlocalized, final short aOffset, final short aItemAmount) {
+ super(aUnlocalized);
+ this.setCreativeTab(AddToCreativeTab.tabMachines);
+ this.setHasSubtypes(true);
+ this.setMaxDamage(0);
+ this.mEnabledItems = new BitSet(aItemAmount);
+ this.mVisibleItems = new BitSet(aItemAmount);
+
+ this.mOffset = (short) Math.min(32766, aOffset);
+ this.mItemAmount = (short) Math.min(aItemAmount, 32766 - this.mOffset);
+ this.mIconList = new IIcon[aItemAmount][1];
+
+ sInstances.put(this.getUnlocalizedName(), this);
+ }
+
+ /**
+ * This adds a Custom Item to the ending Range.
+ *
+ * @param aID The Id of the assigned Item [0 - mItemAmount] (The MetaData gets auto-shifted by +mOffset)
+ * @param aEnglish The Default Localized Name of the created Item
+ * @param aToolTip The Default ToolTip of the created Item, you can also insert null for having no ToolTip
+ * @param aFoodBehavior The Food Value of this Item. Can be null aswell. Just a convenience thing.
+ * @param aRandomData The OreDict Names you want to give the Item. Also used for TC Aspects and some other things.
+ * @return An ItemStack containing the newly created Item.
+ */
+ public final ItemStack addItem(final int aID, final String aEnglish, String aToolTip, final Object... aRandomData) {
+ if (aToolTip == null) {
+ aToolTip = "";
+ }
+ if ((aID >= 0) && (aID < this.mItemAmount)) {
+ final ItemStack rStack = new ItemStack(this, 1, this.mOffset + aID);
+ this.mEnabledItems.set(aID);
+ this.mVisibleItems.set(aID);
+ GT_LanguageManager.addStringLocalization(this.getUnlocalizedName(rStack) + ".name", aEnglish);
+ GT_LanguageManager.addStringLocalization(this.getUnlocalizedName(rStack) + ".tooltip", aToolTip);
+ final List<TC_AspectStack> tAspects = new ArrayList<>();
+ // Important Stuff to do first
+ for (final Object tRandomData : aRandomData) {
+ if (tRandomData instanceof SubTag) {
+ if (tRandomData == SubTag.INVISIBLE) {
+ this.mVisibleItems.set(aID, false);
+ continue;
+ }
+ if (tRandomData == SubTag.NO_UNIFICATION) {
+ GT_OreDictUnificator.addToBlacklist(rStack);
+ continue;
+ }
+ }
+ }
+ // now check for the rest
+ for (final Object tRandomData : aRandomData) {
+ if (tRandomData != null) {
+ boolean tUseOreDict = true;
+
+ if (tRandomData instanceof Interface_ItemBehaviour) {
+ this.addItemBehavior(
+ this.mOffset + aID,
+ (Interface_ItemBehaviour<Gregtech_MetaItem_Base>) tRandomData);
+ tUseOreDict = false;
+ }
+ if (tRandomData instanceof IItemContainer) {
+ ((IItemContainer) tRandomData).set(rStack);
+ tUseOreDict = false;
+ }
+ if (tRandomData instanceof SubTag) {
+ continue;
+ }
+ if (tRandomData instanceof TC_AspectStack) {
+ ((TC_AspectStack) tRandomData).addToAspectList(tAspects);
+ continue;
+ }
+ if (tRandomData instanceof ItemData) {
+ if (GT_Utility.isStringValid(tRandomData)) {
+ GT_OreDictUnificator.registerOre(tRandomData, rStack);
+ } else {
+ GT_OreDictUnificator.addItemData(rStack, (ItemData) tRandomData);
+ }
+ continue;
+ }
+ if (tUseOreDict) {
+ GT_OreDictUnificator.registerOre(tRandomData, rStack);
+ continue;
+ }
+ }
+ }
+ if (GregTech_API.sThaumcraftCompat != null) {
+ GregTech_API.sThaumcraftCompat.registerThaumcraftAspectsToItem(rStack, tAspects, false);
+ }
+ return rStack;
+ }
+ return null;
+ }
+
+ /**
+ * Sets the Furnace Burn Value for the Item.
+ *
+ * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765]
+ * @param aValue 200 = 1 Burn Process = 500 EU, max = 32767 (that is 81917.5 EU)
+ * @return the Item itself for convenience in constructing.
+ */
+ public final Gregtech_MetaItem setBurnValue(final int aMetaValue, final int aValue) {
+ if ((aMetaValue < 0) || (aMetaValue >= (this.mOffset + this.mEnabledItems.length())) || (aValue < 0)) {
+ return this;
+ }
+ if (aValue == 0) {
+ this.mBurnValues.remove((short) aMetaValue);
+ } else {
+ this.mBurnValues.put((short) aMetaValue, aValue > Short.MAX_VALUE ? Short.MAX_VALUE : (short) aValue);
+ }
+ return this;
+ }
+
+ /**
+ * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765]
+ * @param aMaxCharge Maximum Charge. (if this is == 0 it will remove the Electric Behavior)
+ * @param aTransferLimit Transfer Limit.
+ * @param aTier The electric Tier.
+ * @param aSpecialData If this Item has a Fixed Charge, like a SingleUse Battery (if > 0). Use -1 if you want to
+ * make this Battery chargeable (the use and canUse Functions will still discharge if you just
+ * use this) Use -2 if you want to make this Battery dischargeable. Use -3 if you want to make
+ * this Battery charge/discharge-able.
+ * @return the Item itself for convenience in constructing.
+ */
+ public final Gregtech_MetaItem setElectricStats(final int aMetaValue, final long aMaxCharge,
+ final long aTransferLimit, final long aTier, final long aSpecialData, final boolean aUseAnimations) {
+ if ((aMetaValue < 0) || (aMetaValue >= (this.mOffset + this.mEnabledItems.length()))) {
+ return this;
+ }
+ if (aMaxCharge == 0) {
+ this.mElectricStats.remove((short) aMetaValue);
+ } else {
+ this.mElectricStats.put(
+ (short) aMetaValue,
+ new Long[] { aMaxCharge, Math.max(0, aTransferLimit), Math.max(-1, aTier), aSpecialData });
+ if ((aMetaValue >= this.mOffset) && aUseAnimations) {
+ this.mIconList[aMetaValue - this.mOffset] = Arrays.copyOf(
+ this.mIconList[aMetaValue - this.mOffset],
+ Math.max(9, this.mIconList[aMetaValue - this.mOffset].length));
+ }
+ }
+ return this;
+ }
+
+ /**
+ * @param aMetaValue the Meta Value of the Item you want to set it to. [0 - 32765]
+ * @param aMaxCharge Maximum Charge. (if this is == 0 it will remove the Electric Behavior)
+ * @param aTransferLimit Transfer Limit.
+ * @param aTier The electric Tier.
+ * @param aSpecialData If this Item has a Fixed Charge, like a SingleUse Battery (if > 0). Use -1 if you want to
+ * make this Battery chargeable (the use and canUse Functions will still discharge if you just
+ * use this) Use -2 if you want to make this Battery dischargeable. Use -3 if you want to make
+ * this Battery charge/discharge-able.
+ * @return the Item itself for convenience in constructing.
+ */
+ public final Gregtech_MetaItem setFluidContainerStats(final int aMetaValue, final long aCapacity,
+ final long aStacksize) {
+ if ((aMetaValue < 0) || (aMetaValue >= (this.mOffset + this.mEnabledItems.length()))) {
+ return this;
+ }
+ if (aCapacity < 0) {
+ this.mElectricStats.remove((short) aMetaValue);
+ } else {
+ this.mFluidContainerStats.put((short) aMetaValue, new Long[] { aCapacity, Math.max(1, aStacksize) });
+ }
+ return this;
+ }
+
+ /**
+ * @return if this MetaGenerated Item should use my Default Renderer System.
+ */
+ public boolean useStandardMetaItemRenderer() {
+ return true;
+ }
+
+ /**
+ * @return the Color Modulation the Material is going to be rendered with.
+ */
+ public short[] getRGBa(final ItemStack aStack) {
+ return Materials._NULL.getRGBA();
+ }
+
+ /**
+ * @return the Icon the Material is going to be rendered with.
+ */
+ public IIconContainer getIconContainer(final int aMetaData) {
+ return null;
+ }
+
+ /* ---------- INTERNAL OVERRIDES ---------- */
+
+ @Override
+ public ItemStack onItemRightClick(final ItemStack aStack, final World aWorld, final EntityPlayer aPlayer) {
+ return super.onItemRightClick(aStack, aWorld, aPlayer);
+ }
+
+ @Override
+ public int getMaxItemUseDuration(final ItemStack aStack) {
+ return this.mFoodStats.get((short) this.getDamage(aStack)) == null ? 0 : 32;
+ }
+
+ @Override
+ public EnumAction getItemUseAction(final ItemStack aStack) {
+ return EnumAction.none;
+ }
+
+ @Override
+ public final ItemStack onEaten(final ItemStack aStack, final World aWorld, final EntityPlayer aPlayer) {
+ final IFoodStat tStat = this.mFoodStats.get((short) this.getDamage(aStack));
+ if (tStat != null) {}
+
+ return aStack;
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void getSubItems(final Item var1, final CreativeTabs aCreativeTab, final List aList) {
+ for (int i = 0, j = this.mEnabledItems.length(); i < j; i++) {
+ if (this.mVisibleItems.get(i) || (D1 && this.mEnabledItems.get(i))) {
+ final Long[] tStats = this.mElectricStats.get((short) (this.mOffset + i));
+ if ((tStats != null) && (tStats[3] < 0)) {
+ final ItemStack tStack = new ItemStack(this, 1, this.mOffset + i);
+ this.setCharge(tStack, Math.abs(tStats[0]));
+ this.isItemStackUsable(tStack);
+ aList.add(tStack);
+ }
+ if ((tStats == null) || (tStats[3] != -2)) {
+ final ItemStack tStack = new ItemStack(this, 1, this.mOffset + i);
+ this.isItemStackUsable(tStack);
+ aList.add(tStack);
+ }
+ }
+ }
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public final void registerIcons(final IIconRegister aIconRegister) {
+ for (short i = 0, j = (short) this.mEnabledItems.length(); i < j; i++) {
+ if (this.mEnabledItems.get(i)) {
+ for (byte k = 1; k < this.mIconList[i].length; k++) {
+ this.mIconList[i][k] = aIconRegister
+ .registerIcon(GTPlusPlus.ID + ":" + this.getUnlocalizedName() + "/" + i + "/" + k);
+ }
+ this.mIconList[i][0] = aIconRegister
+ .registerIcon(GTPlusPlus.ID + ":" + this.getUnlocalizedName() + "/" + i);
+ }
+ }
+ }
+
+ @Override
+ public final Long[] getElectricStats(final ItemStack aStack) {
+ return this.mElectricStats.get((short) aStack.getItemDamage());
+ }
+
+ @Override
+ public final Long[] getFluidContainerStats(final ItemStack aStack) {
+ return this.mFluidContainerStats.get((short) aStack.getItemDamage());
+ }
+
+ @Override
+ public int getItemEnchantability() {
+ return 0;
+ }
+
+ @Override
+ public boolean isBookEnchantable(final ItemStack aStack, final ItemStack aBook) {
+ return false;
+ }
+
+ @Override
+ public boolean getIsRepairable(final ItemStack aStack, final ItemStack aMaterial) {
+ return false;
+ }
+
+ @Override
+ public int getColorFromItemStack(final ItemStack stack, int HEX_OxFFFFFF) {
+ if (stack.getDisplayName()
+ .contains("LuV")) {
+ HEX_OxFFFFFF = 0xffffcc;
+ } else if (stack.getDisplayName()
+ .contains("ZPM")) {
+ HEX_OxFFFFFF = 0xace600;
+ } else if (stack.getDisplayName()
+ .contains("UV")) {
+ HEX_OxFFFFFF = 0xffff00;
+ } else if (stack.getDisplayName()
+ .contains("MAX")) {
+ HEX_OxFFFFFF = 0xff0000;
+ } else {
+ HEX_OxFFFFFF = 0xffffff;
+ }
+ return HEX_OxFFFFFF;
+ }
+}
diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem_Base.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem_Base.java
new file mode 100644
index 0000000000..3c4418c2bf
--- /dev/null
+++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem_Base.java
@@ -0,0 +1,745 @@
+package gtPlusPlus.xmod.gregtech.api.items;
+
+import static gregtech.api.enums.GT_Values.D1;
+import static gregtech.api.enums.GT_Values.V;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import net.minecraft.dispenser.IBlockSource;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.projectile.EntityArrow;
+import net.minecraft.inventory.Container;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.world.World;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.IFluidContainerItem;
+
+import gregtech.api.enums.SubTag;
+import gregtech.api.util.GT_LanguageManager;
+import gregtech.api.util.GT_Log;
+import gregtech.api.util.GT_ModHandler;
+import gregtech.api.util.GT_Utility;
+import gtPlusPlus.core.util.Utils;
+import gtPlusPlus.xmod.gregtech.api.interfaces.internal.Interface_ItemBehaviour;
+import ic2.api.item.ElectricItem;
+import ic2.api.item.IElectricItem;
+import ic2.api.item.IElectricItemManager;
+import ic2.api.item.ISpecialElectricItem;
+
+public abstract class Gregtech_MetaItem_Base extends Gregtech_Generic_Item
+ implements ISpecialElectricItem, IElectricItemManager, IFluidContainerItem {
+
+ /* ---------- CONSTRUCTOR AND MEMBER VARIABLES ---------- */
+ private final HashMap<Short, ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>>> mItemBehaviors = new HashMap<>();
+
+ /**
+ * Creates the Item using these Parameters.
+ *
+ * @param aUnlocalized The Unlocalized Name of this Item.
+ * @param aGeneratedPrefixList The OreDict Prefixes you want to have generated.
+ */
+ public Gregtech_MetaItem_Base(final String aUnlocalized) {
+ super(aUnlocalized, "Generated Item", null, false);
+ this.setHasSubtypes(true);
+ this.setMaxDamage(0);
+ }
+
+ /**
+ * Adds a special Item Behaviour to the Item.
+ * <p/>
+ * Note: the boolean Behaviours sometimes won't be executed if another boolean Behaviour returned true before.
+ *
+ * @param aMetaValue the Meta Value of the Item you want to add it to. [0 - 32765]
+ * @param aBehavior the Click Behavior you want to add.
+ * @return the Item itself for convenience in constructing.
+ */
+ public final Gregtech_MetaItem_Base addItemBehavior(final int aMetaValue,
+ final Interface_ItemBehaviour<Gregtech_MetaItem_Base> aBehavior) {
+ if ((aMetaValue < 0) || (aMetaValue >= 32766) || (aBehavior == null)) {
+ return this;
+ }
+ ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors.get((short) aMetaValue);
+ if (tList == null) {
+ tList = new ArrayList<>(1);
+ this.mItemBehaviors.put((short) aMetaValue, tList);
+ }
+ tList.add(aBehavior);
+ return this;
+ }
+
+ public abstract Long[] getElectricStats(ItemStack aStack);
+
+ public abstract Long[] getFluidContainerStats(ItemStack aStack);
+
+ @Override
+ public boolean hasProjectile(final SubTag aProjectileType, final ItemStack aStack) {
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ if (tBehavior.hasProjectile(this, aProjectileType, aStack)) {
+ return true;
+ }
+ }
+ }
+ return super.hasProjectile(aProjectileType, aStack);
+ }
+
+ @Override
+ public EntityArrow getProjectile(final SubTag aProjectileType, final ItemStack aStack, final World aWorld,
+ final double aX, final double aY, final double aZ) {
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ final EntityArrow rArrow = tBehavior.getProjectile(this, aProjectileType, aStack, aWorld, aX, aY, aZ);
+ if (rArrow != null) {
+ return rArrow;
+ }
+ }
+ }
+ return super.getProjectile(aProjectileType, aStack, aWorld, aX, aY, aZ);
+ }
+
+ @Override
+ public EntityArrow getProjectile(final SubTag aProjectileType, final ItemStack aStack, final World aWorld,
+ final EntityLivingBase aEntity, final float aSpeed) {
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ final EntityArrow rArrow = tBehavior
+ .getProjectile(this, aProjectileType, aStack, aWorld, aEntity, aSpeed);
+ if (rArrow != null) {
+ return rArrow;
+ }
+ }
+ }
+ return super.getProjectile(aProjectileType, aStack, aWorld, aEntity, aSpeed);
+ }
+
+ @Override
+ public ItemStack onDispense(final IBlockSource aSource, final ItemStack aStack) {
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ if (tBehavior.canDispense(this, aSource, aStack)) {
+ return tBehavior.onDispense(this, aSource, aStack);
+ }
+ }
+ }
+ return super.onDispense(aSource, aStack);
+ }
+
+ @Override
+ public boolean isItemStackUsable(final ItemStack aStack) {
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ if (!tBehavior.isItemStackUsable(this, aStack)) {
+ return false;
+ }
+ }
+ }
+ return super.isItemStackUsable(aStack);
+ }
+
+ @Override
+ public boolean onLeftClickEntity(final ItemStack aStack, final EntityPlayer aPlayer, final Entity aEntity) {
+ this.use(aStack, 0, aPlayer);
+ this.isItemStackUsable(aStack);
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ try {
+ if (tBehavior.onLeftClickEntity(this, aStack, aPlayer, aEntity)) {
+ if (aStack.stackSize <= 0) {
+ aPlayer.destroyCurrentEquippedItem();
+ }
+ return true;
+ }
+ if (aStack.stackSize <= 0) {
+ aPlayer.destroyCurrentEquippedItem();
+ return false;
+ }
+ } catch (final Throwable e) {
+ if (D1) {
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onItemUse(final ItemStack aStack, final EntityPlayer aPlayer, final World aWorld, final int aX,
+ final int aY, final int aZ, final int ordinalSide, final float hitX, final float hitY, final float hitZ) {
+ this.use(aStack, 0, aPlayer);
+ this.isItemStackUsable(aStack);
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ try {
+ if (tBehavior.onItemUse(this, aStack, aPlayer, aWorld, aX, aY, aZ, ordinalSide, hitX, hitY, hitZ)) {
+ if (aStack.stackSize <= 0) {
+ aPlayer.destroyCurrentEquippedItem();
+ }
+ return true;
+ }
+ if (aStack.stackSize <= 0) {
+ aPlayer.destroyCurrentEquippedItem();
+ return false;
+ }
+ } catch (final Throwable e) {
+ if (D1) {
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onItemUseFirst(final ItemStack aStack, final EntityPlayer aPlayer, final World aWorld, final int aX,
+ final int aY, final int aZ, final int ordinalSide, final float hitX, final float hitY, final float hitZ) {
+ this.use(aStack, 0, aPlayer);
+ this.isItemStackUsable(aStack);
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ try {
+ if (tBehavior
+ .onItemUseFirst(this, aStack, aPlayer, aWorld, aX, aY, aZ, ordinalSide, hitX, hitY, hitZ)) {
+ if (aStack.stackSize <= 0) {
+ aPlayer.destroyCurrentEquippedItem();
+ }
+ return true;
+ }
+ if (aStack.stackSize <= 0) {
+ aPlayer.destroyCurrentEquippedItem();
+ return false;
+ }
+ } catch (final Throwable e) {
+ if (D1) {
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public ItemStack onItemRightClick(ItemStack aStack, final World aWorld, final EntityPlayer aPlayer) {
+ this.use(aStack, 0, aPlayer);
+ this.isItemStackUsable(aStack);
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ try {
+ aStack = tBehavior.onItemRightClick(this, aStack, aWorld, aPlayer);
+ } catch (final Throwable e) {
+ if (D1) {
+ e.printStackTrace(GT_Log.err);
+ }
+ }
+ }
+ }
+ return aStack;
+ }
+
+ @Override
+ public final void addInformation(final ItemStack aStack, final EntityPlayer aPlayer, List aList,
+ final boolean aF3_H) {
+ final String tKey = this.getUnlocalizedName(aStack) + ".tooltip",
+ tString = GT_LanguageManager.getTranslation(tKey);
+ if (GT_Utility.isStringValid(tString) && !tKey.equals(tString)) {
+ aList.add(tString);
+ }
+
+ Long[] tStats = this.getElectricStats(aStack);
+ if (tStats != null) {
+ if (tStats[3] > 0) {
+ aList.add(
+ EnumChatFormatting.AQUA + "Contains "
+ + GT_Utility.formatNumbers(tStats[3])
+ + " EU Tier: "
+ + (tStats[2] >= 0 ? tStats[2] : 0)
+ + EnumChatFormatting.GRAY);
+ } else {
+ final long tCharge = this.getRealCharge(aStack);
+ if ((tStats[3] == -2) && (tCharge <= 0)) {
+ aList.add(
+ EnumChatFormatting.AQUA + "Empty. You should recycle it properly." + EnumChatFormatting.GRAY);
+ } else {
+ aList.add(
+ EnumChatFormatting.AQUA + ""
+ + GT_Utility.formatNumbers(tCharge)
+ + " / "
+ + GT_Utility.formatNumbers(Math.abs(tStats[0]))
+ + " EU - Voltage: "
+ + GT_Utility.formatNumbers(
+ V[(int) (tStats[2] >= 0 ? tStats[2] < V.length ? tStats[2] : V.length - 1 : 1)])
+ + EnumChatFormatting.GRAY);
+ }
+ }
+ }
+
+ tStats = this.getFluidContainerStats(aStack);
+ if ((tStats != null) && (tStats[0] > 0)) {
+ final FluidStack tFluid = this.getFluidContent(aStack);
+ aList.add(
+ EnumChatFormatting.BLUE
+ + ((tFluid == null ? "No Fluids Contained" : GT_Utility.getFluidName(tFluid, true)))
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ EnumChatFormatting.BLUE
+ + (GT_Utility.formatNumbers(tFluid == null ? 0 : tFluid.amount) + "L / "
+ + GT_Utility.formatNumbers(tStats[0])
+ + "L")
+ + EnumChatFormatting.GRAY);
+ }
+
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ aList = tBehavior.getAdditionalToolTips(this, aList, aStack);
+ }
+ }
+
+ this.addAdditionalToolTips(aList, aStack);
+ }
+
+ @Override
+ public void onUpdate(final ItemStack aStack, final World aWorld, final Entity aPlayer, final int aTimer,
+ final boolean aIsInHand) {
+ final ArrayList<Interface_ItemBehaviour<Gregtech_MetaItem_Base>> tList = this.mItemBehaviors
+ .get((short) this.getDamage(aStack));
+ if (tList != null) {
+ for (final Interface_ItemBehaviour<Gregtech_MetaItem_Base> tBehavior : tList) {
+ tBehavior.onUpdate(this, aStack, aWorld, aPlayer, aTimer, aIsInHand);
+ }
+ }
+ }
+
+ @Override
+ public final boolean canProvideEnergy(final ItemStack aStack) {
+ final Long[] tStats = this.getElectricStats(aStack);
+ if (tStats == null) {
+ return false;
+ }
+ return (tStats[3] > 0) || ((aStack.stackSize == 1) && ((tStats[3] == -2) || (tStats[3] == -3)));
+ }
+
+ @Override
+ public final double getMaxCharge(final ItemStack aStack) {
+ final Long[] tStats = this.getElectricStats(aStack);
+ if (tStats == null) {
+ return 0;
+ }
+ return Math.abs(tStats[0]);
+ }
+
+ @Override
+ public final double getTransferLimit(final ItemStack aStack) {
+ final Long[] tStats = this.getElectricStats(aStack);
+ if (tStats == null) {
+ return 0;
+ }
+ return Math.max(tStats[1], tStats[3]);
+ }
+
+ @Override
+ public final double charge(final ItemStack aStack, final double aCharge, final int aTier,
+ final boolean aIgnoreTransferLimit, final boolean aSimulate) {
+ final Long[] tStats = this.getElectricStats(aStack);
+ if ((tStats == null) || (tStats[2] > aTier)
+ || !((tStats[3] == -1) || (tStats[3] == -3) || ((tStats[3] < 0) && (aCharge == Integer.MAX_VALUE)))
+ || (aStack.stackSize != 1)) {
+ return 0;
+ }
+ final long tChargeBefore = this.getRealCharge(aStack),
+ tNewCharge = aCharge == Integer.MAX_VALUE ? Long.MAX_VALUE
+ : Math.min(
+ Math.abs(tStats[0]),
+ tChargeBefore + (aIgnoreTransferLimit ? (long) aCharge : Math.min(tStats[1], (long) aCharge)));
+ if (!aSimulate) {
+ this.setCharge(aStack, tNewCharge);
+ }
+ return tNewCharge - tChargeBefore;
+ }
+
+ @Override
+ public final double discharge(final ItemStack aStack, final double aCharge, final int aTier,
+ final boolean aIgnoreTransferLimit, final boolean aBatteryAlike, final boolean aSimulate) {
+ final Long[] tStats = this.getElectricStats(aStack);
+ if ((tStats == null) || (tStats[2] > aTier)) {
+ return 0;
+ }
+ if (aBatteryAlike && !this.canProvideEnergy(aStack)) {
+ return 0;
+ }
+ if (tStats[3] > 0) {
+ if ((aCharge < tStats[3]) || (aStack.stackSize < 1)) {
+ return 0;
+ }
+ if (!aSimulate) {
+ aStack.stackSize--;
+ }
+ return tStats[3];
+ }
+ final long tChargeBefore = this.getRealCharge(aStack), tNewCharge = Math
+ .max(0, tChargeBefore - (aIgnoreTransferLimit ? (long) aCharge : Math.min(tStats[1], (long) aCharge)));
+ if (!aSimulate) {
+ this.setCharge(aStack, tNewCharge);
+ }
+ return tChargeBefore - tNewCharge;
+ }
+
+ @Override
+ public final double getCharge(final ItemStack aStack) {
+ return this.getRealCharge(aStack);
+ }
+
+ @Override
+ public final boolean canUse(final ItemStack aStack, final double aAmount) {
+ return this.getRealCharge(aStack) >= aAmount;
+ }
+
+ @Override
+ public final boolean use(final ItemStack aStack, final double aAmount, final EntityLivingBase aPlayer) {
+ this.chargeFromArmor(aStack, aPlayer);
+ if ((aPlayer instanceof EntityPlayer) && ((EntityPlayer) aPlayer).capabilities.isCreativeMode) {
+ return true;
+ }
+ final double tTransfer = this.discharge(aStack, aAmount, Integer.MAX_VALUE, true, false, true);
+ if (tTransfer == aAmount) {
+ this.discharge(aStack, aAmount, Integer.MAX_VALUE, true, false, false);
+ this.chargeFromArmor(aStack, aPlayer);
+ return true;
+ }
+ this.discharge(aStack, aAmount, Integer.MAX_VALUE, true, false, false);
+ this.chargeFromArmor(aStack, aPlayer);
+ return false;
+ }
+
+ @Override
+ public final void chargeFromArmor(final ItemStack aStack, final EntityLivingBase aPlayer) {
+ if ((aPlayer == null) || aPlayer.worldObj.isRemote) {
+ return;
+ }
+ for (int i = 1; i < 5; i++) {
+ final ItemStack tArmor = aPlayer.getEquipmentInSlot(i);
+ if (GT_ModHandler.isElectricItem(tArmor)) {
+ final IElectricItem tArmorItem = (IElectricItem) tArmor.getItem();
+ if (tArmorItem.canProvideEnergy(tArmor) && (tArmorItem.getTier(tArmor) >= this.getTier(aStack))) {
+ final double tCharge = ElectricItem.manager.discharge(
+ tArmor,
+ this.charge(aStack, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, true, true),
+ Integer.MAX_VALUE,
+ true,
+ true,
+ false);
+ if (tCharge > 0) {
+ this.charge(aStack, tCharge, Integer.MAX_VALUE, true, false);
+ if (aPlayer instanceof EntityPlayer) {
+ final Container tContainer = ((EntityPlayer) aPlayer).openContainer;
+ if (tContainer != null) {
+ tContainer.detectAndSendChanges();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public final long getRealCharge(final ItemStack aStack) {
+ final Long[] tStats = this.getElectricStats(aStack);
+ if (tStats == null) {
+ return 0;
+ }
+ if (tStats[3] > 0) {
+ return (int) (long) tStats[3];
+ }
+ final NBTTagCompound tNBT = aStack.getTagCompound();
+ return tNBT == null ? 0 : tNBT.getLong("GT.ItemCharge");
+ }
+
+ public final boolean setCharge(final ItemStack aStack, long aCharge) {
+ final Long[] tStats = this.getElectricStats(aStack);
+ if ((tStats == null) || (tStats[3] > 0)) {
+ return false;
+ }
+ NBTTagCompound tNBT = aStack.getTagCompound();
+ if (tNBT == null) {
+ tNBT = new NBTTagCompound();
+ }
+ tNBT.removeTag("GT.ItemCharge");
+ aCharge = Math.min(tStats[0] < 0 ? Math.abs(tStats[0] / 2) : aCharge, Math.abs(tStats[0]));
+ if (aCharge > 0) {
+ aStack.setItemDamage(this.getChargedMetaData(aStack));
+ tNBT.setLong("GT.ItemCharge", aCharge);
+ } else {
+ aStack.setItemDamage(this.getEmptyMetaData(aStack));
+ }
+ if (tNBT.hasNoTags()) {
+ aStack.setTagCompound(null);
+ } else {
+ aStack.setTagCompound(tNBT);
+ }
+ this.isItemStackUsable(aStack);
+ return true;
+ }
+
+ public short getChargedMetaData(final ItemStack aStack) {
+ return (short) aStack.getItemDamage();
+ }
+
+ public short getEmptyMetaData(final ItemStack aStack) {
+ return (short) aStack.getItemDamage();
+ }
+
+ @Override
+ public FluidStack getFluid(final ItemStack aStack) {
+ return this.getFluidContent(aStack);
+ }
+
+ @Override
+ public int getCapacity(final ItemStack aStack) {
+ final Long[] tStats = this.getFluidContainerStats(aStack);
+ return tStats == null ? 0 : (int) Math.max(0, tStats[0]);
+ }
+
+ @Override
+ public int fill(final ItemStack aStack, final FluidStack aFluid, final boolean doFill) {
+ if ((aStack == null) || (aStack.stackSize != 1)) {
+ return 0;
+ }
+
+ final ItemStack tStack = GT_Utility.fillFluidContainer(aFluid, aStack, false, false);
+ if (tStack != null) {
+ aStack.setItemDamage(tStack.getItemDamage());
+ aStack.func_150996_a(tStack.getItem());
+ return GT_Utility.getFluidForFilledItem(tStack, false).amount;
+ }
+
+ final Long[] tStats = this.getFluidContainerStats(aStack);
+ if ((tStats == null) || (tStats[0] <= 0)
+ || (aFluid == null)
+ || (aFluid.getFluid()
+ .getID() <= 0)
+ || (aFluid.amount <= 0)) {
+ return 0;
+ }
+
+ FluidStack tFluid = this.getFluidContent(aStack);
+
+ if ((tFluid == null) || (tFluid.getFluid()
+ .getID() <= 0)) {
+ if (aFluid.amount <= tStats[0]) {
+ if (doFill) {
+ this.setFluidContent(aStack, aFluid);
+ }
+ return aFluid.amount;
+ }
+ if (doFill) {
+ tFluid = aFluid.copy();
+ tFluid.amount = (int) (long) tStats[0];
+ this.setFluidContent(aStack, tFluid);
+ }
+ return (int) (long) tStats[0];
+ }
+
+ if (!tFluid.isFluidEqual(aFluid)) {
+ return 0;
+ }
+
+ final int space = (int) (long) tStats[0] - tFluid.amount;
+ if (aFluid.amount <= space) {
+ if (doFill) {
+ tFluid.amount += aFluid.amount;
+ this.setFluidContent(aStack, tFluid);
+ }
+ return aFluid.amount;
+ }
+ if (doFill) {
+ tFluid.amount = (int) (long) tStats[0];
+ this.setFluidContent(aStack, tFluid);
+ }
+ return space;
+ }
+
+ @Override
+ public FluidStack drain(final ItemStack aStack, final int maxDrain, final boolean doDrain) {
+ if ((aStack == null) || (aStack.stackSize != 1)) {
+ return null;
+ }
+
+ FluidStack tFluid = GT_Utility.getFluidForFilledItem(aStack, false);
+ if ((tFluid != null) && (maxDrain >= tFluid.amount)) {
+ final ItemStack tStack = GT_Utility.getContainerItem(aStack, false);
+ if (tStack == null) {
+ aStack.stackSize = 0;
+ return tFluid;
+ }
+ aStack.setItemDamage(tStack.getItemDamage());
+ aStack.func_150996_a(tStack.getItem());
+ return tFluid;
+ }
+
+ final Long[] tStats = this.getFluidContainerStats(aStack);
+ if ((tStats == null) || (tStats[0] <= 0)) {
+ return null;
+ }
+
+ tFluid = this.getFluidContent(aStack);
+ if (tFluid == null) {
+ return null;
+ }
+
+ int used = maxDrain;
+ if (tFluid.amount < used) {
+ used = tFluid.amount;
+ }
+ if (doDrain) {
+ tFluid.amount -= used;
+ this.setFluidContent(aStack, tFluid);
+ }
+
+ final FluidStack drained = tFluid.copy();
+ drained.amount = used;
+ return drained;
+ }
+
+ public FluidStack getFluidContent(final ItemStack aStack) {
+ final Long[] tStats = this.getFluidContainerStats(aStack);
+ if ((tStats == null) || (tStats[0] <= 0)) {
+ return GT_Utility.getFluidForFilledItem(aStack, false);
+ }
+ final NBTTagCompound tNBT = aStack.getTagCompound();
+ return tNBT == null ? null : FluidStack.loadFluidStackFromNBT(tNBT.getCompoundTag("GT.FluidContent"));
+ }
+
+ public void setFluidContent(final ItemStack aStack, final FluidStack aFluid) {
+ NBTTagCompound tNBT = aStack.getTagCompound();
+ if (tNBT == null) {
+ tNBT = new NBTTagCompound();
+ } else {
+ tNBT.removeTag("GT.FluidContent");
+ }
+ if ((aFluid != null) && (aFluid.amount > 0)) {
+ tNBT.setTag("GT.FluidContent", aFluid.writeToNBT(new NBTTagCompound()));
+ }
+ if (tNBT.hasNoTags()) {
+ aStack.setTagCompound(null);
+ } else {
+ aStack.setTagCompound(tNBT);
+ }
+ this.isItemStackUsable(aStack);
+ }
+
+ @Override
+ public int getItemStackLimit(final ItemStack aStack) {
+ Long[] tStats = this.getElectricStats(aStack);
+ if ((tStats != null) && ((tStats[3] == -1) || (tStats[3] == -3)) && (this.getRealCharge(aStack) > 0)) {
+ return 1;
+ }
+ tStats = this.getFluidContainerStats(aStack);
+ if (tStats != null) {
+ return (int) (long) tStats[1];
+ }
+ return 64;
+ }
+
+ @Override
+ public final Item getChargedItem(final ItemStack itemStack) {
+ return this;
+ }
+
+ @Override
+ public final Item getEmptyItem(final ItemStack itemStack) {
+ return this;
+ }
+
+ @Override
+ public final int getTier(final ItemStack aStack) {
+ final Long[] tStats = this.getElectricStats(aStack);
+ return (int) (tStats == null ? Integer.MAX_VALUE : tStats[2]);
+ }
+
+ @Override
+ public final String getToolTip(final ItemStack aStack) {
+ return null;
+ } // This has its own ToolTip Handler, no need to let the IC2 Handler screw us up at this Point
+
+ @Override
+ public final IElectricItemManager getManager(final ItemStack aStack) {
+ return this;
+ } // We are our own Manager
+
+ @Override
+ public final boolean getShareTag() {
+ return true;
+ } // just to be sure.
+
+ @Override
+ public int getItemEnchantability() {
+ return 0;
+ }
+
+ @Override
+ public boolean isBookEnchantable(final ItemStack aStack, final ItemStack aBook) {
+ return false;
+ }
+
+ @Override
+ public boolean getIsRepairable(final ItemStack aStack, final ItemStack aMaterial) {
+ return false;
+ }
+
+ @Override
+ public int getColorFromItemStack(final ItemStack stack, int HEX_OxFFFFFF) {
+ if (stack.getDisplayName()
+ .contains("LuV")) {
+ HEX_OxFFFFFF = 0xffffcc;
+ } else if (stack.getDisplayName()
+ .contains("ZPM")) {
+ HEX_OxFFFFFF = 0xace600;
+ } else if (stack.getDisplayName()
+ .contains("UV")) {
+ HEX_OxFFFFFF = 0xffff00;
+ } else if (stack.getDisplayName()
+ .contains("MAX")) {
+ HEX_OxFFFFFF = 0xff0000;
+ } else if (stack.getDisplayName()
+ .contains("Sodium")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(0, 0, 150);
+ } else if (stack.getDisplayName()
+ .contains("Cadmium")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(50, 50, 60);
+ } else if (stack.getDisplayName()
+ .contains("Lithium")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(225, 220, 255);
+ } else {
+ HEX_OxFFFFFF = 0xffffff;
+ }
+ return HEX_OxFFFFFF;
+ }
+}
diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem_X32.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem_X32.java
new file mode 100644
index 0000000000..c04acb9537
--- /dev/null
+++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaItem_X32.java
@@ -0,0 +1,266 @@
+package gtPlusPlus.xmod.gregtech.api.items;
+
+import java.util.Arrays;
+import java.util.List;
+
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.IIcon;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import gregtech.api.GregTech_API;
+import gregtech.api.enums.GT_Values;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.OrePrefixes;
+import gregtech.api.interfaces.IIconContainer;
+import gregtech.api.util.GT_LanguageManager;
+import gregtech.api.util.GT_OreDictUnificator;
+import gregtech.api.util.GT_Utility;
+import gtPlusPlus.core.util.Utils;
+import gtPlusPlus.core.util.math.MathUtils;
+
+/**
+ * @author Gregorius Techneticies
+ * <p/>
+ * One Item for everything!
+ * <p/>
+ * This brilliant Item Class is used for automatically generating all possible variations of Material Items,
+ * like Dusts, Ingots, Gems, Plates and similar. It saves me a ton of work, when adding Items, because I always
+ * have to make a new Item SubType for each OreDict Prefix, when adding a new Material.
+ * <p/>
+ * As you can see, up to 32766 Items can be generated using this Class. And the last 766 Items can be custom
+ * defined, just to save space and MetaData.
+ * <p/>
+ * These Items can also have special RightClick abilities, electric Charge or even be set to become a Food alike
+ * Item.
+ */
+public abstract class Gregtech_MetaItem_X32 extends Gregtech_MetaItem {
+
+ protected final OrePrefixes[] mGeneratedPrefixList;
+
+ /**
+ * Creates the Item using these Parameters.
+ *
+ * @param aUnlocalized The Unlocalized Name of this Item.
+ * @param aGeneratedPrefixList The OreDict Prefixes you want to have generated.
+ */
+ public Gregtech_MetaItem_X32(final String aUnlocalized, final OrePrefixes... aGeneratedPrefixList) {
+ super(aUnlocalized, (short) 32000, (short) 766);
+ this.mGeneratedPrefixList = Arrays.copyOf(aGeneratedPrefixList, 32);
+
+ for (int i = 0; i < 32000; i++) {
+ final OrePrefixes tPrefix = this.mGeneratedPrefixList[i / 1000];
+ if (tPrefix == null) {
+ continue;
+ }
+ final Materials tMaterial = GregTech_API.sGeneratedMaterials[i % 1000];
+ if (tMaterial == null) {
+ continue;
+ }
+ if (this.doesMaterialAllowGeneration(tPrefix, tMaterial)) {
+ final ItemStack tStack = new ItemStack(this, 1, i);
+ GT_LanguageManager.addStringLocalization(
+ this.getUnlocalizedName(tStack) + ".name",
+ this.getDefaultLocalization(tPrefix, tMaterial, i));
+ GT_LanguageManager.addStringLocalization(
+ this.getUnlocalizedName(tStack) + ".tooltip",
+ tMaterial.getToolTip(tPrefix.mMaterialAmount / GT_Values.M));
+ if (tPrefix.mIsUnificatable) {
+ GT_OreDictUnificator.set(tPrefix, tMaterial, tStack);
+ } else {
+ GT_OreDictUnificator.registerOre(tPrefix.get(tMaterial), tStack);
+ }
+ if (((tPrefix == OrePrefixes.stick) || (tPrefix == OrePrefixes.wireFine))
+ && ((tMaterial == Materials.Lead) || (tMaterial == Materials.Tin)
+ || (tMaterial == Materials.SolderingAlloy))) {
+ GregTech_API.sSolderingMetalList.add(tStack);
+ }
+ }
+ }
+ }
+
+ /* ---------- OVERRIDEABLE FUNCTIONS ---------- */
+
+ /**
+ * @return the Color Modulation the Material is going to be rendered with.
+ */
+ @Override
+ public short[] getRGBa(final ItemStack aStack) {
+ final Materials tMaterial = GregTech_API.sGeneratedMaterials[this.getDamage(aStack) % 1000];
+ return tMaterial == null ? Materials._NULL.mRGBa : tMaterial.mRGBa;
+ }
+
+ /**
+ * @param aPrefix this can be null, you have to return false in that case
+ * @param aMaterial this can be null, you have to return false in that case
+ * @return if this Item should be generated and visible.
+ */
+ public boolean doesMaterialAllowGeneration(final OrePrefixes aPrefix, final Materials aMaterial) {
+ // You have to check for at least these Conditions in every Case! So add a super Call like the following for
+ // this before executing your Code:
+ // if (!super.doesMaterialAllowGeneration(aPrefix, aMaterial)) return false;
+ return (aPrefix != null) && (aMaterial != null) && aPrefix.doGenerateItem(aMaterial);
+ }
+
+ /* ---------- OVERRIDEABLE FUNCTIONS ---------- */
+
+ /**
+ * @param aPrefix the OreDict Prefix
+ * @param aMaterial the Material
+ * @param aMetaData a Index from [0 - 31999]
+ * @return the Localized Name when default LangFiles are used.
+ */
+ public String getDefaultLocalization(final OrePrefixes aPrefix, final Materials aMaterial, final int aMetaData) {
+ return aPrefix.getDefaultLocalNameForItem(aMaterial);
+ }
+
+ /**
+ * @param aMetaData a Index from [0 - 31999]
+ * @param aMaterial the Material
+ * @return an Icon Container for the Item Display.
+ */
+ public final IIconContainer getIconContainer(final int aMetaData, final Materials aMaterial) {
+ return (this.mGeneratedPrefixList[aMetaData / 1000] != null)
+ && (this.mGeneratedPrefixList[aMetaData / 1000].mTextureIndex >= 0)
+ ? aMaterial.mIconSet.mTextures[this.mGeneratedPrefixList[aMetaData / 1000].mTextureIndex]
+ : null;
+ }
+
+ /**
+ * @param aPrefix always != null
+ * @param aMaterial always != null
+ * @param aDoShowAllItems this is the Configuration Setting of the User, if he wants to see all the Stuff like Tiny
+ * Dusts or Crushed Ores as well.
+ * @return if this Item should be visible in NEI or Creative
+ */
+ public boolean doesShowInCreative(final OrePrefixes aPrefix, final Materials aMaterial,
+ final boolean aDoShowAllItems) {
+ return true;
+ }
+
+ /* ---------- INTERNAL OVERRIDES ---------- */
+
+ @Override
+ public ItemStack getContainerItem(final ItemStack aStack) {
+ final int aDamage = aStack.getItemDamage();
+ if ((aDamage < 32000) && (aDamage >= 0)) {
+ final Materials aMaterial = GregTech_API.sGeneratedMaterials[aDamage % 1000];
+ if ((aMaterial != null) && (aMaterial != Materials.Empty) && (aMaterial != Materials._NULL)) {
+ final OrePrefixes aPrefix = this.mGeneratedPrefixList[aDamage / 1000];
+ if (aPrefix != null) {
+ return GT_Utility.copyAmount(1, aPrefix.mContainerItem);
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public final IIconContainer getIconContainer(final int aMetaData) {
+ return GregTech_API.sGeneratedMaterials[aMetaData % 1000] == null ? null
+ : this.getIconContainer(aMetaData, GregTech_API.sGeneratedMaterials[aMetaData % 1000]);
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public final void getSubItems(final Item var1, final CreativeTabs aCreativeTab, final List aList) {
+ for (int i = 0; i < 32000; i++) {
+ if (this.doesMaterialAllowGeneration(
+ this.mGeneratedPrefixList[i / 1000],
+ GregTech_API.sGeneratedMaterials[i % 1000])
+ && this.doesShowInCreative(
+ this.mGeneratedPrefixList[i / 1000],
+ GregTech_API.sGeneratedMaterials[i % 1000],
+ GregTech_API.sDoShowAllItemsInCreative)) {
+ final ItemStack tStack = new ItemStack(this, 1, i);
+ this.isItemStackUsable(tStack);
+ aList.add(tStack);
+ }
+ }
+ super.getSubItems(var1, aCreativeTab, aList);
+ }
+
+ @Override
+ public final IIcon getIconFromDamage(final int aMetaData) {
+ if (aMetaData < 0) {
+ return null;
+ }
+ if (aMetaData < 32000) {
+ final Materials tMaterial = GregTech_API.sGeneratedMaterials[aMetaData % 1000];
+ if (tMaterial == null) {
+ return null;
+ }
+ final IIconContainer tIcon = this.getIconContainer(aMetaData, tMaterial);
+ if (tIcon != null) {
+ return tIcon.getIcon();
+ }
+ return null;
+ }
+ return (aMetaData - 32000) < this.mIconList.length ? this.mIconList[aMetaData - 32000][0] : null;
+ }
+
+ @Override
+ public int getItemStackLimit(final ItemStack aStack) {
+ final int tDamage = this.getDamage(aStack);
+ if ((tDamage < 32000) && (this.mGeneratedPrefixList[tDamage / 1000] != null)) {
+ return Math
+ .min(super.getItemStackLimit(aStack), this.mGeneratedPrefixList[tDamage / 1000].mDefaultStackSize);
+ }
+ return super.getItemStackLimit(aStack);
+ }
+
+ @Override
+ public int getColorFromItemStack(final ItemStack stack, int HEX_OxFFFFFF) {
+
+ int aMeta = stack.getItemDamage();
+ if (stack.getDisplayName()
+ .contains("Sodium")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(90, 90, 255);
+ } else if (stack.getDisplayName()
+ .contains("Cadmium")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(150, 150, 80);
+ } else if (stack.getDisplayName()
+ .contains("Lithium")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(225, 220, 255);
+ } else if (stack.getDisplayName()
+ .contains("Wrought")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(200, 180, 180);
+ } else if (stack.getDisplayName()
+ .contains("Bronze")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(255, 128, 0);
+ } else if (stack.getDisplayName()
+ .contains("Brass")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(255, 180, 0);
+ } else if (stack.getDisplayName()
+ .contains("Invar")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(180, 180, 120);
+ } else {
+ if (aMeta > 50 && aMeta != 150) {
+ HEX_OxFFFFFF = 0xffffff;
+ } else if (stack.getDisplayName()
+ .contains("ULV")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(200, 180, 180);
+ } else if (stack.getDisplayName()
+ .contains("LuV")) {
+ HEX_OxFFFFFF = 0xffffcc;
+ } else if (stack.getDisplayName()
+ .contains("ZPM")) {
+ HEX_OxFFFFFF = 0xffe600;
+ } else if (stack.getDisplayName()
+ .contains("UV")) {
+ HEX_OxFFFFFF = 0xffb300;
+ } else if (stack.getDisplayName()
+ .contains("MAX")) {
+ HEX_OxFFFFFF = Utils.rgbtoHexValue(
+ MathUtils.randInt(220, 250),
+ MathUtils.randInt(221, 251),
+ MathUtils.randInt(220, 250));
+ } else {
+ HEX_OxFFFFFF = 0xffffff;
+ }
+ }
+ return HEX_OxFFFFFF;
+ }
+}
diff --git a/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaTool.java b/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaTool.java
new file mode 100644
index 0000000000..fcfa5fae50
--- /dev/null
+++ b/src/main/java/gtPlusPlus/xmod/gregtech/api/items/Gregtech_MetaTool.java
@@ -0,0 +1,692 @@
+package gtPlusPlus.xmod.gregtech.api.items;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import net.minecraft.block.Block;
+import net.minecraft.enchantment.Enchantment;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.SharedMonsterAttributes;
+import net.minecraft.entity.item.EntityMinecart;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.potion.Potion;
+import net.minecraft.stats.AchievementList;
+import net.minecraft.stats.StatList;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.MathHelper;
+import net.minecraft.world.World;
+import net.minecraftforge.event.world.BlockEvent;
+
+import buildcraft.api.tools.IToolWrench;
+import cpw.mods.fml.common.Optional;
+import gregtech.api.enchants.Enchantment_Radioactivity;
+import gregtech.api.enums.Materials;
+import gregtech.api.enums.Mods;
+import gregtech.api.interfaces.IDamagableItem;
+import gregtech.api.interfaces.IToolStats;
+import gregtech.api.items.GT_MetaGenerated_Tool;
+import gregtech.api.util.GT_ModHandler;
+import gregtech.api.util.GT_Utility;
+import gtPlusPlus.core.creative.AddToCreativeTab;
+import gtPlusPlus.xmod.gregtech.api.interfaces.internal.Interface_ToolStats;
+import mods.railcraft.api.core.items.IToolCrowbar;
+
+/**
+ * This is an example on how you can create a Tool ItemStack, in this case a Bismuth Wrench:
+ * GT_MetaGenerated_Tool.sInstances.get("gt.metatool.01").getToolWithStats(16, 1, Materials.Bismuth, Materials.Bismuth,
+ * null);
+ */
+@Optional.InterfaceList({
+ @Optional.Interface(iface = "forestry.api.arboriculture.IToolGrafter", modid = Mods.Names.FORESTRY),
+ @Optional.Interface(iface = "mods.railcraft.api.core.items.IToolCrowbar", modid = Mods.Names.RAILCRAFT),
+ @Optional.Interface(iface = "buildcraft.api.tools.IToolWrench", modid = "BuildCraft"),
+ @Optional.Interface(iface = "crazypants.enderio.api.tool.ITool", modid = Mods.Names.ENDER_I_O) })
+public abstract class Gregtech_MetaTool extends GT_MetaGenerated_Tool
+ implements IDamagableItem, IToolCrowbar, IToolWrench {
+
+ /**
+ * All instances of this Item Class are listed here. This gets used to register the Renderer to all Items of this
+ * Type, if useStandardMetaItemRenderer() returns true.
+ * <p/>
+ * You can also use the unlocalized Name gotten from getUnlocalizedName() as Key if you want to get a specific Item.
+ */
+ public static final HashMap<String, Gregtech_MetaTool> sInstances = new HashMap<>();
+
+ /* ---------- CONSTRUCTOR AND MEMBER VARIABLES ---------- */
+
+ public final HashMap<Short, IToolStats> mToolStats = new HashMap<>();
+
+ /**
+ * Creates the Item using these Parameters.
+ *
+ * @param aUnlocalized The Unlocalized Name of this Item.
+ */
+ public Gregtech_MetaTool(final String aUnlocalized) {
+ super(aUnlocalized);
+ GT_ModHandler.registerBoxableItemToToolBox(new ItemStack(this));
+ this.setCreativeTab(AddToCreativeTab.tabMachines);
+ this.setMaxStackSize(1);
+ sInstances.put(this.getUnlocalizedName(), this);
+ }
+
+ /**
+ * Called by the Block Harvesting Event within the GT_Proxy
+ */
+ @Override
+ public void onHarvestBlockEvent(final ArrayList<ItemStack> aDrops, final ItemStack aStack,
+ final EntityPlayer aPlayer, final Block aBlock, final int aX, final int aY, final int aZ, final byte aMetaData,
+ final int aFortune, final boolean aSilkTouch, final BlockEvent.HarvestDropsEvent aEvent) {
+ final IToolStats tStats = this.getToolStats(aStack);
+ if (this.isItemStackUsable(aStack) && (this.getDigSpeed(aStack, aBlock, aMetaData) > 0.0F)) {
+ this.doDamage(
+ aStack,
+ tStats.convertBlockDrops(
+ aDrops,
+ aStack,
+ aPlayer,
+ aBlock,
+ aX,
+ aY,
+ aZ,
+ aMetaData,
+ aFortune,
+ aSilkTouch,
+ aEvent) * tStats.getToolDamagePerDropConversion());
+ }
+ }
+
+ @Override
+ public boolean onLeftClickEntity(final ItemStack aStack, final EntityPlayer aPlayer, final Entity aEntity) {
+ final IToolStats tStats = this.getToolStats(aStack);
+ if ((tStats == null) || !this.isItemStackUsable(aStack)) {
+ return true;
+ }
+ GT_Utility.doSoundAtClient(tStats.getEntityHitSound(), 1, 1.0F);
+ if (super.onLeftClickEntity(aStack, aPlayer, aEntity)) {
+ return true;
+ }
+ if (aEntity.canAttackWithItem() && !aEntity.hitByEntity(aPlayer)) {
+ final float tMagicDamage = tStats.getMagicDamageAgainstEntity(
+ aEntity instanceof EntityLivingBase
+ ? EnchantmentHelper.getEnchantmentModifierLiving(aPlayer, (EntityLivingBase) aEntity)
+ : 0.0F,
+ aEntity,
+ aStack,
+ aPlayer);
+ float tDamage = tStats.getNormalDamageAgainstEntity(
+ (float) aPlayer.getEntityAttribute(SharedMonsterAttributes.attackDamage)
+ .getAttributeValue() + this.getToolCombatDamage(aStack),
+ aEntity,
+ aStack,
+ aPlayer);
+ if ((tDamage + tMagicDamage) > 0.0F) {
+ final boolean tCriticalHit = (aPlayer.fallDistance > 0.0F) && !aPlayer.onGround
+ && !aPlayer.isOnLadder()
+ && !aPlayer.isInWater()
+ && !aPlayer.isPotionActive(Potion.blindness)
+ && (aPlayer.ridingEntity == null)
+ && (aEntity instanceof EntityLivingBase);
+ if (tCriticalHit && (tDamage > 0.0F)) {
+ tDamage *= 1.5F;
+ }
+ tDamage += tMagicDamage;
+ if (aEntity.attackEntityFrom(tStats.getDamageSource(aPlayer, aEntity), tDamage)) {
+ if (aEntity instanceof EntityLivingBase) {
+ aEntity.setFire(EnchantmentHelper.getFireAspectModifier(aPlayer) * 4);
+ }
+ final int tKnockcack = (aPlayer.isSprinting() ? 1 : 0) + (aEntity instanceof EntityLivingBase
+ ? EnchantmentHelper.getKnockbackModifier(aPlayer, (EntityLivingBase) aEntity)
+ : 0);
+ if (tKnockcack > 0) {
+ aEntity.addVelocity(
+ -MathHelper.sin((aPlayer.rotationYaw * (float) Math.PI) / 180.0F) * tKnockcack * 0.5F,
+ 0.1D,
+ MathHelper.cos((aPlayer.rotationYaw * (float) Math.PI) / 180.0F) * tKnockcack * 0.5F);
+ aPlayer.motionX *= 0.6D;
+ aPlayer.motionZ *= 0.6D;
+ aPlayer.setSprinting(false);
+ }
+ if (tCriticalHit) {
+ aPlayer.onCriticalHit(aEntity);
+ }
+ if (tMagicDamage > 0.0F) {
+ aPlayer.onEnchantmentCritical(aEntity);
+ }
+ if (tDamage >= 18.0F) {
+ aPlayer.triggerAchievement(AchievementList.overkill);
+ }
+ aPlayer.setLastAttacker(aEntity);
+ if (aEntity instanceof EntityLivingBase) {
+ EnchantmentHelper.func_151384_a((EntityLivingBase) aEntity, aPlayer);
+ }
+ EnchantmentHelper.func_151385_b(aPlayer, aEntity);
+ if (aEntity instanceof EntityLivingBase) {
+ aPlayer.addStat(StatList.damageDealtStat, Math.round(tDamage * 10.0F));
+ }
+ aEntity.hurtResistantTime = Math
+ .max(1, tStats.getHurtResistanceTime(aEntity.hurtResistantTime, aEntity));
+ aPlayer.addExhaustion(0.3F);
+ this.doDamage(aStack, tStats.getToolDamagePerEntityAttack());
+ }
+ }
+ }
+ if (aStack.stackSize <= 0) {
+ aPlayer.destroyCurrentEquippedItem();
+ }
+ return true;
+ }
+
+ @Override
+ public ItemStack onItemRightClick(final ItemStack aStack, final World aWorld, final EntityPlayer aPlayer) {
+ final IToolStats tStats = this.getToolStats(aStack);
+ if ((tStats != null) && tStats.canBlock()) {
+ aPlayer.setItemInUse(aStack, 72000);
+ }
+ return super.onItemRightClick(aStack, aWorld, aPlayer);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void addAdditionalToolTips(final List aList, final ItemStack aStack) {
+ final long tMaxDamage = getToolMaxDamage(aStack);
+ final Materials tMaterial = getPrimaryMaterial(aStack);
+ final IToolStats tStats = this.getToolStats(aStack);
+ final int tOffset = this.getElectricStats(aStack) != null ? 2 : 1;
+ if (tStats != null) {
+ final String name = aStack.getUnlocalizedName();
+ if (name.equals("gt.metatool.01.170") || name.equals("gt.metatool.01.172")
+ || name.equals("gt.metatool.01.174")
+ || name.equals("gt.metatool.01.176")) {
+ aList.add(
+ tOffset + 0,
+ EnumChatFormatting.WHITE + "Durability: "
+ + EnumChatFormatting.GREEN
+ + (tMaxDamage - getToolDamage(aStack))
+ + " / "
+ + tMaxDamage
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 1,
+ EnumChatFormatting.WHITE + tMaterial.mDefaultLocalName
+ + EnumChatFormatting.YELLOW
+ + " lvl "
+ + this.getHarvestLevel(aStack, "")
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 2,
+ EnumChatFormatting.WHITE + "Turbine Efficency: "
+ + EnumChatFormatting.BLUE
+ + (50.0F + (10.0F * this.getToolCombatDamage(aStack)))
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 3,
+ EnumChatFormatting.WHITE + "Optimal Steam flow: "
+ + EnumChatFormatting.LIGHT_PURPLE
+ + Math.max(
+ Float.MIN_NORMAL,
+ tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * 1000)
+ + EnumChatFormatting.GRAY
+ + "L/sec");
+ aList.add(
+ tOffset + 3,
+ EnumChatFormatting.WHITE + "Optimal Gas flow(EU burnvalue per tick): "
+ + EnumChatFormatting.LIGHT_PURPLE
+ + Math.max(
+ Float.MIN_NORMAL,
+ tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * 25)
+ + EnumChatFormatting.GRAY
+ + "EU/t");
+ aList.add(
+ tOffset + 3,
+ EnumChatFormatting.WHITE + "Optimal Plasma flow(Plasma energyvalue per tick): "
+ + EnumChatFormatting.LIGHT_PURPLE
+ + Math.max(
+ Float.MIN_NORMAL,
+ tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * 1000)
+ + EnumChatFormatting.GRAY
+ + "EU/t");
+
+ } else {
+ aList.add(
+ tOffset + 0,
+ EnumChatFormatting.WHITE + "Durability: "
+ + EnumChatFormatting.GREEN
+ + (tMaxDamage - getToolDamage(aStack))
+ + " / "
+ + tMaxDamage
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 1,
+ EnumChatFormatting.WHITE + tMaterial.mDefaultLocalName
+ + EnumChatFormatting.YELLOW
+ + " lvl "
+ + this.getHarvestLevel(aStack, "")
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 2,
+ EnumChatFormatting.WHITE + "Attack Damage: "
+ + EnumChatFormatting.BLUE
+ + this.getToolCombatDamage(aStack)
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 3,
+ EnumChatFormatting.WHITE + "Mining Speed: "
+ + EnumChatFormatting.LIGHT_PURPLE
+ + Math
+ .max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed)
+ + EnumChatFormatting.GRAY);
+ }
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void addAdditionalToolTips(final List aList, final ItemStack aStack, final EntityPlayer aPlayer) {
+ final long tMaxDamage = getToolMaxDamage(aStack);
+ final Materials tMaterial = getPrimaryMaterial(aStack);
+ final IToolStats tStats = this.getToolStats(aStack);
+ final int tOffset = this.getElectricStats(aStack) != null ? 2 : 1;
+ if (tStats != null) {
+ final String name = aStack.getUnlocalizedName();
+ if (name.equals("gt.metatool.01.170") || name.equals("gt.metatool.01.172")
+ || name.equals("gt.metatool.01.174")
+ || name.equals("gt.metatool.01.176")) {
+ aList.add(
+ tOffset + 0,
+ EnumChatFormatting.WHITE + "Durability: "
+ + EnumChatFormatting.GREEN
+ + (tMaxDamage - getToolDamage(aStack))
+ + " / "
+ + tMaxDamage
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 1,
+ EnumChatFormatting.WHITE + tMaterial.mDefaultLocalName
+ + EnumChatFormatting.YELLOW
+ + " lvl "
+ + this.getHarvestLevel(aStack, "")
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 2,
+ EnumChatFormatting.WHITE + "Turbine Efficency: "
+ + EnumChatFormatting.BLUE
+ + (50.0F + (10.0F * this.getToolCombatDamage(aStack)))
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 3,
+ EnumChatFormatting.WHITE + "Optimal Steam flow: "
+ + EnumChatFormatting.LIGHT_PURPLE
+ + Math.max(
+ Float.MIN_NORMAL,
+ tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * 1000)
+ + EnumChatFormatting.GRAY
+ + "L/sec");
+ aList.add(
+ tOffset + 3,
+ EnumChatFormatting.WHITE + "Optimal Gas flow(EU burnvalue per tick): "
+ + EnumChatFormatting.LIGHT_PURPLE
+ + Math.max(
+ Float.MIN_NORMAL,
+ tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * 50)
+ + EnumChatFormatting.GRAY
+ + "EU/t");
+ aList.add(
+ tOffset + 3,
+ EnumChatFormatting.WHITE + "Optimal Plasma flow(Plasma energyvalue per tick): "
+ + EnumChatFormatting.LIGHT_PURPLE
+ + Math.max(
+ Float.MIN_NORMAL,
+ tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed * 1000)
+ + EnumChatFormatting.GRAY
+ + "EU/t");
+
+ } else {
+ aList.add(
+ tOffset + 0,
+ EnumChatFormatting.WHITE + "Durability: "
+ + EnumChatFormatting.GREEN
+ + (tMaxDamage - getToolDamage(aStack))
+ + " / "
+ + tMaxDamage
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 1,
+ EnumChatFormatting.WHITE + tMaterial.mDefaultLocalName
+ + EnumChatFormatting.YELLOW
+ + " lvl "
+ + this.getHarvestLevel(aStack, "")
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 2,
+ EnumChatFormatting.WHITE + "Attack Damage: "
+ + EnumChatFormatting.BLUE
+ + this.getToolCombatDamage(aStack)
+ + EnumChatFormatting.GRAY);
+ aList.add(
+ tOffset + 3,
+ EnumChatFormatting.WHITE + "Mining Speed: "
+ + EnumChatFormatting.LIGHT_PURPLE
+ + Math
+ .max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed)
+ + EnumChatFormatting.GRAY);
+ NBTTagCompound aNBT = aStack.getTagCompound();
+ if (aNBT != null) {
+ aNBT = aNBT.getCompoundTag("GT.ToolStats");
+ if ((aNBT != null) && aNBT.hasKey("Heat")) {
+ int tHeat = aNBT.getInteger("Heat");
+ final long tWorldTime = aPlayer.getEntityWorld()
+ .getWorldTime();
+ if (aNBT.hasKey("HeatTime")) {
+ final long tHeatTime = aNBT.getLong("HeatTime");
+ if (tWorldTime > (tHeatTime + 10)) {
+ tHeat = (int) (tHeat - ((tWorldTime - tHeatTime) / 10));
+ if ((tHeat < 300) && (tHeat > -10000)) {
+ tHeat = 300;
+ }
+ }
+ aNBT.setLong("HeatTime", tWorldTime);
+ if (tHeat > -10000) {
+ aNBT.setInteger("Heat", tHeat);
+ }
+ }
+
+ aList.add(
+ tOffset + 3,
+ EnumChatFormatting.RED + "Heat: "
+ + aNBT.getInteger("Heat")
+ + " K"
+ + EnumChatFormatting.GRAY);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public Long[] getFluidContainerStats(final ItemStack aStack) {
+ return null;
+ }
+
+ @Override
+ public Long[] getElectricStats(final ItemStack aStack) {
+ NBTTagCompound aNBT = aStack.getTagCompound();
+ if (aNBT != null) {
+ aNBT = aNBT.getCompoundTag("GT.ToolStats");
+ if ((aNBT != null) && aNBT.getBoolean("Electric")) {
+ return new Long[] { aNBT.getLong("MaxCharge"), aNBT.getLong("Voltage"), aNBT.getLong("Tier"),
+ aNBT.getLong("SpecialData") };
+ }
+ }
+ return new Long[] {};
+ }
+
+ @Override
+ public float getToolCombatDamage(final ItemStack aStack) {
+ final IToolStats tStats = this.getToolStats(aStack);
+ if (tStats == null) {
+ return 0;
+ }
+ return tStats.getBaseDamage() + getPrimaryMaterial(aStack).mToolQuality;
+ }
+
+ @Override
+ public float getDigSpeed(final ItemStack aStack, final Block aBlock, final int aMetaData) {
+ if (!this.isItemStackUsable(aStack)) {
+ return 0.0F;
+ }
+ final IToolStats tStats = this.getToolStats(aStack);
+ if ((tStats == null) || (Math.max(0, this.getHarvestLevel(aStack, "")) < aBlock.getHarvestLevel(aMetaData))) {
+ return 0.0F;
+ }
+ return tStats.isMinableBlock(aBlock, (byte) aMetaData)
+ ? Math.max(Float.MIN_NORMAL, tStats.getSpeedMultiplier() * getPrimaryMaterial(aStack).mToolSpeed)
+ : 0.0F;
+ }
+
+ @Override
+ public boolean onBlockDestroyed(final ItemStack aStack, final World aWorld, final Block aBlock, final int aX,
+ final int aY, final int aZ, final EntityLivingBase aPlayer) {
+ if (!this.isItemStackUsable(aStack)) {
+ return false;
+ }
+ final IToolStats tStats = this.getToolStats(aStack);
+ if (tStats == null) {
+ return false;
+ }
+ GT_Utility.doSoundAtClient(tStats.getMiningSound(), 1, 1.0F);
+ this.doDamage(
+ aStack,
+ (int) Math.max(1, aBlock.getBlockHardness(aWorld, aX, aY, aZ) * tStats.getToolDamagePerBlockBreak()));
+ return this.getDigSpeed(aStack, aBlock, aWorld.getBlockMetadata(aX, aY, aZ)) > 0.0F;
+ }
+
+ private ItemStack getContainerItem(ItemStack aStack, final boolean playSound) {
+ if (!this.isItemStackUsable(aStack)) {
+ return null;
+ }
+ aStack = GT_Utility.copyAmount(1, aStack);
+ final IToolStats tStats = this.getToolStats(aStack);
+ if (tStats == null) {
+ return null;
+ }
+ this.doDamage(aStack, tStats.getToolDamagePerContainerCraft());
+ aStack = aStack.stackSize > 0 ? aStack : null;
+ if (playSound) {}
+ return aStack;
+ }
+
+ @Override
+ public Interface_ToolStats getToolStats(final ItemStack aStack) {
+ this.isItemStackUsable(aStack);
+ return this.getToolStatsInternal(aStack);
+ }
+
+ private Interface_ToolStats getToolStatsInternal(final ItemStack aStack) {
+ return (Interface_ToolStats) (aStack == null ? null : this.mToolStats.get((short) aStack.getItemDamage()));
+ }
+
+ @Override
+ public boolean canWhack(final EntityPlayer aPlayer, final ItemStack aStack, final int aX, final int aY,
+ final int aZ) {
+ if (!this.isItemStackUsable(aStack)) {
+ return false;
+ }
+ final IToolStats tStats = this.getToolStats(aStack);
+ return (tStats != null) && tStats.isCrowbar();
+ }
+
+ @Override
+ public void onWhack(final EntityPlayer aPlayer, final ItemStack aStack, final int aX, final int aY, final int aZ) {
+ final IToolStats tStats = this.getToolStats(aStack);
+ if (tStats != null) {
+ this.doDamage(aStack, tStats.getToolDamagePerEntityAttack());
+ }
+ }
+
+ @Override
+ public boolean canWrench(final EntityPlayer player, final int x, final int y, final int z) {
+ // System.out.println("canWrench");
+ if (player == null) {
+ return false;
+ }
+ if (player.getCurrentEquippedItem() == null) {
+ return false;
+ }
+ if (!this.isItemStackUsable(player.getCurrentEquippedItem())) {
+ return false;
+ }
+ final Interface_ToolStats tStats = this.getToolStats(player.getCurrentEquippedItem());
+ return (tStats != null) && tStats.isWrench();
+ }
+
+ @Override
+ public void wrenchUsed(final EntityPlayer player, final int x, final int y, final int z) {
+ if (player == null) {
+ return;
+ }
+ if (player.getCurrentEquippedItem() == null) {
+ return;
+ }
+ final IToolStats tStats = this.getToolStats(player.getCurrentEquippedItem());
+ if (tStats != null) {
+ this.doDamage(player.getCurrentEquippedItem(), tStats.getToolDamagePerEntityAttack());
+ }
+ }
+
+ @Override
+ public boolean canLink(final EntityPlayer aPlayer, final ItemStack aStack, final EntityMinecart cart) {
+ if (!this.isItemStackUsable(aStack)) {
+ return false;
+ }
+ final IToolStats tStats = this.getToolStats(aStack);
+ return (tStats != null) && tStats.isCrowbar();
+ }
+
+ @Override
+ public void onLink(final EntityPlayer aPlayer, final ItemStack aStack, final EntityMinecart cart) {
+ final IToolStats tStats = this.getToolStats(aStack);
+ if (tStats != null) {
+ this.doDamage(aStack, tStats.getToolDamagePerEntityAttack());
+ }
+ }
+
+ @Override
+ public boolean canBoost(final EntityPlayer aPlayer, final ItemStack aStack, final EntityMinecart cart) {
+ if (!this.isItemStackUsable(aStack)) {
+ return false;
+ }
+ final IToolStats tStats = this.getToolStats(aStack);
+ return (tStats != null) && tStats.isCrowbar();
+ }
+
+ @Override
+ public void onBoost(final EntityPlayer aPlayer, final ItemStack aStack, final EntityMinecart cart) {
+ final IToolStats tStats = this.getToolStats(aStack);
+ if (tStats != null) {
+ this.doDamage(aStack, tStats.getToolDamagePerEntityAttack());
+ }
+ }
+
+ @Override
+ public void onCreated(final ItemStack aStack, final World aWorld, final EntityPlayer aPlayer) {
+ final IToolStats tStats = this.getToolStats(aStack);
+ if ((tStats != null) && (aPlayer != null)) {
+ tStats.onToolCrafted(aStack, aPlayer);
+ }
+ super.onCreated(aStack, aWorld, aPlayer);
+ }
+
+ @Override
+ public boolean isFull3D() {
+ return true;
+ }
+
+ @Override
+ public boolean isItemStackUsable(final ItemStack aStack) {
+ final IToolStats tStats = this.getToolStatsInternal(aStack);
+ if (((aStack.getItemDamage() % 2) == 1) || (tStats == null)) {
+ final NBTTagCompound aNBT = aStack.getTagCompound();
+ if (aNBT != null) {
+ aNBT.removeTag("ench");
+ }
+ return false;
+ }
+ final Materials aMaterial = getPrimaryMaterial(aStack);
+ final HashMap<Integer, Integer> tMap = new HashMap<>(), tResult = new HashMap<>();
+ if (aMaterial.mEnchantmentTools != null) {
+ tMap.put(aMaterial.mEnchantmentTools.effectId, (int) aMaterial.mEnchantmentToolsLevel);
+ if (aMaterial.mEnchantmentTools == Enchantment.fortune) {
+ tMap.put(Enchantment.looting.effectId, (int) aMaterial.mEnchantmentToolsLevel);
+ }
+ if (aMaterial.mEnchantmentTools == Enchantment.knockback) {
+ tMap.put(Enchantment.power.effectId, (int) aMaterial.mEnchantmentToolsLevel);
+ }
+ if (aMaterial.mEnchantmentTools == Enchantment.fireAspect) {
+ tMap.put(Enchantment.flame.effectId, (int) aMaterial.mEnchantmentToolsLevel);
+ }
+ }
+ final Enchantment[] tEnchants = tStats.getEnchantments(aStack);
+ final int[] tLevels = tStats.getEnchantmentLevels(aStack);
+ for (int i = 0; i < tEnchants.length; i++) {
+ if (tLevels[i] > 0) {
+ final Integer tLevel = tMap.get(tEnchants[i].effectId);
+ tMap.put(
+ tEnchants[i].effectId,
+ tLevel == null ? tLevels[i] : tLevel == tLevels[i] ? tLevel + 1 : Math.max(tLevel, tLevels[i]));
+ }
+ }
+ for (final Entry<Integer, Integer> tEntry : tMap.entrySet()) {
+ if ((tEntry.getKey() == 33) || ((tEntry.getKey() == 20) && (tEntry.getValue() > 2))
+ || (tEntry.getKey() == Enchantment_Radioactivity.INSTANCE.effectId)) {
+ tResult.put(tEntry.getKey(), tEntry.getValue());
+ } else {
+ switch (Enchantment.enchantmentsList[tEntry.getKey()].type) {
+ case weapon:
+ if (tStats.isWeapon()) {
+ tResult.put(tEntry.getKey(), tEntry.getValue());
+ }
+ break;
+ case all:
+ tResult.put(tEntry.getKey(), tEntry.getValue());
+ break;
+ case armor:
+ case armor_feet:
+ case armor_head:
+ case armor_legs:
+ case armor_torso:
+ break;
+ case bow:
+ if (tStats.isRangedWeapon()) {
+ tResult.put(tEntry.getKey(), tEntry.getValue());
+ }
+ break;
+ case breakable:
+ break;
+ case fishing_rod:
+ break;
+ case digger:
+ if (tStats.isMiningTool()) {
+ tResult.put(tEntry.getKey(), tEntry.getValue());
+ }
+ break;
+ }
+ }
+ }
+ EnchantmentHelper.setEnchantments(tResult, aStack);
+ return true;
+ }
+
+ @Override
+ public short getChargedMetaData(final ItemStack aStack) {
+ return (short) (aStack.getItemDamage() - (aStack.getItemDamage() % 2));
+ }
+
+ @Override
+ public short getEmptyMetaData(final ItemStack aStack) {
+ final NBTTagCompound aNBT = aStack.getTagCompound();
+ if (aNBT != null) {
+ aNBT.removeTag("ench");
+ }
+ return (short) ((aStack.getItemDamage() + 1) - (aStack.getItemDamage() % 2));
+ }
+
+ @Override
+ public int getItemEnchantability() {
+ return 0;
+ }
+
+ @Override
+ public boolean isBookEnchantable(final ItemStack aStack, final ItemStack aBook) {
+ return false;
+ }
+
+ @Override
+ public boolean getIsRepairable(final ItemStack aStack, final ItemStack aMaterial) {
+ return false;
+ }
+}