From 58b473aa1a9f06803685230d9749f8a9ab2ff2da Mon Sep 17 00:00:00 2001
From: YuTian <2953516620@qq.com>
Date: Thu, 22 Aug 2024 17:23:33 +0800
Subject: [PATCH] 1.0
---
.gitignore | 4 +
pom.xml | 71 +++++
.../io/yutian/refinesystem/RefineSystem.java | 83 ++++++
.../refinesystem/RefineSystemSetting.java | 68 +++++
.../yutian/refinesystem/data/RefineData.java | 69 +++++
.../yutian/refinesystem/data/SkillData.java | 65 +++++
.../io/yutian/refinesystem/gui/GuiHolder.java | 14 +
.../io/yutian/refinesystem/gui/RefineGui.java | 265 ++++++++++++++++++
.../refinesystem/gui/RefineResultGui.java | 93 ++++++
.../refinesystem/listener/GuiListener.java | 33 +++
.../refinesystem/util/ItemStackUtil.java | 96 +++++++
.../util/PlayerInventoryUtil.java | 41 +++
.../refinesystem/util/RandomBuilder.java | 83 ++++++
.../yutian/refinesystem/util/RandomUtil.java | 59 ++++
.../yutian/refinesystem/util/StringUtil.java | 19 ++
src/main/resources/config.yml | 48 ++++
src/main/resources/plugin.yml | 6 +
17 files changed, 1117 insertions(+)
create mode 100644 .gitignore
create mode 100644 pom.xml
create mode 100644 src/main/java/com/io/yutian/refinesystem/RefineSystem.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/RefineSystemSetting.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/data/RefineData.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/data/SkillData.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/gui/GuiHolder.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/gui/RefineGui.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/gui/RefineResultGui.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/listener/GuiListener.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/util/ItemStackUtil.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/util/PlayerInventoryUtil.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/util/RandomBuilder.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/util/RandomUtil.java
create mode 100644 src/main/java/com/io/yutian/refinesystem/util/StringUtil.java
create mode 100644 src/main/resources/config.yml
create mode 100644 src/main/resources/plugin.yml
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..254a369
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/.idea/
+/lib/
+/target/
+/RefineSystem.iml
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..6653a3a
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,71 @@
+
+
+ 4.0.0
+
+ com.io.yutian
+ RefineSystem
+ 1.0-SNAPSHOT
+ jar
+
+ RefineSystem
+
+
+ 1.8
+ UTF-8
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+
+ ${java.version}
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+
+
+ papermc-repo
+ https://repo.papermc.io/repository/maven-public/
+
+
+ sonatype
+ https://oss.sonatype.org/content/groups/public/
+
+
+
+
+
+ com.destroystokyo.paper
+ paper-api
+ 1.12.2-R0.1-SNAPSHOT
+ provided
+
+
+
diff --git a/src/main/java/com/io/yutian/refinesystem/RefineSystem.java b/src/main/java/com/io/yutian/refinesystem/RefineSystem.java
new file mode 100644
index 0000000..bd97c85
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/RefineSystem.java
@@ -0,0 +1,83 @@
+package com.io.yutian.refinesystem;
+
+import com.io.yutian.refinesystem.gui.GuiHolder;
+import com.io.yutian.refinesystem.gui.RefineGui;
+import com.io.yutian.refinesystem.listener.GuiListener;
+import de.tr7zw.itemnbtapi.NBTItem;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class RefineSystem extends JavaPlugin {
+
+ private static RefineSystem instance;
+
+ @Override
+ public void onEnable() {
+ instance = this;
+ Bukkit.getPluginManager().registerEvents(new GuiListener(), this);
+
+ RefineSystemSetting.reload();
+ }
+
+ @Override
+ public void onDisable() {
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ if (player.getOpenInventory() != null) {
+ InventoryHolder inventoryHolder = player.getOpenInventory().getTopInventory().getHolder();
+ if (inventoryHolder instanceof GuiHolder) {
+ player.closeInventory();
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (args.length == 1 && args[0].equalsIgnoreCase("reload") && sender.isOp()) {
+ RefineSystemSetting.reload();
+ sender.sendMessage("§8§l[§a§l!§8§l] §7重载成功");
+ return true;
+ }
+ if (args.length == 1 && args[0].equalsIgnoreCase("item") && sender.isOp()) {
+ Player player = (Player) sender;
+ ItemStack itemStack = new ItemStack(Material.IRON_PICKAXE);
+ List lores = new ArrayList<>();
+ lores.add("§f品质: §b稀有");
+ lores.add("§7- < §1§5§r§7尚未进行洗炼§1§5§r§7 >");
+ ItemMeta itemMeta = itemStack.getItemMeta();
+ itemMeta.setLore(lores);
+ itemStack.setItemMeta(itemMeta);
+ player.getInventory().addItem(itemStack);
+ ItemStack itemStack1 = new ItemStack(Material.PAPER);
+ ItemMeta itemMeta1 = itemStack1.getItemMeta();
+ itemMeta1.setDisplayName("§f雨天洗炼符");
+ itemStack1.setItemMeta(itemMeta1);
+ NBTItem item = new NBTItem(itemStack1);
+ item.setString("refineType", "雨天洗炼符");
+ player.getInventory().addItem(item.getItem());
+ sender.sendMessage("§8§l[§a§l!§8§l] §7获取物品成功");
+ return true;
+ }
+ if (!(sender instanceof Player)) {
+ return true;
+ }
+ Player player = (Player) sender;
+ new RefineGui(player).open();
+ return true;
+ }
+
+ public static RefineSystem inst() {
+ return instance;
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/RefineSystemSetting.java b/src/main/java/com/io/yutian/refinesystem/RefineSystemSetting.java
new file mode 100644
index 0000000..53b7b41
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/RefineSystemSetting.java
@@ -0,0 +1,68 @@
+package com.io.yutian.refinesystem;
+
+import com.io.yutian.refinesystem.data.RefineData;
+import com.io.yutian.refinesystem.data.SkillData;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.FileConfiguration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class RefineSystemSetting {
+
+ private static String detectionLore;
+ private static Map refineDatas = new HashMap<>();
+ private static Map tierLevels = new HashMap<>();
+
+ public static void reload() {
+ refineDatas.clear();
+ RefineSystem.inst().saveDefaultConfig();
+ RefineSystem.inst().reloadConfig();
+ FileConfiguration config = RefineSystem.inst().getConfig();
+ detectionLore = config.getString("detectionLore");
+ ConfigurationSection section = config.getConfigurationSection("options");
+ for (String key : section.getKeys(false)) {
+ double chance = section.getDouble(key+".chance");
+ int needQuality = section.getInt(key+".needQuality");
+ int minGlossaryAmount = section.getInt(key+".glossaryAmount.min");
+ int maxGlossaryAmount = section.getInt(key+".glossaryAmount.max");
+ ConfigurationSection skillSection = section.getConfigurationSection(key+".skills");
+ Map skillDatas = new HashMap<>();
+ for (String skillKey : skillSection.getKeys(false)) {
+ double skillChance = skillSection.getDouble(skillKey+".chance");
+ int minSkillLevel = skillSection.getInt(skillKey+".level.min");
+ int maxSkillLevel = skillSection.getInt(skillKey+".level.max");
+ double minTrigger = skillSection.getDouble(skillKey+".trigger.min");
+ double maxTrigger = skillSection.getDouble(skillKey+".trigger.max");
+ skillDatas.put(skillKey, new SkillData(skillKey, skillChance, minSkillLevel, maxSkillLevel, minTrigger, maxTrigger));
+ }
+ refineDatas.put(key, new RefineData(key, chance, needQuality, minGlossaryAmount, maxGlossaryAmount, skillDatas));
+ }
+ ConfigurationSection tierSection = config.getConfigurationSection("tierLevels");
+ for (String tierKey : tierSection.getKeys(false)) {
+ int tierLevel = tierSection.getInt(tierKey);
+ tierLevels.put(tierKey, tierLevel);
+ }
+ }
+
+ public static String getDetectionLore() {
+ return detectionLore;
+ }
+
+ public static boolean hasRefineData(String id) {
+ return refineDatas.containsKey(id);
+ }
+
+ public static RefineData getRefineData(String id) {
+ return refineDatas.get(id);
+ }
+
+ public static Map getRefineDatas() {
+ return refineDatas;
+ }
+
+ public static Map getTierLevels() {
+ return tierLevels;
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/data/RefineData.java b/src/main/java/com/io/yutian/refinesystem/data/RefineData.java
new file mode 100644
index 0000000..160a985
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/data/RefineData.java
@@ -0,0 +1,69 @@
+package com.io.yutian.refinesystem.data;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class RefineData {
+
+ private String id;
+ private double chance;
+ private int needQuality;
+ private int minGlossaryAmount;
+ private int maxGlossaryAmount;
+
+ private Map skillDatas;
+
+ protected final Map skillChances = new HashMap<>();
+
+ public RefineData(String id, double chance, int needQuality, int minGlossaryAmount, int maxGlossaryAmount, Map skillDatas) {
+ this.id = id;
+ this.chance = chance;
+ this.needQuality = needQuality;
+ this.minGlossaryAmount = minGlossaryAmount;
+ this.maxGlossaryAmount = maxGlossaryAmount;
+ this.skillDatas = skillDatas;
+ for (SkillData sd : skillDatas.values()) {
+ skillChances.put(sd.getId(), sd.getChance());
+ }
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public double getChance() {
+ return chance;
+ }
+
+ public int getNeedQuality() {
+ return needQuality;
+ }
+
+ public int getMinGlossaryAmount() {
+ return minGlossaryAmount;
+ }
+
+ public int getMaxGlossaryAmount() {
+ return maxGlossaryAmount;
+ }
+
+ public Map getSkillDatas() {
+ return skillDatas;
+ }
+
+ public Map getSkillChances() {
+ return skillChances;
+ }
+
+ @Override
+ public String toString() {
+ return "RefineData{" +
+ "id='" + id + '\'' +
+ ", chance=" + chance +
+ ", needQuality=" + needQuality +
+ ", minGlossaryAmount=" + minGlossaryAmount +
+ ", maxGlossaryAmount=" + maxGlossaryAmount +
+ ", skillDatas=" + skillDatas +
+ '}';
+ }
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/data/SkillData.java b/src/main/java/com/io/yutian/refinesystem/data/SkillData.java
new file mode 100644
index 0000000..cc559c5
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/data/SkillData.java
@@ -0,0 +1,65 @@
+package com.io.yutian.refinesystem.data;
+
+import com.io.yutian.refinesystem.util.RandomUtil;
+import com.io.yutian.refinesystem.util.StringUtil;
+
+public class SkillData {
+
+ private String id;
+ private double chance;
+ private int minLevel;
+ private int maxLevel;
+ private double minTrigger;
+ private double maxTrigger;
+
+ public SkillData(String id, double chance, int minLevel, int maxLevel, double minTrigger, double maxTrigger) {
+ this.id = id;
+ this.chance = chance;
+ this.minLevel = minLevel;
+ this.maxLevel = maxLevel;
+ this.minTrigger = minTrigger;
+ this.maxTrigger = maxTrigger;
+ }
+
+ public String randomSkillLore() {
+ int level = RandomUtil.getRandomInt(minLevel, maxLevel);
+ double trigger = RandomUtil.getRandomDouble(minTrigger, maxTrigger, 1);
+ return "§f§0§4§r"+id+" "+ StringUtil.intToRoman(level) +"§0§4§r§f §8| §f§0§5§r§f"+trigger+"§0§5§r§f% §7(被动技)";
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public double getChance() {
+ return chance;
+ }
+
+ public int getMinLevel() {
+ return minLevel;
+ }
+
+ public int getMaxLevel() {
+ return maxLevel;
+ }
+
+ public double getMinTrigger() {
+ return minTrigger;
+ }
+
+ public double getMaxTrigger() {
+ return maxTrigger;
+ }
+
+ @Override
+ public String toString() {
+ return "SkillData{" +
+ "id='" + id + '\'' +
+ ", chance=" + chance +
+ ", minLevel=" + minLevel +
+ ", maxLevel=" + maxLevel +
+ ", minTrigger=" + minTrigger +
+ ", maxTrigger=" + maxTrigger +
+ '}';
+ }
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/gui/GuiHolder.java b/src/main/java/com/io/yutian/refinesystem/gui/GuiHolder.java
new file mode 100644
index 0000000..577995f
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/gui/GuiHolder.java
@@ -0,0 +1,14 @@
+package com.io.yutian.refinesystem.gui;
+
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+
+public interface GuiHolder {
+
+ void onClick(InventoryClickEvent event);
+
+ void onClose(InventoryCloseEvent event);
+
+ void open();
+
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/gui/RefineGui.java b/src/main/java/com/io/yutian/refinesystem/gui/RefineGui.java
new file mode 100644
index 0000000..63c4ee2
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/gui/RefineGui.java
@@ -0,0 +1,265 @@
+package com.io.yutian.refinesystem.gui;
+
+import com.io.yutian.refinesystem.RefineSystemSetting;
+import com.io.yutian.refinesystem.data.RefineData;
+import com.io.yutian.refinesystem.data.SkillData;
+import com.io.yutian.refinesystem.util.ItemStackUtil;
+import com.io.yutian.refinesystem.util.PlayerInventoryUtil;
+import com.io.yutian.refinesystem.util.RandomBuilder;
+import com.io.yutian.refinesystem.util.RandomUtil;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class RefineGui implements InventoryHolder, GuiHolder {
+
+ private static final int[] ARRAY_1 = new int[] {0,2,3,5,6,8,12,14,18,20,21,23,24,26};
+ private static final int[] ARRAY_2 = new int[] {1,7,9,11,15,17,19,25};
+ private static final int[] ARRAY_3 = new int[] {4,22};
+
+ private static final ItemStack ITEM_1;
+ private static final ItemStack ITEM_2;
+ private static final ItemStack ITEM_3;
+ private static final ItemStack ITEM_4;
+ private static final ItemStack ITEM_5;
+ private static final ItemStack ITEM_6;
+ private static final ItemStack ITEM_7;
+ private static final ItemStack ITEM_10;
+
+ private Inventory inventory;
+ private Player player;
+
+ private ItemStack inputItem;
+ private ItemStack refineItem;
+
+ public RefineGui(Player player) {
+ this.player = player;
+ this.inventory = Bukkit.createInventory(this, 27, "洗练系统");
+ for (int i : ARRAY_1) {
+ this.inventory.setItem(i, ITEM_1);
+ }
+ for (int i : ARRAY_2) {
+ this.inventory.setItem(i, ITEM_2);
+ }
+ for (int i : ARRAY_3) {
+ this.inventory.setItem(i, ITEM_3);
+ }
+ this.inventory.setItem(10, ITEM_4);
+ this.inventory.setItem(13, ITEM_10);
+ this.inventory.setItem(16, ITEM_6);
+ }
+
+ @Override
+ public void onClick(InventoryClickEvent event) {
+ Inventory clickedInventory = event.getClickedInventory();
+ int slot = event.getRawSlot();
+ event.setCancelled(true);
+ if (slot < 27) {
+ if (slot == 10) {
+ removeInputItem(10);
+ } else if (slot == 16) {
+ removeRefineItem(16);
+ } else if (slot == 13) {
+ refine();
+ }
+ } else {
+ ItemStack clickedItem = event.getCurrentItem();
+ if (clickedItem == null || clickedItem.getType() == Material.AIR) {
+ return;
+ }
+ if (ItemStackUtil.isRefineItem(clickedItem)) {
+ setRefineItem(clickedItem, clickedInventory, event.getSlot());
+ return;
+ }
+ if (ItemStackUtil.canRefine(clickedItem)) {
+ setInputItem(clickedItem, clickedInventory, event.getSlot());
+ return;
+ }
+ if (this.inputItem == null || this.refineItem == null) {
+ player.sendMessage("§8§l[§e§l!§8§l] §7该物品不是可洗练的物品或洗练符");
+ player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1.6F);
+ }
+ }
+ }
+
+ public void setInputItem(ItemStack inputItem, Inventory inventory, int slot) {
+ if (this.inputItem != null) {
+ return;
+ }
+ this.inputItem = inputItem;
+ update();
+ inventory.setItem(slot, null);
+ player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
+ }
+
+ public void setRefineItem(ItemStack refineItem, Inventory inventory, int slot) {
+ if (this.refineItem != null) {
+ return;
+ }
+ int amount = refineItem.getAmount();
+ ItemStack itemStack1 = refineItem.clone();
+ ItemStack itemStack2 = refineItem.clone();
+ if (amount > 1) {
+ itemStack1.setAmount(1);
+ itemStack2.setAmount(amount - 1);
+ } else {
+ itemStack2 = null;
+ }
+ this.refineItem = itemStack1;
+ update();
+ inventory.setItem(slot, itemStack2);
+ player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
+ }
+
+ public void removeInputItem(int index) {
+ if (this.inputItem == null) {
+ return;
+ }
+ if (!PlayerInventoryUtil.hasFreeSlot(player)) {
+ player.sendMessage("§8§l[§c§l!§8§l] §7您的背包空间不足,无法拿下物品");
+ return;
+ }
+ PlayerInventoryUtil.giveItemStack(player, this.inputItem);
+ this.inputItem = null;
+ update();
+ player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
+ }
+
+ public void removeRefineItem(int index) {
+ if (this.refineItem == null) {
+ return;
+ }
+ if (!PlayerInventoryUtil.hasFreeSlot(player)) {
+ player.sendMessage("§8§l[§c§l!§8§l] §7您的背包空间不足,无法拿下物品");
+ return;
+ }
+ PlayerInventoryUtil.giveItemStack(player, this.refineItem);
+ this.refineItem = null;
+ update();
+ player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
+ }
+
+ public void refine() {
+ if (this.inputItem == null || this.refineItem == null) {
+ return;
+ }
+ int tierLevel = ItemStackUtil.getTierLevel(this.inputItem);
+ String refineType = ItemStackUtil.getRefineType(this.refineItem);
+ if (!RefineSystemSetting.hasRefineData(refineType)) {
+ return;
+ }
+ RefineData refineData = RefineSystemSetting.getRefineData(refineType);
+ if (tierLevel < refineData.getNeedQuality()) {
+ player.sendMessage("§8§l[§c§l!§8§l] §7该物品的品质未达到洗练要求,无法洗练");
+ player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_NO, 1, 1.6F);
+ return;
+ }
+ boolean success = RandomUtil.random(refineData.getChance());
+ ItemStack itemStack = this.inputItem;
+ if (success) {
+ player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1);
+ player.sendMessage("§8§l[§a§l!§8§l] §7恭喜您,洗炼成功!");
+ itemStack = applyRefine(this.inputItem, refineData);
+ } else {
+ player.playSound(player.getLocation(), Sound.ENTITY_BLAZE_DEATH, 1, 1);
+ player.sendMessage("§8§l[§e§l!§8§l] §7很遗憾,洗炼失败");
+ }
+ this.inputItem = null;
+ this.refineItem = null;
+ new RefineResultGui(player, itemStack).open();
+ }
+
+ public ItemStack applyRefine(ItemStack inputItem, RefineData refineData) {
+ ItemStack itemStack = inputItem.clone();
+ int glossaryAmount = RandomUtil.getRandomInt(refineData.getMinGlossaryAmount(), refineData.getMaxGlossaryAmount());
+ List lores = new ArrayList<>();
+ Map cacheMap = new HashMap<>(refineData.getSkillChances());
+ for (int i = 0; i < glossaryAmount; i++) {
+ RandomBuilder randomBuilder = new RandomBuilder<>(cacheMap);
+ String skill = randomBuilder.random();
+ if (skill == null) {
+ continue;
+ }
+ cacheMap.remove(skill);
+ SkillData skillData = refineData.getSkillDatas().get(skill);
+ lores.add(skillData.randomSkillLore());
+ }
+ itemStack = ItemStackUtil.replaceLore(itemStack, RefineSystemSetting.getDetectionLore(), lores);
+ return itemStack;
+ }
+
+ private void update() {
+ this.inventory.setItem(10, this.inputItem != null ? this.inputItem : ITEM_4);
+ this.inventory.setItem(16, this.refineItem != null ? this.refineItem : ITEM_6);
+ }
+
+ @Override
+ public void onClose(InventoryCloseEvent event) {
+ if (this.inputItem != null) {
+ PlayerInventoryUtil.giveItemStack(player, this.inputItem);
+ }
+ if (this.refineItem != null) {
+ PlayerInventoryUtil.giveItemStack(player, this.refineItem);
+ }
+ this.inputItem = null;
+ this.refineItem = null;
+ }
+
+ @Override
+ public void open() {
+ player.openInventory(inventory);
+ }
+
+ @Override
+ public Inventory getInventory() {
+ return inventory;
+ }
+
+ static {
+ ITEM_1 = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 15);
+ ITEM_2 = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 0);
+ ITEM_3 = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 5);
+ ITEM_4 = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 14);
+ ITEM_5 = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 1);
+ ITEM_6 = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 2);
+ ITEM_7 = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 14);
+ ITEM_10 = new ItemStack(Material.ANVIL, 1);
+ ItemMeta itemMeta1 = ITEM_1.getItemMeta();
+ itemMeta1.setDisplayName(" ");
+ ITEM_1.setItemMeta(itemMeta1);
+ ItemMeta itemMeta2 = ITEM_2.getItemMeta();
+ itemMeta2.setDisplayName("");
+ ITEM_2.setItemMeta(itemMeta2);
+ ItemMeta itemMeta3 = ITEM_3.getItemMeta();
+ itemMeta3.setDisplayName(" ");
+ ITEM_3.setItemMeta(itemMeta3);
+ ItemMeta itemMeta4 = ITEM_4.getItemMeta();
+ itemMeta4.setDisplayName("§a物品孔");
+ ITEM_4.setItemMeta(itemMeta4);
+ ItemMeta itemMeta5 = ITEM_5.getItemMeta();
+ itemMeta5.setDisplayName(" ");
+ ITEM_5.setItemMeta(itemMeta5);
+ ItemMeta itemMeta6 = ITEM_6.getItemMeta();
+ itemMeta6.setDisplayName("§a洗练符孔");
+ ITEM_6.setItemMeta(itemMeta6);
+ ItemMeta itemMeta7 = ITEM_7.getItemMeta();
+ itemMeta7.setDisplayName(" ");
+ ITEM_7.setItemMeta(itemMeta7);
+ ItemMeta itemMeta10 = ITEM_10.getItemMeta();
+ itemMeta10.setDisplayName("§f点击洗练");
+ ITEM_10.setItemMeta(itemMeta10);
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/gui/RefineResultGui.java b/src/main/java/com/io/yutian/refinesystem/gui/RefineResultGui.java
new file mode 100644
index 0000000..6c4d8b6
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/gui/RefineResultGui.java
@@ -0,0 +1,93 @@
+package com.io.yutian.refinesystem.gui;
+
+import com.io.yutian.refinesystem.util.PlayerInventoryUtil;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.Sound;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+public class RefineResultGui implements InventoryHolder, GuiHolder {
+
+ private static final int[] ARRAY_1 = new int[] {0,8,9,17,18,26};
+ private static final int[] ARRAY_2 = new int[] {1,2,3,5,6,7,10,11,15,16,19,20,21,23,24,25};
+ private static final int[] ARRAY_3 = new int[] {4,12,14,22};
+
+ private static final ItemStack ITEM_1;
+ private static final ItemStack ITEM_2;
+ private static final ItemStack ITEM_3;
+
+ private static final int SLOT = 13;
+
+ private Inventory inventory;
+ private Player player;
+
+ private ItemStack result;
+
+ public RefineResultGui(Player player, ItemStack result) {
+ this.player = player;
+ this.result = result;
+ this.inventory = Bukkit.createInventory(this, 27, "洗练界面");
+ for (int i : ARRAY_1) {
+ inventory.setItem(i, ITEM_1);
+ }
+ for (int i : ARRAY_2) {
+ inventory.setItem(i, ITEM_2);
+ }
+ for (int i : ARRAY_3) {
+ inventory.setItem(i, ITEM_3);
+ }
+ this.inventory.setItem(SLOT, result);
+ }
+
+ @Override
+ public void onClick(InventoryClickEvent event) {
+ event.setCancelled(true);
+ Inventory clickedInventory = event.getClickedInventory();
+ int slot = event.getRawSlot();
+ if (slot == SLOT) {
+ PlayerInventoryUtil.giveItemStack(player, result);
+ player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 1, 1);
+ result = null;
+ player.closeInventory();
+ }
+ }
+
+ @Override
+ public void onClose(InventoryCloseEvent event) {
+ if (result != null) {
+ PlayerInventoryUtil.giveItemStack(player, result);
+ }
+ }
+
+ @Override
+ public void open() {
+ player.openInventory(inventory);
+ }
+
+ @Override
+ public Inventory getInventory() {
+ return inventory;
+ }
+
+ static {
+ ITEM_1 = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 15);
+ ITEM_2 = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 0);
+ ITEM_3 = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 5);
+ ItemMeta itemMeta1 = ITEM_1.getItemMeta();
+ itemMeta1.setDisplayName(" ");
+ ITEM_1.setItemMeta(itemMeta1);
+ ItemMeta itemMeta2 = ITEM_2.getItemMeta();
+ itemMeta2.setDisplayName("");
+ ITEM_2.setItemMeta(itemMeta2);
+ ItemMeta itemMeta3 = ITEM_3.getItemMeta();
+ itemMeta3.setDisplayName(" ");
+ ITEM_3.setItemMeta(itemMeta3);
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/listener/GuiListener.java b/src/main/java/com/io/yutian/refinesystem/listener/GuiListener.java
new file mode 100644
index 0000000..f829d48
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/listener/GuiListener.java
@@ -0,0 +1,33 @@
+package com.io.yutian.refinesystem.listener;
+
+import com.io.yutian.refinesystem.gui.GuiHolder;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+
+public class GuiListener implements Listener {
+
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event) {
+ Inventory inventory = event.getInventory();
+ InventoryHolder holder = inventory.getHolder();
+ if (holder != null && holder instanceof GuiHolder) {
+ GuiHolder guiHolder = (GuiHolder) holder;
+ guiHolder.onClick(event);
+ }
+ }
+
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent event) {
+ Inventory inventory = event.getInventory();
+ InventoryHolder holder = inventory.getHolder();
+ if (holder != null && holder instanceof GuiHolder) {
+ GuiHolder guiHolder = (GuiHolder) holder;
+ guiHolder.onClose(event);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/io/yutian/refinesystem/util/ItemStackUtil.java b/src/main/java/com/io/yutian/refinesystem/util/ItemStackUtil.java
new file mode 100644
index 0000000..5f6dffd
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/util/ItemStackUtil.java
@@ -0,0 +1,96 @@
+package com.io.yutian.refinesystem.util;
+
+import com.io.yutian.refinesystem.RefineSystemSetting;
+import de.tr7zw.itemnbtapi.NBTItem;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class ItemStackUtil {
+
+ public static boolean canRefine(ItemStack itemStack) {
+ if (itemStack == null || itemStack.getType() == Material.AIR) {
+ return false;
+ }
+ ItemMeta itemMeta = itemStack.getItemMeta();
+ if (!itemMeta.hasLore()) {
+ return false;
+ }
+ List lore = itemMeta.getLore();
+ for (String s : lore) {
+ if (s.contains(RefineSystemSetting.getDetectionLore())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isRefineItem(ItemStack itemStack) {
+ if (itemStack == null || itemStack.getType() == Material.AIR) {
+ return false;
+ }
+ NBTItem nbtItem = new NBTItem(itemStack);
+ if (nbtItem.hasKey("refineType")) {
+ return true;
+ }
+ return false;
+ }
+
+ public static String getRefineType(ItemStack itemStack) {
+ if (itemStack == null || itemStack.getType() == Material.AIR) {
+ return null;
+ }
+ NBTItem nbtItem = new NBTItem(itemStack);
+ if (nbtItem.hasKey("refineType")) {
+ return nbtItem.getString("refineType");
+ }
+ return null;
+ }
+
+ public static int getTierLevel(ItemStack itemStack) {
+ if (itemStack == null || itemStack.getType() == Material.AIR) {
+ return -1;
+ }
+ ItemMeta itemMeta = itemStack.getItemMeta();
+ if (!itemMeta.hasLore()) {
+ return -1;
+ }
+ List lore = itemMeta.getLore();
+ for (String s : lore) {
+ for (Map.Entry entry : RefineSystemSetting.getTierLevels().entrySet()) {
+ if (s.contains(entry.getKey())) {
+ return entry.getValue();
+ }
+ }
+ }
+ return -1;
+ }
+
+ public static ItemStack replaceLore(ItemStack itemStack, String oldLore, List newLores) {
+ ItemStack itemStack1 = itemStack.clone();
+ ItemMeta itemMeta = itemStack1.getItemMeta();
+ List lores = itemMeta.hasLore() ? itemMeta.getLore() : new ArrayList<>();
+ int index = -1;
+ for (int i = 0; i < lores.size(); i++) {
+ String s = lores.get(i);
+ if (s.contains(oldLore)) {
+ index = i;
+ break;
+ }
+ }
+ lores.remove(index);
+ int i = 0;
+ for (String s : newLores) {
+ lores.add(index+i, s);
+ i++;
+ }
+ itemMeta.setLore(lores);
+ itemStack1.setItemMeta(itemMeta);
+ return itemStack1;
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/util/PlayerInventoryUtil.java b/src/main/java/com/io/yutian/refinesystem/util/PlayerInventoryUtil.java
new file mode 100644
index 0000000..fcc1ffd
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/util/PlayerInventoryUtil.java
@@ -0,0 +1,41 @@
+package com.io.yutian.refinesystem.util;
+
+import org.bukkit.Material;
+import org.bukkit.entity.Item;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+public class PlayerInventoryUtil {
+
+ public static boolean hasFreeSlot(Player player) {
+ return getFreeSize(player) > 0;
+ }
+
+ public static int getFreeSize(Player player) {
+ int index = -1;
+ int freesize = 0;
+ while (index < 35) {
+ index++;
+ ItemStack i = player.getInventory().getItem(index);
+ if (i == null) {
+ freesize++;
+ continue;
+ }
+ if (i.getType().equals(Material.AIR)) {
+ freesize++;
+ }
+ }
+ return freesize;
+ }
+
+ public static void giveItemStack(Player player, ItemStack itemStack) {
+ if (PlayerInventoryUtil.hasFreeSlot(player)) {
+ player.getInventory().addItem(itemStack);
+ } else {
+ Item item = player.getLocation().getWorld().dropItem(player.getLocation(), itemStack);
+ item.setCanMobPickup(false);
+ item.setPickupDelay(20);
+ }
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/util/RandomBuilder.java b/src/main/java/com/io/yutian/refinesystem/util/RandomBuilder.java
new file mode 100644
index 0000000..9a2abec
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/util/RandomBuilder.java
@@ -0,0 +1,83 @@
+package com.io.yutian.refinesystem.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+public class RandomBuilder {
+
+ private Map valueMap;
+
+ private List elementList = new ArrayList<>();
+ private double maxElement = 0;
+
+ public RandomBuilder(Map map) {
+ valueMap = map;
+
+ double minElement = 0;
+
+ for (Map.Entry entry : map.entrySet()) {
+ minElement = maxElement;
+ maxElement += entry.getValue();
+ elementList.add(new Element(entry.getKey(), minElement, maxElement));
+ }
+ }
+
+ public T random() {
+ return random(new Random());
+ }
+
+ public T random(Random random) {
+ double d = random.nextDouble() * maxElement;
+ if (d == 0) {
+ d = 0.1 * maxElement;
+ }
+ int size = valueMap.size();
+ for (int i = 0; i < elementList.size(); i++) {
+ Element element = elementList.get(i);
+ if (element.isContainKey(d)) {
+ return element.getValue();
+ }
+ }
+ return null;
+ }
+
+ public double getMaxElement() {
+ return maxElement;
+ }
+
+ public List getElementList() {
+ return elementList;
+ }
+
+ public Map getValueMap() {
+ return valueMap;
+ }
+
+ private class Element {
+
+ private T value;
+
+ private final double minElement;
+ private final double maxElement;
+
+ public Element(T value, double element0, double element1) {
+ this.value = value;
+ this.minElement = Math.min(element0, element1);
+ this.maxElement = Math.max(element0, element1);
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public boolean isContainKey(double element) {
+ return element > minElement && element <= maxElement;
+ }
+
+ }
+
+
+
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/util/RandomUtil.java b/src/main/java/com/io/yutian/refinesystem/util/RandomUtil.java
new file mode 100644
index 0000000..36a56de
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/util/RandomUtil.java
@@ -0,0 +1,59 @@
+package com.io.yutian.refinesystem.util;
+
+import org.bukkit.Color;
+import org.bukkit.Location;
+import org.bukkit.World;
+
+import java.util.List;
+import java.util.Random;
+
+public class RandomUtil {
+
+ public static boolean random(double d) {
+ return d >= new Random().nextFloat();
+ }
+
+ public static Color getRandomColor() {
+ Random random = new Random();
+ int r = random.nextInt(256);
+ int g = random.nextInt(256);
+ int b = random.nextInt(256);
+ return Color.fromRGB(r, g, b);
+ }
+
+ public static Location getRandomLocation(World world, double minX, double maxX, double minZ, double maxZ) {
+ double rx = getRandomDouble(minX, maxX, 3);
+ double rz = getRandomDouble(minZ, maxZ, 3);
+ int y = world.getHighestBlockAt((int)rx, (int)rz).getY()+1;
+ Location location = new Location(world, rx, y, rz);
+ return location;
+ }
+
+ public static E getRandomElement(List list) {
+ if (list.size() == 0) {
+ return null;
+ }
+ return list.get(getRandomInt(0, list.size()-1));
+ }
+
+ public static String getRandomString(String[] array) {
+ Random r = new Random();
+ return array[getRandomInt(0, array.length)];
+ }
+
+ public static int getRandomInt(int min, int max) {
+ if (min == max) {
+ return max;
+ }
+ Random r = new Random();
+ int i = min < max ? min : max;
+ int a = min < max ? max : min;
+ return r.nextInt(a - i + 1) + i;
+ }
+
+ public static double getRandomDouble(double min, double max, int scl) {
+ int pow = (int) Math.pow(10, scl);
+ return Math.floor((Math.random() * (max - min) + min) * pow) / pow;
+ }
+
+}
diff --git a/src/main/java/com/io/yutian/refinesystem/util/StringUtil.java b/src/main/java/com/io/yutian/refinesystem/util/StringUtil.java
new file mode 100644
index 0000000..89b76d9
--- /dev/null
+++ b/src/main/java/com/io/yutian/refinesystem/util/StringUtil.java
@@ -0,0 +1,19 @@
+package com.io.yutian.refinesystem.util;
+
+public class StringUtil {
+
+ public static String intToRoman(int number) {
+ int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
+ String[] symbols = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
+ StringBuilder roman = new StringBuilder();
+ for (int i = 0; i < values.length; i++) {
+ while (number >= values[i]) {
+ number -= values[i];
+ roman.append(symbols[i]);
+ }
+ }
+ return roman.toString();
+ }
+
+
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
new file mode 100644
index 0000000..946e3c5
--- /dev/null
+++ b/src/main/resources/config.yml
@@ -0,0 +1,48 @@
+tierLevels:
+ '§f品质: §b稀有': 1
+ '§f品质: §e超稀有': 2
+ '§f品质: §5史诗': 3
+ '§f品质: §6传说': 4
+ '§f品质: §d卓越': 5
+ '§f品质: §c神圣': 6
+detectionLore: '§7- < §1§5§r§7尚未进行洗炼§1§5§r§7 >'
+options:
+ # NbtKey
+ 雨天洗炼符:
+ # 洗炼成功率
+ chance: 1.0
+ # 武器需要达到什么品质
+ needQuality: 1
+ # 可随机添加多少个词条
+ glossaryAmount:
+ min: 2
+ max: 3
+ skills:
+ # name
+ 冲击:
+ # 抽中概率
+ chance: 10
+ # 等级随机 需要转化成 I II III IV V IV IIV IIIV IX X
+ level:
+ min: 1
+ max: 3
+ # 被动触发概率
+ trigger:
+ min: 10.5
+ max: 18.6
+ 吸血:
+ chance: 10
+ level:
+ min: 1
+ max: 3
+ trigger:
+ min: 9.85
+ max: 30.5
+ 暗黑火焰:
+ chance: 10
+ level:
+ min: 1
+ max: 3
+ trigger:
+ min: 10.5
+ max: 20.2
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
new file mode 100644
index 0000000..b754a52
--- /dev/null
+++ b/src/main/resources/plugin.yml
@@ -0,0 +1,6 @@
+name: RefineSystem
+version: '${project.version}'
+main: com.io.yutian.refinesystem.RefineSystem
+commands:
+ refinesystem:
+ aliases: [rs]
\ No newline at end of file