Solved Click Patterns

Discussion in 'Plugin Development' started by plisov, Jul 27, 2017.

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

    plisov

    Im trying to make a plugin where if you click a certain pattern with your mouse, something happens. For example, you click L-R-L (Left - Right - Left) and an arrow shoots. If you click L-L-L (Left - Left - Left) a snowball shoots. I don't know where to begin besides a PlayerInteractEvent. Thats about it.
    [​IMG][​IMG][​IMG]

    Any help is appreciated.
     
  2. Offline

    Zombie_Striker

    @plisov
    1. Create a hashmap. The keys will be UUIDs and the values will be an array of ints. This represents which combination the player clicked.
    2. Create another hashmap. The keys are UUIDs and values will be Longs. This represents the last time the mouse was clicked.
    3. On Player InteractEvent.
    4. If the last time a player clicked a key was greater than a certain amount of time and if the first hashmap contains the player, clear the player from the first hashmap. We don't want to be able to contribute to the spell triggered ten minutes ago.
    5. Else, if the player was not in the second hashmap or if it was greater than the certain amount of time and if the player is not in the first hashmap, create a new int array and set the first value to be equal to the action. (1 being right, 2 being left)
    6. Else, if the time was less than a certain amount of time:
    7. If the second value array is not full (if the int in the array is -1), add the action to the second index.
    8. Else, if the second value is full, add the action to the third array and "cast" the corresponding spell.
     
  3. Offline

    plisov

    This was a lot of help but there were a few things I didn't understand. Here is the code. I filled in the spaces I didnt understand with questions :p. I know, very creative
     
    Last edited: Jul 30, 2017
  4. Offline

    Zombie_Striker

    The values should be Integer arrays. This will currently only store one int.
    System.currentTimeMillis() - longs.get(player.getUniqueId()) >= 20*1000

    Replace event.getAction() with
    Code:
    ( event.getAction()==Action.RIGHT_CLICK_BLOCK|| event.getAction()==ACTION>RIGHT_CLICK_AIR)? 1:2
    It will return 1 if the action is right click, and 2 if it is left click.
    if(ints.get(player.getUniqueId())[1] != -1){
    BTW: This will only store two clicks. If you really only want two clicks, replace the [1] above with [0].
    The else statement already covers if it is full. You can remove this if statement.
     
  5. Offline

    plisov

    Thanks for this. How would I have it store 3 clicks?

    Also how do I set it up where if a certain combination was clicked, for example L R L, something would happen?
     
    Last edited: Jul 30, 2017
  6. Offline

    Zombie_Striker

    @plisov
    1. To add more clicks, change int[2] to int[3].
    2. The int array should be stored inside the hashmap, not as its own field. The hashmap is there to allow multiple players to have their own array, and as such, their own spell combination.
    3. After this, in an else statement, check if the array's three values equal a specific spell (in this case, it would be 2,1,2 for indexes 0,1,2 respectively). If this is the case, cast the spell, remove the player from "ints" and 'longs'.
    4. Also, you will need to add a check in the beginning, before the time check. If the player is not in the longs time, then add the player and the current time to 'longs', and create a new int[3] for the 'ints' hashmap. We need this, because currently there is no way to add the player to the hashmap.
     
  7. Offline

    plisov

    I moved the
    int[] intArray = new int[3]; into the else statement as you said. I assume that's what you meant

    How do I check the array's values?
     
    Last edited: Jul 30, 2017
  8. Offline

    Zombie_Striker

    What do you mean by this? What exactly are you checking? If you want to check orders, you will need to do individual checks like:
    Code:
    if(array[0] == 1 && array[1] == 2 && array[2] == 1)
     
  9. Offline

    plisov

    @Zombie_Striker

    You said ' check if the array's three values equal a specific spell'. How do I do so
     
  10. Offline

    Zombie_Striker

    @plisov
    Exactly as I posted above (*I made an edit to it)
     
  11. Offline

    plisov

    Ah I see. I tried it out and its saying there is a NullPointerException error on line 22
     
    Last edited: Jul 30, 2017
  12. Offline

    Zombie_Striker

    @plisov
    Before that first if statement, check if they are not in the hashmap. If not, add them to the hashmap with a the current time for long, and a new int array[3] for ints.

    Also:
    This will always be an empty array. Since we know the hashmap int needs to contain the player in order for it to reach this bit of code, grab the int array from ints instead of creating a new one.
     
  13. Offline

    plisov

    Im not sure if I did this correctly. I added the check but I'm not sure how to get the int array from the hashmap as you said
     
    Last edited: Jul 30, 2017
  14. Offline

    Zombie_Striker

    Just add the bold line to the if statement, and replace intArray with
     
  15. Offline

    plisov

    Ooh. I'm not sure if I did this correctly because when I went to try it, it doesnt send the 'Working!!' message that it is supposed to send at the bottom.

    Also, how do I print out the actions like the images show in the first post?
     
    Last edited: Jul 30, 2017
  16. Offline

    Zombie_Striker

    I re-reviewed the code and noticed you had this line. This will never be true, so you should be able to remove it.

    Also, this line here will also never be true, nor is it what you want if it was true (this says to only trigger the rest of the code if the last click was over 20 seconds ago). Remove this if statement.

    This should be inside the top, first if statement (the one with the !long.containsKey...)

    Main problem: Well, more like one of the main problems. One of the reasons why it is not printing out working is because the third arg (intArray[2]) is never set. Right before you do that check, add this line to set it equal to the action that was issued:
    Code:
    intArray[2] = (event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_AIR) ? 1 : 2;
     
  17. Offline

    plisov

    Im not sure which check you were talking about in the Main problem section so I put that bit of code above the inArray[1]. I'm sure thats not where it goes. I also fixed the mistakes you pointed out
     
    Last edited: Jul 30, 2017
  18. Offline

    Zombie_Striker

    @plisov
    Put it right above this:
    Also, move intArray above this line
    The way you currently have it will mean it may be triggered before the player is added to the hashmap, meaning it may be null.

    [edit] Also, add a return; line after
    so that if the player is starting to click, it won't consider duplicating the action.
     
  19. Offline

    plisov

    Ah. Okay I think I've done it correctly however the intArray[0] line is undefined as the array is under neath it above the line you mentioned in the previous post.
     
    Last edited: Jul 30, 2017
  20. Offline

    Zombie_Striker

    @plisov
    A quick fix for this would be to copy and paste the intArray variable into that if statement, above intArray[0] and below ints.put.
     
  21. Offline

    plisov

    You mean like this? The other ones in the else statement at the bottom aren't defined. I think I'm just being really out of it right now. :p
     
    Last edited: Jul 30, 2017
  22. Offline

    Zombie_Striker

    @plisov
    Yeah, I just meant for you to copy and paste the line there, not move the line. Copy that line (without deleting it), and paste the line back above the sendMessage line.
     
  23. Offline

    plisov

    Ooh I get it :p. It says there is an error with the line
    After I try the 1 2 1 combination. And after that whenever I click it gives the same error. NullPointerException
     
    Last edited: Jul 30, 2017
  24. Offline

    Zombie_Striker

    @plisov
    Try the following:
    1. Print out if ints is null.
    2. Print out ints.get(......) and see if the array is null.
    3. Finally, if both of are not null, then print out what intArray[1] is equal to.
     
  25. Offline

    plisov

    Not sure if I set this up correctly but I tried it and it sends the 0 is Null message
     
    Last edited: Jul 30, 2017
  26. Offline

    Zombie_Striker

    @plisov
    Since ints is the hashmap, which requires UUIDs, it should return null. Try this instead:
    Code:
    if(ints == null) {
    player.sendMessage("Ints is Null");
    } else if(
    ints.get(player.getUniqueId())== null) {
    player.sendMessage("whole array is Null");
    } else if(player.getUniqueId())[0] == null) {
    player.sendMessage("0 is Null");
    } else if(player.getUniqueId())[1] == null) {
    player.sendMessage("1 is Null");
    } else ifplayer.getUniqueId())[2] == null) {
    player.sendMessage("2 is Null");
    }
    Remember to put this above the line that is causing the error; you want to be able to see the messages before the error stops the rest of the code from being read.

    Also,this will be an issue in the future; add these lines after the "Working!!" if statement. We don't want to store old spells once they are casted:
     
    Last edited: Jul 29, 2017
  27. Offline

    plisov

    Its saying that player.getUniqueId() must be an array and its showing as red
     
    Last edited: Jul 30, 2017
  28. Offline

    Zombie_Striker

    @plisov
    My mistake. I meant to add "ints.put(" before the uuid so we get the array. Replace that with:
    Code:
    if(ints == null) {
    player.sendMessage("Ints is Null");
    } else if(
    ints.get(player.getUniqueId())== null) {
    player.sendMessage("whole array is Null");
    } else if(ints.put(player.getUniqueId())[0] == null) {
    player.sendMessage("0 is Null");
    } else if(ints.put(player.getUniqueId())[1] == null) {
    player.sendMessage("1 is Null");
    } else if(ints.put(player.getUniqueId())[2] == null) {
    player.sendMessage("2 is Null");
    }
     
  29. Offline

    plisov

    .get is red. It says The method get(UUID, int[]) in the type HashMap<UUID,int[]> is not applicable for the arguments (UUID) When I add intArray after player.getUniqueId the whole line turns red.
     
    Last edited: Jul 30, 2017
  30. Offline

    Caderape2

    @plisov
    you try to put and get in a same time, that can't work.
    You have to choose between ints.put(uuid, new int[]) or ints.get(UUId)[0] for get the first number of the array.
    And a number in a int array will never return null. By default, it's 0. Only the array of int can be null
     
Thread Status:
Not open for further replies.

Share This Page