Skip to content

이벤트

Daybreak edited this page Oct 15, 2020 · 1 revision

이벤트

이번에는 Bukkit의 Event를 수신하여 다뤄보겠습니다.
기본적으로 Bukkit-API를 다뤄봤던 분이라면, Listener interface@EventHandler 어노테이션은 자주 사용해보셨겠죠.
Listener는 서버의 다양한 이벤트 (플레이어가 접속함, 엔티티가 대미지를 입음 등) 를 객체로 전달받아 어떠한 작업을 수행하기 위해 사용됩니다.
능력에서의 이벤트 수신은 매우 간단합니다.

Event를 상속받는 타입의 객체를 유일한 매개변수로 갖는 메소드를 만들어, @SubscribeEvent 어노테이션을 붙여주면 됩니다.
잘 이해가 되지 않는다면 아래의 코드를 참고하세요.

@SubscribeEvent
private void onPlayerDropItem(final PlayerDropItemEvent e) {
	e.getPlayer().sendMessage("아이템을 버렸습니다!");
}

@SubscribeEvent 어노테이션은 변경할 수 있는 다양한 속성이 있습니다.
지금부터 그 속성들에 대해서 알아보도록 하겠습니다.


onlyRelevant

이벤트가 이 능력과 관련이 있는 경우에만 이벤트를 수신하고 싶을 때 사용합니다.
이 속성 없이도 아래와 같이 수신 이벤트를 제한할 수 있습니다.

@SubscribeEvent
private void onPlayerDropItem(final PlayerDropItemEvent e) {
	if (this.getPlayer().equals(e.getPlayer()) {
		e.getPlayer().sendMessage("아이템을 버렸습니다!");
	}
}

이 속성을 이용하면, 더욱 간결한 코드로 목적을 달성할 수 있습니다.

@SubscribeEvent(onlyRelevant = true)
private void onPlayerDropItem(final PlayerDropItemEvent e) {
	e.getPlayer().sendMessage("아이템을 버렸습니다!");
}

onlyRelevant 속성을 이용했을 때 해당 이벤트가 이 능력과 관련이 있는지 판단하는 방법은 다음과 같습니다. (편의를 위해 '이 능력'을 this로 작성.)
AbilityEvent를 확장하는 경우: event.getAbility()this 와 동일한가?
ParticipantEvent를 확장하는 경우: event.getParticipant()this.getParticipant() 와 동일한가?
PlayerEvent를 확장하는 경우: event.getPlayer()this.getPlayer() 와 동일한가?
EntityEvent를 확장하는 경우: event.getEntity()this.getPlayer() 와 동일한가?


ignoreCancelled

이미 캔슬된 이벤트를 수신하고 싶지 않을 때 사용합니다.
이 속성 없이도 아래와 같이 수신 이벤트를 제한할 수 있습니다.

@SubscribeEvent
private void onPlayerDropItem(final PlayerDropItemEvent e) {
	if (!e.isCancelled()) {
		e.getPlayer().sendMessage("아이템을 버렸습니다!");
	}
}

이 속성을 이용하면, 더욱 간결한 코드로 목적을 달성할 수 있습니다.

@SubscribeEvent(ignoreCancelled = true)
private void onPlayerDropItem(final PlayerDropItemEvent e) {
	e.getPlayer().sendMessage("아이템을 버렸습니다!");
}



priority

이벤트 발생시 이벤트 수신 우선순위를 설정하기 위해 사용됩니다.
우선순위가 높을수록 나중에 호출되며, 나중에 호출되기 때문에 호출 이전에 다른 핸들러에서 변경된
내용을 처리하고, 덮어씌울 수 있습니다. 예시는 아래 코드를 참고하세요.

// 나에게 들어오는 엔티티 공격 대미지 모두 취소하기
@SubscribeEvent(onlyRelevant = true, priority = 5)
private void onEntityDamageByEntity(final EntityDamageByEntityEvent e) {
	e.setCancelled(true);
	e.getPlayer().sendMessage("대미지를 취소했습니다.");
}
Clone this wiki locally