mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2024-12-31 06:07:34 +01:00
New Upgrade Downgrade Mechanics:
+ When the item breaks (durability), it instead dowgrades by 1 level and repairs completely. + When the player dies, Death Downgrade Chance stat that causes one or more of the items the player has equipped to downgrade. 'GUI Display IDX' Stat for purely organizational purposes of the `/mmoitems browse` menu
This commit is contained in:
parent
afc3b8d19b
commit
4689465b6d
@ -170,6 +170,9 @@ public class ItemStats {
|
||||
// Abilities & Upgrading
|
||||
ABILITIES = new Abilities(),
|
||||
UPGRADE = new UpgradeStat(),
|
||||
DOWNGRADE_ON_BREAK = new BooleanStat("BREAK_DOWNGRADE", Material.DAMAGED_ANVIL, "Downgrade when Broken", new String[]{"If this item's durability reaches 0,", "it will be fully repaired but also", "downgraded by one level.", "", "&cIt will only break if it cannot be", "&cdowngraded further", "", "Requires to define an &6Upgrade Template", "Required to define &6Custom Durability"}, new String[] { "piercing", "slashing", "blunt", "offhand", "range", "tool", "armor", "consumable", "accessory" }),
|
||||
DOWNGRADE_ON_DEATH = new BooleanStat("DEATH_DOWNGRADE", Material.DAMAGED_ANVIL, "Downgrade on Death", new String[]{"If the wearer of this item dies, it may", "downgrade (based on &6Death Downgrade", "&6Chance &7stat)", "", "Required to define an &6Upgrade Template", "Requires keep-inventory gamerule. "}, new String[] { "piercing", "slashing", "blunt", "offhand", "range", "tool", "armor", "consumable", "accessory" }),
|
||||
DOWNGRADE_ON_DEATH_CHANCE = new EvilDoubleStat("DEATH_DOWNGRADE_CHANCE", Material.SKELETON_SKULL, "Death Downgrade Chance", new String[]{"Probability that an item with &cDowngrade ", "&con Death&7 will be downgraded when the", "player dies. ", "", "Exceeding 100% will for sure downgrade", "one item, and roll again to downgrade", "another (with the excess probability).", "&6The same item wont be downgraded twice."}, new String[]{"!miscellaneous", "!block", "all"}),
|
||||
|
||||
// Unique Item Stats
|
||||
SKULL_TEXTURE = new SkullTextureStat(),
|
||||
@ -185,13 +188,13 @@ public class ItemStats {
|
||||
CUSTOM_DURABILITY = new CustomDurability(),
|
||||
STORED_TAGS = new StoredTags(),
|
||||
ITEM_LEVEL = new ItemLevel(),
|
||||
INTERNAL_REVISION_ID = new InternalRevisionID();
|
||||
INTERNAL_REVISION_ID = new InternalRevisionID(),
|
||||
BROWSER_DISPLAY_IDX = new BrowserDisplayIDX();
|
||||
|
||||
/**
|
||||
* @deprecated Item damage is now {@link ItemDamage} and
|
||||
* custom durability is now {@link CustomDurability}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final ItemStat DURABILITY = ITEM_DAMAGE;
|
||||
@Deprecated public static final ItemStat DURABILITY = ITEM_DAMAGE;
|
||||
|
||||
}
|
||||
|
@ -99,9 +99,7 @@ public class MMOItems extends LuminePlugin {
|
||||
|
||||
private static final int MYTHICLIB_COMPATIBILITY_INDEX = 4;
|
||||
|
||||
public MMOItems() {
|
||||
plugin = this;
|
||||
}
|
||||
public MMOItems() { plugin = this; }
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
|
@ -6,7 +6,8 @@ import net.Indyuce.mmoitems.stat.data.AbilityData;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
/**
|
||||
* Ability that requires a direction to be cast
|
||||
* Ability that requires a direction to be cast. For
|
||||
* instance, a projectile like {@link Firebolt}
|
||||
*
|
||||
* @deprecated Abilities were moved over to MythicLib.
|
||||
* Abilities are being replaced by {@link io.lumine.mythic.lib.skill.handler.SkillHandler}
|
||||
|
@ -212,6 +212,19 @@ public class Type {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The parentmost parent of this type, or itself, if it has no parent.
|
||||
*/
|
||||
public Type getSupertype() {
|
||||
Type parentMost = this;
|
||||
|
||||
while (parentMost.isSubtype()) {
|
||||
parentMost = parentMost.getParent();
|
||||
}
|
||||
|
||||
return parentMost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Either if the two types are the same,
|
||||
* or if this type is a subtype of the given type.
|
||||
|
@ -122,7 +122,7 @@ public class UpgradeTemplate {
|
||||
UpgradeData dat;
|
||||
if (mmoitem.hasData(ItemStats.UPGRADE)) {
|
||||
dat = (UpgradeData) mmoitem.getData(ItemStats.UPGRADE);
|
||||
} else { dat = new UpgradeData(null, null, false, false, 0, 100); }
|
||||
} else { dat = new UpgradeData(null, null, false, false, 0, 0, 100); }
|
||||
dat.setLevel(level);
|
||||
mmoitem.setData(ItemStats.UPGRADE, dat);
|
||||
//UPGR//MMOItems.log("\u00a76>\u00a73>\u00a7a> \u00a77Upgrading to level \u00a7e" + dat.getLevel());
|
||||
|
@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
public class ItemSkin extends UseItem {
|
||||
public ItemSkin(Player player, NBTItem item) {
|
||||
@ -41,15 +42,25 @@ public class ItemSkin extends UseItem {
|
||||
}
|
||||
|
||||
boolean compatible = false;
|
||||
|
||||
//SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a77 Applying onto " + MMOUtils.getDisplayName(target.getItem()));
|
||||
|
||||
if (getMMOItem().hasData(ItemStats.COMPATIBLE_TYPES)) {
|
||||
for (String type : ((StringListData) getMMOItem().getData(ItemStats.COMPATIBLE_TYPES)).getList()) {
|
||||
//SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a77 Testing that TYPE is compatible: ");
|
||||
|
||||
List<String> acceptedTypes = ((StringListData) getMMOItem().getData(ItemStats.COMPATIBLE_TYPES)).getList();
|
||||
|
||||
for (String type : acceptedTypes) {
|
||||
//SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a7e >\u00a7f " + type);
|
||||
|
||||
if (type.equalsIgnoreCase(targetType.getId())) {
|
||||
compatible = true;
|
||||
break;
|
||||
}
|
||||
//SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a7a Matched");
|
||||
compatible = true; break; }
|
||||
}
|
||||
|
||||
if (!compatible) {
|
||||
if (!compatible && acceptedTypes.size() > 0) {
|
||||
//SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a7c Incompatible");
|
||||
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
|
||||
Message.SKIN_INCOMPATIBLE.format(ChatColor.RED, "#item#", MMOUtils.getDisplayName(target.getItem()))
|
||||
.send(player);
|
||||
@ -58,14 +69,21 @@ public class ItemSkin extends UseItem {
|
||||
}
|
||||
|
||||
if (getMMOItem().hasData(ItemStats.COMPATIBLE_IDS)) {
|
||||
for (String id : ((StringListData) getMMOItem().getData(ItemStats.COMPATIBLE_IDS)).getList()) {
|
||||
//SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a77 Testing that ID is compatible: ");
|
||||
|
||||
List<String> acceptedIDs = ((StringListData) getMMOItem().getData(ItemStats.COMPATIBLE_IDS)).getList();
|
||||
|
||||
for (String id : acceptedIDs) {
|
||||
//SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a76 >\u00a7f " + id);
|
||||
|
||||
if (id.equalsIgnoreCase(target.getString("MMOITEMS_ITEM_ID"))) {
|
||||
compatible = true;
|
||||
break;
|
||||
}
|
||||
//SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a7a Matched");
|
||||
compatible = true;break; }
|
||||
}
|
||||
|
||||
if (!compatible) {
|
||||
if (!compatible && acceptedIDs.size() > 0) {
|
||||
//SKIN//MMOItems.log("\u00a78SKIN \u00a7eCPT\u00a7c Incompatible");
|
||||
|
||||
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 2);
|
||||
Message.SKIN_INCOMPATIBLE.format(ChatColor.RED, "#item#", MMOUtils.getDisplayName(target.getItem()))
|
||||
.send(player);
|
||||
|
@ -1,13 +1,20 @@
|
||||
package net.Indyuce.mmoitems.api.interaction.util;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.item.SupportedNBTTagValues;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.event.item.CustomDurabilityDamage;
|
||||
import net.Indyuce.mmoitems.api.event.item.CustomDurabilityRepair;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem;
|
||||
import net.Indyuce.mmoitems.api.item.util.LoreUpdate;
|
||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||
import net.Indyuce.mmoitems.stat.data.DoubleData;
|
||||
import net.Indyuce.mmoitems.stat.data.UpgradeData;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
@ -73,7 +80,7 @@ public class DurabilityItem {
|
||||
0;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
@Nullable public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@ -113,6 +120,53 @@ public class DurabilityItem {
|
||||
public boolean isLostWhenBroken() {
|
||||
return nbtItem.getBoolean("MMOITEMS_WILL_BREAK");
|
||||
}
|
||||
public boolean isDowngradedWhenBroken() {
|
||||
return nbtItem.getBoolean("MMOITEMS_BREAK_DOWNGRADE");
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Assuming you already called {@link #isDowngradedWhenBroken()}</b>, when the item is
|
||||
* being broken. This method will downgrade the item for one level and apply changes to
|
||||
* the stored {@link #getNBTItem()}.
|
||||
*
|
||||
* If the item cannot be downgraded (due to not having upgrade data / reaching minimum
|
||||
* upgrades), this method will return <code>null</code>, no change will be made to the
|
||||
* NBTItem, and you should break the item.
|
||||
*
|
||||
* @return If the item could not be downgraded, and thus should break, will be <code>null</code>.
|
||||
* If the item was successfully downgraded, this will uuuh, will return the NBTItem of
|
||||
* the downgraded version.
|
||||
*/
|
||||
@Nullable public ItemStack shouldBreakWhenDowngraded() {
|
||||
ItemTag uTag = ItemTag.getTagAtPath(ItemStats.UPGRADE.getNBTPath(), getNBTItem(), SupportedNBTTagValues.STRING);
|
||||
if (uTag == null) { return null; }
|
||||
|
||||
try {
|
||||
|
||||
// Read data
|
||||
UpgradeData data = new UpgradeData(new JsonParser().parse((String) uTag.getValue()).getAsJsonObject());
|
||||
|
||||
// If it cannot be downgraded (reached min), DEATH
|
||||
if (data.getLevel() <= data.getMin()) { return null; }
|
||||
|
||||
// Downgrading operation
|
||||
LiveMMOItem mmo = new LiveMMOItem(getNBTItem());
|
||||
|
||||
// Remove one level
|
||||
mmo.getUpgradeTemplate().upgradeTo(mmo, data.getLevel() - 1);
|
||||
|
||||
// Build NBT
|
||||
NBTItem preRet = mmo.newBuilder().buildNBT();
|
||||
|
||||
// Set durability to zero (full repair)
|
||||
DurabilityItem dur = new DurabilityItem(getPlayer(), preRet);
|
||||
dur.addDurability(dur.getMaxDurability());
|
||||
|
||||
// Yes
|
||||
return dur.toItem();
|
||||
|
||||
} catch (JsonSyntaxException |IllegalStateException exception) { return null; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Since
|
||||
@ -120,7 +174,7 @@ public class DurabilityItem {
|
||||
* @return If the item actually supports custom durability.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return maxDurability > 0 && player.getGameMode() != GameMode.CREATIVE;
|
||||
return maxDurability > 0 && player != null && player.getGameMode() != GameMode.CREATIVE;
|
||||
}
|
||||
|
||||
public DurabilityItem addDurability(int gain) {
|
||||
@ -180,8 +234,7 @@ public class DurabilityItem {
|
||||
if (!barHidden) {
|
||||
int damage = (durability == maxDurability) ? 0
|
||||
: Math.max(1, (int) ((1. - ((double) durability / maxDurability)) * nbtItem.getItem().getType().getMaxDurability()));
|
||||
nbtItem.addTag(new ItemTag("Damage", damage));
|
||||
}
|
||||
nbtItem.addTag(new ItemTag("Damage", damage)); }
|
||||
|
||||
nbtItem.addTag(new ItemTag("MMOITEMS_DURABILITY", durability));
|
||||
|
||||
@ -189,9 +242,9 @@ public class DurabilityItem {
|
||||
ItemStack item = nbtItem.toItem();
|
||||
|
||||
// Item lore update
|
||||
String format = MythicLib.inst().parseColors(MMOItems.plugin.getLanguage().getStatFormat("durability").replace("#m", "" + maxDurability));
|
||||
String old = format.replace("#c", "" + initialDurability);
|
||||
String replaced = format.replace("#c", "" + durability);
|
||||
String format = MythicLib.inst().parseColors(MMOItems.plugin.getLanguage().getStatFormat("durability").replace("#m", String.valueOf(maxDurability)));
|
||||
String old = format.replace("#c", String.valueOf(initialDurability));
|
||||
String replaced = format.replace("#c", String.valueOf(durability));
|
||||
return new LoreUpdate(item, old, replaced).updateLore();
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,16 @@
|
||||
package net.Indyuce.mmoitems.api.interaction.util;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.SupportedNBTTagValues;
|
||||
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.stat.data.UpgradeData;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class UntargetedDurabilityItem extends DurabilityItem {
|
||||
private final EquipmentSlot slot;
|
||||
@ -26,12 +33,38 @@ public class UntargetedDurabilityItem extends DurabilityItem {
|
||||
|
||||
public void update() {
|
||||
|
||||
if (isBroken() && isLostWhenBroken()) {
|
||||
if (slot == EquipmentSlot.OFF_HAND)
|
||||
getPlayer().getInventory().setItemInOffHand(null);
|
||||
else
|
||||
getPlayer().getInventory().setItemInMainHand(null);
|
||||
return;
|
||||
// Cannot update null player
|
||||
if (getPlayer() == null) { return; }
|
||||
|
||||
// If it broke (funny)
|
||||
if (isBroken()) {
|
||||
|
||||
// Attempt to counter by downgrading
|
||||
if (isDowngradedWhenBroken()) {
|
||||
|
||||
ItemStack counterUpgraded = shouldBreakWhenDowngraded();
|
||||
if (counterUpgraded != null) {
|
||||
|
||||
// Edit item
|
||||
getNBTItem().getItem().setItemMeta(counterUpgraded.getItemMeta());
|
||||
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Still here? Remove if lost when broken
|
||||
if (isLostWhenBroken()) {
|
||||
|
||||
// Delete item
|
||||
if (slot == EquipmentSlot.OFF_HAND) {
|
||||
getPlayer().getInventory().setItemInOffHand(null);
|
||||
|
||||
} else { getPlayer().getInventory().setItemInMainHand(null); }
|
||||
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
getNBTItem().getItem().setItemMeta(toItem().getItemMeta());
|
||||
|
@ -0,0 +1,26 @@
|
||||
package net.Indyuce.mmoitems.api.player.inventory;
|
||||
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class EditableEquippedItem extends EquippedItem {
|
||||
public EditableEquippedItem(ItemStack item, EquipmentSlot slot) {
|
||||
super(item, slot);
|
||||
}
|
||||
|
||||
public EditableEquippedItem(NBTItem item, EquipmentSlot slot) {
|
||||
super(item, slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows editing the item, wherever it is that it is
|
||||
* currently equipped, due to stats like
|
||||
* {@link net.Indyuce.mmoitems.ItemStats#DOWNGRADE_ON_DEATH}
|
||||
* that target equipped items.
|
||||
*
|
||||
* @param item Item to replace in the current slot
|
||||
*/
|
||||
public abstract void setItem(@Nullable ItemStack item);
|
||||
}
|
@ -18,7 +18,7 @@ public class EquippedItem {
|
||||
* @param slot The corresponding MMOItems slot type
|
||||
*/
|
||||
public EquippedItem(ItemStack item, EquipmentSlot slot) {
|
||||
this(MythicLib.plugin.getVersion().getWrapper().getNBTItem(item), slot);
|
||||
this(NBTItem.get(item), slot);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6,6 +6,7 @@ import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem;
|
||||
public class EquippedPlayerItem {
|
||||
private final VolatileMMOItem item;
|
||||
private final EquipmentSlot slot;
|
||||
private final EquippedItem equipped;
|
||||
|
||||
/**
|
||||
* An item equipped by a player in a specific slot
|
||||
@ -13,15 +14,19 @@ public class EquippedPlayerItem {
|
||||
* @param item The item equipped
|
||||
*/
|
||||
public EquippedPlayerItem(EquippedItem item) {
|
||||
this.equipped = item;
|
||||
this.item = new VolatileMMOItem(item.getItem());
|
||||
this.slot = item.getSlot();
|
||||
}
|
||||
|
||||
public VolatileMMOItem getItem() {
|
||||
return item;
|
||||
}
|
||||
/**
|
||||
* @return honestly I do not know why EquippedPlayerItem even exists?
|
||||
* you can get all the values from the {@link EquippedItem}
|
||||
* it came from. Its like a funny wrapper.
|
||||
*/
|
||||
public EquippedItem getEquipped() { return equipped; }
|
||||
|
||||
public EquipmentSlot getSlot() {
|
||||
return slot;
|
||||
}
|
||||
public VolatileMMOItem getItem() { return item; }
|
||||
|
||||
public EquipmentSlot getSlot() { return slot; }
|
||||
}
|
||||
|
@ -30,9 +30,7 @@ public class InventoryUpdateHandler {
|
||||
/**
|
||||
* Used to handle player inventory updates.
|
||||
*/
|
||||
public InventoryUpdateHandler(PlayerData player) {
|
||||
this.player = player;
|
||||
}
|
||||
public InventoryUpdateHandler(PlayerData player) { this.player = player; }
|
||||
|
||||
/**
|
||||
* @return All equipped MMOItems in the player's inventory. Also includes
|
||||
@ -43,8 +41,7 @@ public class InventoryUpdateHandler {
|
||||
}
|
||||
|
||||
public void updateCheck() {
|
||||
if (!player.isOnline())
|
||||
return;
|
||||
if (!player.isOnline()) { return; }
|
||||
|
||||
PlayerInventory inv = player.getPlayer().getInventory();
|
||||
if (isNotSame(helmet, inv.getHelmet()) || isNotSame(chestplate, inv.getChestplate()) || isNotSame(leggings, inv.getLeggings())
|
||||
|
@ -63,6 +63,7 @@ public enum Message {
|
||||
UPGRADE_SUCCESS("You successfully upgraded your &6#item#&e!"),
|
||||
NOT_HAVE_ITEM_UPGRADE("You don't have the item to upgrade!"),
|
||||
UPGRADE_REQUIREMENT_SAFE_CHECK("You would not meet the upgraded item requirements."),
|
||||
DEATH_DOWNGRADING("&cYour &6#item#&c got severely damaged that fight..."),
|
||||
|
||||
// Crafting stations
|
||||
NOT_ENOUGH_MATERIALS("You do not have enough materials to craft this item."),
|
||||
|
@ -4,6 +4,7 @@ import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||
import net.Indyuce.mmoitems.api.player.inventory.EquippedItem;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -14,19 +15,25 @@ import java.util.List;
|
||||
* Armor slots, mainhand and offhand.
|
||||
*/
|
||||
public class DefaultPlayerInventory implements PlayerInventory {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<EquippedItem> getInventory(Player player) {
|
||||
List<EquippedItem> list = new ArrayList<>();
|
||||
|
||||
if (player.getEquipment() == null) { return list; }
|
||||
|
||||
// Mainhand
|
||||
list.add(new EquippedItem(player.getEquipment().getItemInMainHand(), EquipmentSlot.MAIN_HAND));
|
||||
list.add(new EIDefaultInventory(player, -7, player.getEquipment().getItemInMainHand(), EquipmentSlot.MAIN_HAND));
|
||||
|
||||
// Offhand
|
||||
list.add(new EquippedItem(player.getEquipment().getItemInOffHand(), EquipmentSlot.OFF_HAND));
|
||||
list.add(new EIDefaultInventory(player, -106, player.getEquipment().getItemInOffHand(), EquipmentSlot.OFF_HAND));
|
||||
|
||||
// Armour
|
||||
for (ItemStack armor : player.getInventory().getArmorContents())
|
||||
list.add(new EquippedItem(armor, EquipmentSlot.ARMOR));
|
||||
// Armor
|
||||
list.add(new EIDefaultInventory(player, 103, player.getEquipment().getHelmet(), EquipmentSlot.ARMOR));
|
||||
list.add(new EIDefaultInventory(player, 102, player.getEquipment().getChestplate(), EquipmentSlot.ARMOR));
|
||||
list.add(new EIDefaultInventory(player, 101, player.getEquipment().getLeggings(), EquipmentSlot.ARMOR));
|
||||
list.add(new EIDefaultInventory(player, 100, player.getEquipment().getBoots(), EquipmentSlot.ARMOR));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
package net.Indyuce.mmoitems.comp.inventory;
|
||||
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||
import net.Indyuce.mmoitems.api.player.inventory.EditableEquippedItem;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class EIDefaultInventory extends EditableEquippedItem {
|
||||
@NotNull public Player getPlayer() { return player; }
|
||||
@NotNull Player player;
|
||||
|
||||
public int getSlotNumber() { return slotNumber; }
|
||||
int slotNumber;
|
||||
|
||||
public EIDefaultInventory(@NotNull Player player, int slotNumber, ItemStack item, EquipmentSlot slot) {
|
||||
super(item, slot);
|
||||
this.player = player;
|
||||
this.slotNumber = slotNumber;
|
||||
}
|
||||
|
||||
public EIDefaultInventory(@NotNull Player player, int slotNumber, NBTItem item, EquipmentSlot slot) {
|
||||
super(item, slot);
|
||||
this.player = player;
|
||||
this.slotNumber = slotNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(@Nullable ItemStack item) {
|
||||
|
||||
switch (getSlotNumber()) {
|
||||
case -106:
|
||||
getPlayer().getInventory().setItemInOffHand(item);
|
||||
break;
|
||||
case -7:
|
||||
getPlayer().getInventory().setItemInMainHand(item);
|
||||
break;
|
||||
case 103:
|
||||
getPlayer().getInventory().setHelmet(item);
|
||||
break;
|
||||
case 102:
|
||||
getPlayer().getInventory().setChestplate(item);
|
||||
break;
|
||||
case 101:
|
||||
getPlayer().getInventory().setLeggings(item);
|
||||
break;
|
||||
case 100:
|
||||
getPlayer().getInventory().setBoots(item);
|
||||
break;
|
||||
default:
|
||||
getPlayer().getInventory().setItem(getSlotNumber(), item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,14 +4,15 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.item.ItemTag;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.util.AltChar;
|
||||
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
|
||||
import io.lumine.mythic.lib.version.VersionMaterial;
|
||||
import io.lumine.mythic.utils.adventure.text.Component;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import net.Indyuce.mmoitems.api.edition.NewItemEdition;
|
||||
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
|
||||
import net.Indyuce.mmoitems.gui.edition.ItemEdition;
|
||||
import net.Indyuce.mmoitems.stat.BrowserDisplayIDX;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
@ -23,6 +24,7 @@ import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -47,106 +49,100 @@ public class ItemBrowser extends PluginInventory {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
int[] usedSlots = type != null && type.isFourGUIMode() ? slotsAlt : slots;
|
||||
int min = (page - 1) * usedSlots.length;
|
||||
int max = page * usedSlots.length;
|
||||
int n = 0;
|
||||
@NotNull @Override public Inventory getInventory() {
|
||||
|
||||
/*
|
||||
* Displays all possible item types if no
|
||||
* type was previously selected by the player
|
||||
* ------------------------------
|
||||
* TYPE BROWSER
|
||||
*
|
||||
* Displays all possible item types if no type was previously selected by the player.
|
||||
* ------------------------------
|
||||
*/
|
||||
if (type == null) {
|
||||
|
||||
int[] usedSlots = slots;
|
||||
int min = (page - 1) * usedSlots.length;
|
||||
int max = page * usedSlots.length;
|
||||
int n = 0;
|
||||
|
||||
// Create inventory
|
||||
Inventory inv = Bukkit.createInventory(this, 54, "Item Explorer");
|
||||
|
||||
// Fetch the list of types
|
||||
List<Type> types = new ArrayList<>(MMOItems.plugin.getTypes().getAll());
|
||||
for (int j = min; j < Math.min(max, types.size()); j++) {
|
||||
Type type = types.get(j);
|
||||
int items = MMOItems.plugin.getTemplates().getTemplates(type).size();
|
||||
|
||||
ItemStack item = type.getItem();
|
||||
// Current type to display into the GUI
|
||||
Type currentType = types.get(j);
|
||||
|
||||
// Get number of items
|
||||
int items = MMOItems.plugin.getTemplates().getTemplates(currentType).size();
|
||||
|
||||
// Display how many items are in the type
|
||||
ItemStack item = currentType.getItem();
|
||||
item.setAmount(Math.max(1, Math.min(64, items)));
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
meta.setDisplayName(ChatColor.GREEN + type.getName() + ChatColor.DARK_GRAY + " (Click to browse)");
|
||||
meta.setDisplayName(ChatColor.GREEN + currentType.getName() + ChatColor.DARK_GRAY + " (Click to browse)");
|
||||
meta.addItemFlags(ItemFlag.values());
|
||||
List<String> lore = new ArrayList<>();
|
||||
lore.add(ChatColor.GRAY + "" + ChatColor.ITALIC + "There " + (items != 1 ? "are" : "is") + " "
|
||||
+ (items < 1 ? "" + ChatColor.RED + ChatColor.ITALIC + "no" : "" + ChatColor.GOLD + ChatColor.ITALIC + items) + ChatColor.GRAY
|
||||
+ ChatColor.ITALIC + " item" + (items != 1 ? "s" : "") + " in that type.");
|
||||
lore.add(String.valueOf(ChatColor.GRAY) + ChatColor.ITALIC + "There " + (items == 1 ? "is" : "are") + " "
|
||||
+ (items < 1 ? String.valueOf(ChatColor.RED) + ChatColor.ITALIC + "no" : String.valueOf(ChatColor.GOLD) + ChatColor.ITALIC + items) + ChatColor.GRAY
|
||||
+ ChatColor.ITALIC + " item" + (items == 1 ? "" : "s") + " in that currentType.");
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
inv.setItem(slots[n++], NBTItem.get(item).addTag(new ItemTag("typeId", type.getId())).toItem());
|
||||
// Set item
|
||||
inv.setItem(slots[n++], NBTItem.get(item).addTag(new ItemTag("typeId", currentType.getId())).toItem());
|
||||
}
|
||||
|
||||
// Fill remainder slots with 'No Type' notice
|
||||
ItemStack glass = VersionMaterial.GRAY_STAINED_GLASS_PANE.toItem();
|
||||
ItemMeta glassMeta = glass.getItemMeta();
|
||||
glassMeta.setDisplayName(ChatColor.RED + "- No type -");
|
||||
glass.setItemMeta(glassMeta);
|
||||
|
||||
// Next Page
|
||||
ItemStack next = new ItemStack(Material.ARROW);
|
||||
ItemMeta nextMeta = next.getItemMeta();
|
||||
nextMeta.setDisplayName(ChatColor.GREEN + "Next Page");
|
||||
next.setItemMeta(nextMeta);
|
||||
|
||||
// Previous Page
|
||||
ItemStack previous = new ItemStack(Material.ARROW);
|
||||
ItemMeta previousMeta = previous.getItemMeta();
|
||||
previousMeta.setDisplayName(ChatColor.GREEN + "Previous Page");
|
||||
previous.setItemMeta(previousMeta);
|
||||
|
||||
while (n < slots.length)
|
||||
inv.setItem(slots[n++], glass);
|
||||
// Fill
|
||||
while (n < slots.length) { inv.setItem(slots[n++], glass); }
|
||||
inv.setItem(18, page > 1 ? previous : null);
|
||||
inv.setItem(26, max >= MMOItems.plugin.getTypes().getAll().size() ? null : next);
|
||||
|
||||
// Done
|
||||
return inv;
|
||||
}
|
||||
|
||||
/*
|
||||
* ------------------------------
|
||||
* ITEM BROWSER
|
||||
*
|
||||
* Displays all the items of the chosen Type
|
||||
* ------------------------------
|
||||
*/
|
||||
Inventory inv = Bukkit.createInventory(this, 54, (deleteMode ? ("Delete Mode: ") : ("Item Explorer: ")) + type.getName());
|
||||
|
||||
/*
|
||||
* Build cool Item Stacks for buttons and sh
|
||||
*/
|
||||
ItemStack error = VersionMaterial.RED_STAINED_GLASS_PANE.toItem();
|
||||
ItemMeta errorMeta = error.getItemMeta();
|
||||
errorMeta.setDisplayName(ChatColor.RED + "- Error -");
|
||||
List<String> errorLore = new ArrayList<>();
|
||||
errorLore.add(ChatColor.GRAY + "" + ChatColor.ITALIC + "An error occurred while");
|
||||
errorLore.add(ChatColor.GRAY + "" + ChatColor.ITALIC + "trying to generate that item.");
|
||||
errorLore.add("\u00a7\u00a7oAn error occurred while");
|
||||
errorLore.add("\u00a7\u00a7otrying to generate that item.");
|
||||
errorMeta.setLore(errorLore);
|
||||
error.setItemMeta(errorMeta);
|
||||
|
||||
List<MMOItemTemplate> templates = new ArrayList<>(MMOItems.plugin.getTemplates().getTemplates(type));
|
||||
|
||||
/*
|
||||
* Displays every item in a specific type. Items are cached inside the
|
||||
* map at the top to reduce performance impact and are directly rendered
|
||||
*/
|
||||
Inventory inv = Bukkit.createInventory(this, 54, (deleteMode ? ("Delete Mode: ") : ("Item Explorer: ")) + type.getName());
|
||||
for (int j = min; j < Math.min(max, templates.size()); j++) {
|
||||
MMOItemTemplate template = templates.get(j);
|
||||
ItemStack item = template.newBuilder(playerData.getRPG()).build().newBuilder().build();
|
||||
if (item == null || item.getType() == Material.AIR) {
|
||||
cached.put(template.getId(), error);
|
||||
inv.setItem(usedSlots[n++], error);
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
|
||||
lore.add("");
|
||||
|
||||
if (deleteMode) {
|
||||
lore.add(ChatColor.RED + AltChar.cross + " CLICK TO DELETE " + AltChar.cross);
|
||||
meta.setDisplayName(ChatColor.RED + "DELETE: " + (meta.hasDisplayName() ? meta.getDisplayName() : MMOUtils.getDisplayName(item)));
|
||||
} else {
|
||||
lore.add(ChatColor.YELLOW + AltChar.smallListDash + " Left click to obtain this item.");
|
||||
lore.add(ChatColor.YELLOW + AltChar.smallListDash + " Right click to edit this item.");
|
||||
}
|
||||
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
cached.put(template.getId(), item);
|
||||
|
||||
inv.setItem(usedSlots[n++], cached.get(template.getId()));
|
||||
}
|
||||
|
||||
ItemStack noItem = VersionMaterial.GRAY_STAINED_GLASS_PANE.toItem();
|
||||
ItemMeta noItemMeta = noItem.getItemMeta();
|
||||
noItemMeta.setDisplayName(ChatColor.RED + "- No Item -");
|
||||
@ -185,17 +181,121 @@ public class ItemBrowser extends PluginInventory {
|
||||
ChatColor.RED + "By downloading the default resourcepack you can", ChatColor.RED + "edit the blocks however you want.",
|
||||
ChatColor.RED + "You will still have to add it to your server!"));
|
||||
downloadPack.setItemMeta(downloadMeta);
|
||||
inv.setItem(45, downloadPack);
|
||||
inv.setItem(45, downloadPack); }
|
||||
|
||||
// Get templates of this type
|
||||
HashMap<Double, ArrayList<MMOItemTemplate>> templates = BrowserDisplayIDX.select(MMOItems.plugin.getTemplates().getTemplates(type));
|
||||
|
||||
/*
|
||||
* -----------
|
||||
* CALCULATE GUI BOUNDS AND PAGE SIZES
|
||||
*
|
||||
* Each display index claims the entire column of items, such that there will be
|
||||
* empty spaces added to fill the inventories.
|
||||
*
|
||||
* In Four GUI mode, columns are four slots tall, else they are three slots tall.
|
||||
* -----------
|
||||
*/
|
||||
int[] usedSlots = type.isFourGUIMode() ? slotsAlt : slots;
|
||||
int min = (page - 1) * usedSlots.length;
|
||||
int max = page * usedSlots.length;
|
||||
int n = 0;
|
||||
|
||||
int sc = type.isFourGUIMode() ? 4 : 3;
|
||||
int totalSpaceCount = 0;
|
||||
|
||||
for (Map.Entry<Double, ArrayList<MMOItemTemplate>> indexTemplates : templates.entrySet()) {
|
||||
|
||||
// Claim columns
|
||||
int totalSpaceAdd = indexTemplates.getValue().size();
|
||||
while (totalSpaceAdd > 0) { totalSpaceCount += sc; totalSpaceAdd -= sc; } }
|
||||
|
||||
/*
|
||||
* Over the page-range currently in use...
|
||||
*/
|
||||
for (int j = min; j < Math.min(max, totalSpaceCount); j++) {
|
||||
MMOItemTemplate template = BrowserDisplayIDX.getAt(j, templates);
|
||||
|
||||
// No template here?
|
||||
if (template == null) {
|
||||
|
||||
// Set Item
|
||||
inv.setItem(usedSlots[n], noItem);
|
||||
|
||||
/*
|
||||
* Calculate next n from the slots.
|
||||
*
|
||||
* #1 Adding 7 will give you the slot immediately under
|
||||
*
|
||||
* #2 If it overflows, subtract 7sc (column space * 7)
|
||||
* and add one
|
||||
*/
|
||||
n += 7;
|
||||
if (n >= usedSlots.length) { n -= 7 * sc; n++; }
|
||||
continue;
|
||||
}
|
||||
|
||||
// Build item -> any errors?
|
||||
ItemStack item = template.newBuilder(playerData.getRPG()).build().newBuilder().build();
|
||||
if (item == null || item.getType().isAir() || !item.getType().isItem() || item.getItemMeta() == null) {
|
||||
|
||||
// Set Item
|
||||
cached.put(template.getId(), error);
|
||||
inv.setItem(usedSlots[n], error);
|
||||
|
||||
/*
|
||||
* Calculate next n from the slots.
|
||||
*
|
||||
* #1 Adding 7 will give you the slot immediately under
|
||||
*
|
||||
* #2 If it overflows, subtract 7sc (column space * 7)
|
||||
* and add one
|
||||
*/
|
||||
n += 7;
|
||||
if (n >= usedSlots.length) { n -= 7 * sc; n++; }
|
||||
continue; }
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null) { lore = new ArrayList<>(); }
|
||||
lore.add("");
|
||||
|
||||
// Deleting lore?
|
||||
if (deleteMode) {
|
||||
lore.add(ChatColor.RED + AltChar.cross + " CLICK TO DELETE " + AltChar.cross);
|
||||
meta.setDisplayName(ChatColor.RED + "DELETE: " + (meta.hasDisplayName() ? meta.getDisplayName() : MMOUtils.getDisplayName(item)));
|
||||
|
||||
// Editing lore?
|
||||
} else {
|
||||
lore.add(ChatColor.YELLOW + AltChar.smallListDash + " Left click to obtain this item.");
|
||||
lore.add(ChatColor.YELLOW + AltChar.smallListDash + " Right click to edit this item."); }
|
||||
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
// Set item
|
||||
cached.put(template.getId(), item);
|
||||
inv.setItem(usedSlots[n], cached.get(template.getId()));
|
||||
|
||||
/*
|
||||
* Calculate next n from the slots.
|
||||
*
|
||||
* #1 Adding 7 will give you the slot immediately under
|
||||
*
|
||||
* #2 If it overflows, subtract 7sc (column space * 7)
|
||||
* and add one
|
||||
*/
|
||||
n += 7;
|
||||
if (n >= usedSlots.length) { n -= 7 * sc; n++; }
|
||||
}
|
||||
|
||||
while (n < usedSlots.length)
|
||||
inv.setItem(usedSlots[n++], noItem);
|
||||
if (!deleteMode)
|
||||
inv.setItem(51, create);
|
||||
// Put the buttons
|
||||
if (!deleteMode) { inv.setItem(51, create); }
|
||||
inv.setItem(47, delete);
|
||||
inv.setItem(49, back);
|
||||
inv.setItem(18, page > 1 ? previous : null);
|
||||
inv.setItem(26, max >= templates.size() ? null : next);
|
||||
inv.setItem(26, max >= totalSpaceCount ? null : next);
|
||||
for (int i : usedSlots) { if (SilentNumbers.isAir(inv.getItem(i))) { inv.setItem(i, noItem); } }
|
||||
return inv;
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,22 @@ public class UpgradingEdition extends EditionInventory {
|
||||
maxItemMeta.setLore(maxItemLore);
|
||||
maxItem.setItemMeta(maxItemMeta);
|
||||
inv.setItem(40, maxItem);
|
||||
|
||||
int min = getEditedSection().getInt("upgrade.min", 0);
|
||||
ItemStack minItem = new ItemStack(Material.BARRIER);
|
||||
ItemMeta minItemMeta = minItem.getItemMeta();
|
||||
minItemMeta.setDisplayName(ChatColor.GREEN + "Min Upgrades");
|
||||
List<String> minItemLore = new ArrayList<>();
|
||||
minItemLore.add(ChatColor.GRAY + "The minimum level your item can be");
|
||||
minItemLore.add(ChatColor.GRAY + "downgraded to (by dying or breaking).");
|
||||
minItemLore.add("");
|
||||
minItemLore.add(ChatColor.GRAY + "Current Value: " + (min == 0 ? ChatColor.RED + "0" : ChatColor.GOLD + String.valueOf(min)));
|
||||
minItemLore.add("");
|
||||
minItemLore.add(ChatColor.YELLOW + AltChar.listDash + " Click to chance this value.");
|
||||
minItemLore.add(ChatColor.YELLOW + AltChar.listDash + " Right click to reset.");
|
||||
minItemMeta.setLore(minItemLore);
|
||||
minItem.setItemMeta(minItemMeta);
|
||||
inv.setItem(41, minItem);
|
||||
} else {
|
||||
inv.setItem(20, notAvailable);
|
||||
inv.setItem(22, notAvailable);
|
||||
@ -182,6 +198,17 @@ public class UpgradingEdition extends EditionInventory {
|
||||
}
|
||||
}
|
||||
|
||||
if (item.getItemMeta().getDisplayName().equals(ChatColor.GREEN + "Min Upgrades")) {
|
||||
if (event.getAction() == InventoryAction.PICKUP_ALL)
|
||||
new StatEdition(this, ItemStats.UPGRADE, "min").enable("Write in the chat the number you want.");
|
||||
|
||||
if (event.getAction() == InventoryAction.PICKUP_HALF && getEditedSection().contains("upgrade.min")) {
|
||||
getEditedSection().set("upgrade.min", null);
|
||||
registerTemplateEdition();
|
||||
player.sendMessage(MMOItems.plugin.getPrefix() + "Successfully reset the number of min level.");
|
||||
}
|
||||
}
|
||||
|
||||
if (item.getItemMeta().getDisplayName().equals(ChatColor.GREEN + "Upgrade Template")) {
|
||||
if (event.getAction() == InventoryAction.PICKUP_ALL)
|
||||
new StatEdition(this, ItemStats.UPGRADE, "template").enable("Write in the chat the upgrade template ID you want.");
|
||||
|
@ -76,9 +76,32 @@ public class DurabilityListener implements Listener {
|
||||
* If the item is broken and if it is meant to be lost when broken,
|
||||
* do NOT cancel the event and make sure the item is destroyed
|
||||
*/
|
||||
if (item.isBroken() && item.isLostWhenBroken()) {
|
||||
event.setDamage(999);
|
||||
return;
|
||||
if (item.isBroken()) {
|
||||
|
||||
// Attempt to counter by downgrading
|
||||
if (item.isDowngradedWhenBroken()) {
|
||||
|
||||
ItemStack counterUpgraded = item.shouldBreakWhenDowngraded();
|
||||
if (counterUpgraded != null) {
|
||||
|
||||
// Counter Event
|
||||
event.setCancelled(true);
|
||||
event.getItem().setItemMeta(counterUpgraded.getItemMeta());
|
||||
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Still here? Remove if lost when broken
|
||||
if (item.isLostWhenBroken()) {
|
||||
|
||||
// Delete item
|
||||
event.setDamage(999);
|
||||
|
||||
// Allow event to proceed
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
@ -105,10 +128,32 @@ public class DurabilityListener implements Listener {
|
||||
if (item.isValid() && stack.getType().getMaxDurability() == 0) {
|
||||
item.decreaseDurability(damage);
|
||||
|
||||
if (item.isBroken() && item.isLostWhenBroken()) {
|
||||
player.getInventory().setItem(slot, null);
|
||||
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1.0f, 1.0f);
|
||||
return;
|
||||
if (item.isBroken()) {
|
||||
|
||||
// Attempt to counter by downgrading
|
||||
if (item.isDowngradedWhenBroken()) {
|
||||
|
||||
ItemStack counterUpgraded = item.shouldBreakWhenDowngraded();
|
||||
if (counterUpgraded != null) {
|
||||
|
||||
// Edit item
|
||||
player.getInventory().getItem(slot).setItemMeta(counterUpgraded.getItemMeta());
|
||||
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Still here? Remove if lost when broken
|
||||
if (item.isLostWhenBroken()) {
|
||||
|
||||
// Delete item
|
||||
player.getInventory().setItem(slot, null);
|
||||
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1.0f, 1.0f);
|
||||
|
||||
// No more
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
player.getInventory().getItem(slot).setItemMeta(item.toItem().getItemMeta());
|
||||
|
@ -1,27 +1,41 @@
|
||||
package net.Indyuce.mmoitems.listener;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.event.skill.PlayerCastSkillEvent;
|
||||
import io.lumine.mythic.lib.api.item.NBTItem;
|
||||
import io.lumine.mythic.lib.api.player.EquipmentSlot;
|
||||
import io.lumine.mythic.lib.api.util.ui.SilentNumbers;
|
||||
import io.lumine.mythic.lib.skill.trigger.TriggerType;
|
||||
import io.lumine.mythic.utils.Schedulers;
|
||||
import io.lumine.mythic.utils.events.extra.ArmorEquipEvent;
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.MMOUtils;
|
||||
import net.Indyuce.mmoitems.api.SoulboundInfo;
|
||||
import net.Indyuce.mmoitems.api.Type;
|
||||
import net.Indyuce.mmoitems.api.event.AbilityUseEvent;
|
||||
import net.Indyuce.mmoitems.api.interaction.util.DurabilityItem;
|
||||
import net.Indyuce.mmoitems.api.interaction.util.InteractItem;
|
||||
import net.Indyuce.mmoitems.api.interaction.weapon.Weapon;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.LiveMMOItem;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem;
|
||||
import net.Indyuce.mmoitems.api.player.PlayerData;
|
||||
import net.Indyuce.mmoitems.api.player.inventory.EditableEquippedItem;
|
||||
import net.Indyuce.mmoitems.api.player.inventory.EquippedItem;
|
||||
import net.Indyuce.mmoitems.api.player.inventory.EquippedPlayerItem;
|
||||
import net.Indyuce.mmoitems.api.util.message.Message;
|
||||
import net.Indyuce.mmoitems.skill.RegisteredSkill;
|
||||
import net.Indyuce.mmoitems.stat.data.AbilityData;
|
||||
import net.Indyuce.mmoitems.stat.data.UpgradeData;
|
||||
import net.Indyuce.mmoitems.stat.type.NameData;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Trident;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -30,10 +44,7 @@ import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class PlayerListener implements Listener {
|
||||
private final Map<Player, ArrayList<ItemStack>> deathItems = new HashMap<>();
|
||||
@ -41,22 +52,156 @@ public class PlayerListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void loadPlayerData(PlayerJoinEvent event) {
|
||||
MMOItems.plugin.getRecipes().refreshRecipeBook(event.getPlayer());
|
||||
PlayerData.load(event.getPlayer());
|
||||
}
|
||||
PlayerData.load(event.getPlayer()); }
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void savePlayerData(PlayerQuitEvent event) {
|
||||
PlayerData.get(event.getPlayer()).save();
|
||||
public void savePlayerData(PlayerQuitEvent event) { PlayerData.get(event.getPlayer()).save(); }
|
||||
|
||||
|
||||
public static boolean ChanceSuccess(int percentChance) {
|
||||
Random rand = new Random();
|
||||
return rand.nextInt(100) <= percentChance;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* If the player dies, its time to roll the death-downgrade stat!
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onDeathForUpgradeLoss(PlayerDeathEvent event) {
|
||||
|
||||
// No
|
||||
if (event instanceof Cancellable) { if (((Cancellable) event).isCancelled()) { return; } }
|
||||
|
||||
// Get Player
|
||||
PlayerData data = PlayerData.get(event.getEntity());
|
||||
|
||||
// Get total downgrade chance, anything less than zero is invalid
|
||||
double deathChance = data.getStats().getStat(ItemStats.DOWNGRADE_ON_DEATH_CHANCE);
|
||||
//DET//MMOItems.log("\u00a78DETH \u00a7cDG\u00a77 Current chance:\u00a7b " + deathChance);
|
||||
if (deathChance <= 0) { return; }
|
||||
|
||||
List<EquippedPlayerItem> items = data.getInventory().getEquipped();
|
||||
ArrayList<EditableEquippedItem> equipped = new ArrayList<>();
|
||||
|
||||
// Equipped Player Items yeah...
|
||||
for (EquippedPlayerItem playerItem : items) {
|
||||
|
||||
// Null
|
||||
if (playerItem == null) { continue; }
|
||||
//DET//playerItem.getItem().hasData(ItemStats.NAME);
|
||||
//DET//MMOItems.log("\u00a78DETH \u00a7cDG\u00a77 Item:\u00a7b " + playerItem.getItem().getData(ItemStats.NAME));
|
||||
|
||||
// Cannot perform operations of items that are uneditable
|
||||
if (!(playerItem.getEquipped() instanceof EditableEquippedItem)) {
|
||||
//DET//MMOItems.log("\u00a78DETH \u00a7cDG\u00a77 Not equippable. \u00a7cCancel");
|
||||
continue; }
|
||||
|
||||
// Not downgradeable on death? Snooze
|
||||
if (!playerItem.getItem().hasData(ItemStats.DOWNGRADE_ON_DEATH)) {
|
||||
//DET//MMOItems.log("\u00a78DETH \u00a7cDG\u00a77 Not Downgradeable. \u00a7cCancel");
|
||||
continue; }
|
||||
|
||||
// No upgrade template no snooze
|
||||
if(!playerItem.getItem().hasData(ItemStats.UPGRADE)) {
|
||||
//DET//MMOItems.log("\u00a78DETH \u00a7cDG\u00a77 Not Upgradeable. \u00a7cCancel");
|
||||
continue; }
|
||||
if (!playerItem.getItem().hasUpgradeTemplate()) {
|
||||
//DET//MMOItems.log("\u00a78DETH \u00a7cDG\u00a77 Null Template. \u00a7cCancel");
|
||||
continue; }
|
||||
|
||||
// If it can be downgraded by one level...
|
||||
UpgradeData upgradeData = (UpgradeData) playerItem.getItem().getData(ItemStats.UPGRADE);
|
||||
if (upgradeData.getLevel() <= upgradeData.getMin()) {
|
||||
//DET//MMOItems.log("\u00a78DETH \u00a7cDG\u00a77 Too downgraded. \u00a7cCancel");
|
||||
continue; }
|
||||
|
||||
// Okay explore stat
|
||||
equipped.add((EditableEquippedItem) playerItem.getEquipped());
|
||||
//DET//MMOItems.log("\u00a78DETH \u00a7cDG\u00a77 Yes. \u00a7aAccepted");
|
||||
}
|
||||
|
||||
// Nothing to perform operations? Snooze
|
||||
if (equipped.size() == 0) {
|
||||
//DET//MMOItems.log("\u00a78DETH \u00a7cDG\u00a77 No items to downgrade. ");
|
||||
return; }
|
||||
Random random = new Random();
|
||||
|
||||
// Degrade those items!
|
||||
while (deathChance >= 100 && equipped.size() > 0) {
|
||||
|
||||
// Decrease
|
||||
deathChance -= 100;
|
||||
|
||||
// Downgrade random item
|
||||
int d = random.nextInt(equipped.size());
|
||||
|
||||
/*
|
||||
* The item was chosen, we must downgrade it by one level.
|
||||
*/
|
||||
EditableEquippedItem equip = equipped.get(d);
|
||||
LiveMMOItem mmo = new LiveMMOItem(equip.getItem());
|
||||
mmo.getUpgradeTemplate().upgradeTo(mmo, mmo.getUpgradeLevel() - 1);
|
||||
|
||||
// Build NBT
|
||||
ItemStack bakedItem = mmo.newBuilder().build();
|
||||
|
||||
// Set durability to zero (full repair)
|
||||
DurabilityItem dur = new DurabilityItem(event.getEntity(), mmo.newBuilder().buildNBT());
|
||||
|
||||
if (dur.getDurability() != dur.getMaxDurability()) {
|
||||
dur.addDurability(dur.getMaxDurability());
|
||||
bakedItem.setItemMeta(dur.toItem().getItemMeta());}
|
||||
|
||||
// AH
|
||||
equip.setItem(bakedItem);
|
||||
equipped.remove(d);
|
||||
|
||||
Message.DEATH_DOWNGRADING.format(ChatColor.RED, "#item#", SilentNumbers.getItemName(equip.getItem().getItem(), false))
|
||||
.send(event.getEntity());
|
||||
|
||||
//DET//MMOItems.log("\u00a78DETH \u00a7cDG\u00a77 Autodegrading\u00a7a " + mmo.getData(ItemStats.NAME));
|
||||
}
|
||||
|
||||
// If there is chance, and there is size, and there is chance success
|
||||
if (deathChance > 0 && equipped.size() > 0 && random.nextInt(100) < deathChance) {
|
||||
|
||||
// Downgrade random item
|
||||
int d = random.nextInt(equipped.size());
|
||||
|
||||
/*
|
||||
* The item was chosen, we must downgrade it by one level.
|
||||
*/
|
||||
EditableEquippedItem equip = equipped.get(d);
|
||||
LiveMMOItem mmo = new LiveMMOItem(equip.getItem());
|
||||
mmo.getUpgradeTemplate().upgradeTo(mmo, mmo.getUpgradeLevel() - 1);
|
||||
|
||||
// Build NBT
|
||||
ItemStack bakedItem = mmo.newBuilder().build();
|
||||
|
||||
// Set durability to zero (full repair)
|
||||
DurabilityItem dur = new DurabilityItem(event.getEntity(), mmo.newBuilder().buildNBT());
|
||||
|
||||
if (dur.getDurability() != dur.getMaxDurability()) {
|
||||
dur.addDurability(dur.getMaxDurability());
|
||||
bakedItem.setItemMeta(dur.toItem().getItemMeta());}
|
||||
|
||||
// AH
|
||||
equip.setItem(bakedItem);
|
||||
equipped.remove(d);
|
||||
|
||||
Message.DEATH_DOWNGRADING.format(ChatColor.RED, "#item#", SilentNumbers.getItemName(equip.getItem().getItem(), false))
|
||||
.send(event.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent players from dropping items which are bound to them with a
|
||||
* soulbound. Items are cached inside a map waiting for the player to
|
||||
* respawn. If he does not respawn the items are dropped on the ground, this
|
||||
* way there don't get lost
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onDeath(PlayerDeathEvent event) {
|
||||
public void onDeathForSoulbound(PlayerDeathEvent event) {
|
||||
if (event.getKeepInventory() || !MMOItems.plugin.getLanguage().keepSoulboundOnDeath)
|
||||
return;
|
||||
|
||||
|
@ -27,7 +27,7 @@ public class RFGKeepUpgrades implements Listener {
|
||||
//UPGRD//MMOItems.log(" \u00a7e* \u00a77Existing Upgrade Detected");
|
||||
|
||||
// Get current ig
|
||||
UpgradeData processed = new UpgradeData(newOne.getReference(), newOne.getTemplateName(), newOne.isWorkbench(), newOne.isDestroy(), newOne.getMax(), newOne.getSuccess());
|
||||
UpgradeData processed = new UpgradeData(newOne.getReference(), newOne.getTemplateName(), newOne.isWorkbench(), newOne.isDestroy(), newOne.getMax(), newOne.getMin(), newOne.getSuccess());
|
||||
|
||||
// Edit level
|
||||
processed.setLevel(Math.min(upgrade.getLevel(), newOne.getMaxUpgrades()));
|
||||
|
110
src/main/java/net/Indyuce/mmoitems/stat/BrowserDisplayIDX.java
Normal file
110
src/main/java/net/Indyuce/mmoitems/stat/BrowserDisplayIDX.java
Normal file
@ -0,0 +1,110 @@
|
||||
package net.Indyuce.mmoitems.stat;
|
||||
|
||||
import net.Indyuce.mmoitems.ItemStats;
|
||||
import net.Indyuce.mmoitems.api.item.build.ItemStackBuilder;
|
||||
import net.Indyuce.mmoitems.api.item.mmoitem.ReadMMOItem;
|
||||
import net.Indyuce.mmoitems.api.item.template.MMOItemTemplate;
|
||||
import net.Indyuce.mmoitems.api.util.NumericStatFormula;
|
||||
import net.Indyuce.mmoitems.stat.data.type.StatData;
|
||||
import net.Indyuce.mmoitems.stat.type.DoubleStat;
|
||||
import org.bukkit.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class BrowserDisplayIDX extends DoubleStat {
|
||||
|
||||
public BrowserDisplayIDX() { super("BROWSER_IDX", Material.GHAST_TEAR, "Browser Index", new String[] {"Used to display similar items together,", "neatly in the GUI \u00a7a/mmoitems browse", "", "Items with the same index are grouped."}, new String[]{"all"}); }
|
||||
|
||||
// Does not participate in actual items
|
||||
@Override public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StatData data) { }
|
||||
@Override public void whenLoaded(@NotNull ReadMMOItem mmoitem) { }
|
||||
|
||||
/**
|
||||
* They will be ordered.
|
||||
*
|
||||
* @return The MMOItem Templates separated by Index. Those with no index
|
||||
* will be linked to the null index.
|
||||
*/
|
||||
@NotNull public static HashMap<Double, ArrayList<MMOItemTemplate>> select(@NotNull Collection<MMOItemTemplate> templates) {
|
||||
HashMap<Double, ArrayList<MMOItemTemplate>> ret = new HashMap<>();
|
||||
|
||||
// Go through them all
|
||||
for (MMOItemTemplate template : templates) {
|
||||
if (template == null) { continue; }
|
||||
|
||||
Double armorIDX = null;
|
||||
if (template.getType().getAvailableStats().contains(ItemStats.BROWSER_DISPLAY_IDX)) {
|
||||
NumericStatFormula indexData = (NumericStatFormula) template.getBaseItemData().get(ItemStats.BROWSER_DISPLAY_IDX);
|
||||
|
||||
// Get value if it existed
|
||||
if (indexData != null && indexData.getBase() != 0) { armorIDX = indexData.getBase(); }
|
||||
}
|
||||
|
||||
// Get that map
|
||||
ArrayList<MMOItemTemplate> perIndexTemplates = ret.get(armorIDX);
|
||||
if (perIndexTemplates == null) { perIndexTemplates = new ArrayList<>(); }
|
||||
|
||||
// Include template
|
||||
perIndexTemplates.add(template);
|
||||
ret.put(armorIDX, perIndexTemplates);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param i Index you search
|
||||
*
|
||||
* @param templates Templates from which to gather
|
||||
*
|
||||
* @return The Ith Template of this Array.
|
||||
*/
|
||||
@Nullable public static MMOItemTemplate getAt(int i, @NotNull HashMap<Double, ArrayList<MMOItemTemplate>> templates) {
|
||||
Map.Entry<Double, ArrayList<MMOItemTemplate>> nullEntry = null;
|
||||
|
||||
// Iterate every entry
|
||||
for (Map.Entry<Double, ArrayList<MMOItemTemplate>> entry : templates.entrySet()) {
|
||||
|
||||
// Null entry are always displayed at the end, reference and skip.
|
||||
if (entry.getKey() == null) { nullEntry = entry; continue; }
|
||||
|
||||
// Identify list, add null entries until it has a size multiple of four.
|
||||
@NotNull ArrayList<MMOItemTemplate> list = entry.getValue();
|
||||
while (list.size() % 4 != 0) { list.add(null); }
|
||||
|
||||
/*
|
||||
* Go through each entry until i equals zero
|
||||
*/
|
||||
for (MMOItemTemplate observed : list) {
|
||||
|
||||
// Yes
|
||||
if (i == 0) { return observed; }
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
// No more
|
||||
if (nullEntry == null) { return null; }
|
||||
|
||||
// Still standing...
|
||||
@NotNull ArrayList<MMOItemTemplate> list = nullEntry.getValue();
|
||||
|
||||
/*
|
||||
* Go through each entry until i equals zero
|
||||
*/
|
||||
for (MMOItemTemplate observed : list) {
|
||||
|
||||
// Yes
|
||||
if (i == 0) { return observed; }
|
||||
i--;
|
||||
}
|
||||
|
||||
// None found
|
||||
return null;
|
||||
}
|
||||
}
|
@ -13,10 +13,4 @@ public class LostWhenBroken extends BooleanStat {
|
||||
public LostWhenBroken() {
|
||||
super("WILL_BREAK", Material.SHEARS, "Lost when Broken?", new String[] { "If set to true, the item will be lost", "once it reaches 0 durability." }, new String[] { "!block", "all" });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenApplied(@NotNull ItemStackBuilder item, @NotNull StatData data) {
|
||||
if (((BooleanData) data).isEnabled())
|
||||
item.addItemTag(new ItemTag("MMOITEMS_WILL_BREAK", true));
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class RepairPower extends DoubleStat implements ConsumableItemInteraction
|
||||
if (durItem.getDurability() < durItem.getMaxDurability()) {
|
||||
target.getItem().setItemMeta(durItem.addDurability(called.getRepaired()).toItem().getItemMeta());
|
||||
Message.REPAIRED_ITEM
|
||||
.format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem()), "#amount#", "" + called.getRepaired())
|
||||
.format(ChatColor.YELLOW, "#item#", MMOUtils.getDisplayName(target.getItem()), "#amount#", String.valueOf(called.getRepaired()))
|
||||
.send(player);
|
||||
CustomSoundListener.playConsumableSound(consumable.getItem(), player);
|
||||
}
|
||||
|
@ -113,6 +113,15 @@ public class UpgradeStat extends ItemStat implements ConsumableItemInteraction {
|
||||
return;
|
||||
}
|
||||
|
||||
if (info[0].equals("min")) {
|
||||
int i = Integer.parseInt(message);
|
||||
inv.getEditedSection().set("upgrade.min", i);
|
||||
inv.registerTemplateEdition();
|
||||
inv.getPlayer()
|
||||
.sendMessage(MMOItems.plugin.getPrefix() + "Min level successfully set to " + ChatColor.GOLD + i + ChatColor.GRAY + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
if (info[0].equals("rate")) {
|
||||
double d = MMOUtils.parseDouble(message);
|
||||
inv.getEditedSection().set("upgrade.success", d);
|
||||
@ -173,7 +182,7 @@ public class UpgradeStat extends ItemStat implements ConsumableItemInteraction {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public StatData getClearStatData() { return new UpgradeData(null, null, false, false, 0, 0D); }
|
||||
public StatData getClearStatData() { return new UpgradeData(null, null, false, false, 0, 0, 0D); }
|
||||
|
||||
@Override
|
||||
public boolean handleConsumableEffect(@NotNull InventoryClickEvent event, @NotNull PlayerData playerData, @NotNull Consumable consumable, @NotNull NBTItem target, Type targetType) {
|
||||
|
@ -42,22 +42,51 @@ public class UpgradeData implements StatData, RandomStatData, Cloneable {
|
||||
/**
|
||||
* @return Max amount of upgrades this can hold
|
||||
*/
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
public int getMax() { return max; }
|
||||
/**
|
||||
* @return Minimum level this item can be downgraded to
|
||||
*/
|
||||
public int getMin() { return min; }
|
||||
|
||||
@Nullable private final String reference, template;
|
||||
private final boolean workbench, destroy;
|
||||
private final double success;
|
||||
private final int max;
|
||||
private final int min;
|
||||
private int level;
|
||||
|
||||
/**
|
||||
* Create a new UpgradeData
|
||||
*
|
||||
* @param reference Upgrade Reference to use
|
||||
* @param template Upgrade Template to follow
|
||||
* @param workbench If it is upgraded in workbench (I don't know for sure)?
|
||||
* @param destroy If it will destroy the item if the upgrade fails
|
||||
* @param max Max Level attainable
|
||||
* @param success Success Chance
|
||||
*/
|
||||
public UpgradeData(@Nullable String reference, @Nullable String template, boolean workbench, boolean destroy, int max, double success) {
|
||||
this(reference, template, workbench, destroy, max, 0, success);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new UpgradeData
|
||||
*
|
||||
* @param reference Upgrade Reference to use
|
||||
* @param template Upgrade Template to follow
|
||||
* @param workbench If it is upgraded in workbench (I don't know for sure)?
|
||||
* @param destroy If it will destroy the item if the upgrade fails
|
||||
* @param max Max Level attainable
|
||||
* @param min Min Level attainable through downgrading
|
||||
* @param success Success Chance
|
||||
*/
|
||||
public UpgradeData(@Nullable String reference, @Nullable String template, boolean workbench, boolean destroy, int max, int min, double success) {
|
||||
this.reference = reference;
|
||||
this.template = template;
|
||||
this.workbench = workbench;
|
||||
this.destroy = destroy;
|
||||
this.max = max;
|
||||
this.min = min;
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
@ -67,6 +96,7 @@ public class UpgradeData implements StatData, RandomStatData, Cloneable {
|
||||
workbench = section.getBoolean("workbench");
|
||||
destroy = section.getBoolean("destroy");
|
||||
max = section.getInt("max");
|
||||
min = section.getInt("min", 0);
|
||||
success = section.getDouble("success") / 100;
|
||||
}
|
||||
|
||||
@ -77,6 +107,7 @@ public class UpgradeData implements StatData, RandomStatData, Cloneable {
|
||||
reference = object.has("Reference") ? object.get("Reference").getAsString() : null;
|
||||
level = object.get("Level").getAsInt();
|
||||
max = object.get("Max").getAsInt();
|
||||
min = object.has("Min") ? object.get("Min").getAsInt() : 0;
|
||||
success = object.get("Success").getAsDouble();
|
||||
}
|
||||
|
||||
@ -100,9 +131,7 @@ public class UpgradeData implements StatData, RandomStatData, Cloneable {
|
||||
*/
|
||||
public void setLevel(int l) { level = l; }
|
||||
|
||||
public int getMaxUpgrades() {
|
||||
return max;
|
||||
}
|
||||
public int getMaxUpgrades() { return max; }
|
||||
|
||||
public boolean canLevelUp() {
|
||||
return max == 0 || level < max;
|
||||
@ -150,6 +179,7 @@ public class UpgradeData implements StatData, RandomStatData, Cloneable {
|
||||
json.addProperty("Destroy", destroy);
|
||||
json.addProperty("Level", level);
|
||||
json.addProperty("Max", max);
|
||||
json.addProperty("Min", min);
|
||||
json.addProperty("Success", success);
|
||||
|
||||
return json;
|
||||
@ -169,5 +199,5 @@ public class UpgradeData implements StatData, RandomStatData, Cloneable {
|
||||
public UpgradeData clone() {
|
||||
try { super.clone(); } catch (CloneNotSupportedException ignored) { }
|
||||
|
||||
return new UpgradeData(reference, template, workbench, destroy, max, success); }
|
||||
return new UpgradeData(reference, template, workbench, destroy, max, min, success); }
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package net.Indyuce.mmoitems.stat.type;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public class EvilDoubleStat extends DoubleStat {
|
||||
|
||||
public EvilDoubleStat(String id, Material mat, String name, String[] lore) { super(id, mat, name, lore); }
|
||||
public EvilDoubleStat(String id, Material mat, String name, String[] lore, String[] types, Material... materials) { super(id, mat, name, lore, types, materials); }
|
||||
|
||||
@Override public boolean moreIsBetter() { return false; }
|
||||
}
|
Loading…
Reference in New Issue
Block a user