mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2025-01-02 06:27:42 +01:00
DamageTypeRestriction modifier for ATTACK ability trigger, very fun to use yes. Includes an advanced translation system to express this modifier.
This commit: (1) Allows the GUI to correctly display the DamageTypeRestriction modifier (2) Includes code to parse input for the DamageTypeRestriction (3) Translation system to display the trigger in a more user-friendly manner (4) Fixes offhand abilities firing even when encumbered by two-handedness
This commit is contained in:
parent
7c243e4ac8
commit
0994e6b0c3
@ -1,6 +1,7 @@
|
|||||||
package net.Indyuce.mmoitems.api.player;
|
package net.Indyuce.mmoitems.api.player;
|
||||||
|
|
||||||
import io.lumine.mythic.lib.MythicLib;
|
import io.lumine.mythic.lib.MythicLib;
|
||||||
|
import io.lumine.mythic.lib.api.crafting.recipes.MythicCraftingManager;
|
||||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||||
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||||
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||||
@ -216,11 +217,18 @@ public class PlayerData {
|
|||||||
final VolatileMMOItem item = equipped.getCached();
|
final VolatileMMOItem item = equipped.getCached();
|
||||||
|
|
||||||
// Abilities
|
// Abilities
|
||||||
if (item.hasData(ItemStats.ABILITIES))
|
if (item.hasData(ItemStats.ABILITIES) &&
|
||||||
|
|
||||||
|
// Do not add this ability if it is offhanded and offhand abilities are disabled
|
||||||
|
!(equipped.getSlot() == EquipmentSlot.OFF_HAND && MMOItems.plugin.getLanguage().disableOffhandAbilities) &&
|
||||||
|
|
||||||
|
// Do not add this ability if it is either of the hand slots, and the player is encumbered, and abilities don't bypass encumbering
|
||||||
|
!((equipped.getSlot() == EquipmentSlot.MAIN_HAND || equipped.getSlot() == EquipmentSlot.OFF_HAND) &&
|
||||||
|
isEncumbered() && !MMOItems.plugin.getLanguage().abilitiesBypassEncumbering))
|
||||||
|
|
||||||
for (AbilityData abilityData : ((AbilityListData) item.getData(ItemStats.ABILITIES)).getAbilities()) {
|
for (AbilityData abilityData : ((AbilityListData) item.getData(ItemStats.ABILITIES)).getAbilities()) {
|
||||||
ModifierSource modSource = equipped.getCached().getType().getModifierSource();
|
ModifierSource modSource = equipped.getCached().getType().getModifierSource();
|
||||||
mmoData.getPassiveSkillMap().addModifier(new PassiveSkill("MMOItemsItem", abilityData, equipped.getSlot(), modSource));
|
mmoData.getPassiveSkillMap().addModifier(new PassiveSkill("MMOItemsItem", abilityData, equipped.getSlot(), modSource));}
|
||||||
}
|
|
||||||
|
|
||||||
// Modifier application rules
|
// Modifier application rules
|
||||||
final ModifierSource source = item.getType().getModifierSource();
|
final ModifierSource source = item.getType().getModifierSource();
|
||||||
|
@ -0,0 +1,445 @@
|
|||||||
|
package net.Indyuce.mmoitems.api.util;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import io.lumine.mythic.lib.skill.trigger.TriggerType;
|
||||||
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The DamageTypeRestriction [DTR] modifier has several built-in features, so it's easier
|
||||||
|
* to keep them all in this one place, since they also include functions to use them:
|
||||||
|
* <br><br>
|
||||||
|
* + Translate the trigger name depending on the DTR <br>
|
||||||
|
* + Change color of damage types / scalings in modifiers <br>
|
||||||
|
* +
|
||||||
|
*/
|
||||||
|
public class DamageTypeRestrictionSettings {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the values directly off a configuration section
|
||||||
|
*
|
||||||
|
* @param config The configuration section, supposedly in the plugin config.yml
|
||||||
|
*/
|
||||||
|
public DamageTypeRestrictionSettings(@Nullable ConfigurationSection config) {
|
||||||
|
if (config == null) {
|
||||||
|
//DTR//MythicCraftingManager.log("\u00a78DTR\u00a7a SET\u00a7c Null config provided");
|
||||||
|
return; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* damage-type-restrictions:
|
||||||
|
*
|
||||||
|
* damage-type-translations:
|
||||||
|
* MAGIC: "Magic"
|
||||||
|
* PHYSICAL: "Melee"
|
||||||
|
* PROJECTILE: "Ranged"
|
||||||
|
* WEAPON: "Weapon"
|
||||||
|
* SKILL: "Skill"
|
||||||
|
* UNARMED: "Unarmed"
|
||||||
|
* ON_HIT: "Reaction"
|
||||||
|
* MINION: "Minion"
|
||||||
|
* DOT: "Lingering"
|
||||||
|
*
|
||||||
|
* attack-type-translations:
|
||||||
|
* WEAPON: "Attack"
|
||||||
|
* SKILL: "Ability Hit"
|
||||||
|
* NEITHER: "Damage"
|
||||||
|
* BOTH: "Ability-Assisted Attack"
|
||||||
|
*
|
||||||
|
* damage-type-colors:
|
||||||
|
* MAGIC: "&9"
|
||||||
|
* PHYSICAL: "&8"
|
||||||
|
* WEAPON: "&7"
|
||||||
|
* SKILL: "&f"
|
||||||
|
* PROJECTILE: "&a"
|
||||||
|
* UNARMED: "&e"
|
||||||
|
* ON_HIT: "&0"
|
||||||
|
* MINION: "&d"
|
||||||
|
* DOT: "&3"
|
||||||
|
*/
|
||||||
|
ConfigurationSection damageTypeTranslations = config.isConfigurationSection("damage-type-translations") ? config.getConfigurationSection("damage-type-translations") : null;
|
||||||
|
ConfigurationSection attackTypeTranslations = config.isConfigurationSection("attack-type-translations") ? config.getConfigurationSection("attack-type-translations") : null;
|
||||||
|
if (damageTypeTranslations == null || attackTypeTranslations == null) { advancedTriggerDisplay = false; } else {
|
||||||
|
//DTR//MythicCraftingManager.log("\u00a78DTR\u00a7a SET\u00a7a Accepted advanced trigger display");
|
||||||
|
|
||||||
|
// Both are defined, use advanced trigger display
|
||||||
|
advancedTriggerDisplay = true;
|
||||||
|
|
||||||
|
// Translate damage types
|
||||||
|
damageNames.put(DamageType.MAGIC, damageTypeTranslations.getString("MAGIC", "Magic"));
|
||||||
|
damageNames.put(DamageType.PHYSICAL, damageTypeTranslations.getString("PHYSICAL", "Melee"));
|
||||||
|
damageNames.put(DamageType.PROJECTILE, damageTypeTranslations.getString("PROJECTILE", "Projectile"));
|
||||||
|
damageNames.put(DamageType.WEAPON, damageTypeTranslations.getString("WEAPON", "Weapon"));
|
||||||
|
damageNames.put(DamageType.SKILL, damageTypeTranslations.getString("SKILL", "Skill"));
|
||||||
|
damageNames.put(DamageType.UNARMED, damageTypeTranslations.getString("UNARMED", "Unarmed"));
|
||||||
|
damageNames.put(DamageType.ON_HIT, damageTypeTranslations.getString("ON_HIT", "Reaction"));
|
||||||
|
damageNames.put(DamageType.MINION, damageTypeTranslations.getString("MINION", "Minion"));
|
||||||
|
damageNames.put(DamageType.DOT, damageTypeTranslations.getString("DOT", "Lingering"));
|
||||||
|
|
||||||
|
// Translate attack types
|
||||||
|
attackNames.put(AttackType.WEAPON, attackTypeTranslations.getString("WEAPON", "Attack"));
|
||||||
|
attackNames.put(AttackType.SKILL, attackTypeTranslations.getString("SKILL", "Ability Hit"));
|
||||||
|
attackNames.put(AttackType.BOTH, attackTypeTranslations.getString("BOTH", "Ability-Assisted Attack"));
|
||||||
|
attackNames.put(AttackType.NEITHER, attackTypeTranslations.getString("NEITHER", "Damage"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationSection damageTypeColors = config.isConfigurationSection("damage-type-colors") ? config.getConfigurationSection("damage-type-colors") : null;
|
||||||
|
if (damageTypeColors == null) { advancedRecoloring = false; } else {
|
||||||
|
//DTR//MythicCraftingManager.log("\u00a78DTR\u00a7a SET\u00a7a Accepted advanced recoloring");
|
||||||
|
|
||||||
|
// Colors are defined
|
||||||
|
advancedRecoloring = true;
|
||||||
|
|
||||||
|
// This information actually already exists
|
||||||
|
for (DamageType dt : DamageType.values()) {
|
||||||
|
|
||||||
|
// Well is there an override?
|
||||||
|
String colour = damageTypeColors.getString(dt.toString(), null);
|
||||||
|
if (colour == null) { continue; }
|
||||||
|
|
||||||
|
// Just match the name of the damage type, default to its default color
|
||||||
|
damageColor.put(dt, colour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return If trigger names will be translated depending on the DTR, this has the
|
||||||
|
* advantage of being user-friendly at the disadvantage of having to configure
|
||||||
|
* names of each modifier combination ~ WEAPON MAGIC !SKILL for example would be
|
||||||
|
* 'Staff Attack'
|
||||||
|
*/
|
||||||
|
public boolean isAdvancedTriggerDisplay() { return advancedTriggerDisplay; }
|
||||||
|
boolean advancedTriggerDisplay = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return If the color of damage type modifiers in modifier names
|
||||||
|
* and trigger names will be recolored when actually displaying
|
||||||
|
* into the item.
|
||||||
|
*/
|
||||||
|
public boolean isAdvancedRecoloring() { return advancedRecoloring; }
|
||||||
|
boolean advancedRecoloring = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example:
|
||||||
|
* PROJECTILE -> Ranged
|
||||||
|
*
|
||||||
|
* @param type The damage type you intend to translate
|
||||||
|
*
|
||||||
|
* @return The player-friendly name off this damage type
|
||||||
|
*/
|
||||||
|
@NotNull public String getDamageName(@NotNull DamageType type) { return damageNames.getOrDefault(type, SilentNumbers.titleCaseConversion(type.toString().replace("-", " ").replace("_", " "))); }
|
||||||
|
@NotNull HashMap<DamageType, String> damageNames = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example:
|
||||||
|
* SKILL -> Ability Hit
|
||||||
|
*
|
||||||
|
* @param type The attack type you intend to translate
|
||||||
|
*
|
||||||
|
* @return The player-friendly name off this attack type
|
||||||
|
*/
|
||||||
|
@NotNull public String getAttackName(@NotNull AttackType type) { return attackNames.getOrDefault(type, "Damage"); }
|
||||||
|
@NotNull HashMap<AttackType, String> attackNames = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example:
|
||||||
|
* SKILL &f (default) -> <#FEEFEF> (specified in config)
|
||||||
|
*
|
||||||
|
* @param type The damage you intend to get its color
|
||||||
|
*
|
||||||
|
* @return The 'translated' color of this damage type, to
|
||||||
|
* override the default damage colors mostly.
|
||||||
|
*/
|
||||||
|
@NotNull public String getDamageColor(@NotNull DamageType type) { return damageColor.getOrDefault(type, SilentNumbers.titleCaseConversion(type.toString().replace("-", " ").replace("_", " "))); }
|
||||||
|
@NotNull HashMap<DamageType, String> damageColor = new HashMap<>();
|
||||||
|
|
||||||
|
@NotNull public static final String SKMOD_DAMAGE_TYPE_DAMAGE = "\u00a7o■";
|
||||||
|
@NotNull public static final String SKMOD_DAMAGE_TYPE_BLACK = "\u00a7c!";
|
||||||
|
@NotNull public static final String SKMOD_DAMAGE_TYPE_AND = "\u00a77 ";
|
||||||
|
@NotNull public static final String SKMOD_DAMAGE_TYPE_COMMA = "\u00a77,";
|
||||||
|
@NotNull public static final String SKMOD_DAMAGE_TYPE_OR = "\u00a77/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usually the displayed name of the trigger is just... the name of the trigger.
|
||||||
|
* <p>
|
||||||
|
* However, when using the Damage Type skill modifier, this can be misleading;
|
||||||
|
* for example, the {@link TriggerType#ATTACK} will no longer trigger with any attack.
|
||||||
|
* </p>
|
||||||
|
* This method will rename it correctly; for example: WEAPON MAGIC = Magic Attack
|
||||||
|
* <p></p>
|
||||||
|
* This only supports the trigger {@link TriggerType#ATTACK}
|
||||||
|
*
|
||||||
|
* @param trigger The trigger by which this skill fires
|
||||||
|
* @param attackType The encoded skill modifier value
|
||||||
|
*
|
||||||
|
* @return The way the trigger should display in lore.
|
||||||
|
*/
|
||||||
|
@NotNull public String getTriggerDisplayName(@NotNull TriggerType trigger, double attackType) {
|
||||||
|
|
||||||
|
// Use the default?
|
||||||
|
String triggerDisplayName = MMOItems.plugin.getLanguage().getCastingModeName(trigger);
|
||||||
|
|
||||||
|
// If no skill modifiers are used, or the config option is disabled
|
||||||
|
if (attackType == 0 || !isAdvancedTriggerDisplay()) {
|
||||||
|
//APP//MythicCraftingManager.log("\u00a78ABT\u00a73 APP\u00a7c No advanced trigger display\u00a7e " + attackType);
|
||||||
|
return triggerDisplayName; }
|
||||||
|
|
||||||
|
// Currently, only ATTACK trigger is supported
|
||||||
|
if (!TriggerType.ATTACK.equals(trigger)) {
|
||||||
|
//APP//MythicCraftingManager.log("\u00a78ABT\u00a73 APP\u00a7c Not a supported trigger");
|
||||||
|
return triggerDisplayName; }
|
||||||
|
|
||||||
|
boolean named = false;
|
||||||
|
boolean orMode = false;
|
||||||
|
if (attackType < 0) { orMode = true; attackType *= -1; }
|
||||||
|
String separatorSymbol = (orMode ? SKMOD_DAMAGE_TYPE_OR : SKMOD_DAMAGE_TYPE_AND);
|
||||||
|
|
||||||
|
// Decode
|
||||||
|
ArrayList<DamageType> white = DamageType.getWhitelist(attackType);
|
||||||
|
ArrayList<DamageType> black = DamageType.getBlacklist(attackType);
|
||||||
|
|
||||||
|
// Currently, only ATTACK trigger is supported
|
||||||
|
if (white.isEmpty()) {
|
||||||
|
//APP//MythicCraftingManager.log("\u00a78ABT\u00a73 APP\u00a7c Empty whitelist, blacklist is not supported");
|
||||||
|
return triggerDisplayName; }
|
||||||
|
|
||||||
|
// Special names sector
|
||||||
|
if (TriggerType.ATTACK.equals(trigger)) {
|
||||||
|
//APP//MythicCraftingManager.log("\u00a78ABT\u00a73 APP\u00a77 Identified as the ATTACK trigger");
|
||||||
|
|
||||||
|
// Very specific overrides
|
||||||
|
if (white.size() == 1 && white.contains(DamageType.MINION)) {
|
||||||
|
|
||||||
|
// Minion Attack
|
||||||
|
triggerDisplayName = getDamageName(DamageType.MINION) + SKMOD_DAMAGE_TYPE_AND + getAttackName(AttackType.WEAPON);
|
||||||
|
named = true;
|
||||||
|
|
||||||
|
} else if (white.size() == 1 && white.contains(DamageType.DOT)) {
|
||||||
|
|
||||||
|
// Lingering Attack
|
||||||
|
triggerDisplayName = getDamageName(DamageType.DOT) + SKMOD_DAMAGE_TYPE_AND + getAttackName(AttackType.WEAPON);
|
||||||
|
named = true;
|
||||||
|
|
||||||
|
} else if (white.size() == 2 && white.contains(DamageType.MINION) && white.contains(DamageType.PROJECTILE)) {
|
||||||
|
|
||||||
|
// Minion Ranged Attack
|
||||||
|
triggerDisplayName = getDamageName(DamageType.MINION) + SKMOD_DAMAGE_TYPE_AND + getDamageName(DamageType.PROJECTILE) + SKMOD_DAMAGE_TYPE_AND + getAttackName(AttackType.WEAPON);
|
||||||
|
named = true;
|
||||||
|
|
||||||
|
} else if (white.size() == 2 && white.contains(DamageType.MINION) && white.contains(DamageType.MAGIC)) {
|
||||||
|
|
||||||
|
// Minion Magic Attack
|
||||||
|
triggerDisplayName = getDamageName(DamageType.MINION) + SKMOD_DAMAGE_TYPE_AND + getDamageName(DamageType.MAGIC) + SKMOD_DAMAGE_TYPE_AND + getAttackName(AttackType.WEAPON);
|
||||||
|
named = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Skill, Attack, or generic damage
|
||||||
|
boolean isWeapon = white.contains(DamageType.WEAPON);
|
||||||
|
boolean isSkill = white.contains(DamageType.SKILL);
|
||||||
|
boolean both = isWeapon && isSkill;
|
||||||
|
boolean neither = !isWeapon && !isSkill;
|
||||||
|
|
||||||
|
// Elemental type
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (DamageType whitelisted : white) {
|
||||||
|
|
||||||
|
// Ignore weapon and skill
|
||||||
|
if (whitelisted == DamageType.WEAPON ||
|
||||||
|
whitelisted == DamageType.SKILL) {
|
||||||
|
continue; }
|
||||||
|
|
||||||
|
// Append separator
|
||||||
|
if (builder.length() > 1) { builder.append(separatorSymbol); }
|
||||||
|
|
||||||
|
// Append the type
|
||||||
|
builder
|
||||||
|
//.append(damageColors(whitelisted.getColor())) // Sawala doesn't think colours are gud
|
||||||
|
.append(getDamageName(whitelisted));
|
||||||
|
}
|
||||||
|
|
||||||
|
String latter;
|
||||||
|
String built = builder.toString();
|
||||||
|
String former = "";
|
||||||
|
|
||||||
|
// Requires any other damage type?
|
||||||
|
if (built.length() > 0) {
|
||||||
|
if (neither) { latter = SKMOD_DAMAGE_TYPE_AND + getAttackName(AttackType.NEITHER); }
|
||||||
|
else if (both) { latter = SKMOD_DAMAGE_TYPE_AND + getAttackName(AttackType.BOTH); }
|
||||||
|
else if (isWeapon) { latter = SKMOD_DAMAGE_TYPE_AND + getAttackName(AttackType.WEAPON); }
|
||||||
|
else { latter = SKMOD_DAMAGE_TYPE_AND + getAttackName(AttackType.SKILL); }
|
||||||
|
|
||||||
|
// Only characterized by weapon
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (neither) { latter = getAttackName(AttackType.NEITHER); }
|
||||||
|
else if (both) { latter = getAttackName(AttackType.BOTH); }
|
||||||
|
else if (isWeapon) { latter = getAttackName(AttackType.WEAPON); }
|
||||||
|
else { latter = getAttackName(AttackType.SKILL); }
|
||||||
|
}
|
||||||
|
|
||||||
|
//APP//MythicCraftingManager.log("\u00a78ABT\u00a73 APP\u00a77 Former:\u00a73 " + former);
|
||||||
|
//APP//MythicCraftingManager.log("\u00a78ABT\u00a73 APP\u00a77 Built:\u00a73 " + built);
|
||||||
|
//APP//MythicCraftingManager.log("\u00a78ABT\u00a73 APP\u00a77 Latter:\u00a73 " + latter);
|
||||||
|
|
||||||
|
named = true;
|
||||||
|
triggerDisplayName = former + built + latter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just display the damage type restriction as squares
|
||||||
|
else if (TriggerType.KILL_ENTITY.equals(trigger)) {
|
||||||
|
|
||||||
|
// Elemental type
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (DamageType whitelisted : white) {
|
||||||
|
|
||||||
|
// Append separator
|
||||||
|
if (builder.length() > 1) { builder.append(separatorSymbol); }
|
||||||
|
|
||||||
|
// Append the type
|
||||||
|
builder
|
||||||
|
//.append(damageColors(whitelisted.getColor())) // Sawala doesn't think colours are gud
|
||||||
|
.append(getDamageName(whitelisted));
|
||||||
|
}
|
||||||
|
|
||||||
|
named = true;
|
||||||
|
triggerDisplayName = builder + SKMOD_DAMAGE_TYPE_AND + triggerDisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No special name just default it
|
||||||
|
if (!named) {
|
||||||
|
|
||||||
|
// Append that
|
||||||
|
triggerDisplayName += " " + damageTypeRestrictionDisplay(separatorSymbol, white, black);
|
||||||
|
}
|
||||||
|
|
||||||
|
return triggerDisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param damageTypeRestriction Number that encodes for the damage type restriction
|
||||||
|
*
|
||||||
|
* @return A nice chain of colored boxes (real) that represents this damage type restriction.
|
||||||
|
*/
|
||||||
|
@NotNull String damageTypeRestrictionDisplay(double damageTypeRestriction) {
|
||||||
|
|
||||||
|
boolean orMode = false;
|
||||||
|
if (damageTypeRestriction < 0) { orMode = true; damageTypeRestriction *= -1; }
|
||||||
|
String separatorSymbol = (orMode ? SKMOD_DAMAGE_TYPE_OR : SKMOD_DAMAGE_TYPE_AND);
|
||||||
|
|
||||||
|
// Decode
|
||||||
|
ArrayList<DamageType> white = DamageType.getWhitelist(damageTypeRestriction);
|
||||||
|
ArrayList<DamageType> black = DamageType.getBlacklist(damageTypeRestriction);
|
||||||
|
|
||||||
|
// Just build the string man
|
||||||
|
return damageTypeRestrictionDisplay(separatorSymbol, white, black);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param separatorSymbol Separator symbol to use between whitelisted damage types
|
||||||
|
* @param white Damage types whitelisted
|
||||||
|
* @param black Damage types blacklisted
|
||||||
|
*
|
||||||
|
* @return A nice chain of colored boxes (real) that represents this damage type restriction.
|
||||||
|
*/
|
||||||
|
@NotNull String damageTypeRestrictionDisplay(@NotNull String separatorSymbol, @NotNull ArrayList<DamageType> white, @NotNull ArrayList<DamageType> black) {
|
||||||
|
|
||||||
|
StringBuilder append = new StringBuilder();
|
||||||
|
for (DamageType w : white) {
|
||||||
|
|
||||||
|
// Append separator
|
||||||
|
if (append.length() > 1) { append.append(separatorSymbol); }
|
||||||
|
|
||||||
|
// Append damage
|
||||||
|
append.append(damageColors(w.getColor())).append(SKMOD_DAMAGE_TYPE_DAMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Separator for blacklist
|
||||||
|
if (append.length() > 1 && black.size() > 0) { append.append(SKMOD_DAMAGE_TYPE_COMMA); }
|
||||||
|
|
||||||
|
for (DamageType b : black) {
|
||||||
|
|
||||||
|
// Append separator
|
||||||
|
if (append.length() > 1) { append.append(SKMOD_DAMAGE_TYPE_AND); }
|
||||||
|
|
||||||
|
// Append damage
|
||||||
|
append.append(SKMOD_DAMAGE_TYPE_BLACK).append(damageColors(b.getColor())).append(SKMOD_DAMAGE_TYPE_DAMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return append.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param in The colored string in the default format
|
||||||
|
*
|
||||||
|
* @return Color overridden by user-specified counterpart.
|
||||||
|
*/
|
||||||
|
@NotNull public String damageColors(@Nullable String in) {
|
||||||
|
//SDC//MythicCraftingManager.log("\u00a78ABT\u00a7c SDC\u00a77 Recoloring\u00a7b " + in);
|
||||||
|
if (in == null) { return ""; }
|
||||||
|
if (!isAdvancedRecoloring()) { return in; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sawala's agony color replacements
|
||||||
|
*
|
||||||
|
* Because I literally had everything consistent in &8 &a &9 and he was like &4 &2 <HEX0038C2>;
|
||||||
|
* what on earth even is <HEX0038C2> ffs for magic damage some ugly ass deep blue (I sleep)
|
||||||
|
*/
|
||||||
|
for (DamageType ty : damageColor.keySet()) {
|
||||||
|
|
||||||
|
//SDC//MythicCraftingManager.log("\u00a78ABT\u00a7c SDC\u00a7e +\u00a77 Damage Type\u00a7b " + ty.toString());
|
||||||
|
//SDC//MythicCraftingManager.log("\u00a78ABT\u00a7c SDC\u00a7e +\u00a77 Default Col\u00a7b " + ty.getColor() + "O");
|
||||||
|
//SDC//MythicCraftingManager.log("\u00a78ABT\u00a7c SDC\u00a7e +\u00a77 Override Cl\u00a7b " + getDamageColor(ty) + "O");
|
||||||
|
|
||||||
|
// Both & and §
|
||||||
|
in = in.replace(ty.getColor().replace('\u00a7', '&'), getDamageColor(ty));
|
||||||
|
in = in.replace(ty.getColor(), getDamageColor(ty));
|
||||||
|
}
|
||||||
|
//SDC//MythicCraftingManager.log("\u00a78ABT\u00a7c SDC\u00a77 Result\u00a7b " + in);
|
||||||
|
|
||||||
|
// he he ha ha
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A way to classify and translate the result of an {@link io.lumine.mythic.lib.damage.AttackMetadata},
|
||||||
|
*/
|
||||||
|
enum AttackType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dealing damage with weapons (real), Attacks.
|
||||||
|
*/
|
||||||
|
WEAPON,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dealing damage with abilities, Ability Hits.
|
||||||
|
*/
|
||||||
|
SKILL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No information on skill or weapon damage,
|
||||||
|
* treated as just generic Damage.
|
||||||
|
*/
|
||||||
|
NEITHER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Both skill and weapon damage types are present,
|
||||||
|
* this would make sense if the lore of the ability
|
||||||
|
* implies that your weapon is being used in the attack.
|
||||||
|
* <br><br>
|
||||||
|
* Compare simply casting a fireball, vs simply hitting
|
||||||
|
* with a baton, vs coating the baton with magic fire and
|
||||||
|
* then attacking with it. <br>
|
||||||
|
* The last case would be an 'Ability-Assisted Attack'
|
||||||
|
*/
|
||||||
|
BOTH
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package net.Indyuce.mmoitems.gui.edition;
|
package net.Indyuce.mmoitems.gui.edition;
|
||||||
|
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import io.lumine.mythic.lib.skill.handler.SkillHandler;
|
||||||
import io.lumine.mythic.lib.skill.trigger.TriggerType;
|
import io.lumine.mythic.lib.skill.trigger.TriggerType;
|
||||||
import net.Indyuce.mmoitems.ItemStats;
|
import net.Indyuce.mmoitems.ItemStats;
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
@ -22,6 +24,8 @@ import org.bukkit.event.inventory.InventoryClickEvent;
|
|||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -64,16 +68,14 @@ public class AbilityEdition extends EditionInventory {
|
|||||||
abilityItemMeta.setLore(abilityItemLore);
|
abilityItemMeta.setLore(abilityItemLore);
|
||||||
abilityItem.setItemMeta(abilityItemMeta);
|
abilityItem.setItemMeta(abilityItemMeta);
|
||||||
|
|
||||||
|
TriggerType castMode = null;
|
||||||
if (ability != null) {
|
if (ability != null) {
|
||||||
String castModeConfigString = getEditedSection().getString("ability." + configKey + ".mode");
|
String castModeConfigString = getEditedSection().getString("ability." + configKey + ".mode");
|
||||||
String castModeFormat = castModeConfigString == null ? ""
|
String castModeFormat = castModeConfigString == null ? ""
|
||||||
: castModeConfigString.toUpperCase().replace(" ", "_").replace("-", "_").replaceAll("[^A-Z0-9_]", "");
|
: castModeConfigString.toUpperCase().replace(" ", "_").replace("-", "_").replaceAll("[^A-Z0-9_]", "");
|
||||||
TriggerType castMode;
|
|
||||||
try {
|
try {
|
||||||
castMode = TriggerType.valueOf(castModeFormat);
|
castMode = TriggerType.valueOf(castModeFormat);
|
||||||
} catch (RuntimeException exception) {
|
} catch (RuntimeException ignored) { }
|
||||||
castMode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemStack castModeItem = new ItemStack(Material.ARMOR_STAND);
|
ItemStack castModeItem = new ItemStack(Material.ARMOR_STAND);
|
||||||
ItemMeta castModeItemMeta = castModeItem.getItemMeta();
|
ItemMeta castModeItemMeta = castModeItem.getItemMeta();
|
||||||
@ -96,6 +98,8 @@ public class AbilityEdition extends EditionInventory {
|
|||||||
if (ability != null) {
|
if (ability != null) {
|
||||||
ConfigurationSection section = getEditedSection().getConfigurationSection("ability." + configKey);
|
ConfigurationSection section = getEditedSection().getConfigurationSection("ability." + configKey);
|
||||||
for (String modifier : ability.getHandler().getModifiers()) {
|
for (String modifier : ability.getHandler().getModifiers()) {
|
||||||
|
if (!sensibleModifier(modifier, castMode)) { continue; }
|
||||||
|
|
||||||
ItemStack modifierItem = VersionMaterial.GRAY_DYE.toItem();
|
ItemStack modifierItem = VersionMaterial.GRAY_DYE.toItem();
|
||||||
ItemMeta modifierItemMeta = modifierItem.getItemMeta();
|
ItemMeta modifierItemMeta = modifierItem.getItemMeta();
|
||||||
modifierItemMeta.setDisplayName(ChatColor.GREEN + MMOUtils.caseOnWords(modifier.toLowerCase().replace("-", " ")));
|
modifierItemMeta.setDisplayName(ChatColor.GREEN + MMOUtils.caseOnWords(modifier.toLowerCase().replace("-", " ")));
|
||||||
@ -105,9 +109,32 @@ public class AbilityEdition extends EditionInventory {
|
|||||||
modifierItemLore.add("");
|
modifierItemLore.add("");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
// Current Value Yeah
|
||||||
|
NumericStatFormula heuh = new NumericStatFormula(section.get(modifier));
|
||||||
|
String currentValue = heuh.toString();
|
||||||
|
if (SkillHandler.SKMOD_DAMAGE_TYPE.equals(modifier)) {
|
||||||
|
double dam = heuh.getBase();
|
||||||
|
boolean orMode = dam < 0;
|
||||||
|
if (orMode) { dam *= -1; }
|
||||||
|
|
||||||
|
// Parse display
|
||||||
|
ArrayList<DamageType> whitelist = DamageType.getWhitelist(dam);
|
||||||
|
ArrayList<DamageType> blacklist = DamageType.getBlacklist(dam);
|
||||||
|
|
||||||
|
// I guess append
|
||||||
|
StringBuilder builder = new StringBuilder(orMode ? "OR" : "");
|
||||||
|
for (DamageType white : whitelist) { if (builder.length() > 0) { builder.append(" "); } builder.append(white); }
|
||||||
|
for (DamageType black : blacklist) { if (builder.length() > 0) { builder.append(" "); } builder.append("!").append(black); }
|
||||||
|
|
||||||
|
// Build Input
|
||||||
|
currentValue = builder.toString() + " \u00a78(\u00a79" + heuh.toString() + "\u00a78)";
|
||||||
|
}
|
||||||
|
|
||||||
modifierItemLore.add(ChatColor.GRAY + "Current Value: " + ChatColor.GOLD
|
modifierItemLore.add(ChatColor.GRAY + "Current Value: " + ChatColor.GOLD
|
||||||
+ (section.contains(modifier) ? new NumericStatFormula(section.get(modifier)).toString()
|
+ (section.contains(modifier) ? currentValue
|
||||||
: MODIFIER_FORMAT.format(ability.getDefaultModifier(modifier))));
|
: MODIFIER_FORMAT.format(ability.getDefaultModifier(modifier))));
|
||||||
|
|
||||||
} catch (IllegalArgumentException exception) {
|
} catch (IllegalArgumentException exception) {
|
||||||
modifierItemLore.add(ChatColor.GRAY + "Could not read value. Using default");
|
modifierItemLore.add(ChatColor.GRAY + "Could not read value. Using default");
|
||||||
}
|
}
|
||||||
@ -146,6 +173,29 @@ public class AbilityEdition extends EditionInventory {
|
|||||||
return inv;
|
return inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some modifiers, like Timer or Damage Type Restriction,
|
||||||
|
* only make sense if used in the triggers where they are
|
||||||
|
* supported.
|
||||||
|
*
|
||||||
|
* @param modifier Modifier in question
|
||||||
|
* @param trigger Trigger in question
|
||||||
|
*
|
||||||
|
* @return If this modifier makes sense for this trigger
|
||||||
|
*/
|
||||||
|
boolean sensibleModifier(@NotNull String modifier, @Nullable TriggerType trigger) {
|
||||||
|
|
||||||
|
// Missing cast mode might as well show all modifiers
|
||||||
|
if (trigger == null) { return true; }
|
||||||
|
|
||||||
|
// These modifiers only work with the specific trigger
|
||||||
|
if (modifier.equals(SkillHandler.SKMOD_DAMAGE_TYPE)) { return trigger.equals(TriggerType.ATTACK); }
|
||||||
|
if (modifier.equals(SkillHandler.SKMOD_TIMER)) { return trigger.equals(TriggerType.TIMER); }
|
||||||
|
|
||||||
|
// Modifier is compatible with any trigger by default
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void whenClicked(InventoryClickEvent event) {
|
public void whenClicked(InventoryClickEvent event) {
|
||||||
ItemStack item = event.getCurrentItem();
|
ItemStack item = event.getCurrentItem();
|
||||||
|
@ -7,6 +7,7 @@ import net.Indyuce.mmoitems.api.ConfigFile;
|
|||||||
import net.Indyuce.mmoitems.api.ReforgeOptions;
|
import net.Indyuce.mmoitems.api.ReforgeOptions;
|
||||||
import net.Indyuce.mmoitems.api.item.util.ConfigItem;
|
import net.Indyuce.mmoitems.api.item.util.ConfigItem;
|
||||||
import net.Indyuce.mmoitems.api.item.util.ConfigItems;
|
import net.Indyuce.mmoitems.api.item.util.ConfigItems;
|
||||||
|
import net.Indyuce.mmoitems.api.util.DamageTypeRestrictionSettings;
|
||||||
import net.Indyuce.mmoitems.api.util.NumericStatFormula;
|
import net.Indyuce.mmoitems.api.util.NumericStatFormula;
|
||||||
import net.Indyuce.mmoitems.api.util.message.Message;
|
import net.Indyuce.mmoitems.api.util.message.Message;
|
||||||
import net.Indyuce.mmoitems.stat.GemUpgradeScaling;
|
import net.Indyuce.mmoitems.stat.GemUpgradeScaling;
|
||||||
@ -36,6 +37,7 @@ public class ConfigManager implements Reloadable {
|
|||||||
|
|
||||||
// cached config files
|
// cached config files
|
||||||
private ConfigFile loreFormat, stats, dynLore;
|
private ConfigFile loreFormat, stats, dynLore;
|
||||||
|
private FileConfiguration abilities;
|
||||||
|
|
||||||
// Language
|
// Language
|
||||||
private final Map<TriggerType, String> triggerTypeNames = new HashMap<>();
|
private final Map<TriggerType, String> triggerTypeNames = new HashMap<>();
|
||||||
@ -48,6 +50,8 @@ public class ConfigManager implements Reloadable {
|
|||||||
public NumericStatFormula defaultItemCapacity;
|
public NumericStatFormula defaultItemCapacity;
|
||||||
public ReforgeOptions revisionOptions, gemRevisionOptions, phatLootsOptions;
|
public ReforgeOptions revisionOptions, gemRevisionOptions, phatLootsOptions;
|
||||||
public final List<String> opStats = new ArrayList<>();
|
public final List<String> opStats = new ArrayList<>();
|
||||||
|
public boolean abilitiesBypassEncumbering, disableOffhandAbilities;
|
||||||
|
public DamageTypeRestrictionSettings damageTypeRestrictionSettings;
|
||||||
|
|
||||||
public ConfigManager() {
|
public ConfigManager() {
|
||||||
mkdir("layouts");
|
mkdir("layouts");
|
||||||
@ -144,7 +148,7 @@ public class ConfigManager implements Reloadable {
|
|||||||
|
|
||||||
// Trigger types
|
// Trigger types
|
||||||
triggerTypeNames.clear();
|
triggerTypeNames.clear();
|
||||||
final FileConfiguration abilities = new ConfigFile("/language", "abilities").getConfig();
|
abilities = new ConfigFile("/language", "abilities").getConfig();
|
||||||
for (TriggerType type : TriggerType.values())
|
for (TriggerType type : TriggerType.values())
|
||||||
triggerTypeNames.put(type, abilities.getString("cast-mode." + type.getLowerCaseId(), type.getName()));
|
triggerTypeNames.put(type, abilities.getString("cast-mode." + type.getLowerCaseId(), type.getName()));
|
||||||
}
|
}
|
||||||
@ -155,6 +159,7 @@ public class ConfigManager implements Reloadable {
|
|||||||
loreFormat = new ConfigFile("/language", "lore-format");
|
loreFormat = new ConfigFile("/language", "lore-format");
|
||||||
stats = new ConfigFile("/language", "stats");
|
stats = new ConfigFile("/language", "stats");
|
||||||
dynLore = new ConfigFile("/language", "dynamic-lore");
|
dynLore = new ConfigFile("/language", "dynamic-lore");
|
||||||
|
abilities = new ConfigFile("/language", "abilities").getConfig();
|
||||||
|
|
||||||
loadTranslations();
|
loadTranslations();
|
||||||
|
|
||||||
@ -173,6 +178,8 @@ public class ConfigManager implements Reloadable {
|
|||||||
keepSoulboundOnDeath = MMOItems.plugin.getConfig().getBoolean("soulbound.keep-on-death");
|
keepSoulboundOnDeath = MMOItems.plugin.getConfig().getBoolean("soulbound.keep-on-death");
|
||||||
rerollOnItemUpdate = MMOItems.plugin.getConfig().getBoolean("item-revision.reroll-when-updated");
|
rerollOnItemUpdate = MMOItems.plugin.getConfig().getBoolean("item-revision.reroll-when-updated");
|
||||||
levelSpread = MMOItems.plugin.getConfig().getDouble("item-level-spread");
|
levelSpread = MMOItems.plugin.getConfig().getDouble("item-level-spread");
|
||||||
|
abilitiesBypassEncumbering = MMOItems.plugin.getConfig().getBoolean("abilities-bypass-encumbering", !MMOItems.plugin.getConfig().getBoolean("two-handed-item-restriction", true));
|
||||||
|
disableOffhandAbilities = MMOItems.plugin.getConfig().getBoolean("disable-abilities-in-offhand", false);
|
||||||
|
|
||||||
opStatsEnabled = MMOItems.plugin.getConfig().getBoolean("op-item-stats.enabled");
|
opStatsEnabled = MMOItems.plugin.getConfig().getBoolean("op-item-stats.enabled");
|
||||||
opStats.clear();
|
opStats.clear();
|
||||||
@ -187,6 +194,8 @@ public class ConfigManager implements Reloadable {
|
|||||||
gemRevisionOptions = gemKeepData != null ? new ReforgeOptions(gemKeepData) : new ReforgeOptions(false, false, false, false, false, false, false, true);
|
gemRevisionOptions = gemKeepData != null ? new ReforgeOptions(gemKeepData) : new ReforgeOptions(false, false, false, false, false, false, false, true);
|
||||||
phatLootsOptions = phatLoots != null ? new ReforgeOptions(phatLoots) : new ReforgeOptions(false, false, false, false, false, false, false, true);
|
phatLootsOptions = phatLoots != null ? new ReforgeOptions(phatLoots) : new ReforgeOptions(false, false, false, false, false, false, false, true);
|
||||||
|
|
||||||
|
damageTypeRestrictionSettings = new DamageTypeRestrictionSettings(abilities.getConfigurationSection("damage-type-restriction"));
|
||||||
|
|
||||||
List<String> exemptedPhatLoots = MMOItems.plugin.getConfig().getStringList("item-revision.disable-phat-loot");
|
List<String> exemptedPhatLoots = MMOItems.plugin.getConfig().getStringList("item-revision.disable-phat-loot");
|
||||||
for (String epl : exemptedPhatLoots)
|
for (String epl : exemptedPhatLoots)
|
||||||
phatLootsOptions.addToBlacklist(epl);
|
phatLootsOptions.addToBlacklist(epl);
|
||||||
|
@ -5,8 +5,15 @@ import io.lumine.mythic.lib.MythicLib;
|
|||||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||||
import io.lumine.mythic.lib.api.item.SupportedNBTTagValues;
|
import io.lumine.mythic.lib.api.item.SupportedNBTTagValues;
|
||||||
import io.lumine.mythic.lib.api.util.AltChar;
|
import io.lumine.mythic.lib.api.util.AltChar;
|
||||||
|
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackCategory;
|
||||||
|
import io.lumine.mythic.lib.api.util.ui.FriendlyFeedbackProvider;
|
||||||
|
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
|
||||||
|
import io.lumine.mythic.lib.damage.DamageType;
|
||||||
|
import io.lumine.mythic.lib.skill.handler.SkillHandler;
|
||||||
import io.lumine.mythic.lib.skill.trigger.TriggerType;
|
import io.lumine.mythic.lib.skill.trigger.TriggerType;
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
|
import net.Indyuce.mmoitems.api.util.DamageTypeRestrictionSettings;
|
||||||
|
import net.Indyuce.mmoitems.api.util.message.FFPMMOItems;
|
||||||
import net.Indyuce.mmoitems.util.MMOUtils;
|
import net.Indyuce.mmoitems.util.MMOUtils;
|
||||||
import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
|
import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
|
||||||
import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem;
|
import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem;
|
||||||
@ -56,16 +63,24 @@ public class Abilities extends ItemStat<RandomAbilityListData, AbilityListData>
|
|||||||
//Modify Lore
|
//Modify Lore
|
||||||
List<String> abilityLore = new ArrayList<>();
|
List<String> abilityLore = new ArrayList<>();
|
||||||
boolean splitter = !MMOItems.plugin.getLanguage().abilitySplitter.equals("");
|
boolean splitter = !MMOItems.plugin.getLanguage().abilitySplitter.equals("");
|
||||||
|
DamageTypeRestrictionSettings settings = MMOItems.plugin.getLanguage().damageTypeRestrictionSettings;
|
||||||
|
|
||||||
String modifierFormat = ItemStat.translate("ability-modifier"), abilityFormat = ItemStat.translate("ability-format");
|
String modifierFormat = ItemStat.translate("ability-modifier"), abilityFormat = ItemStat.translate("ability-format");
|
||||||
|
|
||||||
data.getAbilities().forEach(ability -> {
|
data.getAbilities().forEach(ability -> {
|
||||||
abilityLore.add(abilityFormat.replace("{trigger}", MMOItems.plugin.getLanguage().getCastingModeName(ability.getTrigger())).replace("{ability}", ability.getAbility().getName()));
|
|
||||||
|
// Replace name of trigger, as well as name of ability
|
||||||
|
String triggerDisplayName = settings.getTriggerDisplayName(ability.getTrigger(), ability.getModifier(SkillHandler.SKMOD_DAMAGE_TYPE));
|
||||||
|
abilityLore.add(abilityFormat.replace("{trigger}", triggerDisplayName).replace("{ability}", ability.getAbility().getName()));
|
||||||
|
|
||||||
for (String modifier : ability.getModifiers()) {
|
for (String modifier : ability.getModifiers()) {
|
||||||
|
|
||||||
|
// Damage Type Modifier does not display in lore
|
||||||
|
if (modifier.equals(SkillHandler.SKMOD_DAMAGE_TYPE)) { continue; }
|
||||||
|
|
||||||
item.getLore().registerPlaceholder("ability_" + ability.getAbility().getHandler().getId().toLowerCase() + "_" + modifier,
|
item.getLore().registerPlaceholder("ability_" + ability.getAbility().getHandler().getId().toLowerCase() + "_" + modifier,
|
||||||
MythicLib.plugin.getMMOConfig().decimal.format(ability.getModifier(modifier)));
|
MythicLib.plugin.getMMOConfig().decimal.format(ability.getModifier(modifier)));
|
||||||
abilityLore.add(modifierFormat.replace("{modifier}", ability.getAbility().getModifierName(modifier)).replace("{value}",
|
abilityLore.add(modifierFormat.replace("{modifier}", settings.damageColors(ability.getAbility().getModifierName(modifier))).replace("{value}",
|
||||||
MythicLib.plugin.getMMOConfig().decimal.format(ability.getModifier(modifier))));
|
MythicLib.plugin.getMMOConfig().decimal.format(ability.getModifier(modifier))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,8 +148,65 @@ public class Abilities extends ItemStat<RandomAbilityListData, AbilityListData>
|
|||||||
+ ChatColor.GRAY + ".");
|
+ ChatColor.GRAY + ".");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
String number = message;
|
||||||
|
|
||||||
new NumericStatFormula(message).fillConfigurationSection(inv.getEditedSection(), "ability." + configKey + "." + edited,
|
// If we are editing the damage types and the provided value is not a number already
|
||||||
|
if (SkillHandler.SKMOD_DAMAGE_TYPE.equals(edited) && !SilentNumbers.IntTryParse(number)) {
|
||||||
|
|
||||||
|
// Might come in handy....
|
||||||
|
FriendlyFeedbackProvider ffp = new FriendlyFeedbackProvider(FFPMMOItems.get());
|
||||||
|
ffp.activatePrefix(true, "Edition");
|
||||||
|
boolean failure = false;
|
||||||
|
|
||||||
|
// Or Mode
|
||||||
|
boolean orMode = message.startsWith("OR ");
|
||||||
|
if (orMode) { message = message.substring("OR ".length()); }
|
||||||
|
|
||||||
|
// Build arrays
|
||||||
|
ArrayList<DamageType> whitelisted = new ArrayList<>();
|
||||||
|
ArrayList<DamageType> blacklisted = new ArrayList<>();
|
||||||
|
|
||||||
|
// Split by spaces
|
||||||
|
String[] typesSplit = message.split(" ");
|
||||||
|
for (String ty : typesSplit) {
|
||||||
|
|
||||||
|
// Crop blacklist
|
||||||
|
boolean blacklist = false;
|
||||||
|
String observed = ty.toUpperCase().replace("-", "_").replace(" ", "_");
|
||||||
|
if (observed.startsWith("!")) { observed = observed.substring(1); blacklist = true; }
|
||||||
|
|
||||||
|
// Identify Damage Type
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Un-parse
|
||||||
|
DamageType damageType = DamageType.valueOf(observed);
|
||||||
|
|
||||||
|
// Add to the lists
|
||||||
|
if (blacklist) { blacklisted.add(damageType); } else { whitelisted.add(damageType); }
|
||||||
|
|
||||||
|
// Mention
|
||||||
|
} catch (IllegalArgumentException ignored) {
|
||||||
|
|
||||||
|
// no
|
||||||
|
failure = true;
|
||||||
|
|
||||||
|
ffp.log(FriendlyFeedbackCategory.ERROR, "Unknown damage type '$r{0}$b' in '$u{1}$b'. ", observed, ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel
|
||||||
|
if (failure) {
|
||||||
|
|
||||||
|
// Errors
|
||||||
|
ffp.sendAllTo(inv.getPlayer());
|
||||||
|
throw new IllegalArgumentException("$bInvalid input! Please specify damage types to require or blacklist, for example: '$eMAGIC WEAPON !SKILL$b' or '$eOR PHYSICAL PROJECTILE MINION !MAGIC$b'. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bake number
|
||||||
|
number = String.valueOf(DamageType.encodeDamageTypeMatch(whitelisted, blacklisted, orMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
new NumericStatFormula(number).fillConfigurationSection(inv.getEditedSection(), "ability." + configKey + "." + edited,
|
||||||
FormulaSaveOption.NONE);
|
FormulaSaveOption.NONE);
|
||||||
inv.registerTemplateEdition();
|
inv.registerTemplateEdition();
|
||||||
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + ChatColor.GOLD + MMOUtils.caseOnWords(edited.replace("-", " ")) + ChatColor.GRAY
|
inv.getPlayer().sendMessage(MMOItems.plugin.getPrefix() + ChatColor.GOLD + MMOUtils.caseOnWords(edited.replace("-", " ")) + ChatColor.GRAY
|
||||||
|
@ -21,3 +21,42 @@ cast-mode:
|
|||||||
trident-hit: Trident Hit
|
trident-hit: Trident Hit
|
||||||
damaged-by-entity: Damaged By Entity
|
damaged-by-entity: Damaged By Entity
|
||||||
shift-right-click: Shift Right Click
|
shift-right-click: Shift Right Click
|
||||||
|
|
||||||
|
# For the On Attack trigger there exists the
|
||||||
|
# Modifier 'Damage Type Restriction' that supports
|
||||||
|
# advanced translation logic
|
||||||
|
damage-type-restrictions:
|
||||||
|
|
||||||
|
## -----
|
||||||
|
## Translate the damage types
|
||||||
|
damage-type-translations:
|
||||||
|
MAGIC: "Magic"
|
||||||
|
PHYSICAL: "Melee"
|
||||||
|
PROJECTILE: "Ranged"
|
||||||
|
WEAPON: "Weapon"
|
||||||
|
SKILL: "Skill"
|
||||||
|
UNARMED: "Unarmed"
|
||||||
|
ON_HIT: "Reaction"
|
||||||
|
MINION: "Minion"
|
||||||
|
DOT: "Lingering"
|
||||||
|
|
||||||
|
## -----
|
||||||
|
# Translate the types of attack
|
||||||
|
attack-type-translations:
|
||||||
|
WEAPON: "Attack"
|
||||||
|
SKILL: "Ability Hit"
|
||||||
|
NEITHER: "Damage"
|
||||||
|
BOTH: "Ability-Assisted Attack"
|
||||||
|
|
||||||
|
## -----
|
||||||
|
## Change the color of scalings
|
||||||
|
# damage-type-colors:
|
||||||
|
# MAGIC: "&9"
|
||||||
|
# PHYSICAL: "&8"
|
||||||
|
# WEAPON: "&7"
|
||||||
|
# SKILL: "&f"
|
||||||
|
# PROJECTILE: "&a"
|
||||||
|
# UNARMED: "&e"
|
||||||
|
# ON_HIT: "&0"
|
||||||
|
# MINION: "&d"
|
||||||
|
# DOT: "&3"
|
2
pom.xml
2
pom.xml
@ -57,7 +57,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.lumine</groupId>
|
<groupId>io.lumine</groupId>
|
||||||
<artifactId>MythicLib-dist</artifactId>
|
<artifactId>MythicLib-dist</artifactId>
|
||||||
<version>1.5.1-SNAPSHOT</version>
|
<version>1.5.2-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Jetbrains Annotations -->
|
<!-- Jetbrains Annotations -->
|
||||||
|
Loading…
Reference in New Issue
Block a user