Search in sources :

Example 1 with Powder

use of com.wynntils.core.framework.enums.Powder in project Wynntils by Wynntils.

the class ChatItemManager method encodeItem.

/**
 * Encodes the given item, as long as it is a standard gear item, into the following format
 *
 * START character (U+F5FF0)
 * Item name (optionally encoded)
 * SEPARATOR character (U+F5FF2)
 * Identifications/stars (encoded)
 * SEPARATOR (only if powdered)
 * Powders (encoded) (only if powdered)
 * Rerolls (encoded)
 * END character (U+F5FF1)
 *
 * Any encoded "value" is added to the OFFSET character value U+F5000 and then converted into the corresponding Unicode character:
 *
 * The name is encoded based on the ASCII value of each character minus 32
 *
 * Identifications are encoded either as the raw value minus the minimum value of that ID, or if the range is larger than 100,
 * the percent value 0 to 100 of the given roll.
 * Regardless of either case, this number is multiplied by 4, and the number of stars present on that ID is added.
 * This ensures that the value and star count can be encoded into a single character and be decoded later.
 *
 * Powders are encoded as numerical values 1-5. Up to 4 powders are encoded into a single character - for each new powder,
 * the running total is multiplied by 6 before the new powder value is added. Thus, each individual powder can be decoded.
 *
 * Rerolls are simply encoded as a raw number.
 */
public static String encodeItem(ItemStack stack) {
    String itemName = TextFormatting.getTextWithoutFormattingCodes(stack.getDisplayName());
    // not a gear item, cannot be encoded
    if (!stack.getTagCompound().hasKey("wynntils") && WebManager.getItems().get(itemName) == null)
        return null;
    // get identification data
    NBTTagCompound itemData = ItemIdentificationOverlay.generateData(stack, IdentificationType.PERCENTAGES);
    ItemProfile item = WebManager.getItems().get(itemData.getString("originName"));
    // sort list to ensure encoding/decoding is always 1:1
    List<String> sortedIds = new ArrayList<>(item.getStatuses().keySet());
    sortedIds.sort(Comparator.comparingInt(IdentificationOrderer.INSTANCE::getOrder));
    // item is missing id data when it shouldn't, abort
    if (!itemData.hasKey("ids") && !sortedIds.isEmpty())
        return null;
    // name
    StringBuilder encoded = new StringBuilder(START);
    encoded.append(ENCODE_NAME ? encodeString(item.getDisplayName()) : item.getDisplayName());
    encoded.append(SEPARATOR);
    // ids
    for (String id : sortedIds) {
        IdentificationContainer status = item.getStatuses().get(id);
        // don't care about these
        if (status.isFixed())
            continue;
        // some kind of mismatch
        if (!itemData.getCompoundTag("ids").hasKey(id))
            return null;
        int idValue = itemData.getCompoundTag("ids").getInteger(id);
        int translatedValue = 0;
        if (Math.abs(status.getBaseValue()) > 100) {
            // calculate percent
            translatedValue = (int) Math.round((idValue * 100.0 / status.getBaseValue()) - 30);
        } else {
            // raw value
            translatedValue = idValue - status.getMin();
        }
        // stars
        int stars = itemData.getCompoundTag("ids").hasKey(id + "*") ? itemData.getCompoundTag("ids").getInteger(id + "*") : 0;
        // encode value + stars in one character
        encoded.append(encodeNumber(translatedValue * 4 + stars));
    }
    // powders
    if (itemData.hasKey("powderSlots")) {
        List<Powder> powders = Powder.findPowders(itemData.getString("powderSlots"));
        if (!powders.isEmpty()) {
            encoded.append(SEPARATOR);
            int counter = 0;
            int encodedPowders = 0;
            for (Powder p : powders) {
                // shift left
                encodedPowders *= 6;
                // 0 represents no more powders
                encodedPowders += p.ordinal() + 1;
                counter++;
                if (counter == 4) {
                    // max # of powders encoded in a single char
                    encoded.append(encodeNumber(encodedPowders));
                    encodedPowders = 0;
                    counter = 0;
                    continue;
                }
            }
            // catch any leftover powders
            if (encodedPowders != 0)
                encoded.append(encodeNumber(encodedPowders));
        }
    }
    // rerolls
    int rerolls = itemData.hasKey("rerollAmount") ? itemData.getInteger("rerollAmount") : 0;
    encoded.append(encodeNumber(rerolls));
    encoded.append(END);
    return encoded.toString();
}
Also used : IdentificationOrderer(com.wynntils.webapi.profiles.item.IdentificationOrderer) ItemProfile(com.wynntils.webapi.profiles.item.ItemProfile) NBTTagCompound(net.minecraft.nbt.NBTTagCompound) ArrayList(java.util.ArrayList) IdentificationContainer(com.wynntils.webapi.profiles.item.objects.IdentificationContainer) TextComponentString(net.minecraft.util.text.TextComponentString) Powder(com.wynntils.core.framework.enums.Powder)

Example 2 with Powder

use of com.wynntils.core.framework.enums.Powder in project Wynntils by Wynntils.

the class WynnBuilderOverlay method getPowders.

private void getPowders(StringBuilder urlData, NonNullList<ItemStack> inventory, int slot) {
    ItemStack stack = inventory.get(slot);
    if (ItemUtils.getStringLore(stack).contains("Powder Slots [")) {
        ItemUtils.getLore(stack).forEach(line -> {
            if (line.contains("Powder Slots [")) {
                List<Powder> powders = Powder.findPowders(line);
                int powderSections = (int) Math.ceil((double) powders.size() / 6.0);
                // Number of powders / 6 for looping
                urlData.append(fromIntN(powderSections, 1));
                while (!powders.isEmpty()) {
                    List<Powder> section = powders.subList(0, Math.min(6, powders.size()));
                    int powderHash = 0;
                    for (Powder powder : section) {
                        // Powders each use 5 bits
                        powderHash <<= 5;
                        // Powder ids are the ordinal of the type of powder * 6 + tier of the powder - 1 and adds 1 to each powder
                        powderHash += 6 + powder.ordinal() * 6;
                    }
                    urlData.append(fromIntN(powderHash, 5));
                    powders = new ArrayList<>(powders.subList(Math.min(6, powders.size()), powders.size()));
                }
            }
        });
    } else {
        // No powders
        urlData.append(fromIntN(0, 1));
    }
}
Also used : ItemStack(net.minecraft.item.ItemStack) Powder(com.wynntils.core.framework.enums.Powder)

Example 3 with Powder

use of com.wynntils.core.framework.enums.Powder in project Wynntils by Wynntils.

the class PowderProfile method getStack.

public ItemStack getStack() {
    if (itemStack != null)
        return itemStack;
    ItemStack stack = new ItemStack(Items.DYE);
    if (tier <= 3)
        stack.setItemDamage(element.getLowTierDamage());
    else
        stack.setItemDamage(element.getHighTierDamage());
    String name = element.getName();
    Powder opposingElement = element.getOpposingElement();
    List<String> itemLore = new ArrayList<>();
    StringBuilder tierStringBuilder = new StringBuilder(String.valueOf(element.getDarkColor()));
    for (int i = 1; i <= tier; i++) {
        tierStringBuilder.append('■');
    }
    tierStringBuilder.append(TextFormatting.DARK_GRAY);
    for (int i = tier; i < 6; i++) {
        tierStringBuilder.append('■');
    }
    itemLore.add(TextFormatting.GRAY + "Tier " + tier + " [" + tierStringBuilder + TextFormatting.GRAY + "]");
    itemLore.add("");
    itemLore.add(element.getDarkColor() + "Effect on Weapons:");
    itemLore.add(element.getDarkColor() + "— " + TextFormatting.GRAY + "+" + min + "-" + max + " " + element.getLightColor() + element.getSymbol() + " " + name + " " + TextFormatting.GRAY + "Damage");
    itemLore.add(element.getDarkColor() + "— " + TextFormatting.GRAY + "+" + convertedFromNeutral + "% " + TextFormatting.GOLD + "✣ Neutral" + TextFormatting.GRAY + " to " + element.getLightColor() + element.getSymbol() + " " + name);
    itemLore.add("");
    itemLore.add(element.getDarkColor() + "Effect on Armour:");
    itemLore.add(element.getDarkColor() + "— " + TextFormatting.GRAY + "+" + addedDefence + " " + element.getLightColor() + element.getSymbol() + " " + name + " " + TextFormatting.GRAY + "Defence");
    itemLore.add(element.getDarkColor() + "— " + TextFormatting.GRAY + "-" + removedDefence + " " + opposingElement.getLightColor() + opposingElement.getSymbol() + " " + StringUtils.capitalizeFirst(opposingElement.name().toLowerCase(Locale.ROOT)) + " " + TextFormatting.GRAY + "Defence");
    itemLore.add("");
    itemLore.add(TextFormatting.DARK_GRAY + "Add this powder to your items by visiting a Powder Master or use it as an ingredient when crafting.");
    if (tier > 3) {
        itemLore.add("");
        itemLore.add(TextFormatting.DARK_GRAY + "Adding 2 powders of tier 4-6 at the powder master will unlock a special attack/effect.");
    }
    NBTTagCompound tag = new NBTTagCompound();
    NBTTagCompound display = new NBTTagCompound();
    NBTTagList loreList = new NBTTagList();
    itemLore.forEach(c -> loreList.appendTag(new NBTTagString(c)));
    display.setTag("Lore", loreList);
    if (UtilitiesConfig.Items.INSTANCE.romanNumeralItemTier)
        // item display name
        display.setString("Name", element.getLightColor() + String.valueOf(element.getSymbol()) + " " + name + " Powder " + StringUtils.integerToRoman(tier));
    else
        // item display name
        display.setString("Name", element.getLightColor() + String.valueOf(element.getSymbol()) + " " + name + " Powder " + tier);
    tag.setTag("display", display);
    // this allow items like reliks to have damage
    tag.setBoolean("Unbreakable", true);
    stack.setTagCompound(tag);
    return itemStack = stack;
}
Also used : NBTTagList(net.minecraft.nbt.NBTTagList) ArrayList(java.util.ArrayList) NBTTagCompound(net.minecraft.nbt.NBTTagCompound) NBTTagString(net.minecraft.nbt.NBTTagString) NBTTagString(net.minecraft.nbt.NBTTagString) ItemStack(net.minecraft.item.ItemStack) Powder(com.wynntils.core.framework.enums.Powder)

Example 4 with Powder

use of com.wynntils.core.framework.enums.Powder in project Wynntils by Wynntils.

the class ChatItemManager method decodeItem.

public static ITextComponent decodeItem(String encoded) {
    Matcher m = ENCODED_PATTERN.matcher(encoded);
    if (!m.matches())
        return null;
    String name = ENCODE_NAME ? decodeString(m.group("Name")) : m.group("Name");
    int[] ids = decodeNumbers(m.group("Ids"));
    int[] powders = m.group("Powders") != null ? decodeNumbers(m.group("Powders")) : new int[0];
    int rerolls = decodeNumbers(m.group("Rerolls"))[0];
    ItemProfile item = WebManager.getItems().get(name);
    if (item == null)
        return null;
    // create stack
    ItemStack stack = item.getItemInfo().asItemStack();
    stack.setStackDisplayName(item.getTier().getTextColor() + item.getDisplayName());
    stack.setTagInfo("Unbreakable", new NBTTagByte((byte) 1));
    stack.setTagInfo("HideFlags", new NBTTagInt(6));
    List<String> itemLore = new ArrayList<>();
    // identifier
    itemLore.add(DARK_GRAY.toString() + ITALIC + "From chat");
    // attack speed
    if (item.getAttackSpeed() != null) {
        itemLore.add(item.getAttackSpeed().asLore());
        itemLore.add(" ");
    }
    // damages
    Map<String, String> damageTypes = item.getDamageTypes();
    if (damageTypes.size() > 0) {
        if (damageTypes.containsKey("neutral"))
            itemLore.add(GOLD + "✣ Neutral Damage: " + damageTypes.get("neutral"));
        if (damageTypes.containsKey("fire"))
            itemLore.add(RED + "✹ Fire" + GRAY + " Damage: " + damageTypes.get("fire"));
        if (damageTypes.containsKey("water"))
            itemLore.add(AQUA + "❉ Water" + GRAY + " Damage: " + damageTypes.get("water"));
        if (damageTypes.containsKey("air"))
            itemLore.add(WHITE + "❋ Air" + GRAY + " Damage: " + damageTypes.get("air"));
        if (damageTypes.containsKey("thunder"))
            itemLore.add(YELLOW + "✦ Thunder" + GRAY + " Damage: " + damageTypes.get("thunder"));
        if (damageTypes.containsKey("earth"))
            itemLore.add(DARK_GREEN + "✤ Earth" + GRAY + " Damage: " + damageTypes.get("earth"));
        itemLore.add(" ");
    }
    // defenses
    Map<String, Integer> defenseTypes = item.getDefenseTypes();
    if (defenseTypes.size() > 0) {
        if (defenseTypes.containsKey("health"))
            itemLore.add(DARK_RED + "❤ Health: " + (defenseTypes.get("health") > 0 ? "+" : "") + defenseTypes.get("health"));
        if (defenseTypes.containsKey("fire"))
            itemLore.add(RED + "✹ Fire" + GRAY + " Defence: " + (defenseTypes.get("fire") > 0 ? "+" : "") + defenseTypes.get("fire"));
        if (defenseTypes.containsKey("water"))
            itemLore.add(AQUA + "❉ Water" + GRAY + " Defence: " + (defenseTypes.get("water") > 0 ? "+" : "") + defenseTypes.get("water"));
        if (defenseTypes.containsKey("air"))
            itemLore.add(WHITE + "❋ Air" + GRAY + " Defence: " + (defenseTypes.get("air") > 0 ? "+" : "") + defenseTypes.get("air"));
        if (defenseTypes.containsKey("thunder"))
            itemLore.add(YELLOW + "✦ Thunder" + GRAY + " Defence: " + (defenseTypes.get("thunder") > 0 ? "+" : "") + defenseTypes.get("thunder"));
        if (defenseTypes.containsKey("earth"))
            itemLore.add(DARK_GREEN + "✤ Earth" + GRAY + " Defence: " + (defenseTypes.get("earth") > 0 ? "+" : "") + defenseTypes.get("earth"));
        itemLore.add(" ");
    }
    // requirements
    ItemRequirementsContainer requirements = item.getRequirements();
    if (requirements.hasRequirements(item.getItemInfo().getType())) {
        if (requirements.requiresQuest())
            itemLore.add(GREEN + "✔ " + GRAY + "Quest Req: " + requirements.getQuest());
        if (requirements.requiresClass(item.getItemInfo().getType()))
            itemLore.add(GREEN + "✔ " + GRAY + "Class Req: " + requirements.getRealClass(item.getItemInfo().getType()).getDisplayName());
        if (requirements.getLevel() != 0)
            itemLore.add(GREEN + "✔ " + GRAY + "Combat Lv. Min: " + requirements.getLevel());
        if (requirements.getStrength() != 0)
            itemLore.add(GREEN + "✔ " + GRAY + "Strength Min: " + requirements.getStrength());
        if (requirements.getAgility() != 0)
            itemLore.add(GREEN + "✔ " + GRAY + "Agility Min: " + requirements.getAgility());
        if (requirements.getDefense() != 0)
            itemLore.add(GREEN + "✔ " + GRAY + "Defense Min: " + requirements.getDefense());
        if (requirements.getIntelligence() != 0)
            itemLore.add(GREEN + "✔ " + GRAY + "Intelligence Min: " + requirements.getIntelligence());
        if (requirements.getDexterity() != 0)
            itemLore.add(GREEN + "✔ " + GRAY + "Dexterity Min: " + requirements.getDexterity());
        itemLore.add(" ");
    }
    // ids
    List<String> sortedIds = new ArrayList<>(item.getStatuses().keySet());
    sortedIds.sort(Comparator.comparingInt(IdentificationOrderer.INSTANCE::getOrder));
    // for id value array
    int counter = 0;
    for (String id : sortedIds) {
        IdentificationContainer status = item.getStatuses().get(id);
        String stars = "";
        int value;
        if (status.isFixed()) {
            value = status.getBaseValue();
        } else {
            // some kind of mismatch, abort
            if (counter > ids.length)
                return null;
            // id value
            int encodedValue = ids[counter] / 4;
            if (Math.abs(status.getBaseValue()) > 100) {
                // using bigdecimal here for precision when rounding
                value = new BigDecimal(encodedValue + 30).movePointLeft(2).multiply(new BigDecimal(status.getBaseValue())).setScale(0, RoundingMode.HALF_UP).intValue();
            } else {
                value = encodedValue + status.getMin();
            }
            // stars
            stars = DARK_GREEN + "***".substring(0, ids[counter] % 4);
            counter++;
        }
        // name
        String longName = IdentificationContainer.getAsLongName(id);
        SpellType spell = SpellType.fromName(longName);
        if (spell != null) {
            ClassType requiredClass = item.getClassNeeded();
            if (requiredClass != null) {
                longName = spell.forOtherClass(requiredClass).getName() + " Spell Cost";
            } else {
                longName = spell.forOtherClass(PlayerInfo.get(CharacterData.class).getCurrentClass()).getGenericAndSpecificName() + " Cost";
            }
        }
        // value string
        String lore;
        if (IdentificationOrderer.INSTANCE.isInverted(id))
            lore = (value < 0 ? GREEN.toString() : value > 0 ? RED + "+" : GRAY.toString()) + value + status.getType().getInGame(id);
        else
            lore = (value < 0 ? RED.toString() : value > 0 ? GREEN + "+" : GRAY.toString()) + value + status.getType().getInGame(id);
        lore += stars + " " + GRAY + longName;
        itemLore.add(lore);
    }
    if (!sortedIds.isEmpty())
        itemLore.add(" ");
    // major ids
    if (item.getMajorIds() != null && item.getMajorIds().size() > 0) {
        for (MajorIdentification majorId : item.getMajorIds()) {
            Stream.of(StringUtils.wrapTextBySize(majorId.asLore(), 150)).forEach(c -> itemLore.add(DARK_AQUA + c));
        }
        itemLore.add(" ");
    }
    // powders
    if (item.getPowderAmount() > 0) {
        int powderCount = 0;
        String powderList = "";
        if (powders.length > 0) {
            // must reverse powders so they are read in reverse order
            ArrayUtils.reverse(powders);
            for (int powderNum : powders) {
                // once powderNum is 0, all the powders have been read
                while (powderNum > 0) {
                    Powder p = Powder.values()[powderNum % 6 - 1];
                    // prepend powders because they are decoded in reverse
                    powderList = p.getColoredSymbol() + " " + powderList;
                    powderCount++;
                    powderNum /= 6;
                }
            }
        }
        String powderString = TextFormatting.GRAY + "[" + powderCount + "/" + item.getPowderAmount() + "] Powder Slots ";
        if (powderCount > 0)
            powderString += "[" + powderList.trim() + TextFormatting.GRAY + "]";
        itemLore.add(powderString);
    }
    // tier & rerolls
    String tierString = item.getTier().asLore();
    if (rerolls > 1)
        tierString += " [" + rerolls + "]";
    itemLore.add(tierString);
    // untradable
    if (item.getRestriction() != null)
        itemLore.add(RED + StringUtils.capitalizeFirst(item.getRestriction()) + " Item");
    // item lore
    if (item.getLore() != null && !item.getLore().isEmpty()) {
        itemLore.addAll(McIf.mc().fontRenderer.listFormattedStringToWidth(DARK_GRAY + item.getLore(), 150));
    }
    ItemUtils.replaceLore(stack, itemLore);
    // add advanced id info if enabled - force percentages because this will only ever run once
    ItemIdentificationOverlay.replaceLore(stack, IdentificationType.PERCENTAGES);
    // create text component
    ITextComponent msg = new TextComponentString(item.getTier().getTextColor() + TextFormatting.UNDERLINE + item.getDisplayName());
    msg.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new TextComponentString(stack.writeToNBT(new NBTTagCompound()).toString())));
    return msg;
}
Also used : Matcher(java.util.regex.Matcher) NBTTagByte(net.minecraft.nbt.NBTTagByte) ArrayList(java.util.ArrayList) IdentificationContainer(com.wynntils.webapi.profiles.item.objects.IdentificationContainer) ITextComponent(net.minecraft.util.text.ITextComponent) NBTTagCompound(net.minecraft.nbt.NBTTagCompound) TextComponentString(net.minecraft.util.text.TextComponentString) SpellType(com.wynntils.core.framework.enums.SpellType) Powder(com.wynntils.core.framework.enums.Powder) IdentificationOrderer(com.wynntils.webapi.profiles.item.IdentificationOrderer) ItemProfile(com.wynntils.webapi.profiles.item.ItemProfile) HoverEvent(net.minecraft.util.text.event.HoverEvent) NBTTagInt(net.minecraft.nbt.NBTTagInt) ClassType(com.wynntils.core.framework.enums.ClassType) BigDecimal(java.math.BigDecimal) TextComponentString(net.minecraft.util.text.TextComponentString) ItemRequirementsContainer(com.wynntils.webapi.profiles.item.objects.ItemRequirementsContainer) MajorIdentification(com.wynntils.webapi.profiles.item.objects.MajorIdentification) CharacterData(com.wynntils.core.framework.instances.data.CharacterData) ItemStack(net.minecraft.item.ItemStack)

Aggregations

Powder (com.wynntils.core.framework.enums.Powder)4 ArrayList (java.util.ArrayList)3 ItemStack (net.minecraft.item.ItemStack)3 NBTTagCompound (net.minecraft.nbt.NBTTagCompound)3 IdentificationOrderer (com.wynntils.webapi.profiles.item.IdentificationOrderer)2 ItemProfile (com.wynntils.webapi.profiles.item.ItemProfile)2 IdentificationContainer (com.wynntils.webapi.profiles.item.objects.IdentificationContainer)2 TextComponentString (net.minecraft.util.text.TextComponentString)2 ClassType (com.wynntils.core.framework.enums.ClassType)1 SpellType (com.wynntils.core.framework.enums.SpellType)1 CharacterData (com.wynntils.core.framework.instances.data.CharacterData)1 ItemRequirementsContainer (com.wynntils.webapi.profiles.item.objects.ItemRequirementsContainer)1 MajorIdentification (com.wynntils.webapi.profiles.item.objects.MajorIdentification)1 BigDecimal (java.math.BigDecimal)1 Matcher (java.util.regex.Matcher)1 NBTTagByte (net.minecraft.nbt.NBTTagByte)1 NBTTagInt (net.minecraft.nbt.NBTTagInt)1 NBTTagList (net.minecraft.nbt.NBTTagList)1 NBTTagString (net.minecraft.nbt.NBTTagString)1 ITextComponent (net.minecraft.util.text.ITextComponent)1