Citizens: How do I detect when a player right clicks

Discussion in 'Plugin Development' started by Zombie_Striker, Sep 18, 2017.

Thread Status:
Not open for further replies.
  1. Offline

    Zombie_Striker

    I have tried using Traits, but the NPCClickEvent does not get called. How am I supposed to listen if a player clicks a NPC?
     
  2. Offline

    RcExtract

    PlayerInteractEntityEvent is a good event to handle (I am not familiar with the npc plugins' API so I suggest this method). Handle the event and check whether the entity location contains an npc. If yes, check the equality between entity name and npc name. If true, do something.
     
  3. Offline

    CraftCreeper6

    @Zombie_Striker
    I found this on their API;
    Code:
    // An example event handler. All traits will be registered automatically as Bukkit Listeners.
        @EventHandler
        public void click(net.citizensnpcs.api.event.NPCClickEvent event){
            //Handle a click on a NPC. The event has a getNPC() method.
            //Be sure to check event.getNPC() == this.getNPC() so you only handle clicks on this NPC!
           
        }
         
    
    I presume just swapping out NPCClickEvent with NPCRightClickEvent should do the trick.
     
  4. Offline

    Zombie_Striker

    @RcExtract
    PlayerInteractEntityEvent is only triggered for actual entities, not the 'fake' ones created by Citizens

    @CraftCreeper6
    Tried it, and its other events:
    Code:
        // An example event handler. All traits will be registered automatically as
        // Bukkit Listeners.
        @EventHandler
        public void click(NPCClickEvent event) {
            // Handle a click on a NPC. The event has a getNPC() method.
            // Be sure to check event.getNPC() == this.getNPC() so you only handle
            // clicks on this NPC!
            if(event.getNPC() == this.getNPC()){
                Bukkit.broadcastMessage("test");
            }
        }
        @EventHandler
        public void clickr(NPCRightClickEvent event) {
            if(event.getNPC() == this.getNPC()){
                Bukkit.broadcastMessage("test");
            }
        }
        @EventHandler
        public void clickl(NPCLeftClickEvent event) {
            if(event.getNPC() == this.getNPC()){
                Bukkit.broadcastMessage("test");
            }
        }
    
    The events are not even being called when the trait is added to an npc.
     
  5. Offline

    Horsey

    The PlayerAnimationEvent might be a work-around, otherwise there's always manually listening for the packet.
     
  6. Offline

    CraftCreeper6

    @Zombie_Striker
    I did some more searching around and found that this is quite a common issue. Though it's usually seen with the NPCClickEvent and not the NPCRightClickEvent. Although I don't see a fix. The only potential solution I could find (I've never worked with this API) was moving the event outside of the traits class and registering it by itself.

    Code:
    CitizensAPI.getTraitFactory().registerTrait(net.citizensnpcs.api.trait.TraitInfo.create(LobbyTrait.class).withName("Lobby"));
    I'm unsure if this has any relevance but I guess you could give it a shot.
     
  7. Offline

    Zombie_Striker

    @CraftCreeper6
    Moving it to a new listener class worked for the right click event. Leftclicking or general-clicking still does not work.

    The docs say that Traits are automatically registered, so its strange this it requires its own listener class in order to work.

    I'll leave this thread unsolved in case someone knows a fix for left clicking.
     
  8. Offline

    CraftCreeper6

    @Zombie_Striker
    This GitHub page explains that NPCClickEvent is not meant to be used but instead its subevents, such like NPCRightClickEvent and NPCLeftClickEvent.

    Did you create a different new class for each event, i.e NPCRightClickEventClass.class and NPCLeftClickEventClass.class (Names for convenience of explaining). Or have you combined both the two into a different single class. Such that both events are in the same class but outside of your original traits class.

    I'll keep looking but I'm not sure I'll find much because most of the links lead to something totally irrelevant.

    EDIT: I found this; the code used for the event itself.
    Code:
    @EventHandler
        public void onEntityDamage(EntityDamageEvent event) {
            NPC npc = npcRegistry.getNPC(event.getEntity());
    
            if (npc == null) {
                if (event instanceof EntityDamageByEntityEvent) {
                    npc = npcRegistry.getNPC(((EntityDamageByEntityEvent) event).getDamager());
                    if (npc == null)
                        return;
                    event.setCancelled(!npc.data().get(NPC.DAMAGE_OTHERS_METADATA, true));
                    NPCDamageEntityEvent damageEvent = new NPCDamageEntityEvent(npc, (EntityDamageByEntityEvent) event);
                    Bukkit.getPluginManager().callEvent(damageEvent);
                }
                return;
            }
            event.setCancelled(npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true));
            if (event instanceof EntityDamageByEntityEvent) {
                NPCDamageByEntityEvent damageEvent = new NPCDamageByEntityEvent(npc, (EntityDamageByEntityEvent) event);
                Bukkit.getPluginManager().callEvent(damageEvent);
    
                if (!damageEvent.isCancelled() || !(damageEvent.getDamager() instanceof Player))
                    return;
                Player damager = (Player) damageEvent.getDamager();
    
                NPCLeftClickEvent leftClickEvent = new NPCLeftClickEvent(npc, damager);
                Bukkit.getPluginManager().callEvent(leftClickEvent);
            } else if (event instanceof EntityDamageByBlockEvent) {
                Bukkit.getPluginManager().callEvent(new NPCDamageByBlockEvent(npc, (EntityDamageByBlockEvent) event));
            } else {
                Bukkit.getPluginManager().callEvent(new NPCDamageEvent(npc, event));
            }
    }
    Could provide a potential work-around if you can't get it to work.
    (Every NPC has metadata "NPC" set to true so you could just check the entities metadata.)
     
    Last edited: Sep 20, 2017
  9. Offline

    mine2012craft

    Mine works perfectly fine. Have you tried removing the "if" statements?

    This is one of my classes that uses the RightClickEvent. In my world, it works fine:

    Code:
        @EventHandler
        public void onRightClick(NPCRightClickEvent event){
            NPC npc = event.getNPC();
            if (npc.getName().contains("Dungeon Guide")){
                Player player = event.getClicker();
                player.openInventory(DungeonEnlisterMenu.getMenu());
                player.sendMessage(ChatColor.AQUA + "Dungeon Guide: " + ChatColor.YELLOW + "What dungeon would you like to attempt today?");
            }
        }
    I never learned to use those "if(event.getNPC() == this.getNPC()){" statements above, and mine still works fine. If you're looking for a specific npc, you can always detect for its name, or add some sort of metadata to it, or to a hashmap or something.

    EDIT: The NPCLeftClickEvent works fine too. The NPCClickEvent seems bugged though. Doesn't get called. If you need for it to function on both right and left, you can always create a method for the code you need to run, create two events (Left and Right), then use the method in there.
     
    Last edited: Sep 20, 2017
  10. Offline

    CraftCreeper6

    @mine2012craft
    The NPCClickEvent doesn't do anything, that's its purpose. It's used for the two subevents, left and right click.
     
  11. Offline

    AdamDev

    @Zombie_Striker
    Inside of the CitizensAPI, it does show an example of using the NPCClickEvent,etc. There is one problem. The "this.getNPC();" I've only seen it in traits. So as @mine2012craft had said:
    Just don't use that stuff.

    Other than that checking for its name is another idea. I'm currently making a blackmarket plugin that uses the NPCRightClickEvent and it works for me.

    It also depends on what your using the right click event for, but that's not the subject of this thread.
     
Thread Status:
Not open for further replies.

Share This Page