Solved Problems With Minecarts?

Discussion in 'Plugin Development' started by savagesun, Jun 16, 2013.

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

    savagesun

    I'm writing a simple plugin to restrict the time in which players can use certain items. All goes well until I try to use minecarts of any kind.
    I store the required data in two hash maps here:
    Code:
    public static HashMap<ItemStack, Integer> cooldowns = new HashMap<ItemStack, Integer>();
    public static HashMap<String, LinkedList<ItemStack>> restrictPlayers = new HashMap<String, LinkedList<ItemStack>>();
    And here is the portion of the event handler that works with restrictions:
    Code:
        @EventHandler
        public void onPlayerUseItem(PlayerInteractEvent evt) {
            if(evt.getPlayer().hasPermission("ItemTimer.bypass"))
                return;
     
            if(evt.getAction().equals(Action.LEFT_CLICK_AIR) || evt.getAction().equals(Action.LEFT_CLICK_BLOCK) || evt.getAction().equals(Action.PHYSICAL))
                return;
     
            if(evt.getItem() == null)
                return;
     
            ItemStack cloneStack = evt.getItem().clone();
            cloneStack.setAmount(1);
     
            if(ItemTimer.cooldowns.containsKey(cloneStack)) {
                //check player - restrict as necessary
                if(ItemTimer.restrictPlayers.containsKey(evt.getPlayer().getName())) {
                    if(!ItemTimer.restrictPlayers.get(evt.getPlayer().getName()).contains(cloneStack)) {
                        ItemTimer.restrictPlayers.get(evt.getPlayer().getName()).add(cloneStack);
                        System.out.println("Scheduled new lifter.");
                        Bukkit.getScheduler().runTaskLater(inst, new LiftRestriction(evt.getPlayer().getName(), cloneStack), 20 * ItemTimer.cooldowns.get(cloneStack));
                    } else {
                        evt.getPlayer().sendMessage(ChatColor.RED + "You must wait to use that again!");
                        evt.setCancelled(true);
                    }
                }
            }
        }
    Finally here is the run portion of the LiftRestriction runnable:
    Code:
    System.out.println("List before: " + ItemTimer.restrictPlayers.get(name).toString());
    ItemTimer.restrictPlayers.get(name).remove(item);
    System.out.println("Lifted: "+name + ", " + item.toString());
    I've verified that the maps are populating correctly as well as being removed properly.
    Other items/blocks work perfectly fine, the only trouble makers are the minecarts.
    When I try and place a minecart it tells me I must wait to use it, but it also logs in the console that it has scheduled a new lifter, meaning it's apparently running both parts if the if else statement...?
    I suppose it's worth mentioning that a new LinkedList is added for each player that joins in the restrictPlayers map.

    Any input is appreciated, thanks!

    Edit: Found that boats have the same issue as minecarts.

    Bump

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 2, 2016
  2. Offline

    catageek

    I guess the event is called twice when the item is a vehicle. Try to detect the 2 events, maybe one of two can be filtered.
     
  3. Offline

    savagesun

    That's what I assumed too, but what can I use to differentiate the events if they are indeed being fired twice?
     
  4. Offline

    TheTrixsta


    Boats and Minecarts are registered as Entities

    possibly use this to cancel it:
    Code:
    event.setUseItemInHand(Result.DENY);
    If all else fails try this:
    Code:
    if (event.getItem() instanceof Minecart) {
                ItemStack cloneItem = event.getItem(); //clone the item
                Minecart minecart = (Minecart) event.getItem(); //cast the minecart to the item
                minecart.remove(); //remove the minecart
                event.getPlayer().setItemInHand(cloneItem); //replace the item in hand so they dont lose the item
            }
    it belongs in the PlayerInteractEvent
     
  5. Offline

    savagesun

    Well, the thought that they are entities crossed my mind too. But aren't things like enderpearls treated as entities as well? They don't seem to give me any issues. I tried your Result.DENY idea, and your other one as well. I'm almost certain you can't just cast an item to a Minecart though, which explains why it never runs that portion of the code. I think catageek has it right with the events firing twice. What I think is going on is the event fires once and the code allows it to happen, but the second firing is the actual minecart being placed, which is then blocked because the plugin only allows for the item to be used once every x seconds. I just need a way to allow only the trouble items to be "used" twice in a row.
     
    TheTrixsta likes this.
  6. Offline

    TheTrixsta


    I mean as long as you check the instanceof the item to the minecart then you should be able to cast without problem
     
  7. Offline

    savagesun

    This has been solved, but checking the instance isn't the issue. An ItemStack will never be an instance of a Minecart, so casting to it is not possible.

    Edit: at least in the way you described.
     
Thread Status:
Not open for further replies.

Share This Page