*이 글은 Spigot 1.19.2 버전을 기준으로 하여 제작되었습니다.
지난 화
https://zepelown.tistory.com/44
이전 화에서 유저가 인벤토리의 아이템을 마음대로 가져갈 수 있었습니다.
이 문제를 해결하기 위해 InventoryClickEvent 를 사용할 겁니다.
https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/inventory/InventoryClickEvent.html
InvClickEvent.java
package io.github.zepelown.testplugin.event;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
public class InvClickEvent implements Listener {
@EventHandler
public void onClick(InventoryClickEvent e){
if(e.getClickedInventory() == null)
return;
if(ChatColor.stripColor(e.getView().getTitle()).equalsIgnoreCase("TESTGUI")){
e.setCancelled(true);
Player player = (Player) e.getWhoClicked();
player.sendMessage("인벤토리 클릭이 취소되었습니다.");
}
}
}
TestPlugin.java
package io.github.zepelown.testplugin;
import io.github.zepelown.testplugin.commands.GiveDia;
import io.github.zepelown.testplugin.commands.Help;
import io.github.zepelown.testplugin.commands.OpenInv;
import io.github.zepelown.testplugin.event.BreakEvent;
import io.github.zepelown.testplugin.event.InvClickEvent;
import org.bukkit.plugin.java.JavaPlugin;
public final class TestPlugin extends JavaPlugin {
@Override
public void onEnable() {
// Plugin startup logic
getLogger().info("플러그인 활성화");
getServer().getPluginManager().registerEvents(new BreakEvent(), this);
getServer().getPluginManager().registerEvents(new InvClickEvent(), this);
getServer().getPluginCommand("thelp").setExecutor(new Help());
getServer().getPluginCommand("tgivedia").setExecutor(new GiveDia());
getServer().getPluginCommand("topeninv").setExecutor(new OpenInv());
}
@Override
public void onDisable() {
// Plugin shutdown logic
getLogger().info("플러그인 비활성화");
}
}
이전 강좌에서 BlockBreakEvent를 사용한 것과 비슷한 맥락입니다.
먼저 onClick 매서드 내 첫 줄은 어떤 플레이어가 인벤토리를 클릭했을 때 그 값이 null, 즉 마크 내 기본 인벤토리 일 경우
이벤트를 즉시 종료하게 합니다.
쉽게 말해 창고나 플레이어 인벤토리일 경우 종료 시키는 겁니다.
저희는 새로 만든 TestGUI만 통과 시킬 것이기 때문에 필요가 없습니다.
if(ChatColor.stripColor(e.getView().getTitle()).equalsIgnoreCase("TESTGUI")){
e.setCancelled(true);
Player player = (Player) e.getWhoClicked();
player.sendMessage("인벤토리 클릭이 취소되었습니다.");
}
조금 복잡해 보이실 수도 있습니다만 쉽습니다.
조건문은 만약 인벤토리 클릭 이벤트가 발생했을 경우 그 인벤토리의 이름(타이틀)의 색깔을 지우고
"TESTGUI"와 소문자 대문자 구분 없이 일치하는지를 확인하는 겁니다.
여기서 만약 인벤토리 이름에 색깔을 부여했다면 값이 같다고 리턴하지 않기 때문에
색깔을 지워주셔야합니다.
그리고 e.setCancelled(true)를 통해 그 클릭 이벤트를 취소하고
인벤토리를 누른 플레이어의 정보를 가져와 메시지를 전달하는 겁니다.
이대로 실행하면 위와 같이 작동합니다.
간단한 gui도 구현했으니 기능을 추가해보고 꾸며보겠습니다.
먼저 다이아를 눌렀을 때 그 다이아를 유저에 주는 걸 추가해보겠습니다.
InvClickEvent.java
package io.github.zepelown.testplugin.event;
import io.github.zepelown.testplugin.ItemManager;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
public class InvClickEvent implements Listener {
@EventHandler
public void onClick(InventoryClickEvent e){
if(e.getClickedInventory() == null)
return;
if(ChatColor.stripColor(e.getView().getTitle()).equalsIgnoreCase("TESTGUI")){
e.setCancelled(true);
if(e.getCurrentItem() == null)
return;
else if(e.getCurrentItem().isSimilar(ItemManager.dia)){
Player player = (Player) e.getWhoClicked();
player.getInventory().addItem(ItemManager.dia);
player.sendMessage("다이아가 지급되었습니다.");
player.closeInventory();
}
}
}
}
e.getCurrentItem 을 통해 클릭한 아이템의 정보가 null 즉, 빈칸을 선택한 경우는 함수를 종료시키고
누른 아이템의 ItemStack이 ItemManager의 dia와 유사할 때 (이름, 설명 등을 비교)
플레이어에게 dia를 주고 메시지를 전달 후 인벤토리를 닫습니다.
추가로 인벤토리를 조금 꾸며봤습니다.
ItemManager.java
public static final ItemStack guiGrayGlassPane = buildItem(Material.GRAY_STAINED_GLASS_PANE, 1, ChatColor.GRAY + "빈칸","아이템 설명을 잘 읽어보세요");
아이템을 새로 만들고
TestGUI.java
package io.github.zepelown.testplugin.inventory;
import io.github.zepelown.testplugin.ItemManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
public class TestGUI implements InventoryHolder {
private final Inventory inv;
private void initItemSetting() {
for(int i = 0; i < 9; i++){
if(i==4)
inv.setItem(i,ItemManager.dia);
else
inv.setItem(i,ItemManager.guiGrayGlassPane);
}
}
public TestGUI() {
this.inv = Bukkit.createInventory(null,9,"TESTGUI");
initItemSetting();
}
public void open(Player player){
player.openInventory(inv);
}
@Override
public Inventory getInventory() {
return inv;
}
}
인벤토리를 수정했습니다.
빌드해보겠습니다!
'마인크래프트 > 플러그인 제작 강좌(자바)' 카테고리의 다른 글
[인텔리제이로 마크 플러그인 개발하기]8. 나만의 포션 제작하기 (커스텀 포션) (0) | 2023.01.11 |
---|---|
[인텔리제이로 마크 플러그인 개발하기](보충) Gradle로 jar 빌드하기 (0) | 2023.01.10 |
[인텔리제이로 마크 플러그인 개발하기]6. 나만의 인벤토리 GUI 만들기 1편 (기본적인 인벤토리 작성법) (3) | 2022.09.18 |
[인텔리제이로 마크 플러그인 개발하기]5. 나만의 명령어 만들기 (give, help 명령어 만들어보기) (11) | 2022.09.15 |
[인텔리제이로 마크 플러그인 개발하기]4. 나만의 아이템 제작하기 (ItemStack, ItemMeta에 관하여) (6) | 2022.08.31 |
댓글