

이번 글에서는 아이템에 마우스를 갔다 대었얼 때, 나타나는 툴팁과 아이템에 특정 데이터를 저장해보도록 하자.
툴팁은 위 사진처럼 아이템에 마우스를 갔다대었을 때, 설명이 나타나는 것을 말한다.
툴팁
일단 #2에서 수표아이템을 하나 만들었는데 코드를 좀 수정해주어야 한다.
item 패키지 안에 BIllItem 클래스를 만들어준다.

public class BillItem extends Item {
public BillItem(Properties properties) {
super(properties);
}
@Override
public void appendHoverText(@NotNull ItemStack stack, @NotNull TooltipContext context, List<Component> tooltipComponents, @NotNull TooltipFlag tooltipFlag) {
tooltipComponents.add(Component.translatable("tooltip.lifegame.bill"));
super.appendHoverText(stack, context, tooltipComponents, tooltipFlag);
}
}
appendHoverText
는 아이템 위에 마우스를 갔다 대었을 때, 나타나는 텍스트이다.
#2에서 lang파일에
{
"item.lifegame.bill": "수표"
}
이런 식으로 번역된 내용을 작성한다고 했는데, tooltip.lifegame.bill 키를 만들고 그 값으로 아이템에 대한 설명을 작성하면 된다.
나는 다음과 같이 작성해주었다.
{
"item.lifegame.bill": "수표",
"tooltip.lifegame.bill": "우클릭 하면 액수만큼 돈이 추가됩니다."
}
그리고 ModItems에서 BIllItem 등록 부분을 다음과 같이 수정해준다.
public static final DeferredItem<Item> BILL_ITEM = ITEMS.register("bill",
() -> new BillItem(new Item.Properties().stacksTo(1)));
stackTo는 아이템이 1개씩만 쌓일 수 있다는 것을 나타낸다.
실행시켜서 아이템에 마우스를 갔다 대었을 때, 어떻게 나오나 보자.

위와 같이 아이템 설멍이 잘 나온다.
명령어 색깔을 수정한 것처럼 setStyle을 설정하면 다음과 같이 설명의 색깔은 회색으로 표현할 수도 있다.

아이템 데이터
현재 아이템의 이름이 그냥 수표로 나오는데 저번 글에서는 특정 액수만큼 수표를 뽑았다. 그래서 그냥 수표로 나타낸다면 이 수표가 얼마 짜리 인지 알 수가 없다. 따라서 DataComponent라는 기능으로 아이템에 액수데이터를 추가해야한다.
component란 패키지를 만들고, 안에 BIllDataComponent를 만들어준다.
public class BillDataComponent {
public static final DeferredRegister.DataComponents DATA_COMPONENT_TYPES = DeferredRegister.createDataComponents(Registries.DATA_COMPONENT_TYPE, MODID);
public static final DeferredHolder<DataComponentType<?>, DataComponentType<Integer>> VALUE =
register("value", builder -> builder.persistent(Codec.INT));
private static <T>DeferredHolder<DataComponentType<?>, DataComponentType<T>> register(String name,
UnaryOperator<DataComponentType.Builder<T>> builderOperator) {
return DATA_COMPONENT_TYPES.register(name, () -> builderOperator.apply(DataComponentType.builder()).build());
}
public static void register(IEventBus eventBus) {
DATA_COMPONENT_TYPES.register(eventBus);
}
}
builder.persistent(Codec.INT));
이 부분에는 액수가 숫자이므로 int형식으로 넣는다.
그리고 BillProviderCommand에서
ItemStack BILL = new ItemStack(ModItems.BILL_ITEM.get());
BILL.set(BillDataComponent.VALUE,amount);
player.addItem(BILL);
위 부분처럼 Bill에 BILL.set(BillDataComponent.VALUE,amount);
처럼 액수를 추가하는 부분을 추가하면 된다.
그리고 DataComponent도 등록을 해주어야 사용할 수 있는데, 등록은 메인클래스에
BillDataComponent.*register*(modEventBus);
이 부분을 추가하면 된다.
동적 아이템 이름
“BillItem” 클래스 안에 다음 부분을 추가해주어야한다.
@Override
public @NotNull Component getName(@NotNull ItemStack stack) {
Component translatedName = super.getName(stack);
if(stack.get(BillDataComponent.VALUE) != null) {
String nameWithNumber = "["+translatedName.getString() + "] " + stack.get(BillDataComponent.VALUE);
return Component.literal(nameWithNumber).setStyle(Style.EMPTY.withColor(ChatFormatting.WHITE));
}
return translatedName;
}
DataComponent 로 아이템에 액수를 저장했는데, stack.get(BillDataComponent.VALUE)
로 그 아이템의 액수를 가져온다.
실행해보면 이렇게 액수와 함께 아이템이 추가된다.


우클릭하면 돈이 추가되는 기능
@Override
public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level level, @NotNull Player player, @NotNull InteractionHand usedHand) {
ItemStack stack = player.getItemInHand(usedHand);
if (!level.isClientSide) {
if(stack.get(BillDataComponent.VALUE) != null){
int amount = stack.get(BillDataComponent.VALUE);
PlayerData playerData = new PlayerData();
playerData.addMoney(player, amount);
int MONEY = playerData.getMoney(player);
player.sendSystemMessage(Component.literal("수표 " +stack.get(BillDataComponent.VALUE)+ " 사용, 현재 잔액: " + MONEY));
}
stack.shrink(1);
}
return InteractionResultHolder.success(stack);
}
BillItem에 위 부분을 추가한다 use는 우클릭 useOn은 좌클릭이다. middleClick도 있는데 이건 생각이 안난다.
stack.shrink(1);
는 아이템을 소모시킨다. player.sendSystemMessage
는 아이템을 사용했을 때, 채팅창에 메세지가 나타나게한다.
위 코드를 추가하고 수표를 들고 우클릭을 해보자.


잘 된다.
지금까지 작성한 전체 소스는 깃허브에서 볼 수 있다.
https://github.com/rainbow-server/red-mod