diff options
author | Raven Szewczyk <git@eigenraven.me> | 2024-05-24 19:50:35 +0100 |
---|---|---|
committer | Raven Szewczyk <git@eigenraven.me> | 2024-05-24 19:50:35 +0100 |
commit | 6d1b2216464d4dad449ac6fcfec476832224a55e (patch) | |
tree | 526a0c15f7056313c80e6c0386e025e9b3f61781 /src/main/java/gtPlusPlus/xmod/gregtech/api/items | |
parent | b5d35f40afa606ed1b07061dad82e0521a59c186 (diff) | |
download | GT5-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')
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; + } +} |