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} + ${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