package eiteam.esteemedinnovation.armor.exosuit.steam; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import eiteam.esteemedinnovation.api.Constants; import eiteam.esteemedinnovation.api.SteamChargable; import eiteam.esteemedinnovation.api.exosuit.*; import eiteam.esteemedinnovation.armor.ArmorModule; import eiteam.esteemedinnovation.commons.Config; import eiteam.esteemedinnovation.commons.EsteemedInnovation; import eiteam.esteemedinnovation.storage.steam.BlockTankItem; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.model.ModelBiped; import net.minecraft.client.resources.I18n; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.ai.attributes.AttributeModifier; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.oredict.OreDictionary; import org.apache.commons.lang3.tuple.Pair; import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ItemSteamExosuitArmor extends ItemArmor implements ExosuitArmor, SteamChargable { public ItemSteamExosuitArmor(EntityEquipmentSlot slot, ArmorMaterial mat) { super(mat, 1, slot); setMaxDamage(0); } @Override public boolean getIsRepairable(ItemStack toRepair, ItemStack repair) { return false; } @Override public ResourceLocation getItemIconResource() { return new ResourceLocation(EsteemedInnovation.MOD_ID, "items/steam_exosuit_" + armorType.getName()); } @Override @SideOnly(Side.CLIENT) public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armorSlot, ModelBiped defaultModel) { if (!(entityLiving instanceof EntityPlayer)) { return null; } ModelSteamExosuit modelExosuit = (ModelSteamExosuit) SteamExosuitModelCache.INSTANCE.getModel((EntityPlayer) entityLiving, armorSlot); boolean head = armorSlot == EntityEquipmentSlot.HEAD; modelExosuit.bipedHead.showModel = head; modelExosuit.bipedHeadwear.showModel = head; boolean body = armorSlot == EntityEquipmentSlot.CHEST; boolean legs = armorSlot == EntityEquipmentSlot.LEGS; modelExosuit.bipedBody.showModel = body || legs; modelExosuit.bipedRightArm.showModel = body; modelExosuit.bipedLeftArm.showModel = body; boolean feet = armorSlot == EntityEquipmentSlot.FEET; modelExosuit.bipedRightLeg.showModel = legs || feet; modelExosuit.bipedLeftLeg.showModel = legs || feet; return modelExosuit; } @Override public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot) { if (armor.hasTagCompound()) { if (armor.getTagCompound().hasKey("Plate")) { ExosuitPlate plate = UtilPlates.getPlate(armor.getTagCompound().getString("Plate")); return new ArmorProperties(0, plate.getDamageReductionAmount(armorType, source) / 25.0D, ItemArmor.ArmorMaterial.IRON.getDurability(armorType)); } } return new ArmorProperties(0, ItemArmor.ArmorMaterial.IRON.getDamageReductionAmount(armorType) / 25.0D, ItemArmor.ArmorMaterial.IRON.getDurability(armorType)); } @Override public double getDurabilityForDisplay(ItemStack stack) { updateSteamNBT(stack); //return 0.9D; return 1.0D - (stack.getTagCompound().getInteger("SteamStored") / (double) stack.getTagCompound().getInteger("SteamCapacity")); } @Override public boolean showDurabilityBar(ItemStack stack) { if (!stack.hasTagCompound()) { stack.setTagCompound(new NBTTagCompound()); } if (!stack.getTagCompound().hasKey("SteamCapacity")) { stack.getTagCompound().setInteger("SteamCapacity", 0); } return stack.getTagCompound().getInteger("SteamCapacity") > 0; } @Override public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot) { if (armor.hasTagCompound()) { if (armor.getTagCompound().hasKey("Plate")) { ExosuitPlate plate = UtilPlates.getPlate(armor.getTagCompound().getString("Plate")); return plate.getDamageReductionAmount(armorType, DamageSource.generic); } } return ItemArmor.ArmorMaterial.LEATHER.getDamageReductionAmount(armorType); } @Override public void damageArmor(EntityLivingBase entity, ItemStack stack, DamageSource source, int damage, int slot) { if (armorType == EntityEquipmentSlot.CHEST) { drainSteam(stack, damage * 40, entity); } } @SuppressWarnings("unchecked") @Override public Pair<Integer, Integer>[] engineerCoordinates() { switch (armorType) { case HEAD: { return new Pair[] { Pair.of(1, 19), Pair.of(1, 1), Pair.of(39, 16), Pair.of(59, 36) }; } case CHEST: { return new Pair[] { Pair.of(1, 19), Pair.of(1, 1), Pair.of(49, 33), Pair.of(75, 26), Pair.of(1, 37) }; } case LEGS: { return new Pair[] { Pair.of(1, 19), Pair.of(1, 1), Pair.of(60, 12), Pair.of(37, 40) }; } case FEET: { return new Pair[] { Pair.of(1, 19), Pair.of(1, 1), Pair.of(60, 18), Pair.of(28, 40) }; } default: { break; } } return new Pair[] { Pair.of(49, 26) }; } public boolean hasPlates(ItemStack me) { if (getStackInSlot(me, 1) != null) { if (!me.hasTagCompound()) { me.setTagCompound(new NBTTagCompound()); } ItemStack clone = getStackInSlot(me, 1).copy(); clone.stackSize = 1; if (UtilPlates.getPlate(clone) != null) { me.getTagCompound().setString("Plate", UtilPlates.getPlate(clone).getIdentifier()); return true; } else { UtilPlates.removePlate(me); return false; } } else { if (!me.hasTagCompound()) { me.setTagCompound(new NBTTagCompound()); } UtilPlates.removePlate(me); return false; } } @Override public boolean hasUpgrade(ItemStack me, Item check) { if (me != null && check != null && me.hasTagCompound() && me.getTagCompound().hasKey("Upgrades")) { for (int i = 1; i < 10; i++) { if (me.getTagCompound().getCompoundTag("Upgrades").hasKey(Integer.toString(i))) { ItemStack stack = ItemStack.loadItemStackFromNBT(me.getTagCompound().getCompoundTag("Upgrades").getCompoundTag(Integer.toString(i))); if (stack.getItem() == check) { return true; } } } } return false; } @Override public ItemStack getStackInSlot(ItemStack me, int var1) { if (me.hasTagCompound()) { if (me.getTagCompound().hasKey("Upgrades")) { if (me.getTagCompound().getCompoundTag("Upgrades").hasKey(Integer.toString(var1))) { return ItemStack.loadItemStackFromNBT(me.getTagCompound().getCompoundTag("Upgrades").getCompoundTag(Integer.toString(var1))); } } } return null; } @Override public void setInventorySlotContents(ItemStack me, int var1, ItemStack stack) { if (!me.hasTagCompound()) { me.setTagCompound(new NBTTagCompound()); } if (!me.getTagCompound().hasKey("Upgrades")) { me.getTagCompound().setTag("Upgrades", new NBTTagCompound()); } if (me.getTagCompound().getCompoundTag("Upgrades").hasKey(Integer.toString(var1))) { me.getTagCompound().getCompoundTag("Upgrades").removeTag(Integer.toString(var1)); } NBTTagCompound stc = new NBTTagCompound(); if (stack != null) { stack.writeToNBT(stc); me.getTagCompound().getCompoundTag("Upgrades").setTag(Integer.toString(var1), stc); if (var1 == 5 && armorType == EntityEquipmentSlot.CHEST) { me.getTagCompound().setInteger("SteamStored", 0); me.getTagCompound().setInteger("SteamCapacity", ((ExosuitTank) stack.getItem()).getStorage(me)); if (stack.getItem() instanceof BlockTankItem && stack.getItemDamage() == 1) { me.getTagCompound().setInteger("SteamStored", me.getTagCompound().getInteger("SteamCapacity")); } } } hasPlates(me); } @Override public boolean isItemValidForSlot(ItemStack me, int var1, ItemStack var2) { return true; } @Override public ItemStack decrStackSize(ItemStack me, int var1, int var2) { if (getStackInSlot(me, var1) != null) { ItemStack itemstack; if (getStackInSlot(me, var1).stackSize <= var2) { itemstack = getStackInSlot(me, var1); setInventorySlotContents(me, var1, null); hasPlates(me); return itemstack; } else { ItemStack stack2 = getStackInSlot(me, var1); itemstack = stack2.splitStack(var2); setInventorySlotContents(me, var1, stack2); if (getStackInSlot(me, var1).stackSize == 0) { setInventorySlotContents(me, var1, null); } hasPlates(me); return itemstack; } } else { return null; } } @Override public boolean canPutInSlot(ItemStack me, int slotNum, ItemStack upgrade) { if (slotNum == 0) { ItemStack clone = upgrade.copy(); clone.stackSize = 1; return UtilPlates.getPlate(clone) != null; } if (upgrade.getItem() instanceof ExosuitUpgrade) { ExosuitUpgrade upgradeItem = (ExosuitUpgrade) upgrade.getItem(); ExosuitSlot upgradeSlot = upgradeItem.getSlot(); return (upgradeSlot.getArmorPiece() == armorType && upgradeSlot.getEngineeringSlot() == slotNum) || (upgradeItem.getSlot() == ExosuitSlot.VANITY && upgradeSlot.getEngineeringSlot() == slotNum); } else if (slotNum == ExosuitSlot.VANITY.getEngineeringSlot()) { // TODO: Optimize by using a static list of dye oredicts generated at load time (OreDictHelper). int[] ids = OreDictionary.getOreIDs(upgrade); for (int id : ids) { String str = OreDictionary.getOreName(id); if (str.contains("dye")) { return true; } } } return false; } /** * Checks if the stack has the steam-related NBT values, and if not, sets them to 0. * @param me The ItemStack to check. */ public void updateSteamNBT(ItemStack me) { if (!me.hasTagCompound()) { me.setTagCompound(new NBTTagCompound()); } if (!me.getTagCompound().hasKey("SteamStored")) { me.getTagCompound().setInteger("SteamStored", 0); } if (!me.getTagCompound().hasKey("SteamCapacity")) { me.getTagCompound().setInteger("SteamCapacity", 0); } } @Override public boolean hasPower(ItemStack me, int powerNeeded) { if (armorType == EntityEquipmentSlot.CHEST) { updateSteamNBT(me); if (me.getTagCompound().getInteger("SteamStored") > powerNeeded) { return true; } } return false; } @Override public boolean needsPower(ItemStack me, int powerNeeded) { if (armorType == EntityEquipmentSlot.CHEST) { updateSteamNBT(me); if (me.getTagCompound().getInteger("SteamStored") + powerNeeded < me.getTagCompound().getInteger("SteamCapacity")) { return true; } } return false; } /** * Gets whether the given armor has a tank upgrade. * @param me The ItemStack */ public boolean hasTank(ItemStack me) { if (armorType != EntityEquipmentSlot.CHEST) { return false; } if (!me.hasTagCompound()) { return false; } if (!me.getTagCompound().hasKey("Upgrades")) { return false; } NBTTagCompound inv = me.getTagCompound().getCompoundTag("Upgrades"); for (int i = 1; i < 10; i++) { String s = Integer.toString(i); if (inv.hasKey(s)) { ItemStack stack = ItemStack.loadItemStackFromNBT(inv.getCompoundTag(s)); if (stack != null && stack.getItem() != null && stack.getItem() instanceof ExosuitTank) { return true; } } } return false; } @Override @Nonnull public ExosuitUpgrade[] getUpgrades(ItemStack me) { ArrayList<ExosuitUpgrade> upgrades = new ArrayList<>(); if (me.hasTagCompound()) { if (me.getTagCompound().hasKey("Upgrades")) { for (int i = 2; i < 10; i++) { if (me.getTagCompound().getCompoundTag("Upgrades").hasKey(Integer.toString(i))) { ItemStack stack = ItemStack.loadItemStackFromNBT(me.getTagCompound().getCompoundTag("Upgrades").getCompoundTag(Integer.toString(i))); if (stack.getItem() instanceof ExosuitUpgrade) { upgrades.add((ExosuitUpgrade) stack.getItem()); } } } } } return upgrades.toArray(new ExosuitUpgrade[0]); } @Override public void drawSlot(GuiContainer guiEngineeringTable, int slotNum, int i, int j) { guiEngineeringTable.mc.getTextureManager().bindTexture(Constants.ENG_GUI_TEXTURES); switch (armorType) { case HEAD: case LEGS: case FEET: { switch (slotNum) { case 0: { guiEngineeringTable.drawTexturedModalRect(i, j, 194, 0, 18, 18); break; } case 1: { guiEngineeringTable.drawTexturedModalRect(i, j, 230, 36, 18, 18); break; } default: { break; } } } case CHEST: { switch (slotNum) { case 0: { guiEngineeringTable.drawTexturedModalRect(i, j, 194, 0, 18, 18); break; } case 1: { guiEngineeringTable.drawTexturedModalRect(i, j, 230, 36, 18, 18); break; } case 4: { guiEngineeringTable.drawTexturedModalRect(i, j, 176, 36, 18, 18); break; } default: { guiEngineeringTable.drawTexturedModalRect(i, j, 176, 0, 18, 18); } } } default: { break; } } } @Override public int getMaxDamage(ItemStack stack) { if (armorType == EntityEquipmentSlot.CHEST) { return 10_000; } return 0; } @Override public int getDamage(ItemStack stack) { updateSteamNBT(stack); return (int) (((double) stack.getTagCompound().getInteger("SteamStored")) / stack.getTagCompound().getInteger("SteamCapacity") * 10_000.0D); } @Override public int steamPerDurability() { return Config.exoConsumption; } @Override public boolean canCharge(ItemStack stack) { if (armorType == EntityEquipmentSlot.CHEST) { ItemSteamExosuitArmor item = (ItemSteamExosuitArmor) stack.getItem(); if (item.getStackInSlot(stack, 5) != null && item.getStackInSlot(stack, 5).getItem() instanceof ExosuitTank) { ExosuitTank tank = (ExosuitTank) item.getStackInSlot(stack, 5).getItem(); return tank.canFill(stack); } } return false; } @Override public boolean addSteam(ItemStack me, int amount, EntityLivingBase player) { int curSteam = me.getTagCompound().getInteger("SteamStored"); if (needsPower(me, amount)) { me.getTagCompound().setInteger("SteamStored", curSteam + amount); return true; } return false; } @Override public boolean drainSteam(ItemStack me, int amountToDrain, EntityLivingBase entity) { if (me != null) { if (me.getTagCompound() == null) { me.setTagCompound(new NBTTagCompound()); } if (!me.getTagCompound().hasKey("SteamStored")) { me.getTagCompound().setInteger("SteamStored", 0); } int fill = me.getTagCompound().getInteger("SteamStored"); fill = Math.max(0, fill - amountToDrain); me.getTagCompound().setInteger("SteamStored", fill); return true; } return false; } @Override public Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot armorSlot, ItemStack stack) { Multimap<String, AttributeModifier> map = HashMultimap.create(); ItemSteamExosuitArmor armor = (ItemSteamExosuitArmor) stack.getItem(); if (armor.hasPlates(stack)) { ExosuitPlate plate = UtilPlates.getPlate(stack); if (plate != null) { map.putAll(plate.getAttributeModifiersForExosuit(armorSlot, stack)); } } ExosuitUpgrade[] upgrades = armor.getUpgrades(stack); for (ExosuitUpgrade upgrade : upgrades) { map.putAll(upgrade.getAttributeModifiersForExosuit(armorSlot, stack)); } return map; } @Override @SideOnly(Side.CLIENT) public void addInformation(ItemStack me, EntityPlayer player, List<String> list, boolean advanced) { super.addInformation(me, player, list, advanced); if (me.hasTagCompound()) { // TODO: Abstract into API if (hasPlates(me) && !"Thaumium".equals(UtilPlates.getPlate(me.getTagCompound().getString("Plate")).getIdentifier()) && !"Terrasteel".equals(UtilPlates.getPlate(me.getTagCompound().getString("Plate")).getIdentifier())) { list.add(TextFormatting.BLUE + UtilPlates.getPlate(me.getTagCompound().getString("Plate")).effect()); } if (me.getTagCompound().hasKey("Upgrades")) { for (int i = 3; i < 10; i++) { if (me.getTagCompound().getCompoundTag("Upgrades").hasKey(Integer.toString(i))) { ItemStack stack = ItemStack.loadItemStackFromNBT(me.getTagCompound().getCompoundTag("Upgrades").getCompoundTag(Integer.toString(i))); list.add(TextFormatting.RED + stack.getDisplayName()); } } } if (me.getTagCompound().getCompoundTag("Upgrades").hasKey("2")) { ItemStack stack = ItemStack.loadItemStackFromNBT(me.getTagCompound().getCompoundTag("Upgrades").getCompoundTag("2")); // TODO: Abstract into API if (stack.getItem() == ArmorModule.ENDER_SHROUD) { list.add(TextFormatting.DARK_GREEN + I18n.format("esteemedinnovation.exosuit.shroud")); } else { int dye = -1; int dyeIndex = ModelSteamExosuit.findDyeIndexFromItemStack(stack); if (dyeIndex != -1) { dye = dyeIndex; } if (dye != -1) { list.add(TextFormatting.DARK_GREEN + I18n.format("esteemedinnovation.color." + ModelSteamExosuit.DYES[dye].toLowerCase())); } else { list.add(TextFormatting.DARK_GREEN + stack.getDisplayName()); } } } } updateSteamNBT(me); if (armorType == EntityEquipmentSlot.CHEST) { list.add(TextFormatting.WHITE + "" + me.getTagCompound().getInteger("SteamStored") * 5 + "/" + me.getTagCompound().getInteger("SteamCapacity") * 5 + " SU"); } } @Override public void drawBackground(GuiContainer guiEngineeringTable, int i, int j, int k) { guiEngineeringTable.mc.getTextureManager().bindTexture(Constants.ENG_ARMOR_TEXTURES); guiEngineeringTable.drawTexturedModalRect(j + 26, k + 3, 64 * armorType.getIndex(), 0, 64, 64); } @Nonnull @Override public ExosuitEventHandler[] getInstalledEventHandlers(ItemStack self) { List<ExosuitEventHandler> handlers = new ArrayList<>(Arrays.asList(getUpgrades(self))); if (self.hasTagCompound() && self.getTagCompound().hasKey("Plate")) { handlers.add(UtilPlates.getPlate(self.getTagCompound().getString("Plate"))); } return handlers.toArray(new ExosuitEventHandler[handlers.size()]); } }