package joshie.harvest.tools; import joshie.harvest.animals.HFAnimals; import joshie.harvest.animals.item.ItemAnimalProduct.Sizeable; import joshie.harvest.api.core.ITiered; import joshie.harvest.core.base.item.ItemTool; import joshie.harvest.core.helpers.EntityHelper; import joshie.harvest.core.util.annotations.HFEvents; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.MobEffects; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; import net.minecraft.util.FoodStats; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.DimensionManager; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.entity.player.PlayerWakeUpEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.relauncher.ReflectionHelper; import javax.annotation.Nonnull; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import static joshie.harvest.animals.item.ItemAnimalTool.Tool.BRUSH; import static joshie.harvest.calendar.HFCalendar.TICKS_PER_DAY; import static joshie.harvest.tools.HFTools.*; public class ToolHelper { private static final DamageSource EXHAUSTED = new DamageSource("exhausted") { @Override @Nonnull public ITextComponent getDeathMessage(EntityLivingBase entityLivingBaseIn) { String s = "harvestfestival.death.attack." + this.damageType; return new TextComponentTranslation(s, entityLivingBaseIn.getDisplayName()); } }.setDamageBypassesArmor().setDamageIsAbsolute(); public static boolean isBrush(ItemStack stack) { return HFAnimals.TOOLS.getEnumFromStack(stack) == BRUSH; } //TODO: Reenable in 1.0 when I readd marriage @SuppressWarnings("unused") public static boolean isBlueFeather(ItemStack stack) { return false; //return HFNPCs.TOOLS.getEnumFromStack(stack) == BLUE_FEATHER; } public static boolean isEgg(ItemStack stack) { return stack.getItem() == HFAnimals.ANIMAL_PRODUCT && HFAnimals.ANIMAL_PRODUCT.getEnumFromStack(stack) == Sizeable.EGG; } public static boolean isWool(ItemStack stack) { return stack.getItem() == HFAnimals.ANIMAL_PRODUCT && HFAnimals.ANIMAL_PRODUCT.getEnumFromStack(stack) == Sizeable.WOOL; } public static void levelTool(ItemStack stack) { if (stack == null) return; if (stack.getItem() instanceof ITiered) { ((ITiered)stack.getItem()).levelTool(stack); } } /** * Should always be called client and server side **/ public static void performTask(EntityPlayer player, ItemStack stack, ItemTool tool) { levelTool(stack); //Level up the tool if (player.capabilities.isCreativeMode || !HFTools.HF_CONSUME_HUNGER) return; //If the player is in creative don't exhaust them consumeHunger(player, tool.getExhaustionRate(stack)); if (tool != HFTools.WATERING_CAN) { int max = tool.getMaximumToolDamage(stack); int current = tool.getDamageForDisplay(stack); if (current + 1 >= max) player.renderBrokenItemStack(stack); stack.getSubCompound("Data", true).setInteger("Damage", current + 1); } } @SuppressWarnings("ConstantConditions") public static void consumeHunger(EntityPlayer player, float amount) { if (player == null) return; //No null players allowed int level = player.getFoodStats().getFoodLevel(); if (amount > 0F) player.getFoodStats().addExhaustion(HFTools.EXHAUSTION_AMOUNT * amount); //Add Exhaustion if (level > 2 && level <= 6) { player.removePotionEffect(EXHAUSTION); //Don't ever have fatigue/exhaustion at same time player.addPotionEffect(new PotionEffect(FATIGUE, 6000)); } else if (level <= 2 && !player.isPotionActive(EXHAUSTION)) { player.removePotionEffect(FATIGUE); //Don't ever have fatigue/exhaustion at same time player.addPotionEffect(new PotionEffect(EXHAUSTION, 2000)); } else { PotionEffect effect = player.getActivePotionEffect(EXHAUSTION); if (effect != null && ((level == 0 && effect.getDuration() <= 1990) || (ENABLE_EARLY_FAINTING && effect.getDuration() <= 1500))) { player.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 100, 7)); if (!player.worldObj.isRemote && ENABLE_FAINTING) { if (ENABLE_DEATH_FAINTING) player.attackEntityFrom(EXHAUSTED, 1000F); else { int dimension = player.worldObj.provider.canRespawnHere() ? player.worldObj.provider.getDimension() : 0; BlockPos spawn = player.getBedLocation(dimension) != null ? player.getBedLocation(dimension) : DimensionManager.getWorld(dimension).provider.getRandomizedSpawnPoint(); EntityHelper.teleport(player, dimension, spawn); player.trySleep(spawn); if (ENABLE_FAINTING_SLEEP) { //Force instant sleep player.sleepTimer = 100; } } } //Remove all effects player.removePotionEffect(FATIGUE); player.removePotionEffect(EXHAUSTION); if (HFTools.RESTORE_HUNGER_ON_FAINTING) { restoreHunger(player); } } } } @HFEvents @SuppressWarnings("unused") public static class RestoreHungerOnSleep { public static boolean register() { return HFTools.RESTORE_HUNGER_ON_SLEEP; } @SubscribeEvent public void onWakeup(PlayerWakeUpEvent event) { EntityPlayer player = event.getEntityPlayer(); if (player.worldObj.getWorldTime() % TICKS_PER_DAY == 0) { if (player.isPotionActive(EXHAUSTION)) player.removePotionEffect(EXHAUSTION); if (player.isPotionActive(FATIGUE)) player.removePotionEffect(FATIGUE); restoreHunger(player); } } } private static void restoreHunger(EntityPlayer player) { ReflectionHelper.setPrivateValue(FoodStats.class, player.getFoodStats(), 20, "foodLevel", "field_75127_a"); ReflectionHelper.setPrivateValue(FoodStats.class, player.getFoodStats(), 5F, "foodSaturationLevel", "field_75125_b"); ReflectionHelper.setPrivateValue(FoodStats.class, player.getFoodStats(), 0, "foodExhaustionLevel", "field_75126_c"); ReflectionHelper.setPrivateValue(FoodStats.class, player.getFoodStats(), 0, "foodTimer", "field_75123_d"); } public static void collectDrops(World world, BlockPos pos, IBlockState state, EntityPlayer player, List<ItemStack> drops) { Block block = state.getBlock(); List<ItemStack> blockDrops = new ArrayList<>(); if (block.canSilkHarvest(world, pos, state, player)) { try { Method method = ReflectionHelper.findMethod(Block.class, null, new String[] { "createStackedBlock", "func_180643_i" } , IBlockState.class); ItemStack stack = (ItemStack) method.invoke(block, state); if (stack != null) { blockDrops.add(stack); ForgeEventFactory.fireBlockHarvesting(blockDrops, world, pos, state, 0, 1F, true, player); drops.addAll(blockDrops); //Add all the drops to our list } } catch (IllegalAccessException | InvocationTargetException e) {/**/} } else { blockDrops = block.getDrops(world, pos, state, 0); ForgeEventFactory.fireBlockHarvesting(blockDrops, world, pos, state, 0, 1F, false, player); drops.addAll(blockDrops); //Add all the drops to our list } } public static ItemStack getStackFromBlockState(IBlockState state) { Item item = Item.getItemFromBlock(state.getBlock()); if (item == null) { return null; } else { int i = 0; if (item.getHasSubtypes()) { i = state.getBlock().getMetaFromState(state); } return new ItemStack(item, 1, i); } } }