package slimeknights.tconstruct.tools.modifiers; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityXPOrb; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.player.PlayerPickupXpEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import java.util.List; import slimeknights.tconstruct.library.Util; import slimeknights.tconstruct.library.modifiers.ModifierNBT; import slimeknights.tconstruct.library.modifiers.ModifierTrait; import slimeknights.tconstruct.library.utils.ModifierTagHolder; import slimeknights.tconstruct.library.utils.TagUtil; import slimeknights.tconstruct.library.utils.TinkerUtil; import slimeknights.tconstruct.library.utils.ToolHelper; public class ModMendingMoss extends ModifierTrait { public static final int MENDING_MOSS_LEVELS = 10; private static final String TAG_STORED_XP = "stored_xp"; private static final String TAG_LAST_HEAL = "heal_timestamp"; private static final int DELAY = 20 * 7 + 10; // every 7.5s public ModMendingMoss() { super("mending_moss", 0x43ab32, 3, 0); MinecraftForge.EVENT_BUS.register(this); } @Override public void onUpdate(ItemStack tool, World world, Entity entity, int itemSlot, boolean isSelected) { // only in the hotbar of a player if(!world.isRemote && entity instanceof EntityLivingBase) { // must be in hotbar or offhand for players if(entity instanceof EntityPlayer && !InventoryPlayer.isHotbar(itemSlot) && ((EntityPlayer) entity).getHeldItemOffhand() != tool) { return; } // needs ot be repaired and is in hotbar or offhand if(needsRepair(tool)) { if(useXp(tool, world)) { ToolHelper.healTool(tool, getDurabilityPerXP(tool), (EntityLivingBase) entity); } } } } @SubscribeEvent public void onPickupXp(PlayerPickupXpEvent event) { // try mainhand first, then offhand List<ItemStack> tools = Lists.newArrayList(event.getEntityPlayer().getHeldItemMainhand(), event.getEntityPlayer().getHeldItemOffhand()); EntityXPOrb entityXPOrb = event.getOrb(); for(ItemStack itemStack : tools) { if(itemStack != null && isMendingMossModified(itemStack)) { int stored = storeXp(entityXPOrb.xpValue, itemStack); entityXPOrb.xpValue -= stored; } } } private boolean isMendingMossModified(ItemStack itemStack) { return TinkerUtil.hasModifier(TagUtil.getTagSafe(itemStack), getModifierIdentifier()); } private boolean needsRepair(ItemStack itemStack) { return itemStack != null && itemStack.getItemDamage() > 0 && !ToolHelper.isBroken(itemStack); } private int getDurabilityPerXP(ItemStack itemStack) { return 2 + ModifierTagHolder.getModifier(itemStack, getModifierIdentifier()).getTagData(Data.class).level; } // 100 * 3^(level-1) private int getMaxXp(int level) { if(level <= 1) { return 100; } return getMaxXp(level - 1) * 3; } private boolean canStoreXp(Data data) { return data.storedXp < getMaxXp(data.level); } private int storeXp(int amount, ItemStack itemStack) { ModifierTagHolder modtag = ModifierTagHolder.getModifier(itemStack, getModifierIdentifier()); Data data = modtag.getTagData(Data.class); int change = 0; if(canStoreXp(data)) { int max = getMaxXp(data.level); change = Math.min(amount, max - data.storedXp); data.storedXp += change; modtag.save(); } return change; } private boolean useXp(ItemStack itemStack, World world) { ModifierTagHolder modtag = ModifierTagHolder.getModifier(itemStack, getModifierIdentifier()); Data data = modtag.getTagData(Data.class); if(data.storedXp > 0 && world.getTotalWorldTime() - data.lastHeal > DELAY) { data.storedXp--; data.lastHeal = world.getTotalWorldTime(); modtag.save(); return true; } return false; } @Override public List<String> getExtraInfo(ItemStack tool, NBTTagCompound modifierTag) { Data data = ModifierNBT.readTag(modifierTag, Data.class); String loc = String.format(LOC_Extra, getIdentifier()); return ImmutableList.of( Util.translateFormatted(loc, data.storedXp) ); } public static class Data extends ModifierNBT { public int storedXp; public long lastHeal; @Override public void read(NBTTagCompound tag) { super.read(tag); storedXp = tag.getInteger(TAG_STORED_XP); lastHeal = tag.getLong(TAG_LAST_HEAL); } @Override public void write(NBTTagCompound tag) { super.write(tag); tag.setInteger(TAG_STORED_XP, storedXp); tag.setLong(TAG_LAST_HEAL, lastHeal); } } }