package slimeknights.tconstruct.library.traits; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import slimeknights.tconstruct.library.TinkerRegistry; import slimeknights.tconstruct.library.Util; import slimeknights.tconstruct.library.modifiers.IModifier; import slimeknights.tconstruct.library.modifiers.ModifierAspect; import slimeknights.tconstruct.library.modifiers.ModifierNBT; import slimeknights.tconstruct.library.utils.TagUtil; import slimeknights.tconstruct.library.utils.TinkerUtil; /** * A Trait that has multiple levels and can be applied multiple times * Effectively it's multiple traits that all use one single modifier. */ public abstract class AbstractTraitLeveled extends AbstractTrait { protected final String name; protected final int levels; public AbstractTraitLeveled(String identifier, int color, int maxLevels, int levels) { this(identifier, String.valueOf(levels), color, maxLevels, levels); } public AbstractTraitLeveled(String identifier, String suffix, int color, int maxLevels, int levels) { super(identifier + suffix, color); this.name = identifier; this.levels = levels; // don't overwrite the modifier alias if one with less levels already is present // we basically always want the level1 one to be associated with the modifier used IModifier modifier = TinkerRegistry.getModifier(name); if(modifier != null) { if(modifier instanceof AbstractTraitLeveled && ((AbstractTraitLeveled) modifier).levels > this.levels) { TinkerRegistry.registerModifierAlias(this, name); } } else { TinkerRegistry.registerModifierAlias(this, name); } aspects.clear(); this.addAspects(new ModifierAspect.LevelAspect(this, maxLevels), new ModifierAspect.DataAspect(this, color)); } @Override public void updateNBTforTrait(NBTTagCompound modifierTag, int newColor) { super.updateNBTforTrait(modifierTag, newColor); ModifierNBT data = ModifierNBT.readTag(modifierTag); data.level = 0; // handled by applyEffect in this case data.write(modifierTag); } @Override public void applyEffect(NBTTagCompound rootCompound, NBTTagCompound modifierTag) { super.applyEffect(rootCompound, modifierTag); // traits are the only things that can modify here safely, since they're only ever called on tool creation NBTTagList tagList = TagUtil.getModifiersTagList(rootCompound); int index = TinkerUtil.getIndexInCompoundList(tagList, getModifierIdentifier()); NBTTagCompound tag = new NBTTagCompound(); if(index > -1) { tag = tagList.getCompoundTagAt(index); } else { index = tagList.tagCount(); tagList.appendTag(tag); } if(!tag.getBoolean(identifier)) { ModifierNBT data = ModifierNBT.readTag(tag); data.level += levels; data.write(tag); tag.setBoolean(identifier, true); tagList.set(index, tag); TagUtil.setModifiersTagList(rootCompound, tagList); applyModifierEffect(rootCompound); } } /** * Called when the trait gets applied. Called for each application/level of the trait. * Only called once per specific trait (e.g. Writable1 and Writable2) but multiple times overall (per specific trait present) * * Unlike Modifiers that get applied with the total result, you can do things incrementally here. */ public void applyModifierEffect(NBTTagCompound rootCompound) { } @Override public String getModifierIdentifier() { return name; } @Override public String getLocalizedName() { String locName = Util.translate(LOC_Name, name); if(levels > 1) { locName += " " + TinkerUtil.getRomanNumeral(levels); } return locName; } @Override public String getLocalizedDesc() { return Util.translate(LOC_Desc, name); } @Override public String getTooltip(NBTTagCompound modifierTag, boolean detailed) { return getLeveledTooltip(modifierTag, detailed); } }