diff options
| author | Lance5057 <Lance5057@gmail.com> | 2017-05-24 03:05:20 -0500 |
|---|---|---|
| committer | Lance5057 <Lance5057@gmail.com> | 2017-05-24 03:05:20 -0500 |
| commit | bd1d6e11213dfc5ad2cd8dab8304badccf428de4 (patch) | |
| tree | 3b4feabea0ca5c9fe79ac8a1537df632e53ceb53 /src/main/java/lance5057 | |
| parent | 1e3d888b8221f6997f009f46e1ff85d1b0ccaf6c (diff) | |
Redoing Armor stuff
Diffstat (limited to 'src/main/java/lance5057')
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)); + } + } +} |
