2
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

538 lines
28 KiB
Java

package com.zivilon.cinder_loe.mixins;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import lotr.common.LOTRConfig;
import lotr.common.LOTRMod;
import lotr.common.enchant.LOTREnchantment;
import lotr.common.enchant.LOTREnchantmentCombining;
import lotr.common.enchant.LOTREnchantmentHelper;
import lotr.common.entity.npc.LOTREntityScrapTrader;
import lotr.common.entity.npc.LOTRTradeable;
import lotr.common.inventory.LOTRContainerAnvil;
import lotr.common.item.AnvilNameColorProvider;
import lotr.common.item.LOTRItemEnchantment;
import lotr.common.item.LOTRItemModifierTemplate;
import lotr.common.item.LOTRMaterial;
import lotr.common.recipe.LOTRRecipePoisonWeapon;
import net.minecraft.init.Items;
import net.minecraft.inventory.IInventory;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.item.ItemTool;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.MathHelper;
import com.zivilon.cinder_loe.CinderLoE;
import com.zivilon.cinder_loe.util.Utilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
@Mixin(LOTRContainerAnvil.class)
public abstract class MixinLOTRContainerAnvil {
@Shadow
public IInventory invInput;
@Shadow
public IInventory invOutput;
@Shadow
public LOTRTradeable theTrader;
@Shadow
public EntityPlayer thePlayer;
@Shadow
public int materialCost;
@Shadow
public int reforgeCost;
@Shadow
public int engraveOwnerCost;
@Shadow
public boolean isSmithScrollCombine;
@Shadow
public boolean isTrader;
@Shadow
private String repairedItemName;
@Shadow
abstract void detectAndSendChanges();
@Shadow
abstract float getTraderMaterialPrice(ItemStack inputItem);
@Shadow
static boolean costsToRename(ItemStack itemstack) {
return false;
}
@Shadow
static String stripFormattingCodes(String name) {
return null;
}
@Shadow
static String applyFormattingCodes(String name, List<EnumChatFormatting> colors) {
return null;
}
@Shadow
static List<EnumChatFormatting> getAppliedFormattingCodes(String name) {
return null;
}
/**
* @author Shinare
* @reason KeyLime
*/
@Overwrite(remap = false)
public boolean isRepairMaterial(ItemStack inputItem, ItemStack materialItem) {
if (inputItem.getItem().getIsRepairable(inputItem, materialItem))
return true;
Item item = inputItem.getItem();
if (item == Items.bow && LOTRMod.rohanBow.getIsRepairable(inputItem, materialItem))
return true;
if (item instanceof net.minecraft.item.ItemFishingRod && materialItem.getItem() == Items.string)
return true;
if (item instanceof net.minecraft.item.ItemShears && materialItem.getItem() == Items.iron_ingot)
return true;
if (item instanceof lotr.common.item.LOTRItemChisel && materialItem.getItem() == Items.iron_ingot)
return true;
if (item instanceof net.minecraft.item.ItemEnchantedBook && materialItem.getItem() == Items.paper)
return true;
Item.ToolMaterial material = null;
if (item instanceof ItemTool) {
material = Item.ToolMaterial.valueOf(((ItemTool)item).getToolMaterialName());
} else if (item instanceof ItemSword) {
material = Item.ToolMaterial.valueOf(((ItemSword)item).getToolMaterialName());
}
if (material == Item.ToolMaterial.WOOD || material == LOTRMaterial.MOREDAIN_WOOD.toToolMaterial())
return LOTRMod.isOreNameEqual(materialItem, "plankWood");
if (material == LOTRMaterial.MALLORN.toToolMaterial())
return (materialItem.getItem() == Item.getItemFromBlock(LOTRMod.planks) && materialItem.getItemDamage() == 1);
if (material == LOTRMaterial.MALLORN_MACE.toToolMaterial())
return (materialItem.getItem() == Item.getItemFromBlock(LOTRMod.wood) && materialItem.getItemDamage() == 1);
if (material == CinderLoE.MATERIAL_RED_DWARF.toToolMaterial())
return (materialItem.getItem() == CinderLoE.redDwarfSteel);
if (material == CinderLoE.MATERIAL_ASH.toToolMaterial())
return (materialItem.getItem() == CinderLoE.ingotAsh);
if (material == CinderLoE.MATERIAL_BONEMOLD.toToolMaterial())
return (materialItem.getItem() == CinderLoE.bonemold);
if (material == CinderLoE.EVENT.toToolMaterial())
return LOTRMod.isOreNameEqual(materialItem, "ice");
if (material == CinderLoE.MATERIAL_BREE.toToolMaterial())
return (materialItem.getItem() == Items.iron_ingot);
if (material == CinderLoE.MATERIAL_WARLORD.toToolMaterial())
return (materialItem.getItem() == LOTRMod.bronze);
if (item instanceof ItemArmor armor) {
ItemArmor.ArmorMaterial armorMaterial = armor.getArmorMaterial();
if (armorMaterial == LOTRMaterial.BONE.toArmorMaterial())
return LOTRMod.isOreNameEqual(materialItem, "bone");
if (armorMaterial == CinderLoE.MATERIAL_RED_DWARF.toArmorMaterial())
return (materialItem.getItem() == CinderLoE.redDwarfSteel);
if (armorMaterial == CinderLoE.MATERIAL_LIMWAITH_WOOD.toArmorMaterial())
return (materialItem.getItem() == Item.getItemFromBlock(LOTRMod.planks) && materialItem.getItemDamage() == 15);
if (armorMaterial == CinderLoE.MATERIAL_BREE.toArmorMaterial())
return (materialItem.getItem() == Items.iron_ingot);
if (armorMaterial == CinderLoE.MATERIAL_BATTLENUN.toArmorMaterial())
return (materialItem.getItem() == Items.iron_ingot);
if (armorMaterial == CinderLoE.MATERIAL_BONEMOLD.toArmorMaterial())
return (materialItem.getItem() == CinderLoE.bonemold);
if (armorMaterial == CinderLoE.MATERIAL_RHUDAUR.toArmorMaterial())
return (materialItem.getItem() == Items.iron_ingot);
if (armorMaterial == CinderLoE.MATERIAL_JADE.toArmorMaterial())
return (materialItem.getItem() == LOTRMod.emerald);
if (armorMaterial == CinderLoE.MATERIAL_SERPENT.toArmorMaterial())
return (materialItem.getItem() == LOTRMod.bronze);
if (armorMaterial == CinderLoE.MATERIAL_WARLORD.toArmorMaterial())
return (materialItem.getItem() == LOTRMod.bronze);
if (armorMaterial == CinderLoE.MATERIAL_USURPER.toArmorMaterial())
return (materialItem.getItem() == Items.iron_ingot);
}
return false;
}
/**
* @author Shinare
* @reason Adding repair kits and removing bad modifiers from 3 modifier limit
**/
@Overwrite(remap = false)
private void updateRepairOutput() {
ItemStack inputItem = this.invInput.getStackInSlot(0);
this.materialCost = 0;
this.reforgeCost = 0;
this.engraveOwnerCost = 0;
this.isSmithScrollCombine = false;
int baseAnvilCost = 0;
int repairCost = 0;
int combineCost = 0;
int renameCost = 0;
if (inputItem == null) {
this.invOutput.setInventorySlotContents(0, null);
this.materialCost = 0;
} else {
ItemStack inputCopy = inputItem.copy();
ItemStack combinerItem = this.invInput.getStackInSlot(1);
ItemStack materialItem = this.isTrader ? null : this.invInput.getStackInSlot(2);
Map<?, ?> inputEnchants = EnchantmentHelper.getEnchantments(inputCopy);
boolean enchantingWithBook = false;
List<LOTREnchantment> inputModifiers = LOTREnchantmentHelper.getEnchantList(inputCopy);
baseAnvilCost = LOTREnchantmentHelper.getAnvilCost(inputItem) + ((combinerItem == null) ? 0 : LOTREnchantmentHelper.getAnvilCost(combinerItem));
this.materialCost = 0;
String previousDisplayName = inputCopy.getDisplayName();
String defaultItemName = inputCopy.getItem().getItemStackDisplayName(inputCopy);
String nameToApply = this.repairedItemName;
String formattedNameToApply = nameToApply;
List<EnumChatFormatting> colorsToApply = new ArrayList<EnumChatFormatting>();
colorsToApply.addAll(getAppliedFormattingCodes(inputCopy.getDisplayName()));
boolean alteringNameColor = false;
if (costsToRename(inputItem) && combinerItem != null) {
if (combinerItem.getItem() instanceof AnvilNameColorProvider) {
AnvilNameColorProvider nameColorProvider = (AnvilNameColorProvider)combinerItem.getItem();
EnumChatFormatting newColor = nameColorProvider.getAnvilNameColor();
boolean isDifferentColor = !colorsToApply.contains(newColor);
if (isDifferentColor) {
for (EnumChatFormatting ecf : EnumChatFormatting.values()) {
if (ecf.isColor())
while (colorsToApply.contains(ecf))
colorsToApply.remove(ecf);
}
colorsToApply.add(newColor);
alteringNameColor = true;
}
} else if (combinerItem.getItem() == Items.flint) {
if (!colorsToApply.isEmpty()) {
colorsToApply.clear();
alteringNameColor = true;
}
}
if (alteringNameColor)
renameCost++;
}
if (!colorsToApply.isEmpty()) {
if (StringUtils.isBlank(formattedNameToApply))
formattedNameToApply = defaultItemName;
formattedNameToApply = applyFormattingCodes(formattedNameToApply, colorsToApply);
}
boolean nameChange = false;
if (formattedNameToApply != null && !formattedNameToApply.equals(previousDisplayName))
if (StringUtils.isBlank(formattedNameToApply) || formattedNameToApply.equals(defaultItemName)) {
if (inputCopy.hasDisplayName()) {
inputCopy.func_135074_t();
if (!stripFormattingCodes(previousDisplayName).equals(stripFormattingCodes(formattedNameToApply)))
nameChange = true;
}
} else {
inputCopy.setStackDisplayName(formattedNameToApply);
if (!stripFormattingCodes(previousDisplayName).equals(stripFormattingCodes(formattedNameToApply)))
nameChange = true;
}
if (nameChange) {
boolean costRename = costsToRename(inputItem);
if (costRename)
renameCost++;
}
if (this.isTrader) {
LOTREnchantmentCombining.CombineRecipe scrollCombine = LOTREnchantmentCombining.getCombinationResult(inputItem, combinerItem);
if (scrollCombine != null) {
this.invOutput.setInventorySlotContents(0, scrollCombine.createOutputItem());
this.materialCost = scrollCombine.cost;
this.reforgeCost = 0;
this.engraveOwnerCost = 0;
this.isSmithScrollCombine = true;
return;
}
}
boolean combining = false;
if (combinerItem != null) {
enchantingWithBook = (combinerItem.getItem() == Items.enchanted_book && Items.enchanted_book.func_92110_g(combinerItem).tagCount() > 0);
if (enchantingWithBook && !LOTRConfig.enchantingVanilla) {
this.invOutput.setInventorySlotContents(0, null);
this.materialCost = 0;
return;
}
LOTREnchantment combinerItemEnchant = null;
if (combinerItem.getItem() instanceof LOTRItemEnchantment) {
combinerItemEnchant = ((LOTRItemEnchantment)combinerItem.getItem()).theEnchant;
} else if (combinerItem.getItem() instanceof LOTRItemModifierTemplate) {
combinerItemEnchant = LOTRItemModifierTemplate.getModifier(combinerItem);
}
if (!enchantingWithBook && combinerItemEnchant == null)
if (inputCopy.isItemStackDamageable() && inputCopy.getItem() == combinerItem.getItem()) {
int inputUseLeft = inputItem.getMaxDamage() - inputItem.getItemDamageForDisplay();
int combinerUseLeft = combinerItem.getMaxDamage() - combinerItem.getItemDamageForDisplay();
int restoredUses = combinerUseLeft + inputCopy.getMaxDamage() * 12 / 100;
int newUsesLeft = inputUseLeft + restoredUses;
int newDamage = inputCopy.getMaxDamage() - newUsesLeft;
newDamage = Math.max(newDamage, 0);
if (newDamage < inputCopy.getItemDamage()) {
inputCopy.setItemDamage(newDamage);
int restoredUses1 = inputCopy.getMaxDamage() - inputUseLeft;
int restoredUses2 = inputCopy.getMaxDamage() - combinerUseLeft;
combineCost += Math.max(0, Math.min(restoredUses1, restoredUses2) / 100);
}
combining = true;
} else if (!alteringNameColor && combinerItem.getItem() != CinderLoE.forgingKit) {
this.invOutput.setInventorySlotContents(0, null);
this.materialCost = 0;
return;
}
Map<Object, Object> outputEnchants = new HashMap<Object, Object>(inputEnchants);
if (LOTRConfig.enchantingVanilla) {
Map combinerEnchants = EnchantmentHelper.getEnchantments(combinerItem);
for (Object obj : combinerEnchants.keySet()) {
int combinedEnchLevel, combinerEnchID = ((Integer)obj).intValue();
Enchantment combinerEnch = Enchantment.enchantmentsList[combinerEnchID];
int inputEnchLevel = 0;
if (outputEnchants.containsKey(Integer.valueOf(combinerEnchID)))
inputEnchLevel = ((Integer)outputEnchants.get(Integer.valueOf(combinerEnchID))).intValue();
int combinerEnchLevel = ((Integer)combinerEnchants.get(Integer.valueOf(combinerEnchID))).intValue();
if (inputEnchLevel == combinerEnchLevel) {
combinedEnchLevel = ++combinerEnchLevel;
} else {
combinedEnchLevel = Math.max(combinerEnchLevel, inputEnchLevel);
}
combinerEnchLevel = combinedEnchLevel;
int levelsAdded = combinerEnchLevel - inputEnchLevel;
boolean canApply = combinerEnch.canApply(inputItem);
if (this.thePlayer.capabilities.isCreativeMode || inputItem.getItem() == Items.enchanted_book)
canApply = true;
for (Object objIn : outputEnchants.keySet()) {
int inputEnchID = ((Integer)objIn).intValue();
Enchantment inputEnch = Enchantment.enchantmentsList[inputEnchID];
if (inputEnchID != combinerEnchID)
if (!combinerEnch.canApplyTogether(inputEnch) || !inputEnch.canApplyTogether(combinerEnch)) {
canApply = false;
combineCost += levelsAdded;
}
}
if (canApply) {
combinerEnchLevel = Math.min(combinerEnchLevel, combinerEnch.getMaxLevel());
outputEnchants.put(Integer.valueOf(combinerEnchID), Integer.valueOf(combinerEnchLevel));
int costPerLevel = 0;
int enchWeight = combinerEnch.getWeight();
if (enchWeight == 1) {
costPerLevel = 8;
} else if (enchWeight == 2) {
costPerLevel = 4;
} else if (enchWeight == 5) {
costPerLevel = 2;
} else if (enchWeight == 10) {
costPerLevel = 1;
}
combineCost += costPerLevel * levelsAdded;
}
}
} else {
outputEnchants.clear();
}
EnchantmentHelper.setEnchantments(outputEnchants, inputCopy);
int maxMods = 3;
List<LOTREnchantment> outputMods = new ArrayList<LOTREnchantment>();
outputMods.addAll(inputModifiers);
List<LOTREnchantment> combinerMods = LOTREnchantmentHelper.getEnchantList(combinerItem);
if (combinerItemEnchant != null) {
combinerMods.add(combinerItemEnchant);
if (combinerItemEnchant == LOTREnchantment.fire) {
Item item = inputCopy.getItem();
if (LOTRRecipePoisonWeapon.poisonedToInput.containsKey(item)) {
Item unpoisoned = (Item)LOTRRecipePoisonWeapon.poisonedToInput.get(item);
inputCopy.func_150996_a(unpoisoned);
}
}
}
for (LOTREnchantment combinerMod : combinerMods) {
boolean canApply = combinerMod.canApply(inputItem, false);
if (canApply)
for (LOTREnchantment mod : outputMods) {
if (!mod.isCompatibleWith(combinerMod) || !combinerMod.isCompatibleWith(mod))
canApply = false;
}
int numOutputMods = 0;
for (LOTREnchantment mod : outputMods) {
if (!mod.bypassAnvilLimit())
numOutputMods++;
}
if (!combinerMod.bypassAnvilLimit() && numOutputMods >= maxMods)
canApply = false;
if (canApply) {
outputMods.add(combinerMod);
if (combinerMod.isBeneficial())
combineCost += Math.max(1, (int)combinerMod.getValueModifier());
}
}
if (combinerItem.getItem() == CinderLoE.forgingKit) {
List<LOTREnchantment> newMods = new ArrayList<LOTREnchantment>();
if (combinerItem.getItemDamage() == 0) {
for (LOTREnchantment mod : outputMods) {
if (Utilities.isBadEnch(mod)) {
combineCost += 2;
} else {
newMods.add(mod);
}
}
} else {
for (LOTREnchantment mod : outputMods) {
if (Utilities.upgradedEnchants.containsKey(mod.enchantName)) {
combineCost += 2;
newMods.add(Utilities.upgradeEnch(inputCopy, mod));
} else {
newMods.add(mod);
}
}
}
outputMods = newMods;
}
LOTREnchantmentHelper.setEnchantList(inputCopy, outputMods);
}
if (combineCost > 0)
combining = true;
int numEnchants = 0;
for (Object obj : inputEnchants.keySet()) {
int enchID = ((Integer)obj).intValue();
Enchantment ench = Enchantment.enchantmentsList[enchID];
int enchLevel = ((Integer)inputEnchants.get(Integer.valueOf(enchID))).intValue();
numEnchants++;
int costPerLevel = 0;
int enchWeight = ench.getWeight();
if (enchWeight == 1) {
costPerLevel = 8;
} else if (enchWeight == 2) {
costPerLevel = 4;
} else if (enchWeight == 5) {
costPerLevel = 2;
} else if (enchWeight == 10) {
costPerLevel = 1;
}
baseAnvilCost += numEnchants + enchLevel * costPerLevel;
}
if (enchantingWithBook && !inputCopy.getItem().isBookEnchantable(inputCopy, combinerItem))
inputCopy = null;
for (LOTREnchantment mod : inputModifiers) {
if (mod.isBeneficial())
baseAnvilCost += Math.max(1, (int)mod.getValueModifier());
}
if (inputCopy.isItemStackDamageable()) {
boolean canRepair = false;
int availableMaterials = 0;
if (this.isTrader) {
canRepair = (getTraderMaterialPrice(inputItem) > 0.0F);
availableMaterials = Integer.MAX_VALUE;
} else {
canRepair = (materialItem != null && isRepairMaterial(inputItem, materialItem));
if (materialItem != null)
availableMaterials = materialItem.stackSize - combineCost - renameCost;
}
int oneItemRepair = Math.min(inputCopy.getItemDamageForDisplay(), inputCopy.getMaxDamage() / 4);
if (canRepair && availableMaterials > 0 && oneItemRepair > 0) {
availableMaterials -= baseAnvilCost;
if (availableMaterials > 0) {
int usedMaterials = 0;
while (oneItemRepair > 0 && usedMaterials < availableMaterials) {
int newDamage = inputCopy.getItemDamageForDisplay() - oneItemRepair;
inputCopy.setItemDamage(newDamage);
oneItemRepair = Math.min(inputCopy.getItemDamageForDisplay(), inputCopy.getMaxDamage() / 4);
usedMaterials++;
}
repairCost += usedMaterials;
} else if (!nameChange && !combining) {
repairCost = 1;
int newDamage = inputCopy.getItemDamageForDisplay() - oneItemRepair;
inputCopy.setItemDamage(newDamage);
}
}
}
boolean repairing = (repairCost > 0);
if (combining || repairing) {
this.materialCost = baseAnvilCost;
this.materialCost += combineCost + repairCost;
} else {
this.materialCost = 0;
}
this.materialCost += renameCost;
if (inputCopy != null) {
int nextAnvilCost = LOTREnchantmentHelper.getAnvilCost(inputItem);
if (combinerItem != null) {
int combinerAnvilCost = LOTREnchantmentHelper.getAnvilCost(combinerItem);
nextAnvilCost = Math.max(nextAnvilCost, combinerAnvilCost);
}
if (combining) {
nextAnvilCost += 2;
} else if (repairing) {
nextAnvilCost++;
}
nextAnvilCost = Math.max(nextAnvilCost, 0);
if (nextAnvilCost > 0)
LOTREnchantmentHelper.setAnvilCost(inputCopy, nextAnvilCost);
}
if (LOTREnchantmentHelper.isReforgeable(inputItem)) {
this.reforgeCost = 2;
if (inputItem.getItem() instanceof ItemArmor)
this.reforgeCost = 3;
if (inputItem.isItemStackDamageable()) {
ItemStack reforgeCopy = inputItem.copy();
int oneItemRepair = Math.min(reforgeCopy.getItemDamageForDisplay(), reforgeCopy.getMaxDamage() / 4);
if (oneItemRepair > 0) {
int usedMaterials = 0;
while (oneItemRepair > 0) {
int newDamage = reforgeCopy.getItemDamageForDisplay() - oneItemRepair;
reforgeCopy.setItemDamage(newDamage);
oneItemRepair = Math.min(reforgeCopy.getItemDamageForDisplay(), reforgeCopy.getMaxDamage() / 4);
usedMaterials++;
}
this.reforgeCost += usedMaterials;
}
}
this.engraveOwnerCost = 2;
} else {
this.reforgeCost = 0;
this.engraveOwnerCost = 0;
}
if (isRepairMaterial(inputItem, new ItemStack(Items.string))) {
int stringFactor = 3;
this.materialCost *= stringFactor;
this.reforgeCost *= stringFactor;
this.engraveOwnerCost *= stringFactor;
}
if (this.isTrader) {
boolean isCommonRenameOnly = (nameChange && this.materialCost == 0);
float materialPrice = getTraderMaterialPrice(inputItem);
if (materialPrice > 0.0F) {
this.materialCost = Math.round(this.materialCost * materialPrice);
this.materialCost = Math.max(this.materialCost, 1);
this.reforgeCost = Math.round(this.reforgeCost * materialPrice);
this.reforgeCost = Math.max(this.reforgeCost, 1);
this.engraveOwnerCost = Math.round(this.engraveOwnerCost * materialPrice);
this.engraveOwnerCost = Math.max(this.engraveOwnerCost, 1);
if (this.theTrader instanceof LOTREntityScrapTrader) {
this.materialCost = MathHelper.ceiling_float_int(this.materialCost * 0.5F);
this.materialCost = Math.max(this.materialCost, 1);
this.reforgeCost = MathHelper.ceiling_float_int(this.reforgeCost * 0.5F);
this.reforgeCost = Math.max(this.reforgeCost, 1);
this.engraveOwnerCost = MathHelper.ceiling_float_int(this.engraveOwnerCost * 0.5F);
this.engraveOwnerCost = Math.max(this.engraveOwnerCost, 1);
}
} else if (!isCommonRenameOnly) {
this.invOutput.setInventorySlotContents(0, null);
this.materialCost = 0;
this.reforgeCost = 0;
this.engraveOwnerCost = 0;
return;
}
}
if (combining || repairing || nameChange || alteringNameColor) {
this.invOutput.setInventorySlotContents(0, inputCopy);
} else {
this.invOutput.setInventorySlotContents(0, null);
this.materialCost = 0;
}
detectAndSendChanges();
}
}
}