This commit is contained in:
yaohunya 2025-07-20 03:22:06 +08:00
parent 9b8cd2dc10
commit 9a0ee2d107
17 changed files with 208 additions and 119 deletions

View File

@ -4,11 +4,10 @@
一个斗罗RPG常见的魂卡系统击杀怪掉落魂卡右键魂卡打开背包并概率吸收魂卡
## 玩法关联插件
- PaperMC 1.12.2
- Spigot 1.12.2
- DemonAPI (核心前置支持)
- AuItemStackLibrary (存储掉落魂卡的战利品)
- DemonMmKillsStats (击杀怪物后概率掉落魂卡)
- DemonMmKillsDrop (记录魂卡掉落数量日志)
- MythicMobs (击杀怪物后概率掉落魂卡)
- AuItemUse (掉落的魂卡 手持右键鉴定)
- AuForge (鉴定后输出的装备魂卡)
- DemonFenJie (分解鉴定后的装备魂卡)
@ -22,6 +21,11 @@
# 更新日志
## v1.0.0 - 2025-05-10
## v1.0.0 - 2025/05/10
- 绑定命令 `/aucard open` 打开魂卡背包
- 初步已实现功能的安装和实装
## v1.1.6 - 2025/07/20
- 取消`Item-NBT-API`的依赖
- 击杀检测依赖更换为 `MythicMobs`
- 已支持繁体

Binary file not shown.

Binary file not shown.

Binary file not shown.

27
pom.xml
View File

@ -30,24 +30,29 @@
<version>1.12.2</version>
</dependency>
<dependency>
<groupId>com.yaohun.demonapi</groupId>
<groupId>me.Demon.DemonPlugin</groupId>
<artifactId>DemonAPI</artifactId>
<version>2.1.4</version>
<version>2.2.9</version>
</dependency>
<dependency>
<groupId>com.yaohun.nbtapi</groupId>
<artifactId>NBT-API</artifactId>
<version>1.12.2</version>
</dependency>
<dependency>
<groupId>com.yaohun.itemku</groupId>
<artifactId>AuItemStackLib</artifactId>
<version>1.4.4</version>
<groupId>com.io.yaohun.itemlibrary</groupId>
<artifactId>AuItemStackLibrary</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.serverct.ersha.jd</groupId>
<artifactId>AttributePlus</artifactId>
<version>2.0</version>
<version>2.3.7</version>
</dependency>
<dependency>
<groupId>io.lumine.xikage.mythicmobs</groupId>
<artifactId>MythicMobs</artifactId>
<version>4.11.0-008</version>
</dependency>
<dependency>
<groupId>com.yaohun.morespace</groupId>
<artifactId>AuMoreSpace</artifactId>
<version>1.0.9</version>
</dependency>
</dependencies>

View File

@ -5,6 +5,7 @@ import com.yaohun.cardbackpack.gui.CardGui;
import com.yaohun.cardbackpack.gui.ConfirmGui;
import com.yaohun.cardbackpack.listener.KillMobsListener;
import com.yaohun.cardbackpack.listener.PlayerListener;
import com.yaohun.cardbackpack.manage.CacheManager;
import com.yaohun.cardbackpack.manage.DataManager;
import org.bukkit.Sound;
import org.bukkit.command.Command;
@ -16,11 +17,13 @@ public class AuCardBackpack extends JavaPlugin {
private static AuCardBackpack instance;
private static DataManager dataManager;
private static CacheManager cacheManager;
@Override
public void onEnable() {
instance = this;
dataManager = new DataManager();
cacheManager = new CacheManager();
Config.reloadConfig();
getServer().getPluginManager().registerEvents(new CardGui(), this);
getServer().getPluginManager().registerEvents(new ConfirmGui(), this);
@ -67,6 +70,10 @@ public class AuCardBackpack extends JavaPlugin {
return dataManager;
}
public static CacheManager getCacheManager() {
return cacheManager;
}
public static void sendMessage(CommandSender sender, String message) {
String prefix = Config.langData.getMessage("prefix");
if(sender instanceof Player){

View File

@ -1,6 +1,6 @@
package com.yaohun.cardbackpack.data;
import com.yaohun.cardbackpack.util.RandomUtil;
import me.Demon.DemonPlugin.Util.RandomUtil;
public class CardData {

View File

@ -1,6 +1,6 @@
package com.yaohun.cardbackpack.data;
import de.tr7zw.itemnbtapi.NBTItem;
import me.Demon.DemonPlugin.data.NbtItem;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
@ -47,7 +47,7 @@ public class PlayerData {
public boolean isCardYearsExit(String hunkaKey){
for (ItemStack itemStack : itemStackHashMap.values()) {
NBTItem nbtItem = new NBTItem(itemStack);
NbtItem nbtItem = new NbtItem(itemStack);
if(nbtItem.hasKey("hunkaKey")){
if(nbtItem.getString("hunkaKey").equals(hunkaKey)){
return true;

View File

@ -5,9 +5,9 @@ import com.yaohun.cardbackpack.config.Config;
import com.yaohun.cardbackpack.data.PlayerData;
import com.yaohun.cardbackpack.manage.DataManager;
import com.yaohun.cardbackpack.util.StackUtil;
import de.tr7zw.itemnbtapi.NBTItem;
import me.Demon.DemonPlugin.DemonAPI;
import me.Demon.DemonPlugin.Util.CDTimeAPI;
import me.Demon.DemonPlugin.data.NbtItem;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Sound;
@ -53,8 +53,8 @@ public class CardGui implements Listener {
inv.setItem(2,StackUtil.iconHide("§e百年魂卡槽"));
inv.setItem(3,StackUtil.iconHide("§d千年魂卡槽"));
inv.setItem(4,StackUtil.iconHide("§7万年魂卡槽"));
inv.setItem(5,StackUtil.iconHide("§c十万年魂卡槽"));
inv.setItem(6,StackUtil.iconHide("§r"));
inv.setItem(5,StackUtil.iconHide("§c异变魂卡槽"));
inv.setItem(6,StackUtil.iconHide("§c十万年魂卡槽"));
inv.setItem(7,StackUtil.iconHide("§r"));
// 设置已穿戴的魂卡
HashMap<Integer, ItemStack> stackHashMap = playerData.itemStackHashMap;
@ -86,7 +86,9 @@ public class CardGui implements Listener {
// 判断点击的物品是否是卡牌槽
if(rawSlot == 1 || rawSlot == 2 || rawSlot == 3 ||
rawSlot == 4 || rawSlot == 5 || rawSlot == 6 || rawSlot == 7){
if(DemonAPI.itemIsNull(click))return;
if(DemonAPI.itemIsNull(click)) {
return;
}
DataManager dataManager = AuCardBackpack.getDataManager();
PlayerData playerData = dataManager.getPlayerData(playerName);
// 若点击此处并非空白则将物品返还给玩家
@ -105,7 +107,7 @@ public class CardGui implements Listener {
// 获取鼠标上的物品
ItemStack cursor = e.getCursor();
if(!DemonAPI.itemIsNull(cursor)){
NBTItem nbtItem = new NBTItem(cursor);
NbtItem nbtItem = new NbtItem(cursor);
if(nbtItem.hasKey("hunkaKey")){
String hunkaKey = nbtItem.getString("hunkaKey");
if(playerData.isCardYearsExit(hunkaKey)){
@ -138,7 +140,7 @@ public class CardGui implements Listener {
for (int i : new int[]{0,1,2,3,4,5,6,7}){
ItemStack stack = inventory.getItem(i);
if(!DemonAPI.itemIsNull(stack)){
NBTItem nbtItem = new NBTItem(stack);
NbtItem nbtItem = new NbtItem(stack);
if(nbtItem.hasKey("hunkaKey")){
ItemMeta meta = stack.getItemMeta();
List<String> lore = meta.getLore();

View File

@ -6,9 +6,9 @@ import com.yaohun.cardbackpack.data.CardData;
import com.yaohun.cardbackpack.data.PlayerData;
import com.yaohun.cardbackpack.manage.DataManager;
import com.yaohun.cardbackpack.util.StackUtil;
import de.tr7zw.itemnbtapi.NBTItem;
import me.Demon.DemonPlugin.DemonAPI;
import me.Demon.DemonPlugin.Util.CDTimeAPI;
import me.Demon.DemonPlugin.data.NbtItem;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Sound;
@ -59,7 +59,7 @@ public class ConfirmGui implements Listener {
}
if(rawSlot == 6){
ItemStack item = e.getCurrentItem();
NBTItem nbtItem = new NBTItem(item);
NbtItem nbtItem = new NbtItem(item);
if(nbtItem.hasKey("hunka")){
String hunkaKey = nbtItem.getString("hunka");
CardData cardData = AuCardBackpack.getDataManager().getCardData(hunkaKey);

View File

@ -1,16 +1,18 @@
package com.yaohun.cardbackpack.listener;
import com.io.yaohun.itemlibrary.api.ItemKuAPI;
import com.yaohun.cardbackpack.util.RandomUtil;
import me.Demon.DemonMmKillsDrop.data.DropLogsData;
import me.Demon.DemonMmKillsDrop.manage.LogsManager;
import me.Demon.DemonMmKillsStats.Event.KillsMobsStatsEvent;
import com.yaohun.cardbackpack.AuCardBackpack;
import com.yaohun.cardbackpack.manage.CacheManager;
import com.yaohun.morespace.api.SpaceAPI;
import io.lumine.xikage.mythicmobs.api.bukkit.events.MythicMobDeathEvent;
import me.Demon.DemonPlugin.DemonAPI;
import me.Demon.DemonPlugin.Util.AreaType;
import me.Demon.DemonPlugin.Util.RandomUtil;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.serverct.ersha.jd.Ha;
import java.util.HashMap;
@ -34,40 +36,66 @@ public class KillMobsListener implements Listener {
}
@EventHandler
public void onkills(KillsMobsStatsEvent e) {
Player player = e.getPlayer();
String mobType = e.getMob_type();
double luckyValue = getLuckyValue(mobType);
double randomChance = RandomUtil.getRandomDouble(0.1D,300.0D,2);
if(luckyValue > randomChance) {
ItemStack stack = getCardStack(mobType);
if(!DemonAPI.itemIsNull(stack)) {
player.getInventory().addItem(stack);
public void onkills(MythicMobDeathEvent e) {
if(!(e.getKiller() instanceof Player)){
return;
}
mobLuckyValue.put(mobType,0.0D); // 清空幸运值
} else {
addLuckyValue(mobType, RandomUtil.getRandomDouble(0.1,1.0,1));
Player player = (Player) e.getKiller();
Entity entity = e.getEntity();
if(entity.getCustomName() == null){
return;
}
}
public ItemStack getCardStack(String mobsType) {
String customName = entity.getCustomName();
String itemKey = null;
if(mobsType.contains("百年")){
itemKey = "百年魂卡";
}else if(mobsType.contains("千年")){
itemKey = "千年魂卡";
}else if(mobsType.contains("万年")){
itemKey = "万年魂卡";
}else if(mobsType.contains("十年")){
itemKey = "十年魂卡";
if(customName.contains("十年靈獸") || customName.contains("十年灵兽")){
itemKey = "十年魂卡鉴定卡";
}else if(customName.contains("百年靈獸") || customName.contains("百年灵兽")){
itemKey = "百年魂卡鉴定卡";
}else if(customName.contains("千年靈獸") || customName.contains("千年灵兽")){
itemKey = "百年魂卡鉴定卡";
}else if(customName.contains("萬年靈獸") || customName.contains("万年灵兽")){
if(RandomUtil.getRandomDouble(0,100,1) >= 95) {
itemKey = "万年魂卡鉴定卡";
}
if(itemKey != null) {
LogsManager logsManager = me.Demon.DemonMmKillsDrop.Main.getDataManager().getLogsManager();
DropLogsData dropLogsData = logsManager.addDropLogsDataMap(mobsType);
dropLogsData.addDropKeyAmount(itemKey);
return ItemKuAPI.getItemSystemNoLog(itemKey);
}else if(customName.contains("異變靈獸") || customName.contains("异变灵兽")){
if(RandomUtil.getRandomDouble(0,100,1) >= 95) {
itemKey = "异变魂卡鉴定卡";
}
}
if (itemKey == null) {
return;
}
double luckyValue = getLuckyValue(itemKey);
CacheManager cacheManager = AuCardBackpack.getCacheManager();
int dropAmount = cacheManager.getDropData(player.getName(), itemKey);
double randomChance = cacheManager.getRandomChance(player.getName(),itemKey);
if(luckyValue > randomChance) {
ItemStack stack = ItemKuAPI.getItemSystemNoLog(itemKey);
if(stack == null){return;}
String itemName = DemonAPI.getItemName(stack);
mobLuckyValue.put(itemKey,0.0D); // 清空幸运值
if(!DemonAPI.itemIsNull(stack)) {
if(SpaceAPI.hasDetectSlotExit(player)){
if(SpaceAPI.isItemStackWhitelistExit(player,stack)){
if(SpaceAPI.isMoreSpaceCapacity(player,stack)){
SpaceAPI.addMoreSpaceItemStack(player,stack);
if(DemonAPI.getAreaType() == AreaType.DEFAULT) {
DemonAPI.sendTitle(player, 0, 20, 10, "", "§a+ §e" + itemName + " §7X §a" + stack.getAmount() + " §8(空间魂导器)");
} else {
return null;
DemonAPI.sendTitle(player, 0, 20, 10, "", "§a+ §e" + itemName + " §7X §a" + stack.getAmount() + " §8(空間魂導器)");
}
return;
}
}
}
player.getInventory().addItem(stack);
DemonAPI.sendTitle(player, 0, 20, 10, "", "§a+ §e" + itemName + " §7X §a" + stack.getAmount());
}
} else {
// 当数量大于128后将不会增加幸运值
if(dropAmount < 128) {
addLuckyValue(itemKey, RandomUtil.getRandomDouble(0.1, 1.0, 1));
}
}
}
}

View File

@ -1,15 +1,25 @@
package com.yaohun.cardbackpack.listener;
import com.yaohun.cardbackpack.AuCardBackpack;
import com.yaohun.cardbackpack.data.PlayerData;
import com.yaohun.cardbackpack.gui.CardGui;
import de.tr7zw.itemnbtapi.NBTItem;
import com.yaohun.cardbackpack.manage.DataManager;
import me.Demon.DemonPlugin.DemonAPI;
import me.Demon.DemonPlugin.data.NbtItem;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.scheduler.BukkitRunnable;
import org.serverct.ersha.jd.AttributeAPI;
import java.util.ArrayList;
import java.util.List;
public class PlayerListener implements Listener {
@ -21,7 +31,7 @@ public class PlayerListener implements Listener {
if(action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK){
ItemStack stack = player.getInventory().getItemInMainHand();
if (!DemonAPI.itemIsNull(stack) && !DemonAPI.itemIsLore(stack)) {
NBTItem nbtItem = new NBTItem(stack);
NbtItem nbtItem = new NbtItem(stack);
if (nbtItem.hasKey("hunkaKey")) {
CardGui.OpenGui(player);
}
@ -29,4 +39,41 @@ public class PlayerListener implements Listener {
}
}
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
String playerName = player.getName();
DataManager dataManager = AuCardBackpack.getDataManager();
new BukkitRunnable() {
@Override
public void run() {
PlayerData playerData = dataManager.getPlayerData(playerName);
String attSource = "cardAttribute";
AttributeAPI.deleteAttribute(player,attSource);
List<String> statsList = new ArrayList<>();
List<ItemStack> stackList = new ArrayList<>(playerData.itemStackHashMap.values());
for (ItemStack stack : stackList) {
if(!DemonAPI.itemIsNull(stack)){
NbtItem nbtItem = new NbtItem(stack);
if(nbtItem.hasKey("hunkaKey")){
ItemMeta meta = stack.getItemMeta();
List<String> lore = meta.getLore();
for (int l = 0; l < lore.size(); l++) {
String s = lore.get(l);
if(s.contains("") || s.contains("") || s.contains("")){
statsList.add(s);
}
}
}
}
}
if(!statsList.isEmpty()) {
AttributeAPI.addAttribute(player, attSource, statsList);
System.out.println("[魂卡 - 进入] " + playerName + " 的魂卡<" + stackList.size() + "张>属性已加载.");
}
}
}.runTaskLater(AuCardBackpack.inst(),50L);
}
}

View File

@ -0,0 +1,46 @@
package com.yaohun.cardbackpack.manage;
import me.Demon.DemonPlugin.Util.RandomUtil;
import java.util.HashMap;
public class CacheManager {
private HashMap<String,HashMap<String,Integer>> dropStatisticsMap = new HashMap<>();
public HashMap<String ,Integer> dropDataMap(String playerName){
if(!dropStatisticsMap.containsKey(playerName)){
dropStatisticsMap.put(playerName,new HashMap<>());
}
return dropStatisticsMap.get(playerName);
}
public int getDropData(String playerName,String mmType){
HashMap<String,Integer> integerHashMap = dropDataMap(playerName);
if(!integerHashMap.containsKey(mmType)){
integerHashMap.put(mmType,0);
dropStatisticsMap.put(mmType,integerHashMap);
}
return integerHashMap.get(mmType);
}
public double getRandomChance(String playerName,String mmType){
// 获取玩家的今日已累计掉落
int dropData = getDropData(playerName,mmType);
// 当掉落数量大于64时掉率 -50%
// 当掉落数量大于128时掉率 -50%
// 当掉落数量大于192时掉率 -50%
double randomMax = 300.0D;
if(dropData > 128){
randomMax = 2050.0D;
} else if(dropData > 64){
randomMax = 1350.0D;
} else if(dropData > 32){
randomMax = 900.0D;
}
return RandomUtil.getRandomDouble(0.1D,randomMax,2);
}
}

View File

@ -16,7 +16,6 @@ public class DataManager {
private HashMap<String, CardData> cardDataMap = new HashMap<>();
private HashMap<String, PlayerData> playerDataMap = new HashMap<>();
public DataManager(){
loadCardData();
}

View File

@ -1,49 +0,0 @@
package com.yaohun.cardbackpack.util;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.Random;
public class RandomUtil {
public static boolean random(double d) {
return d >= new Random().nextFloat();
}
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;
}
public static Location getRandomLocation(World world, double minX, double maxX, double minY, double maxY, double minZ, double maxZ) {
double rx = getRandomDouble(minX, maxX, 3);
double ry = getRandomDouble(minY, maxY, 3);
double rz = getRandomDouble(minZ, maxZ, 3);
return new Location(world, rx, ry, rz);
}
public static Location getRandomLocation(Player zhubo, World world, double minX, double maxX, double minY, double maxY, double minZ, double maxZ) {
Location location = zhubo.getLocation().add(getRandomInt(-3,3),0,getRandomInt(-3,3));
for (int i = 0; i < 10;i++) {
Location loc = new Location(world, getRandomDouble(minX, maxX, 3), getRandomDouble(minY, maxY, 3), getRandomDouble(minZ, maxZ, 3));
if (loc.distance(zhubo.getLocation()) <= 50) {
location = loc;
break;
}
}
return location;
}
}

View File

@ -4,8 +4,8 @@ import com.yaohun.cardbackpack.AuCardBackpack;
import com.yaohun.cardbackpack.config.Config;
import com.yaohun.cardbackpack.data.CardData;
import com.yaohun.cardbackpack.manage.DataManager;
import de.tr7zw.itemnbtapi.NBTItem;
import me.Demon.DemonPlugin.DemonAPI;
import me.Demon.DemonPlugin.data.NbtItem;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@ -20,7 +20,7 @@ public class StackUtil {
ItemMeta meta = stack.getItemMeta();
meta.setDisplayName(name);
stack.setItemMeta(meta);
NBTItem nbtItem = new NBTItem(stack);
NbtItem nbtItem = new NbtItem(stack);
nbtItem.setString("icon","hide");
nbtItem.setString("stex","icon_air");
return nbtItem.getItem();
@ -42,7 +42,7 @@ public class StackUtil {
}
meta.setLore(lore);
stack.setItemMeta(meta);
NBTItem nbtItem = new NBTItem(stack);
NbtItem nbtItem = new NbtItem(stack);
nbtItem.setString("hunka",cardData.getCardKey());
return nbtItem.getItem();
}

View File

@ -1,6 +1,6 @@
name: AuCardBackpack
main: com.yaohun.cardbackpack.AuCardBackpack
version: 1.0.0
version: 1.1.6
depend:
- DemonAPI
- DemonMmKillsStats