package tonius.simplyjetpacks.item; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import net.minecraft.client.model.ModelBiped; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; import net.minecraft.util.IIcon; import net.minecraft.world.World; import net.minecraftforge.common.ISpecialArmor; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidContainerItem; import tonius.simplyjetpacks.SimplyJetpacks; import tonius.simplyjetpacks.client.util.RenderUtils; import tonius.simplyjetpacks.config.Config; import tonius.simplyjetpacks.handler.GuiHandler; import tonius.simplyjetpacks.integration.ModType; import tonius.simplyjetpacks.item.meta.FluxPack; import tonius.simplyjetpacks.item.meta.Jetpack; import tonius.simplyjetpacks.item.meta.PackBase; import tonius.simplyjetpacks.setup.FuelType; import tonius.simplyjetpacks.setup.ModCreativeTab; import tonius.simplyjetpacks.setup.ModEnchantments; import tonius.simplyjetpacks.setup.ModKey; import tonius.simplyjetpacks.util.NBTHelper; import tonius.simplyjetpacks.util.SJStringHelper; import cofh.api.energy.IEnergyContainerItem; import cofh.lib.util.helpers.MathHelper; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class ItemPack<T extends PackBase> extends ItemArmor implements IControllableArmor, ISpecialArmor, IEnergyContainerItem, IFluidContainerItem, IHUDInfoProvider { private static final String TAG_ENERGY = "Energy"; private static final String TAG_FLUID = "Fluid"; public final ModType modType; private final Map<Integer, T> packs = new LinkedHashMap<Integer, T>(); public ItemPack(ModType modType, String registryName) { super(ArmorMaterial.IRON, 2, 1); this.modType = modType; this.setUnlocalizedName(SimplyJetpacks.PREFIX + "pack" + modType.suffix); this.setHasSubtypes(true); this.setMaxDamage(0); this.setCreativeTab(ModCreativeTab.instance); GameRegistry.registerItem(this, registryName); } public ItemStack putPack(int meta, T pack, boolean returnFull) { this.packs.put(meta, pack); ItemStack stack = new ItemStack(this, 1, meta); if (returnFull) { this.addFuel(stack, this.getMaxFuelStored(stack), false); } return stack; } public ItemStack putPack(int meta, T pack) { return this.putPack(meta, pack, false); } public T getPack(ItemStack stack) { return this.packs.get(stack.getItemDamage()); } public Collection<T> getPacks() { return this.packs.values(); } @Override public void onUpdate(ItemStack stack, World world, Entity entity, int par4, boolean par5) { T pack = this.getPack(stack); if (pack != null && entity instanceof EntityPlayer) { pack.tickInventory(world, (EntityPlayer) entity, stack, this); } } @Override public void onArmorTick(World world, EntityPlayer player, ItemStack stack) { T pack = this.getPack(stack); if (pack != null) { pack.tickArmor(world, player, stack, this); } } @Override public String getUnlocalizedName(ItemStack stack) { T pack = this.getPack(stack); if (pack != null) { return "item." + SimplyJetpacks.PREFIX + pack.getBaseName(true) + this.modType.suffix; } return super.getUnlocalizedName(); } @Override public EnumRarity getRarity(ItemStack stack) { T pack = this.getPack(stack); if (pack != null) { return pack.rarity; } return super.getRarity(stack); } @Override public boolean showDurabilityBar(ItemStack stack) { T pack = this.getPack(stack); if (pack != null) { return pack.hasFuelIndicator; } return super.showDurabilityBar(stack); } @Override public double getDurabilityForDisplay(ItemStack stack) { double stored = this.getMaxFuelStored(stack) - this.getFuelStored(stack) + 1; double max = this.getMaxFuelStored(stack) + 1; return stored / max; } @Override public int getItemEnchantability(ItemStack stack) { T pack = this.getPack(stack); if (pack != null) { return pack.enchantability; } return super.getItemEnchantability(stack); } @Override public boolean isItemTool(ItemStack stack) { return this.getItemEnchantability() > 0; } @Override public boolean isBookEnchantable(ItemStack stack, ItemStack book) { return this.getItemEnchantability() > 0; } @Override @SideOnly(Side.CLIENT) @SuppressWarnings("unchecked") public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean par4) { T pack = this.getPack(stack); if (pack != null) { pack.addInformation(stack, this, player, list); if (SJStringHelper.canShowDetails()) { pack.addShiftInformation(stack, this, player, list); } else { list.add(SJStringHelper.getShiftText()); } } } @Override @SideOnly(Side.CLIENT) @SuppressWarnings("unchecked") public void getSubItems(Item item, CreativeTabs tab, List list) { for (Entry<Integer, T> e : this.packs.entrySet()) { e.getValue().addSubItems(this, e.getKey(), list); } } @Override @SideOnly(Side.CLIENT) public void registerIcons(IIconRegister register) { for (T pack : this.packs.values()) { pack.registerIcons(register, this.modType); } } @Override @SideOnly(Side.CLIENT) public IIcon getIcon(ItemStack stack, int pass) { T pack = this.packs.get(stack.getItemDamage()); if (pack != null) { IIcon icon = pack.getIcon(stack); if (icon != null) { return icon; } } return super.getIcon(stack, pass); } @Override @SideOnly(Side.CLIENT) public boolean requiresMultipleRenderPasses() { return true; } @Override @SideOnly(Side.CLIENT) public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type) { T pack = this.getPack(stack); if (pack != null) { return pack.getArmorTexture(stack, entity, slot, this.modType); } return super.getArmorTexture(stack, entity, slot, type); } @Override @SideOnly(Side.CLIENT) public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack stack, int armorSlot) { T pack = this.getPack(stack); if (pack != null && pack.armorModel != null && Config.enableArmor3DModels) { ModelBiped model = RenderUtils.getArmorModel(pack, entityLiving); if (model != null) { return model; } } return super.getArmorModel(entityLiving, stack, armorSlot); } // control @Override public void onKeyPressed(ItemStack stack, EntityPlayer player, ModKey key, boolean showInChat) { T pack = this.getPack(stack); if (pack != null) { switch (key) { case TOGGLE_PRIMARY: pack.togglePrimary(stack, player, showInChat); break; case TOGGLE_SECONDARY: pack.toggleSecondary(stack, player, showInChat); break; case MODE_PRIMARY: pack.switchModePrimary(stack, player, showInChat); break; case MODE_SECONDARY: pack.switchModeSecondary(stack, player, showInChat); break; case OPEN_PACK_GUI: player.openGui(SimplyJetpacks.instance, GuiHandler.PACK, player.worldObj, 0, 0, 0); break; default: } } } // armor protected int getFuelPerDamage(ItemStack stack, T pack) { if (ModEnchantments.fuelEffeciency == null) { return pack.armorFuelPerHit; } int fuelEfficiencyLevel = MathHelper.clampI(EnchantmentHelper.getEnchantmentLevel(ModEnchantments.fuelEffeciency.effectId, stack), 0, 4); return (int) Math.round(pack.armorFuelPerHit * (5 - fuelEfficiencyLevel) / 5.0D); } @Override public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot) { T pack = this.getPack(armor); if (pack != null && pack.isArmored && !source.isUnblockable()) { if (pack.isFluxBased && source.damageType.equals("flux")) { return new ArmorProperties(0, 0.5D, Integer.MAX_VALUE); } int energyPerDamage = this.getFuelPerDamage(armor, pack); int maxAbsorbed = energyPerDamage > 0 ? 25 * (this.getFuelStored(armor) / energyPerDamage) : 0; return new ArmorProperties(0, 0.85D * (pack.armorReduction / 20.0D), maxAbsorbed); } return new ArmorProperties(0, 1, 0); } @Override public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot) { T pack = this.getPack(armor); if (pack != null && pack.isArmored) { if (this.getFuelStored(armor) >= pack.armorFuelPerHit) { return pack.armorReduction; } } return 0; } @Override public void damageArmor(EntityLivingBase entity, ItemStack armor, DamageSource source, int damage, int slot) { T pack = this.getPack(armor); if (pack != null && pack.isArmored && pack.usesFuel) { if (pack.fuelType == FuelType.ENERGY && pack.isFluxBased && source.damageType.equals("flux")) { this.addFuel(armor, damage * (source.getEntity() == null ? pack.armorFuelPerHit / 2 : this.getFuelPerDamage(armor, pack)), false); } else { this.useFuel(armor, damage * this.getFuelPerDamage(armor, pack), false); } } } // fuel public int getFuelStored(ItemStack stack) { T pack = this.getPack(stack); switch (pack.fuelType) { case ENERGY: default: return this.getEnergyStored(stack); case FLUID: FluidStack stored = this.getFluid(stack); return stored != null ? stored.amount : 0; } } public int getMaxFuelStored(ItemStack stack) { T pack = this.getPack(stack); switch (pack.fuelType) { case ENERGY: default: return this.getMaxEnergyStored(stack); case FLUID: return this.getCapacity(stack); } } public int addFuel(ItemStack stack, int maxAdd, boolean simulate) { T pack = this.getPack(stack); if (pack == null) { return 0; } switch (pack.fuelType) { case ENERGY: default: int energy = this.getEnergyStored(stack); int energyReceived = Math.min(this.getMaxEnergyStored(stack) - energy, maxAdd); if (!simulate) { energy += energyReceived; NBTHelper.getNBT(stack).setInteger(TAG_ENERGY, energy); } return energyReceived; case FLUID: if (pack.fuelFluid == null) { return 0; } FluidStack fluid = this.getFluid(stack); int amount = fluid != null ? fluid.amount : 0; int fluidReceived = Math.min(this.getCapacity(stack) - amount, maxAdd); if (!simulate) { amount += fluidReceived; NBTHelper.getNBT(stack).setInteger(TAG_FLUID, amount); } return fluidReceived; } } public int useFuel(ItemStack stack, int maxUse, boolean simulate) { T pack = this.getPack(stack); switch (pack.fuelType) { case ENERGY: default: int energy = this.getEnergyStored(stack); int energyExtracted = Math.min(energy, maxUse); if (!simulate) { energy -= energyExtracted; NBTHelper.getNBT(stack).setInteger(TAG_ENERGY, energy); } return energyExtracted; case FLUID: if (pack.fuelFluid == null) { return 0; } FluidStack fluid = this.getFluid(stack); int amount = fluid != null ? fluid.amount : 0; int fluidExtracted = Math.min(amount, maxUse); if (!simulate) { amount -= fluidExtracted; NBTHelper.getNBT(stack).setInteger(TAG_FLUID, amount); } return fluidExtracted; } } @Override public int receiveEnergy(ItemStack container, int maxReceive, boolean simulate) { T pack = this.getPack(container); if (pack == null || pack.fuelType != FuelType.ENERGY) { return 0; } int energy = this.getEnergyStored(container); int energyReceived = Math.min(this.getMaxEnergyStored(container) - energy, Math.min(maxReceive, pack.fuelPerTickIn)); if (!simulate) { energy += energyReceived; NBTHelper.getNBT(container).setInteger(TAG_ENERGY, energy); } return energyReceived; } @Override public int extractEnergy(ItemStack container, int maxExtract, boolean simulate) { T pack = this.getPack(container); if (pack == null || pack.fuelType != FuelType.ENERGY) { return 0; } int energy = this.getEnergyStored(container); int energyExtracted = Math.min(energy, Math.min(maxExtract, pack.fuelPerTickOut)); if (!simulate) { energy -= energyExtracted; NBTHelper.getNBT(container).setInteger(TAG_ENERGY, energy); } return energyExtracted; } @Override public int getEnergyStored(ItemStack container) { T pack = this.getPack(container); if (pack == null || pack.fuelType != FuelType.ENERGY) { return 0; } return NBTHelper.getNBT(container).getInteger(TAG_ENERGY); } @Override public int getMaxEnergyStored(ItemStack container) { T pack = this.getPack(container); if (pack == null || pack.fuelType != FuelType.ENERGY) { return 0; } return pack.fuelCapacity; } @Override public FluidStack getFluid(ItemStack container) { T pack = this.getPack(container); if (pack == null || pack.fuelType != FuelType.FLUID || pack.fuelFluid == null) { return null; } int amount = NBTHelper.getNBT(container).getInteger(TAG_FLUID); return amount > 0 ? new FluidStack(FluidRegistry.getFluid(pack.fuelFluid), amount) : null; } @Override public int getCapacity(ItemStack container) { T pack = this.getPack(container); if (pack == null || pack.fuelType != FuelType.FLUID || pack.fuelFluid == null) { return 0; } return pack.fuelCapacity; } @Override public int fill(ItemStack container, FluidStack resource, boolean doFill) { if (resource == null) { return 0; } T pack = this.getPack(container); if (pack == null || pack.fuelType != FuelType.FLUID || pack.fuelFluid == null || resource.getFluid() != FluidRegistry.getFluid(pack.fuelFluid)) { return 0; } FluidStack fluid = this.getFluid(container); int amount = fluid != null ? fluid.amount : 0; int fluidReceived = Math.min(this.getCapacity(container) - amount, Math.min(resource.amount, pack.fuelPerTickIn)); if (doFill) { amount += fluidReceived; NBTHelper.getNBT(container).setInteger(TAG_FLUID, amount); } return fluidReceived; } @Override public FluidStack drain(ItemStack container, int maxDrain, boolean doDrain) { T pack = this.getPack(container); if (pack == null || pack.fuelType != FuelType.FLUID || pack.fuelFluid == null) { return null; } FluidStack fluid = this.getFluid(container); int amount = fluid != null ? fluid.amount : 0; int fluidExtracted = Math.min(amount, Math.min(maxDrain, pack.fuelPerTickOut)); if (doDrain) { amount -= fluidExtracted; NBTHelper.getNBT(container).setInteger(TAG_FLUID, amount); } return fluidExtracted > 0 ? new FluidStack(FluidRegistry.getFluid(pack.fuelFluid), fluidExtracted) : null; } // HUD info @Override @SideOnly(Side.CLIENT) public void addHUDInfo(List<String> list, ItemStack stack, boolean showFuel, boolean showState) { T pack = this.getPack(stack); if (pack != null) { if (showFuel && pack.hasFuelIndicator) { list.add(pack.getHUDFuelInfo(stack, this)); } if (showState && pack.hasStateIndicators) { list.add(pack.getHUDStatesInfo(stack, this)); } } } public static class ItemJetpack extends ItemPack<Jetpack> { public ItemJetpack(ModType modType, String registryName) { super(modType, registryName); } } public static class ItemFluxPack extends ItemPack<FluxPack> { public ItemFluxPack(ModType modType, String registryName) { super(modType, registryName); } } }