반응형
SMALL

 

 

이전 강의

https://syntaxack.tistory.com/entry/%EB%A7%88%EC%9D%B8%ED%81%AC%EB%9E%98%ED%94%84%ED%8A%B8%ED%94%8C%EB%9F%AC%EA%B7%B8%EC%9D%B82%EA%B0%95

 

마인크래프트 플러그인 강좌 2강 - 커스텀 커맨드 구현

이전 강의https://syntaxack.tistory.com/entry/%EB%A7%88%EC%9D%B8%ED%81%AC%EB%9E%98%ED%94%84%ED%8A%B8%ED%94%8C%EB%9F%AC%EA%B7%B8%EC%9D%B81%EA%B0%95 마인크래프트 플러그인 강좌 1강 - 첫 플러그인 만들기이전 강의https://syntaxack.ti

syntaxack.tistory.com

아직 2강을 보지 않으신 분들은 2강을 보고 오시는 것을 추천드립니다!

 

커스텀 인벤토리

하이픽셀같은 서버를 들어가보면 인벤토리가 사뭇 다른 것을 확인하실 수 있을텐데요, 오늘은 그것을 한 번 구현해 봅시다.

 

① 코드 작성 준비하기

2강 때 만든 MyCommand 클래스에서 진행하도록 하겠습니다.

 

② 코드 작성하기

1. 인벤토리 열기 함수 구현하기

커스텀 인벤토리를 만들어보겠습니다.

package org.blog.pluginExample;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;

public class MyCommand implements CommandExecutor {

    @Override
    public boolean onCommand(@NotNull CommandSender sender, Command cmd, @NotNull String label, String[] args) {
        if(cmd.getName().equalsIgnoreCase("test")) {
            if(sender instanceof Player) {
                sender.sendMessage("플러그인 작동");
                return false;
            }
            sender.sendMessage("========================" + "\r  \n"
                    + "                콘솔창에서 입력되었습니다." + "\r\n"
                    + "                플레이어가 치시기 바랍니다." + "\r\n"
                    + "                 ========================");
            return false;
        }

        if(cmd.getName().equals("openInventory"))
        {
            if (sender instanceof Player) {
                Player player = (Player) sender;
                openCustomInventory(player);
                return true;
            }
            return false;
        }

        return true;
    }
/////////////////////////////////////////////////////////////////////여기가 추가할 코드
    public void openCustomInventory(Player player)
    {
        Inventory customInventory = Bukkit.createInventory(null, 9, "Custom Inventory");

        ItemStack diamondSword = new ItemStack(Material.DIAMOND_SWORD, 1);
        ItemMeta meta = diamondSword.getItemMeta();
        if(meta != null)
        {
            meta.setDisplayName("Special Diamond Sword");
            diamondSword.setItemMeta(meta);
        }

        customInventory.setItem(8, diamondSword);

        player.openInventory(customInventory);
    }
////////////////////////////////////////////////////////////////////
}

여기서는 커스텀 인벤토리를 열었을 때 9x1 크기의 인벤토리에서 9번 슬롯에 다이아몬드 칼을 두는 코드입니다.

<코드 설명>

1. public void openCustomInventory(Player player)

이 코드는 메서드(함수)를 선언하는 코드입니다. public은 다른 클래스에서도 호출할 수 있도록 접근을 허용합니다. void는 함수가 반환하는 값이 없다라는 뜻이고, openCustomInventory는 함수의 이름입니다. (Player player)은 커스텀 인벤토리를 열 대상 플레이어 객체입니다.

 

2. Inventory customInventory = Bukkit.createInventory(null, 9, "Custom Inventory");

이 코드는 인벤토리를 생성하는 코드입니다. Bukkit.createInventory는 Bukkit API를 사용하여 새로운 인벤토리를 생성합니다. null은 인벤토리의 소유자가 없다는 뜻이므로 모두가 이 인벤토리를 열 수 있다는 뜻이고, 9는 인벤토리 크기를 말합니다. 크기는 항상 9의 배수여야 합니다. 여기서는 9칸짜리 인벤토리를 만듭니다. "Custom  Inventory"는 인벤토리의 이름입니다. 플레이어가 인벤토리를 열 때 이름이 상단에 표시됩니다.

 

3. ItemStack diamondSword = new ItemStack(Material.DIAMOND_SWORD, 1);

이 코드는 다이아몬드 검을 생성합니다. ItemStack은 마인크래프트 아이템을 나타내는 객체입니다. Material.DIAMOND_SWORD는 다이아몬드 검을 의미하고, 1은 아이템 수량을 의미합니다. diamondSword는 변수 이름인 것을 이제는 아시겠죠?

 

4. ItemMeta meta = diamondSword.getItemMeta();

ItemMeta는 아이템의 메타데이터(이름, 설명, 특수 속성)을 의미합니다. diamonSword.getItemMeta()는 생성된 다이아몬드 검에서 메타데이터를 가져옵니다.

 

5. if(meta != null)

메타데이터가 null인지 확입니다. 어떤 아이템은 메타데이터를 가질 수 없으므로 이를 체크합니다.

 

6. meta.setDisplayName("Special Diamond Sword");

setDisplayName은 아이템의 이름을 설정합니다. 플레이어는 Special Diamond Sword라는 이름의 검을 볼 수 있을 것입니다.

 

7. diamondSword.setItemMeta(meta);

수정된 메타데이터를 다이아몬드 검에 다시 적용합니다.

 

8. customInventory.setItem(8, diamondSword);

customInventory.setItem은 특정 슬롯에 아이템을 배치합니다. 8은 슬롯 번호입니다. diamondSword는 위에서 생성한 다이아몬드 검 아이템입니다.(Special Diamond Sword 라는 이름을 가진)

 

9. player.openInventory(customInventory);

player.openInventory는 플레이어가 지정된 인벤토리를 열도록 합니다. customInventory는 위에서 만든 커스텀 인벤토리겠죠?

 

 

③ 커맨드 지정하기

2강에서 커스텀 커맨드를 만든 것처럼 "/openInventory"를 하면 커스텀 인벤토리가 열리게 해보겠습니다.

@Override
    public boolean onCommand(@NotNull CommandSender sender, Command cmd, @NotNull String label, String[] args) {
        if(cmd.getName().equalsIgnoreCase("test")) {
            if(sender instanceof Player) {
                sender.sendMessage("플러그인 작동");
                return false;
            }
            sender.sendMessage("========================" + "\r  \n"
                    + "                콘솔창에서 입력되었습니다." + "\r\n"
                    + "                플레이어가 치시기 바랍니다." + "\r\n"
                    + "                 ========================");
            return false;
        }
		//////////////////////////////////////////////////////추가할 코드
        if(cmd.getName().equals("openInventory"))
        {
            if (sender instanceof Player) {
                Player player = (Player) sender;
                openCustomInventory(player);
                return true;
            }
            return false;
        }
		///////////////////////////////////////////////////////
        return true;
    }

2강에서 했던 것처럼 openInventory라는 명령어를 등록했습니다. 이때 플레이어가 명령어를 입력하면 openCustomInventory(player)을 하여 플레이어가 커스텀 인벤토리를 열도록 하였고, 다른 명령주체(서버, 커맨드블록)에서 명령어를 실행하면 return false를 합니다.

 

이제 메인 클래스인 pluginExample.class에 명령어를 등록해주어야 합니다.

package org.blog.pluginExample;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.Objects;

public final class PluginExample extends JavaPlugin {

    @Override
    public void onEnable() {
        // Plugin startup logic
        getLogger().info("플러그인이 활성화되었습니다.");
        Objects.requireNonNull(this.getCommand("test")).setExecutor(new MyCommand());
        //////////////////////////////////////////////////////추가할 코드
        Objects.requireNonNull(this.getCommand("openInventory")).setExecutor(new MyCommand());
    	///////////////////////////////////////////////////////////////////////////
    }

    @Override
    public void onDisable() {
        // Plugin shutdown logic
        getLogger().info("플러그인이 비활성화되었습니다.");
    }



}
Objects.requireNonNull(this.getCommand("openInventory")).setExecutor(new MyCommand());

이 코드는 2강에서 설명한 것과 동일합니다.

④ plugin.yml 작성하기

다음으로는 plugin.yml을 작성해야합니다. 이 부분도 2강에서 했던 것과 같은 방식으로 진행합니다.

 

name: pluginExample
version: '1.0-SNAPSHOT'
main: org.blog.pluginExample.PluginExample
api-version: '1.21'
authors: [ Gloomn ]
description: Example Plugin
commands:
  test:
    description: "플러그인의 작동 여부를 알려줍니다."
    usage: /test
  openInventory:
    description: "커스텀 인벤토리 작동"
    usage: /openInventory

 

openInventory 부분을 추가해주었습니다. 

 

⑤ 테스트하기

다 작성하셨으면 gradle로 가셔서 jar 빌드를 해주세요.

그 다음 서버랑 마인크래프트를 실행하셔서 직접 테스트해보세요.

 

정상적으로 작동되는 것을 확인할 수 있습니다.

 

마무리

오늘은 커스텀 인벤토리를 만들어보았고, 추가로 아이템까지 넣어보았습니다. 궁금한 점이 있으시면 댓글 달아주시고, 성심성의껏 답변해드리겠습니다. 하트랑 구독도 눌러주시면 감사하겠습니다!

반응형
LIST