TriggerReactor

TriggerReactor

24.6k Downloads

왼손에 물건 들고 PlayerInteract Event 시 트리거 2번 중복 호출

asheswook opened this issue · 2 comments

commented

Describe the bug/버그 증상

왼손에 물건을 들고 PlayerInteractEvent (org.bukkit.event.player.PlayerInteractEvent) 시 한번만 Interact해도 트리거가 2번 중복 호출됩니다. 아래와 같은 간단한 예제 코드가 있다고 할 때, 수표를 한 개 들고 한 번 우클릭 했음에도 불구하고 트리거가 2번 실행되어 그 금액의 2배에 해당되는 금액이 지급됩니다.

이때 왼손에 들고 있는 물건의 종류가 무엇인가와는 상관없이, 항상 오른손에 들고 있는 물건으로 $helditem이 지정되어 2번 호출됩니다.

item = $helditem
itemName = $helditemdisplayname
IF event.getAction().name() == "RIGHT_CLICK_AIR"
    IF itemName == color("5XP 수표")
        item.setAmount(item.getAmount() -1)
        #MESSAGE "5XP 수표를 사용했습니다."
        player.giveExp(5)
    ENDIF
ENDIF

helditemhelditemdisplayname의 플레이스홀더를 아래와 같이 getItemInHand()가 아닌 getItemInMainHand()로 호출하여 써도 동일 현상이 발생합니다.

function mainhelditem(args) {
    if(player == null)
        return null;

    var item = player.getInventory().getItemInMainHand();
    if(item == null) {
        var ItemStack = Java.type('org.bukkit.inventory.ItemStack')
        var Material = Java.type('org.bukkit.Material')
        return new ItemStack(Material.AIR);
    } else {
        return item;
    }
}

여러 차례 테스트해본 결과 2번만 호출되고 그 이상은 중복 호출되지 않아, 플레이어별 전역 변수를 만들고 아래와 같이 임시조치가 가능했습니다.

playeruuid = player.getUniqueId()
IF {playeruuid + "command.isActive"} == true
    {playeruuid + "command.isActive"} = false
    #STOP
ELSE
    {playeruuid + "command.isActive"} = true
ENDIF

// 트리거 시작
item = $helditem
itemName = $helditemdisplayname
IF event.getAction().name() == "RIGHT_CLICK_AIR"
    IF itemName == color("5XP 수표")
        item.setAmount(item.getAmount() -1)
        #MESSAGE "5XP 수표를 사용했습니다."
        player.giveExp(5)
    ENDIF
ENDIF

// 끝
{playeruuid + "command.isActive"} = false

Server information/서버 정보

  • Paper version git-Paper-169 (MC: 1.20.1) (Implementing API version 1.20.1-R0.1-SNAPSHOT) (Git: b4e3b3d)
  • TriggerReactor 3.4.3-Release
commented

이건 트리거리액터의 문제가 아닌 버킷API의 디자인 문제입니다. PlayerInteractEvent는 왼손과 오른손으로 각각 트리거되어 총 2번 호출됩니다.

따라서 아래와 같이 이벤트가 왼손으로 평가될 지 오른손으로 평가될 지 확인해주어야 합니다.

// 왼손은 무시
IF event.getHand() == "OFF_HAND"
  #STOP
ENDIF

비록 영문이지만 JavaDoc에도 나와있으니 한 번 읽어보시면 도움이 될 겁니다.

commented

그런데 이상한 점이, $helditem$helditemdisplayname을 확인해보면 왼쪽 오른쪽 아이템이 각각 제공되는 것이 아니라, 무조건 오른손에 든 itemStack이 두번 제공됩니다. 위 답변으로 미루어보았을 때 제 생각에는 2번 호출될 떄 오른손 ItemStack과 왼손 ItemStack이 제공돼야 한다고 생각하는데, 혹시 이 부분에 대해 확인을 부탁드려도 될까요?

// 왼손은 무시
IF event.getHand() == "OFF_HAND"
  #STOP
ENDIF

// 트리거 시작
item = $helditem
itemName = $helditemdisplayname
IF event.getAction().name() == "RIGHT_CLICK_AIR"
    IF itemName == color("5XP 수표")
        item.setAmount(item.getAmount() -1)
        #MESSAGE "5XP 수표를 사용했습니다."
        player.giveExp(5)
    ENDIF
ENDIF

해당 코드를 적용해서 보면, 수표를 두 개 들고 한번 우클릭하면 트리거가 2번 실행되어 한번의 우클릭에 두개의 수표가 전부 사용되는 문제가 발생합니다. 이전처럼 한 개 들고 우클릭하면 중복 실행되어 원래 금액의 2배의 해당되는 금액이 지급되지는 않습니다.