Player not being removed from array list when they take fall damage.

Discussion in 'Plugin Development' started by Lammazz, Dec 8, 2013.

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

    Lammazz

    So I made a launchpad so that whenever a player walks over sponge it shoots them forward in the direction they're looking, to prevent them dying when they are fired I add them to an ArrayList which prevents fall damage and when they take fall damage they are removed from the list. The problem I have is that when they go onto the launchpad and take fall damage they are not removed from the list and wont take fall damage until a restart, reload ect. whenever the list is reset. The code I'm using is below. I'm relatively new to coding so please explain where I went wrong.

    Code:java
    1. private ArrayList<Player> jumpers = new ArrayList<Player>();
    2. @EventHandler
    3. public void onPlayerMove(PlayerMoveEvent e) {
    4. Player p = e.getPlayer();
    5. if (e.getTo().getBlock().getRelative(BlockFace.DOWN).getType() == Material.SPONGE) {
    6. e.getPlayer().setVelocity(e.getPlayer().getLocation().getDirection().multiply(5));
    7. e.getTo().getBlock().getWorld().playSound(p.getLocation(), org.bukkit.Sound.EXPLODE, 1, 1);
    8. e.getPlayer().setVelocity(new Vector(e.getPlayer().getVelocity().getX(), 1.0D, e.getPlayer().getVelocity().getZ()));
    9. e.getPlayer().sendMessage("§4Factions §5§l> §fWoosh!");
    10. jumpers.add(e.getPlayer());
    11. }
    12. }
    13.  
    14. @EventHandler
    15. public void onPlayerDamage(EntityDamageEvent e) {
    16. if (e.getEntity() instanceof Player) {
    17. Player p = (Player) e.getEntity();
    18. if (e.getCause() == DamageCause.FALL) {
    19. if (jumpers.contains(p)) {
    20. p.sendMessage("§4Factions §5§l> §fSplat!");
    21. e.setDamage(0.0);
    22. jumpers.remove(p);
    23. return;
    24. }
    25. return;
    26. }
    27. }
    28. }
     
  2. Offline

    Rocoty

    Are these both in the same class? If yes, are they in the main class? Please post whole classes, that we can more easily uncover and resolve your problem.
     
  3. Offline

    Lammazz

    They're both in the same class and it is the main class. The whole class, removing other pieces that don't effect this is,
    Code:java
    1. package me.lammazz.factionsmain;
    2.  
    3. import java.util.ArrayList;
    4. import java.util.Arrays;
    5. import java.util.logging.Logger;
    6.  
    7. import org.bukkit.Bukkit;
    8. import org.bukkit.ChatColor;
    9. import org.bukkit.Material;
    10. import org.bukkit.block.BlockFace;
    11. import org.bukkit.command.Command;
    12. import org.bukkit.command.CommandSender;
    13. import org.bukkit.enchantments.Enchantment;
    14. import org.bukkit.entity.Player;
    15. import org.bukkit.event.EventHandler;
    16. import org.bukkit.event.Listener;
    17. import org.bukkit.event.entity.EntityDamageEvent;
    18. import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
    19. import org.bukkit.event.player.PlayerJoinEvent;
    20. import org.bukkit.event.player.PlayerMoveEvent;
    21. import org.bukkit.event.player.PlayerQuitEvent;
    22. import org.bukkit.inventory.ItemStack;
    23. import org.bukkit.inventory.ShapedRecipe;
    24. import org.bukkit.inventory.meta.ItemMeta;
    25. import org.bukkit.plugin.RegisteredServiceProvider;
    26. import org.bukkit.plugin.java.JavaPlugin;
    27. import org.bukkit.util.Vector;
    28.  
    29. public class Main extends JavaPlugin implements Listener {
    30.  
    31. private ArrayList<Player> jumpers = new ArrayList<Player>();
    32.  
    33. public void onEnable() {
    34. Bukkit.getServer().getPluginManager().registerEvents(this, this);
    35. }
    36.  
    37. @EventHandler
    38. public void onPlayerMove(PlayerMoveEvent e) {
    39. Player p = e.getPlayer();
    40. if (e.getTo().getBlock().getRelative(BlockFace.DOWN).getType() == Material.SPONGE) {
    41. e.getPlayer().setVelocity(e.getPlayer().getLocation().getDirection().multiply(5));
    42. e.getTo().getBlock().getWorld().playSound(p.getLocation(), org.bukkit.Sound.EXPLODE, 1, 1);
    43. e.getPlayer().setVelocity(new Vector(e.getPlayer().getVelocity().getX(), 1.0D, e.getPlayer().getVelocity().getZ()));
    44. e.getPlayer().sendMessage("§4Factions §5§l> §fWoosh!");
    45. jumpers.add(e.getPlayer());
    46. }
    47. }
    48.  
    49. @EventHandler
    50. public void onPlayerDamage(EntityDamageEvent e) {
    51. if (e.getEntity() instanceof Player) {
    52. Player p = (Player) e.getEntity();
    53. if (e.getCause() == DamageCause.FALL) {
    54. if (jumpers.contains(p)) {
    55. p.sendMessage("§4Factions §5§l> §fSplat!");
    56. e.setDamage(0.0);
    57. jumpers.remove(p);
    58. return;
    59. }
    60. return;
    61. }
    62. }
    63. }
    64. }
    65. }
    66.  
     
  4. Offline

    Rocoty

    Do you get the splat message?
     
  5. Offline

    Developing

    Lammazz Try removing the 2 return statements.
     
  6. Offline

    Lammazz

    I do get the splat message after using the launchpad once, removing return statements now

    Removing return statements did nothing

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

    Wolfey

    I think I know whats wrong. The player IS being removed from the arraylist, but remember you can add multiple of the same Strings/Integers/booleans/whatever in the same arraylist, and because you're adding them to the arraylist everytime they move, it's going to be hard to remove them all at once, unless you do this:
    Code:java
    1.  
    2. while(arraylist.contains(p.getName())) arraylist.remove(p.getName());
    3.  

    So while the arraylist contains the player, it will repeatedly remove them until they are not.
     
    Rocoty likes this.
  8. Offline

    Rocoty

    Wolfey That was basically my next suggestion in line :)
     
  9. Offline

    Wolfey

    Haha, beat you to the punch!
     
  10. Offline

    Lammazz

    So it should be like this?
    Code:java
    1. @EventHandler
    2. public void onPlayerDamage(EntityDamageEvent e) {
    3. if (e.getEntity() instanceof Player) {
    4. Player p = (Player) e.getEntity();
    5. if (e.getCause() == DamageCause.FALL) {
    6. if (jumpers.contains(p)) {
    7. p.sendMessage("§4Factions §5§l> §fSplat!");
    8. e.setDamage(0.0);
    9. while(jumpers.contains(p.getName())) jumpers.remove(p.getName());
    10. }
    11. }
    12. }
    13. }
     
  11. Offline

    Wolfey

    If you want the player to completely be removed from the arraylist, then yes. Otherwise you're just removing the player once, but there's still like 1000 p.getName()'s in the arraylist.
     
  12. Offline

    Lammazz

    I don't understand, and adding that line didn't work
     
  13. Offline

    _Filip

    Code:java
    1. public void onPlayerMove(PlayerMoveEvent e) {
    2. Player p = e.getPlayer();
    3. if (e.getTo().getBlock().getRelative(BlockFace.DOWN).getType() == Material.SPONGE) {
    4. p.setVelocity(p.getLocation().getDirection().multiply(5));
    5. e.getTo().getBlock().getWorld().playSound(p.getLocation(), org.bukkit.Sound.EXPLODE, 1, 1);
    6. p.setVelocity(new Vector(p.getVelocity().getX(), 1.0D, p.getVelocity().getZ()));
    7. p.sendMessage("<§4Factions §5§l> §fWoosh!");
    8. if (!jumpers.contains(p.getName)
    9. jumpers.add(p.getName);
    10. }
    11. }
    12.  
    13. @EventHandler
    14. public void onPlayerDamage(EntityDamageEvent e) {
    15. if (e.getEntity() instanceof Player) {
    16. Player p = (Player) e.getEntity();
    17. if (e.getCause() == DamageCause.FALL) {
    18. if (jumpers.contains(p.getName()) {
    19. p.sendMessage("§4Factions §5§l> §fSplat!");
    20. e.setCancelled(true);
    21. jumpers.remove(p.getName());
    22. return;
    23. }
    24. return;
    25. }
    26. }
    27. }



    My method checks if they're in the arraylist already.
    But I'm pretty sure a value can only be added once into an arraylist, because if it wasn't, there would be quite a lot of exceptions to catch.

    My method also puts the player's name into the arraylist instead of the player instance.
    This helps prevent memory leaks if the player disconnect.
     
  14. Offline

    Wolfey

    Your PlayerMoveEvent is too sensitive, once they get damaged and even slightly move again, it's gonna add them to the arraylist again.

    But if it didn't work for you, try doing what swampshark19 did and first check if they're not in the arraylist, and if it returns true, add them, otherwise, do nothing. When they get damaged, simple remove them, because they're only going to be in there once.
     
  15. Offline

    Lammazz

    For the line "jumpers.add(p.getName());" add is underlined in red and has the error, "The method add(Player) in the type ArrayList<Player> is not applicable for the arguments (String)"
     
  16. Offline

    _Filip

    Let's dissect that error.

    p.getName() returns a string.

    "jumpers.add(p.getName());" tries to put a string into the arraylist. But the arraylist is set to only accept Players, because of the <Player> parameter.

    We have to change that parameter to accept whatever p.getName() is giving it.

    Try that.
     
  17. Offline

    Lammazz

    Got it working, thanks so much for the help! End code for anyone that's wondering.
    Code:java
    1. @EventHandler
    2. public void onPlayerMove(PlayerMoveEvent e) {
    3. Player p = e.getPlayer();
    4. if (e.getTo().getBlock().getRelative(BlockFace.DOWN).getType() == Material.SPONGE) {
    5. p.setVelocity(p.getLocation().getDirection().multiply(5));
    6. e.getTo().getBlock().getWorld().playSound(p.getLocation(), org.bukkit.Sound.EXPLODE, 1, 1);
    7. p.setVelocity(new Vector(p.getVelocity().getX(), 1.0D, p.getVelocity().getZ()));
    8. p.sendMessage("§4Factions §5§l> §fWoosh!");
    9. if (!jumpers.contains(p)) {
    10. jumpers.add(p);
    11. }
    12.  
    13. }
    14. }
    15.  
    16. @EventHandler
    17. public void onPlayerDamage(EntityDamageEvent e) {
    18. if (e.getEntity() instanceof Player) {
    19. Player p = (Player) e.getEntity();
    20. if (e.getCause() == DamageCause.FALL) {
    21. if (jumpers.contains(p)) {
    22. p.sendMessage("§4Factions §5§l> §fSplat!");
    23. e.setCancelled(true);
    24. jumpers.remove(p);
    25. return;
    26. }
    27. return;
    28. }
    29. }
    30. }
     
  18. Offline

    _Filip

    Lammazz
    You completely ignored my suggestion to prevent memory leaks...
     
  19. Offline

    Dave_


    I noticed it when I first opened the thread. Lammazz use this instead
    1. private ArrayList<String> jumpers = new ArrayList<String>();
    then add the player this way.
    1. jumpers.add(p.getName());
     
Thread Status:
Not open for further replies.

Share This Page