跳到主要内容

4CustomInventory自定义物品栏

我们需要完成的功能如下:

  1. 用户输入/open,给玩家一个9个格子的物品栏,物品栏用户可以自己放置物品
  2. 用户输入/award,给玩家赠送一个附魔的羽毛,但是不可以被取走
  3. 输入/award xxx 给玩家xxx赠送一个附魔的羽毛,但是不可以被取走

配置指令:

commands:
open:
description: 打开一个玩家拥有的自定义物品栏
usage: /<command>
award:
description: 给玩家奖励
usage: /<command> [player-name]

open指令事件:

/**
* @author houyunfei
*/
public class OpenExecutor implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if ("open".equalsIgnoreCase(label)) {
if (sender instanceof Player) {
Player player = (Player) sender;
Inventory inventory = GlobalInventory.getInventory(player.getName());
if (inventory == null) {
inventory = Bukkit.createInventory(player, 9, player.getName() + "的私人背包");
GlobalInventory.addToInventories(player.getName(), inventory);
}
player.openInventory(inventory);
return true;
}
}

return false;
}
}

award指令事件:

/**
* @author houyunfei
*/
public class AwardExecutor implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if ("award".equalsIgnoreCase(label)) {
// 分两种情况,arg.length==0 也就是 /award 此时给自己发奖励 并且自己必须是玩家
if (args.length == 0 && sender instanceof Player) {
Player player = (Player) sender;
// 先获取玩家的背包
Inventory inventory = GlobalInventory.getInventory(player.getName());
if (inventory == null) {
inventory = Bukkit.createInventory(null, 9, player.getName() + "的私人背包");
GlobalInventory.addToInventories(player.getName(), inventory);
}
// 添加奖励物品
if (award(player.getName(), inventory)) {
player.sendMessage(ChatColor.GREEN + "奖励发放成功");
} else {
player.sendMessage(ChatColor.RED + "奖励发放失败");
}
return true;

} else if (args.length == 1) {
Player player = (Player) sender;
// 先获取玩家的背包
Inventory inventory = GlobalInventory.getInventory(args[0]);
if (inventory == null) {
inventory = Bukkit.createInventory(null, 9, args[0] + "的私人背包");
GlobalInventory.addToInventories(args[0] , inventory);
}
// 添加奖励物品
if (award(args[0], inventory)) {
player.sendMessage(ChatColor.GREEN + "奖励发放成功");
} else {
player.sendMessage(ChatColor.RED + "奖励发放失败");
}
return true;

}
}

return false;
}

/**
* 向玩家发放奖励
*
* @param name
* @param inventory
*/
private boolean award(String name, Inventory inventory) {
int index = inventory.firstEmpty();
if (index != -1) {
// 找到空的槽位
ItemStack stack = new ItemStack(Material.FEATHER, 1);
// 先有槽,然后有物品
ItemMeta item = stack.getItemMeta();
// 修改物品的展示名称,lores,附魔
item.setDisplayName(ChatColor.RED + "小鸡毛");
List<String> lores = new ArrayList<>();
lores.add(ChatColor.GREEN + "这是第一行");
lores.add(ChatColor.GREEN + "这是第二行");
lores.add(ChatColor.GREEN + "这是第三行");
item.setLore(lores);

// 添加附魔
item.addEnchant(Enchantment.LUCK_OF_THE_SEA, 1, true);

// 将物品和槽位绑定
stack.setItemMeta(item);
inventory.setItem(index, stack);
return true;
}
return false;
}
}

监听玩家拿走物品(羽毛)的事件:

/**
* @author houyunfei
*/
public class OnTakeAwardFromRemoteChestListener implements Listener {
@EventHandler
public void onTakeAwardFromRemoteChest(InventoryClickEvent event) {
// 当前的物品栏
Inventory currentInv = event.getInventory();
// 点击者,只能是玩家
HumanEntity player = event.getWhoClicked();

// 判断是不是远程的自定义箱子
Inventory remoteInv = GlobalInventory.getInventory(player.getName());
if (remoteInv == null) {
return;
}
if (remoteInv == currentInv) {
// 两者是同一对象
ItemStack clickedStack = event.getCurrentItem();
// 获取stack槽的信息,对比
if (clickedStack == null) {
return;
}
if (clickedStack.getType() == Material.FEATHER &&
(ChatColor.RED + "小鸡毛").equals(clickedStack.getItemMeta().getDisplayName())) {
// 是同一物品 ,则取消点击事件
event.setCancelled(true);
player.sendMessage(ChatColor.RED + "你不能拿走这个物品");
}

}
}
}

在主类中注册:

getCommand("open").setExecutor(new OpenExecutor());
getCommand("award").setExecutor(new AwardExecutor());
Bukkit.getPluginManager().registerEvents(new OnTakeAwardFromRemoteChestListener(), this);

测试结果:

  • 输入/open可以打开背包
  • 输入/award 可以给自己一个羽毛
  • 输入/award xxx 可以给xxx一个羽毛

image-20240909203530500