Search in sources :

Example 1 with ToolStack

use of slimeknights.tconstruct.library.tools.nbt.ToolStack in project TinkersConstruct by SlimeKnights.

the class ModifierLootingHandler method onLooting.

/**
 * Applies the looting bonus for modifiers
 */
private static void onLooting(LootingLevelEvent event) {
    // must be an attacker with our tool
    DamageSource damageSource = event.getDamageSource();
    if (damageSource == null) {
        return;
    }
    Entity source = damageSource.getEntity();
    if (source instanceof LivingEntity) {
        // TODO: consider bow usage, as the attack time is not the same as the death time
        // TODO: extend to armor eventually
        LivingEntity holder = ((LivingEntity) source);
        EquipmentSlot slotType = getLootingSlot(holder);
        ItemStack held = holder.getItemBySlot(slotType);
        int level = event.getLootingLevel();
        if (TinkerTags.Items.MODIFIABLE.contains(held.getItem())) {
            ToolStack tool = ToolStack.from(held);
            level = ModifierUtil.getLootingLevel(tool, holder, event.getEntityLiving(), damageSource);
        // ignore default looting if we are looting from another slot
        } else if (slotType != EquipmentSlot.MAINHAND) {
            level = 0;
        }
        // boot looting with pants
        level = ModifierUtil.getLeggingsLootingLevel(holder, event.getEntityLiving(), damageSource, level);
        event.setLootingLevel(level);
    }
}
Also used : LivingEntity(net.minecraft.world.entity.LivingEntity) LivingEntity(net.minecraft.world.entity.LivingEntity) Entity(net.minecraft.world.entity.Entity) DamageSource(net.minecraft.world.damagesource.DamageSource) EquipmentSlot(net.minecraft.world.entity.EquipmentSlot) ItemStack(net.minecraft.world.item.ItemStack) ToolStack(slimeknights.tconstruct.library.tools.nbt.ToolStack)

Example 2 with ToolStack

use of slimeknights.tconstruct.library.tools.nbt.ToolStack in project TinkersConstruct by SlimeKnights.

the class ModifierUtil method applyHarvestEnchantments.

/**
 * Adds all enchantments from tools. Separate method as tools don't have enchants all the time.
 * Typically called before actions which involve loot, such as breaking blocks or attacking mobs.
 * @param tool     Tool instance
 * @param stack    Base stack instance
 * @param context  Tool harvest context
 * @return  Old tag if enchants were applied
 */
@Nullable
public static ListTag applyHarvestEnchantments(ToolStack tool, ItemStack stack, ToolHarvestContext context) {
    ListTag originalEnchants = null;
    Player player = context.getPlayer();
    if (player == null || !player.isCreative()) {
        Map<Enchantment, Integer> enchantments = new HashMap<>();
        BiConsumer<Enchantment, Integer> enchantmentConsumer = (ench, add) -> {
            if (ench != null && add != null) {
                Integer level = enchantments.get(ench);
                if (level != null) {
                    add += level;
                }
                enchantments.put(ench, add);
            }
        };
        for (ModifierEntry entry : tool.getModifierList()) {
            entry.getModifier().applyHarvestEnchantments(tool, entry.getLevel(), context, enchantmentConsumer);
        }
        // lucky pants
        if (player != null) {
            ItemStack pants = player.getItemBySlot(EquipmentSlot.LEGS);
            if (TinkerTags.Items.LEGGINGS.contains(pants.getItem())) {
                ToolStack pantsTool = ToolStack.from(pants);
                for (ModifierEntry entry : pantsTool.getModifierList()) {
                    IArmorLootModifier leggingLuck = entry.getModifier().getModule(IArmorLootModifier.class);
                    if (leggingLuck != null) {
                        leggingLuck.applyHarvestEnchantments(tool, entry.getLevel(), context, enchantmentConsumer);
                    }
                }
            }
        }
        if (!enchantments.isEmpty()) {
            // note this returns a new list if there is no tag, this is intentional as we need non-null to tell the tool to remove the tag
            originalEnchants = stack.getEnchantmentTags();
            EnchantmentHelper.setEnchantments(enchantments, stack);
        }
    }
    return originalEnchants;
}
Also used : ResourceLocation(net.minecraft.resources.ResourceLocation) Enchantment(net.minecraft.world.item.enchantment.Enchantment) Tag(net.minecraft.nbt.Tag) LivingEntity(net.minecraft.world.entity.LivingEntity) HashMap(java.util.HashMap) Random(java.util.Random) EquipmentChangeContext(slimeknights.tconstruct.library.tools.context.EquipmentChangeContext) TinkerDataKeys(slimeknights.tconstruct.library.tools.capability.TinkerDataKeys) AccessLevel(lombok.AccessLevel) ToolAction(net.minecraftforge.common.ToolAction) DamageSource(net.minecraft.world.damagesource.DamageSource) EnchantmentHelper(net.minecraft.world.item.enchantment.EnchantmentHelper) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) ModifierEntry(slimeknights.tconstruct.library.modifiers.ModifierEntry) Nullable(javax.annotation.Nullable) IArmorLootModifier(slimeknights.tconstruct.library.modifiers.hooks.IArmorLootModifier) TinkerDataKey(slimeknights.tconstruct.library.tools.capability.TinkerDataCapability.TinkerDataKey) IToolStackView(slimeknights.tconstruct.library.tools.nbt.IToolStackView) TinkerTags(slimeknights.tconstruct.common.TinkerTags) ToolHarvestContext(slimeknights.tconstruct.library.tools.context.ToolHarvestContext) Player(net.minecraft.world.entity.player.Player) CompoundTag(net.minecraft.nbt.CompoundTag) Entity(net.minecraft.world.entity.Entity) ItemEntity(net.minecraft.world.entity.item.ItemEntity) ModifierNBT(slimeknights.tconstruct.library.tools.nbt.ModifierNBT) Modifier(slimeknights.tconstruct.library.modifiers.Modifier) EquipmentSlot(net.minecraft.world.entity.EquipmentSlot) Type(net.minecraft.world.entity.EquipmentSlot.Type) ItemStack(net.minecraft.world.item.ItemStack) ListTag(net.minecraft.nbt.ListTag) ToolStack(slimeknights.tconstruct.library.tools.nbt.ToolStack) NoArgsConstructor(lombok.NoArgsConstructor) TinkerDataCapability(slimeknights.tconstruct.library.tools.capability.TinkerDataCapability) Player(net.minecraft.world.entity.player.Player) HashMap(java.util.HashMap) ModifierEntry(slimeknights.tconstruct.library.modifiers.ModifierEntry) Enchantment(net.minecraft.world.item.enchantment.Enchantment) ItemStack(net.minecraft.world.item.ItemStack) ListTag(net.minecraft.nbt.ListTag) ToolStack(slimeknights.tconstruct.library.tools.nbt.ToolStack) IArmorLootModifier(slimeknights.tconstruct.library.modifiers.hooks.IArmorLootModifier) Nullable(javax.annotation.Nullable)

Example 3 with ToolStack

use of slimeknights.tconstruct.library.tools.nbt.ToolStack in project TinkersConstruct by SlimeKnights.

the class ModifierRepairCraftingRecipe method getRelevantInputs.

/**
 * Gets the tool stack and the repair kit material from the crafting grid
 * @param inv  Crafting inventory
 * @return  Relevant inputs, or null if invalid
 */
@Nullable
protected Pair<ToolStack, Integer> getRelevantInputs(CraftingContainer inv) {
    ToolStack tool = null;
    int itemsFound = 0;
    int modifierLevel = 0;
    for (int i = 0; i < inv.getContainerSize(); i++) {
        ItemStack stack = inv.getItem(i);
        if (stack.isEmpty()) {
            continue;
        }
        // repair kit - update material
        if (TinkerTags.Items.DURABILITY.contains(stack.getItem())) {
            // cannot repair multiple tools
            if (tool != null) {
                return null;
            }
            // tool must be damaged
            tool = ToolStack.from(stack);
            if (!tool.isBroken() && tool.getDamage() == 0) {
                return null;
            }
            // tool must have the modifier
            modifierLevel = tool.getModifierLevel(modifier);
            if (modifierLevel == 0) {
                return null;
            }
        // if we found a stack, add it to our count
        } else if (ingredient.test(stack)) {
            itemsFound++;
        } else {
            // unknown item input
            return null;
        }
    }
    // failed to find a tool or item? failed
    if (tool == null || itemsFound == 0) {
        return null;
    }
    return Pair.of(tool, repairAmount * itemsFound * modifierLevel);
}
Also used : ItemStack(net.minecraft.world.item.ItemStack) ToolStack(slimeknights.tconstruct.library.tools.nbt.ToolStack) Nullable(javax.annotation.Nullable)

Example 4 with ToolStack

use of slimeknights.tconstruct.library.tools.nbt.ToolStack in project TinkersConstruct by SlimeKnights.

the class ModifierRepairCraftingRecipe method assemble.

@Override
public ItemStack assemble(CraftingContainer inv) {
    Pair<ToolStack, Integer> inputs = getRelevantInputs(inv);
    if (inputs == null) {
        TConstruct.LOG.error("Recipe repair on {} failed to find items after matching", getId());
        return ItemStack.EMPTY;
    }
    // scale the repair based on the modifiers
    float repairAmount = inputs.getSecond();
    ToolStack tool = inputs.getFirst();
    for (ModifierEntry entry : tool.getModifierList()) {
        repairAmount = entry.getModifier().getRepairFactor(tool, entry.getLevel(), repairAmount);
        if (repairAmount <= 0) {
            // failed to repair
            return ItemStack.EMPTY;
        }
    }
    // repair the tool
    tool = tool.copy();
    ToolDamageUtil.repair(tool, (int) repairAmount);
    return tool.createStack();
}
Also used : ModifierEntry(slimeknights.tconstruct.library.modifiers.ModifierEntry) ToolStack(slimeknights.tconstruct.library.tools.nbt.ToolStack)

Example 5 with ToolStack

use of slimeknights.tconstruct.library.tools.nbt.ToolStack in project TinkersConstruct by SlimeKnights.

the class ModifierRepairTinkerStationRecipe method updateInputs.

@Override
public void updateInputs(ItemStack result, IMutableTinkerStationContainer inv, boolean isServer) {
    ToolStack tool = ToolStack.from(inv.getTinkerableStack());
    // rescale the amount based on modifiers
    float repairFactor = 1.0f;
    for (ModifierEntry entry : tool.getModifierList()) {
        repairFactor = entry.getModifier().getRepairFactor(tool, entry.getLevel(), repairFactor);
        if (repairFactor <= 0) {
            return;
        }
    }
    // also scale by relevant modifier level
    int amountPerItem = (int) (tool.getModifierLevel(modifier) * repairAmount * repairFactor);
    if (amountPerItem < 0) {
        return;
    }
    // how much do we need to subtract from our inputs still
    int repairRemaining = tool.getDamage() - ToolStack.from(result).getDamage();
    IncrementalModifierRecipe.updateInputs(inv, ingredient, repairRemaining, amountPerItem, ItemStack.EMPTY);
}
Also used : ModifierEntry(slimeknights.tconstruct.library.modifiers.ModifierEntry) ToolStack(slimeknights.tconstruct.library.tools.nbt.ToolStack)

Aggregations

ToolStack (slimeknights.tconstruct.library.tools.nbt.ToolStack)64 ItemStack (net.minecraft.world.item.ItemStack)21 ModifierEntry (slimeknights.tconstruct.library.modifiers.ModifierEntry)16 IModifierToolStack (slimeknights.tconstruct.library.tools.nbt.IModifierToolStack)13 Modifier (slimeknights.tconstruct.library.modifiers.Modifier)12 ValidatedResult (slimeknights.tconstruct.library.recipe.tinkerstation.ValidatedResult)12 ItemStack (net.minecraft.item.ItemStack)11 ModDataNBT (slimeknights.tconstruct.library.tools.nbt.ModDataNBT)9 PlayerData (vazkii.psi.common.core.handler.PlayerDataHandler.PlayerData)8 LivingEntity (net.minecraft.world.entity.LivingEntity)7 Player (net.minecraft.world.entity.player.Player)6 SlotCount (slimeknights.tconstruct.library.tools.SlotType.SlotCount)6 SpellContext (vazkii.psi.api.spell.SpellContext)6 Nullable (javax.annotation.Nullable)5 EquipmentSlot (net.minecraft.world.entity.EquipmentSlot)5 MaterialId (slimeknights.tconstruct.library.materials.definition.MaterialId)5 ResourceLocation (net.minecraft.resources.ResourceLocation)4 Level (net.minecraft.world.level.Level)4 PoseStack (com.mojang.blaze3d.vertex.PoseStack)3 CommandSourceStack (net.minecraft.commands.CommandSourceStack)3