summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLance5057 <Lance5057@gmail.com>2017-05-24 03:05:20 -0500
committerLance5057 <Lance5057@gmail.com>2017-05-24 03:05:20 -0500
commitbd1d6e11213dfc5ad2cd8dab8304badccf428de4 (patch)
tree3b4feabea0ca5c9fe79ac8a1537df632e53ceb53
parent1e3d888b8221f6997f009f46e1ff85d1b0ccaf6c (diff)
Redoing Armor stuff
-rw-r--r--src/main/java/lance5057/tDefense/armor/ArmorCore.java739
-rw-r--r--src/main/java/lance5057/tDefense/armor/events/ArmorBaseEvents.java33
-rw-r--r--src/main/java/lance5057/tDefense/armor/items/cloth/TinkersHood.java2
-rw-r--r--src/main/java/lance5057/tDefense/armor/util/ArmorBuilder.java115
4 files changed, 653 insertions, 236 deletions
diff --git a/src/main/java/lance5057/tDefense/armor/ArmorCore.java b/src/main/java/lance5057/tDefense/armor/ArmorCore.java
index 8eefb29..f42fc11 100644
--- a/src/main/java/lance5057/tDefense/armor/ArmorCore.java
+++ b/src/main/java/lance5057/tDefense/armor/ArmorCore.java
@@ -1,31 +1,71 @@
package lance5057.tDefense.armor;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import javax.annotation.Nonnull;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+
+import gnu.trove.set.hash.THashSet;
+import lance5057.tDefense.armor.events.ArmorBaseEvents;
import lance5057.tDefense.armor.materials.MaterialArmor;
import lance5057.tDefense.armor.materials.MaterialCloth;
-import net.minecraft.client.model.ModelBiped;
+import lance5057.tDefense.armor.util.ArmorBuilder;
+import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.EntityEquipmentSlot;
+import net.minecraft.item.EnumRarity;
+import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.nbt.NBTTagString;
import net.minecraft.util.DamageSource;
+import net.minecraft.util.text.TextFormatting;
+import net.minecraft.util.text.translation.I18n;
+import net.minecraft.world.World;
import net.minecraftforge.common.ISpecialArmor;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
+import slimeknights.mantle.util.RecipeMatch;
+import slimeknights.tconstruct.common.ClientProxy;
+import slimeknights.tconstruct.common.config.Config;
+import slimeknights.tconstruct.library.Util;
+import slimeknights.tconstruct.library.materials.HeadMaterialStats;
+import slimeknights.tconstruct.library.materials.Material;
+import slimeknights.tconstruct.library.materials.MaterialTypes;
+import slimeknights.tconstruct.library.modifiers.TinkerGuiException;
+import slimeknights.tconstruct.library.tinkering.Category;
+import slimeknights.tconstruct.library.tinkering.IModifyable;
+import slimeknights.tconstruct.library.tinkering.IRepairable;
+import slimeknights.tconstruct.library.tinkering.ITinkerable;
+import slimeknights.tconstruct.library.tinkering.IToolStationDisplay;
+import slimeknights.tconstruct.library.tinkering.IndestructibleEntityItem;
import slimeknights.tconstruct.library.tinkering.PartMaterialType;
-import slimeknights.tconstruct.library.tools.ToolCore;
-import slimeknights.tconstruct.library.tools.ToolNBT;
+import slimeknights.tconstruct.library.traits.ITrait;
+import slimeknights.tconstruct.library.utils.TagUtil;
+import slimeknights.tconstruct.library.utils.Tags;
+import slimeknights.tconstruct.library.utils.TinkerUtil;
+import slimeknights.tconstruct.library.utils.ToolBuilder;
+import slimeknights.tconstruct.library.utils.ToolHelper;
+import slimeknights.tconstruct.library.utils.TooltipBuilder;
//@Optional.InterfaceList({@Optional.Interface(modid = "Thaumcraft", iface = "thaumcraft.api.IRunicArmor", striprefs = true), @Optional.Interface(modid = "Botania", iface = "vazkii.botania.api.item.IPixieSpawner", striprefs = true)})
-public abstract class ArmorCore extends ToolCore implements ISpecialArmor// ,
+public abstract class ArmorCore extends ItemArmor implements ISpecialArmor, ITinkerable, IModifyable, IRepairable, IToolStationDisplay// ,
// IRunicArmor,
// IPixieSpawner
{
public final EntityEquipmentSlot armorType;
public float reductionPercent = 0f;
- protected int maxReduction = 100;
+ public int maxReduction = 100;
protected static PartMaterialType ArmorplateMat = new PartMaterialType(ArmorBase.armorPlate, MaterialArmor.TYPE);
protected static PartMaterialType ChainmailMat = new PartMaterialType(ArmorBase.chainmail, MaterialArmor.TYPE);
@@ -34,17 +74,19 @@ public abstract class ArmorCore extends ToolCore implements ISpecialArmor// ,
protected static PartMaterialType ClothMat = new PartMaterialType(ArmorBase.cloth, MaterialCloth.TYPE);
- // public String[] renderParts;
+ ArmorProperties armorp;// = new ArmorProperties(0,0,0);
+ /// public String[] renderParts;
// Thaumcraft
boolean Charge = false;
- public ArmorCore(EntityEquipmentSlot slot, PartMaterialType... requiredComponents) {
- super(requiredComponents);
- armorType = slot;
-
- //MinecraftForge.EVENT_BUS.register(this);
- }
+// public ArmorCore(EntityEquipmentSlot slot, PartMaterialType... requiredComponents) {
+// //super(requiredComponents);
+// armorType = slot;
+// //armorp = prop;
+//
+// //MinecraftForge.EVENT_BUS.register(this);
+// }
@SideOnly(Side.CLIENT)
public EntityEquipmentSlot getEquipmentSlot() {
@@ -54,244 +96,471 @@ public abstract class ArmorCore extends ToolCore implements ISpecialArmor// ,
@Override
public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage,
int slot) {
- ArmorProperties armorp;
+
if (!source.isUnblockable()) {
- armorp = new ArmorProperties(0, reductionPercent, maxReduction); // 0.04
- // per
- // half
- // shirt
+ return armorp;
} else {
- armorp = new ArmorProperties(0, 0, 0);
+ return new ArmorProperties(0, 0, 0);
}
- return armorp;
+
}
-
+
@Override
public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot) {
return (int) ((int) reductionPercent / 0.04);
}
- @SideOnly(Side.CLIENT)
- public ModelBiped getModel(String[] color, NBTTagCompound tags) {
- return null;
- }
-
- @Override
- public NBTTagCompound buildTag(
- List<slimeknights.tconstruct.library.materials.Material> materials) {
- ToolNBT data = buildDefaultTag(materials);
- return data.get();
- }
+ protected final PartMaterialType[] requiredComponents;
+ // used to classify what the thing can do
+ protected final Set<Category> categories = new THashSet<Category>();
-// @Override
-// public void damageArmor(EntityLivingBase entity, ItemStack stack, DamageSource source, int damage, int slot) {
-// AbilityHelper.damageTool(stack, damage, entity, false);
-// }
+ public ArmorCore(ArmorMaterial materialIn, int renderIndexIn, EntityEquipmentSlot equipmentSlotIn, ArmorProperties prop, PartMaterialType... requiredComponents) {
+ super(materialIn, renderIndexIn, equipmentSlotIn);
+
+ this.requiredComponents = requiredComponents;
-// @Override
-// @SideOnly(Side.CLIENT)
-// public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) {
-// if (itemStack.getItem() instanceof ToolCore) {
-// final String[] color = new String[10];
-// final ToolCore tool = (ToolCore) itemStack.getItem();
-//
-// for (int j = 0; j < 10; j++) {
-// color[j] = Integer.toHexString(itemStack.getItem().getColorFromItemStack(itemStack, j));
-//
-// switch (j) {
-// case 0:
-// if (tool.getHandleItem() == TinkersDefense.partCloth) {
-// final int ID = itemStack.getTagCompound().getCompoundTag("InfiTool").getInteger("RenderHandle");
-//
-// final CustomMaterial newColor = TConstructRegistry.getCustomMaterial(ID, ClothMaterial.class);
-// color[j] = Integer.toHexString(newColor.color);
-// }
-// break;
-//
-// case 1:
-// if (tool.getHeadItem() == TinkersDefense.partCloth) {
-// final int ID = itemStack.getTagCompound().getCompoundTag("InfiTool").getInteger("RenderHead");
-//
-// final CustomMaterial newColor = TConstructRegistry.getCustomMaterial(ID, ClothMaterial.class);
-// color[j] = Integer.toHexString(newColor.color);
-// }
-// break;
-//
-// case 2:
-// if (tool.getAccessoryItem() != null && tool.getAccessoryItem() == TinkersDefense.partCloth) {
-// final int ID = itemStack.getTagCompound().getCompoundTag("InfiTool")
-// .getInteger("RenderAccessory");
-//
-// final CustomMaterial newColor = TConstructRegistry.getCustomMaterial(ID, ClothMaterial.class);
-// color[j] = Integer.toHexString(newColor.color);
-// }
-// break;
-//
-// case 3:
-// if (tool.getExtraItem() != null && tool.getExtraItem() == TinkersDefense.partCloth) {
-// final int ID = itemStack.getTagCompound().getCompoundTag("InfiTool").getInteger("RenderExtra");
-//
-// final CustomMaterial newColor = TConstructRegistry.getCustomMaterial(ID, ClothMaterial.class);
-// color[j] = Integer.toHexString(newColor.color);
-// }
-// break;
-// }
-// }
-//
-// final ArmorRenderer model = getRenderer();
-// model.SetColors(color, getDefaultFolder(), itemStack);
-// return model;
-// }
-// return null;
-// }
+ this.setMaxStackSize(1);
+
+
+ armorp = prop;
+ armorType = equipmentSlotIn;
+ //this.setHasSubtypes(true);
+ }
-// @SideOnly(Side.CLIENT)
-// public abstract ArmorRenderer getRenderer();
+ /* Tool Information */
+ public List<PartMaterialType> getRequiredComponents() {
+ return ImmutableList.copyOf(requiredComponents);
+ }
-// @Override
-// public Item getAccessoryItem() {
-// return null;
-// }
-//
-// @Override
-// public String getDefaultFolder() {
-// return null;
-// }
-//
-// @Override
-// public String getEffectSuffix() {
-// return null;
-// }
-//
-// @Override
-// public Item getHeadItem() {
-// return null;
-// }
-//
-// @Override
-// public String getIconSuffix(int arg0) {
-// return null;
-// }
-//
-// @Override
-// public String[] getTraits() {
-// return new String[] { "armor" };
-// }
+ public List<PartMaterialType> getToolBuildComponents() {
+ return getRequiredComponents();
+ }
-// @Override
-// public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack) {
-//
-// Modifiers.AMod.UpdateAll((ToolCore) itemStack.getItem(), itemStack, world, player,
-// itemStack.getTagCompound().getCompoundTag("InfiTool"));
-// }
-//
-// @Override
-// public int getRunicCharge(ItemStack itemstack) {
-// return 0;
-// }
+ protected void addCategory(Category... categories) {
+ Collections.addAll(this.categories, categories);
+ }
-// @Override
-// public void onUpdate(ItemStack stack, World world, Entity ent, int p_77663_4_, boolean p_77663_5_) {
-// // Check if runic shielding level has changed
-// if (TDIntegration.thaumcraft) {
-// final NBTTagCompound tcTag = stack.getTagCompound();
-// final NBTTagCompound ticoTag = stack.getTagCompound().getCompoundTag("InfiTool");
-//
-// final byte rs = tcTag.getByte("RS.HARDEN");
-// if (!Charge && rs > 0) {
-// if (ticoTag.getInteger("Modifiers") > 0) {
-// ticoTag.setInteger("Modifiers", ticoTag.getInteger("Modifiers") - 1);
-// Charge = true;
-// } else {
-// tcTag.removeTag("RS.HARDEN");
-// }
-// }
-// }
-// }
+ public boolean hasCategory(Category category) {
+ return categories.contains(category);
+ }
-// public void renderArmor(Entity entity, float f, float f1, float f2, float f3, float f4, float f5, String[] colors,
-// ItemStack stack, int pass) {
-//
-// final ResourceLocation rc = new ResourceLocation(
-// "tinkersdefense:textures/" + getDefaultFolder() + "/" + getTexture(pass, stack) + ".png");
-// FMLClientHandler.instance().getClient().renderEngine.bindTexture(rc);
-//
-// final float size = 1.6f;
-// GL11.glScalef(1.0F / size, 1.0F / size, 1.0F / size);
-// GL11.glTranslatef(0.0F, -0.01F, 0.0F);
-//
-// final int[] intColors = TinkersDefense.hexToRGB(colors[pass]);
-// GL11.glColor3d((float) intColors[0] / 255, (float) intColors[1] / 255, (float) intColors[2] / 255);
-//
-// }
-//
-// public String getTexture(int pass, ItemStack stack) {
-// final NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool");
-// String renderReturn = "";
-// switch (pass) {
-// case 0:
-// renderReturn = handleStrings.get(tags.getInteger("RenderHandle"));
-// break;
-// case 1:
-// renderReturn = headStrings.get(tags.getInteger("RenderHead"));
-// break;
-// case 2:
-// renderReturn = accessoryStrings.get(tags.getInteger("RenderAccessory"));
-// break;
-// case 3:
-// renderReturn = extraStrings.get(tags.getInteger("RenderExtra"));
-// break;
-// //
-// // default:
-// // if(tags != null && tags.hasKey("Effect" + (pass - getPartAmount())))
-// // {
-// // final String effect = effectStrings.get(tags.getInteger("Effect" +
-// // (pass - getPartAmount())));
-// // if(effect != null)
-// // return effect.substring(effect.lastIndexOf("/") + 1);
-// // else
-// // return "";
-// //
-// // }
-// }
-// if (renderReturn != null && renderReturn != "") {
-// renderReturn = renderReturn.substring(renderReturn.indexOf("_"));
-// } else {
-// renderReturn = "";
-// }
-//
-// return renderReturn;
-// }
-//
-// @Override
-// public float getPixieChance(ItemStack stack) {
-// final float chance = stack.getTagCompound().getCompoundTag("InfiTool").getInteger("ElementiumCore") * 5 / 100f;
-// return chance;
-// }
-//
-// @SubscribeEvent
-// public void ToolCraftedEvent(NormalTool event) {
-// if (event.tool instanceof ArmorCore) {
-// final ArmorCore armor = (ArmorCore) event.tool;
-// final ArmorRenderer render = armor.getRenderer();
-// final NBTTagCompound tooltags = event.toolTag;
-// final NBTTagCompound tags = render.defaultTags;// stack.setTagCompound();
-//
-// // for(int i = 0; i < render.defaultTags.; i++)
-// // {
-// // final String rendertag = ((ModelRenderer)
-// // render.boxList.get(i)).boxName;
-// // if(rendertag != null)
-// // {
-// // tags.setBoolean(rendertag, ((ModelRenderer)
-// // render.boxList.get(i)).isHidden);
-// // }
-// // }
-//
-// if (!tags.hasNoTags()) {
-// tooltags.setTag("ArmorRenderer", tags);
-// }
-// }
-// }
+ protected Category[] getCategories() {
+ Category[] out = new Category[categories.size()];
+ int i = 0;
+ for(Category category : categories) {
+ out[i++] = category;
+ }
+
+ return out;
+ }
+
+ /* INDESTRUCTIBLE */
+
+ @Override
+ public boolean hasCustomEntity(ItemStack stack) {
+ return true;
+ }
+
+ @Nonnull
+ @Override
+ public Entity createEntity(World world, Entity location, ItemStack itemstack) {
+ EntityItem entity = new IndestructibleEntityItem(world, location.posX, location.posY, location.posZ, itemstack);
+ if(location instanceof EntityItem) {
+ // workaround for private access on that field >_>
+ NBTTagCompound tag = new NBTTagCompound();
+ location.writeToNBT(tag);
+ entity.setPickupDelay(tag.getShort("PickupDelay"));
+ }
+ entity.motionX = location.motionX;
+ entity.motionY = location.motionY;
+ entity.motionZ = location.motionZ;
+ return entity;
+ }
+
+ /* Building the Item */
+ public boolean validComponent(int slot, ItemStack stack) {
+ if(slot > requiredComponents.length || slot < 0) {
+ return false;
+ }
+
+ return requiredComponents[slot].isValid(stack);
+ }
+
+
+ /**
+ * Builds an Itemstack of this tool with the given materials, if applicable.
+ *
+ * @param stacks Items to build with. Have to be in the correct order and have exact length. No nulls!
+ * @return The built item or null if invalid input.
+ */
+ public ItemStack buildItemFromStacks(ItemStack[] stacks) {
+ List<Material> materials = new ArrayList<Material>(stacks.length);
+
+ if(stacks.length != requiredComponents.length) {
+ return null;
+ }
+
+ // not a valid part arrangement for this tool
+ for(int i = 0; i < stacks.length; i++) {
+ if(!validComponent(i, stacks[i])) {
+ return null;
+ }
+
+ materials.add(TinkerUtil.getMaterialFromStack(stacks[i]));
+ }
+
+ return buildItem(materials);
+ }
+
+ /**
+ * Builds an Itemstack of this tool with the given materials.
+ *
+ * @param materials Materials to build with. Have to be in the correct order. No nulls!
+ * @return The built item or null if invalid input.
+ */
+ public ItemStack buildItem(List<Material> materials) {
+ ItemStack tool = new ItemStack(this);
+ tool.setTagCompound(buildItemNBT(materials));
+
+ return tool;
+ }
+
+ /**
+ * Builds the NBT for a new tinker item with the given data.
+ *
+ * @param materials Materials to build with. Have to be in the correct order. No nulls!
+ * @return The built nbt
+ */
+ public NBTTagCompound buildItemNBT(List<Material> materials) {
+ NBTTagCompound basetag = new NBTTagCompound();
+ NBTTagCompound toolTag = buildTag(materials);
+ NBTTagCompound dataTag = buildData(materials);
+
+ basetag.setTag(Tags.BASE_DATA, dataTag);
+ basetag.setTag(Tags.TOOL_DATA, toolTag);
+ // copy of the original tool data
+ basetag.setTag(Tags.TOOL_DATA_ORIG, toolTag.copy());
+
+ // save categories on the tool
+ TagUtil.setCategories(basetag, getCategories());
+
+ // add traits
+ addMaterialTraits(basetag, materials);
+
+ // fire toolbuilding event
+ ArmorBaseEvents.OnArmorBuilding.fireEvent(basetag, ImmutableList.copyOf(materials), this);
+
+ return basetag;
+ }
+
+ /**
+ * Creates an NBT Tag with the materials that were used to build the item.
+ */
+ private NBTTagCompound buildData(List<Material> materials) {
+ NBTTagCompound base = new NBTTagCompound();
+ NBTTagList materialList = new NBTTagList();
+
+ for(Material material : materials) {
+ materialList.appendTag(new NBTTagString(material.identifier));
+ }
+
+ // pre-type base-modifier list
+ NBTTagList modifierList = new NBTTagList();
+ // we cannot set the type directly, but it gets typed by adding a tag, so we add and remove one
+ modifierList.appendTag(new NBTTagString());
+ modifierList.removeTag(0);
+
+ base.setTag(Tags.BASE_MATERIALS, materialList);
+ base.setTag(Tags.BASE_MODIFIERS, modifierList);
+
+ return base;
+ }
+
+ /**
+ * Builds an unusable tool that only has the rendering info
+ */
+ public ItemStack buildItemForRendering(List<Material> materials) {
+ ItemStack tool = new ItemStack(this);
+ NBTTagCompound base = new NBTTagCompound();
+ base.setTag(Tags.BASE_DATA, buildData(materials));
+ tool.setTagCompound(base);
+
+ return tool;
+ }
+
+ public ItemStack buildItemForRenderingInGui() {
+ List<Material> materials = IntStream.range(0, getRequiredComponents().size())
+ .mapToObj(this::getMaterialForPartForGuiRendering)
+ .collect(Collectors.toList());
+
+ return buildItemForRendering(materials);
+ }
+
+ @SideOnly(Side.CLIENT)
+ public Material getMaterialForPartForGuiRendering(int index) {
+ return ClientProxy.RenderMaterials[index % ClientProxy.RenderMaterials.length];
+ }
+
+ public abstract NBTTagCompound buildTag(List<Material> materials);
+
+ /** Checks whether an Item built from materials has only valid materials. Uses the standard NBT to determine materials. */
+ public boolean hasValidMaterials(ItemStack stack) {
+ // checks if the materials used support all stats needed
+ NBTTagList list = TagUtil.getBaseMaterialsTagList(stack);
+ List<Material> materials = TinkerUtil.getMaterialsFromTagList(list);
+
+ // something went wrooooong
+ if(materials.size() != requiredComponents.length) {
+ return false;
+ }
+
+ // check if all materials used have the stats needed
+ for(int i = 0; i < materials.size(); i++) {
+ Material material = materials.get(i);
+ PartMaterialType required = requiredComponents[i];
+ if(!required.isValidMaterial(material)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public void addMaterialTraits(NBTTagCompound root, List<Material> materials) {
+ int size = requiredComponents.length;
+ // safety
+ if(materials.size() < size) {
+ size = materials.size();
+ }
+ // add corresponding traits per material usage
+ for(int i = 0; i < size; i++) {
+ PartMaterialType required = requiredComponents[i];
+ Material material = materials.get(i);
+ for(ITrait trait : required.getApplicableTraitsForMaterial(material)) {
+ ToolBuilder.addTrait(root, trait, material.materialTextColor);
+ }
+ }
+ }
+
+ /* Repairing */
+
+ /** Returns indices of the parts that are used for repairing */
+ public int[] getRepairParts() {
+ return new int[]{1}; // index 1 usually is the head. 0 is handle.
+ }
+
+ public float getRepairModifierForPart(int index) {
+ return 1f;
+ }
+
+ @Override
+ public ItemStack repair(ItemStack repairable, ItemStack[] repairItems) {
+ if(repairable.getItemDamage() == 0 && !ToolHelper.isBroken(repairable)) {
+ // undamaged and not broken - no need to repair
+ return null;
+ }
+
+ // we assume the first required part exclusively determines repair material
+ List<Material> materials = TinkerUtil.getMaterialsFromTagList(TagUtil.getBaseMaterialsTagList(repairable));
+ if(materials.isEmpty()) {
+ return null;
+ }
+
+ // ensure the items only contain valid items
+ ItemStack[] items = Util.copyItemStackArray(repairItems);
+ boolean foundMatch = false;
+ for(int index : getRepairParts()) {
+ Material material = materials.get(index);
+
+ if(repairCustom(material, items) > 0) {
+ foundMatch = true;
+ }
+
+ RecipeMatch.Match match = material.matches(items);
+
+ // not a single match -> nothing to repair with
+ if(match == null) {
+ continue;
+ }
+ foundMatch = true;
+
+ while((match = material.matches(items)) != null) {
+ RecipeMatch.removeMatch(items, match);
+ }
+ }
+
+ if(!foundMatch) {
+ return null;
+ }
+
+ // check if all items were used
+ for(int i = 0; i < repairItems.length; i++) {
+ // was non-null and did not get modified (stacksize changed or null now, usually)
+ if(repairItems[i] != null && ItemStack.areItemStacksEqual(repairItems[i], items[i])) {
+ // found an item that was not touched
+ return null;
+ }
+ }
+
+ // now do it all over again with the real items, to actually repair \o/
+ ItemStack item = repairable.copy();
+
+ while(item.getItemDamage() > 0) {
+ int amount = calculateRepairAmount(materials, repairItems);
+
+ // nothing to repair with, we're therefore done
+ if(amount <= 0) {
+ break;
+ }
+
+ ToolHelper.repairTool(item, calculateRepair(item, amount));
+ // save that we repaired it :I
+ NBTTagCompound tag = TagUtil.getExtraTag(item);
+ TagUtil.addInteger(tag, Tags.REPAIR_COUNT, 1);
+ TagUtil.setExtraTag(item, tag);
+ }
+
+ return item;
+ }
+
+ /** Allows for custom repair items. Remove used items from the array. */
+ protected int repairCustom(Material material, ItemStack[] repairItems) {
+ return 0;
+ }
+
+ protected int calculateRepairAmount(List<Material> materials, ItemStack[] repairItems) {
+ Set<Material> materialsMatched = Sets.newHashSet();
+ float durability = 0f;
+ // try to match each material once
+ for(int index : getRepairParts()) {
+ Material material = materials.get(index);
+
+ if(materialsMatched.contains(material)) {
+ continue;
+ }
+
+ // custom repairing
+ durability += repairCustom(material, repairItems) * getRepairModifierForPart(index);
+
+ RecipeMatch.Match match = material.matches(repairItems);
+ if(match != null) {
+ HeadMaterialStats stats = material.getStats(MaterialTypes.HEAD);
+ if(stats != null) {
+ materialsMatched.add(material);
+ durability += ((float) stats.durability * (float) match.amount * getRepairModifierForPart(index)) / 144f;
+ RecipeMatch.removeMatch(repairItems, match);
+ }
+ }
+ }
+
+ durability *= 1f + ((float) materialsMatched.size() - 1) / 9f;
+
+ return (int) durability;
+ }
+
+ protected int calculateRepair(ItemStack tool, int amount) {
+ float origDur = TagUtil.getOriginalToolStats(tool).durability;
+ float actualDur = ToolHelper.getDurabilityStat(tool);
+
+ // calculate in modifiers that change the total durability of a tool, like diamond
+ // they should not punish the player with higher repair costs
+ float durabilityFactor = actualDur / origDur;
+ float increase = (float) amount * Math.min(10f, durabilityFactor);
+
+ increase = Math.max(increase, actualDur / 64f);
+ //increase = Math.max(50, increase);
+
+
+ int modifiersUsed = TagUtil.getBaseModifiersUsed(tool.getTagCompound());
+ float mods = 1.0f;
+ if(modifiersUsed == 1) {
+ mods = 0.95f;
+ }
+ else if(modifiersUsed == 2) {
+ mods = 0.9f;
+ }
+ else if(modifiersUsed >= 3) {
+ mods = 0.85f;
+ }
+
+ increase *= mods;
+
+ NBTTagCompound tag = TagUtil.getExtraTag(tool);
+ int repair = tag.getInteger(Tags.REPAIR_COUNT);
+ float repairDimishingReturns = (100 - repair / 2) / 100f;
+ if(repairDimishingReturns < 0.5f) {
+ repairDimishingReturns = 0.5f;
+ }
+ increase *= repairDimishingReturns;
+
+ return (int) Math.ceil(increase);
+ }
+
+ /* Information */
+
+ @Override
+ public void addInformation(ItemStack stack, EntityPlayer playerIn, List<String> tooltip,
+ boolean advanced) {
+ boolean shift = Util.isShiftKeyDown();
+ boolean ctrl = Util.isCtrlKeyDown();
+ // modifiers
+ if(!shift && !ctrl) {
+ getTooltip(stack, tooltip);
+
+ tooltip.add("");
+ // info tooltip for detailed and componend info
+ tooltip.add(Util.translate("tooltip.tool.holdShift"));
+ tooltip.add(Util.translate("tooltip.tool.holdCtrl"));
+
+ tooltip.add(TextFormatting.BLUE +
+ I18n.translateToLocalFormatted("attribute.modifier.plus.0",
+ Util.df.format(ToolHelper.getActualDamage(stack, playerIn)),
+ I18n
+ .translateToLocal("attribute.name.generic.attackDamage")));
+ }
+ // detailed data
+ else if(Config.extraTooltips && shift) {
+ getTooltipDetailed(stack, tooltip);
+ }
+ // component data
+ else if(Config.extraTooltips && ctrl) {
+ getTooltipComponents(stack, tooltip);
+ }
+ }
+
+ @Override
+ public void getTooltip(ItemStack stack, List<String> tooltips) {
+ // Default tooltip: modifiers
+ TooltipBuilder.addModifierTooltips(stack,tooltips);
+ }
+
+ @Nonnull
+ @Override
+ public EnumRarity getRarity(ItemStack stack) {
+ // prevents enchanted items to have a different name color
+ return EnumRarity.COMMON;
+ }
+
+ @Override
+ public boolean isBookEnchantable(ItemStack stack, ItemStack book) {
+ return false;
+ }
+
+ /* NBT loading */
+
+ @Override
+ public boolean updateItemStackNBT(NBTTagCompound nbt) {
+ // when the itemstack is loaded from NBT we recalculate all the data
+ if(nbt.hasKey(Tags.BASE_DATA)) {
+ try {
+ ArmorBuilder.rebuildTool(nbt, this);
+ } catch(TinkerGuiException e) {
+ // nothing to do
+ }
+ }
+
+ // return value shouldn't matter since it's never checked
+ return true;
+ }
}
diff --git a/src/main/java/lance5057/tDefense/armor/events/ArmorBaseEvents.java b/src/main/java/lance5057/tDefense/armor/events/ArmorBaseEvents.java
new file mode 100644
index 0000000..d35a37a
--- /dev/null
+++ b/src/main/java/lance5057/tDefense/armor/events/ArmorBaseEvents.java
@@ -0,0 +1,33 @@
+package lance5057.tDefense.armor.events;
+
+import com.google.common.collect.ImmutableList;
+
+import lance5057.tDefense.armor.ArmorCore;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.fml.common.eventhandler.Event;
+import slimeknights.tconstruct.library.events.TinkerEvent.OnItemBuilding;
+import slimeknights.tconstruct.library.materials.Material;
+import slimeknights.tconstruct.library.tinkering.TinkersItem;
+
+public abstract class ArmorBaseEvents extends Event {
+ public static class OnArmorBuilding extends ArmorBaseEvents {
+
+ public NBTTagCompound tag;
+ public final ImmutableList<Material> materials;
+ public final ArmorCore tool;
+
+ public OnArmorBuilding(NBTTagCompound tag, ImmutableList<Material> materials, ArmorCore tool) {
+ this.tag = tag;
+ this.materials = materials;
+ this.tool = tool;
+ }
+
+ public static OnArmorBuilding fireEvent(NBTTagCompound tag, ImmutableList<Material> materials,
+ ArmorCore armorCore) {
+ OnArmorBuilding event = new OnArmorBuilding(tag, materials, armorCore);
+ MinecraftForge.EVENT_BUS.post(event);
+ return event;
+ }
+ }
+}
diff --git a/src/main/java/lance5057/tDefense/armor/items/cloth/TinkersHood.java b/src/main/java/lance5057/tDefense/armor/items/cloth/TinkersHood.java
index 61eb786..2420459 100644
--- a/src/main/java/lance5057/tDefense/armor/items/cloth/TinkersHood.java
+++ b/src/main/java/lance5057/tDefense/armor/items/cloth/TinkersHood.java
@@ -23,7 +23,7 @@ public class TinkersHood extends ArmorCore
public TinkersHood()
{
- super(EntityEquipmentSlot.HEAD,
+ super(EntityEquipmentSlot.CHEST,
ClothMat,
ClothMat,
RivetMat);
diff --git a/src/main/java/lance5057/tDefense/armor/util/ArmorBuilder.java b/src/main/java/lance5057/tDefense/armor/util/ArmorBuilder.java
new file mode 100644
index 0000000..bdbece5
--- /dev/null
+++ b/src/main/java/lance5057/tDefense/armor/util/ArmorBuilder.java
@@ -0,0 +1,115 @@
+package lance5057.tDefense.armor.util;
+
+import java.util.List;
+
+import org.apache.logging.log4j.Logger;
+
+import com.google.common.collect.ImmutableList;
+
+import lance5057.tDefense.armor.ArmorCore;
+import lance5057.tDefense.armor.events.ArmorBaseEvents;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import slimeknights.tconstruct.library.TinkerRegistry;
+import slimeknights.tconstruct.library.Util;
+import slimeknights.tconstruct.library.materials.Material;
+import slimeknights.tconstruct.library.modifiers.IModifier;
+import slimeknights.tconstruct.library.modifiers.TinkerGuiException;
+import slimeknights.tconstruct.library.tinkering.PartMaterialType;
+import slimeknights.tconstruct.library.utils.TagUtil;
+import slimeknights.tconstruct.library.utils.Tags;
+import slimeknights.tconstruct.library.utils.TinkerUtil;
+
+public final class ArmorBuilder {
+ private static Logger log = Util.getLogger("ToolBuilder");
+
+ public static void rebuildTool(NBTTagCompound rootNBT, ArmorCore tinkersItem) throws TinkerGuiException {
+ boolean broken = TagUtil.getToolTag(rootNBT).getBoolean(Tags.BROKEN);
+ // Recalculate tool base stats from material stats
+ NBTTagList materialTag = TagUtil.getBaseMaterialsTagList(rootNBT);
+ List<Material> materials = TinkerUtil.getMaterialsFromTagList(materialTag);
+ List<PartMaterialType> pms = tinkersItem.getRequiredComponents();
+
+ // ensure all needed Stats are present
+ while(materials.size() < pms.size()) {
+ materials.add(Material.UNKNOWN);
+ }
+ for(int i = 0; i < pms.size(); i++) {
+ if(!pms.get(i).isValidMaterial(materials.get(i))) {
+ materials.set(i, Material.UNKNOWN);
+ }
+ }
+
+ // the base stats of the tool
+ NBTTagCompound toolTag = tinkersItem.buildTag(materials);
+ TagUtil.setToolTag(rootNBT, toolTag);
+ // and its copy for reference
+ rootNBT.setTag(Tags.TOOL_DATA_ORIG, toolTag.copy());
+
+ // save the old modifiers list and clean up all tags that get set by modifiers/traits
+ NBTTagList modifiersTagOld = TagUtil.getModifiersTagList(rootNBT);
+ rootNBT.removeTag(Tags.TOOL_MODIFIERS); // the active-modifiers tag
+ rootNBT.setTag(Tags.TOOL_MODIFIERS, new NBTTagList());
+ rootNBT.removeTag("ench"); // and the enchantments tag
+ rootNBT.removeTag(Tags.ENCHANT_EFFECT); // enchant effect too, will be readded by a trait either way
+
+ // clean up traits
+ rootNBT.removeTag(Tags.TOOL_TRAITS);
+ tinkersItem.addMaterialTraits(rootNBT, materials);
+
+ // fire event
+ ArmorBaseEvents.OnArmorBuilding.fireEvent(rootNBT, ImmutableList.copyOf(materials), tinkersItem);
+
+ // reapply modifiers
+ NBTTagList modifiers = TagUtil.getBaseModifiersTagList(rootNBT);
+ NBTTagList modifiersTag = TagUtil.getModifiersTagList(rootNBT);
+ // copy over and reapply all relevant modifiers
+ for(int i = 0; i < modifiers.tagCount(); i++) {
+ String identifier = modifiers.getStringTagAt(i);
+ IModifier modifier = TinkerRegistry.getModifier(identifier);
+ if(modifier == null) {
+ log.debug("Missing modifier: {}", identifier);
+ continue;
+ }
+
+ NBTTagCompound tag;
+ int index = TinkerUtil.getIndexInList(modifiersTagOld, modifier.getIdentifier());
+
+ if(index >= 0) {
+ tag = modifiersTagOld.getCompoundTagAt(index);
+ }
+ else {
+ tag = new NBTTagCompound();
+ }
+
+ modifier.applyEffect(rootNBT, tag);
+ if(!tag.hasNoTags()) {
+ int indexNew = TinkerUtil.getIndexInList(modifiersTag, modifier.getIdentifier());
+ if(indexNew >= 0) {
+ modifiersTag.set(indexNew, tag);
+ }
+ else {
+ modifiersTag.appendTag(tag);
+ }
+ }
+ }
+
+ // remaining info, get updated toolTag
+ toolTag = TagUtil.getToolTag(rootNBT);
+ // adjust free modifiers
+ int freeModifiers = toolTag.getInteger(Tags.FREE_MODIFIERS);
+ freeModifiers -= TagUtil.getBaseModifiersUsed(rootNBT);
+ toolTag.setInteger(Tags.FREE_MODIFIERS, Math.max(0, freeModifiers));
+
+ // broken?
+ if(broken) {
+ toolTag.setBoolean(Tags.BROKEN, true);
+ }
+
+ TagUtil.setToolTag(rootNBT, toolTag);
+
+ if(freeModifiers < 0) {
+ throw new TinkerGuiException(Util.translateFormatted("gui.error.not_enough_modifiers", -freeModifiers));
+ }
+ }
+}