Solved No fall damage on command?

Discussion in 'Plugin Development' started by GreatMinerZ, Dec 6, 2013.

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

    GreatMinerZ

    I'm creating a plugin where the player types /rocket and they gets launched into the air.
    How would i cancel the falldamage when the player lands again?

    I already have this:

    Code:java
    1. public void onFallDamage(EntityDamageEvent event){
    2. if(event.getEntity() instanceof Player && event.getCause() == DamageCause.FALL)
    3. event.setCancelled(true);
    4. }
     
  2. Offline

    beastman3226

    When the command fires add them to a list; when they land, remove them. Don't forget to check if they exist on the list in your conditional statement.
     
  3. Offline

    NathanWolf

    I think that's the right idea- you'd probably want to store the player's name in a hashset when they launch, and check/remove them on fall damage, so they're only protected one time after using /rocket.

    I do something similar in my "fling" spell- I also track when the player used the command, and don't prevent fall damage if it was more than 5 seconds ago. This prevents accidental protection later on if they use the command but don't actually fall far enough to cause damage.

    EDIT: Ninja'd! Well hopefully my additional comments about having the protection time out are helpful :)
     
  4. Offline

    Wolfey

    Put this in one of your classes
    Code:
    public ArrayList<String> rocket = new ArrayList<String>();
    
    then, when a player performs the command, put this in:
    Code:
    if(rocket.contains(p.getName()) return true;
    
    rocket.add(p.getName());
    
    // launch player and other stuff
    
    then on a fall damage, put this in:
    Code:
    @EventHandler
    public void onFallDamage(EntityDamageEvent event){
    if(event.getEntity() instanceof Player && event.getCause() == DamageCause.FALL) {
    Player p = (Player) e.getEntity();
    if(rocket.contains(p.getName()) {
    event.setCancelled(true);
    rocket.remove(p.getName());
    }
    }
    }
    
     
  5. Offline

    GreatMinerZ

  6. Offline

    DeStickyOne

    make a ArrayList
    when you do the Command Add the player to the ArrayList
    Then check if the player in the list
    and then disable the Event
    and remove the player from the List
     
  7. Offline

    sgavster

    GreatMinerZ
    Code:java
    1. List<String> fall = new ArrayList<String>();
    2. //to check if they are in it
    3. if(fall.contains(player.getName()) {
    4. //code
    5. }
    6. //to add
    7. fall.add(player.getName());
    8. //to remove
    9. fall.remove(player.getName());
     
  8. Offline

    NathanWolf


    I'd make a couple of small-ish changes to this-

    Set<String> fall = new HashSet<String>(); // same interface, more efficient

    if (fall.contains(...)) // typo fix ;)
     
  9. Offline

    sgavster

    NathanWolf ^^ do that, and not an arraylist, his is much more efficient :p
     
  10. Offline

    GreatMinerZ

  11. Offline

    NathanWolf

    Take sgvaster's code - you can use my replacements if you want, the only real important one is fixing the call to "contains" :)

    Those are the pieces you can worth with, you need to stick them in the right places in your command handler and damage listener.
     
  12. Offline

    MrInspector

    Don't forget the @EventHandler above your event! :p
     
  13. Offline

    GreatMinerZ

    Tupay NathanWolf sgavster DeStickyOne Player cannot be resolved. How would i fix this?

    Code:
    Code:java
    1. @EventHandler
    2. public void onFallDamage(EntityDamageEvent event) {
    3. if(fall.contains(player.getName() && event.getCause() == DamageCause.FALL)) {
    4. //code
    5. }
    6. event.setCancelled(true);
    7. }
     
  14. Offline

    L33m4n123


    what about actually creating the variable player?
     
  15. Offline

    GreatMinerZ

    L33m4n123 Can't use Player player = event.getPlayer on EntityDamageEvent
     
  16. Offline

    qlimax5000

    GreatMinerZ

    Since you don't get all these clever correct people (And because i'm really bored) i just made it for you...

    Code:java
    1.  
    2. ArrayList<Player> noFall = new ArrayList<>();
    3.  
    4. public void onEnable() {
    5. getServer().getPluginManager().registerEvents(this, this);
    6. }
    7.  
    8. public boolean onCommand(CommandSender sender, Command command,
    9. String label, String[] args) {
    10. if (command.getName().equalsIgnoreCase("rocket")) {
    11. if (sender instanceof Player) {
    12. Player player = (Player) sender;
    13. player.setVelocity(new Vector(0, 10, 0));
    14. noFall.add(player);
    15. }
    16. }
    17. return false;
    18. }
    19.  
    20. @EventHandler
    21. public void onPlayerDamage(EntityDamageEvent event) {
    22. if (event.getEntity() instanceof Player) {
    23. if (event.getCause().equals(DamageCause.FALL)) {
    24. if (noFall.contains((Player) event.getEntity())) {
    25. event.setCancelled(true);
    26. noFall.remove((Player) event.getEntity());
    27. }
    28. }
    29. }
    30. }
     
  17. Offline

    L33m4n123


    Yes. You only can do getEntity. However check if that is instanceof Player and cast it to player then
     
  18. Offline

    AoH_Ruthless

    GreatMinerZ
    Maybe what others have been saying (listening for an event) may be more efficient than what I do. But what I have done in my plugin PlayerLauncher is I set their velocity, direction, and so on, and when they are launched, I set their fall distance to -1000 so they won't be damaged if they fall less than or equal to 1000 blocks for that specific launch.
     
    NathanWolf likes this.
  19. Offline

    sgavster

    qlimax5000 No. Don't EVER add a player to an arraylist. Add their name. GreatMinerZ Learn java and bukkit.
     
  20. Offline

    AoH_Ruthless

    DeStickyOne qlimax5000

    To reiterate what sgavster said.
    Never, ever store / add players to arraylists. This is because it WILL result in massive memory leaks. Always save the player name if you have to add a player, but not the player itself.
     
    sgavster likes this.
  21. Offline

    qlimax5000

  22. Offline

    MrInspector

    Code:java
    1.  
    2. Player player = (Player) event.getEntity();
    3. // Although i'm not sure if you can just do event.getEntity().getPlayer(); or it might be for PlayerDeathEvent //only.
     
  23. Offline

    GreatMinerZ

    Tupay Tried this, works now but gives me errors in the console because of other entity's.

    Code:java
    1. @EventHandler
    2. public void onFallDamage(EntityDamageEvent event) {
    3. Player player = (Player) event.getEntity();
    4. Entity entity = event.getEntity();
    5.  
    6. if(fall.contains(player.getName())) {
    7. if(entity instanceof Player) {
    8. if(event.getCause() == DamageCause.FALL) {
    9. //code
    10. }
    11. }
    12. event.setCancelled(true);
    13. //to remove
    14. fall.remove(player.getName());
    15. }
    16. }


    Any way to fix this?
     
  24. Offline

    MrInspector

    Can you post your console log here?
     
  25. Offline

    GreatMinerZ

    Tupay i'll do it tomorrow. Pretty busy sorry
     
  26. Offline

    MrInspector

    kk :)
     
  27. Offline

    L33m4n123


    Check first if it is a player before casting it to Player. Otherwise if a Zombie hits a Skeleton or any other entity hits another entity it gives you errors. Most likely you got those
     
  28. Offline

    GreatMinerZ

    L33m4n123 Tupay The problem is indeed the Entity hitting other Entity's what's giving me the error. Tried this but still won't work. How would i check if the entity who's using it is a player?

    Code:java
    1. @EventHandler
    2. public void onFallDamage(EntityDamageEvent event) {
    3. Player player = (Player) event.getEntity();
    4. Entity entity = event.getEntity();
    5.  
    6. if (entity.getType() == EntityType.PLAYER) {
    7. if(fall.contains(player.getName())) {
    8. if(entity instanceof Player) {
    9. if(event.getCause() == DamageCause.FALL) {
    10. //code
    11. }
    12. }
    13. event.setCancelled(true);
    14. //to remove
    15. fall.remove(player.getName());
    16. }
    17. }
    18. }
     
  29. Offline

    L33m4n123

    Before doing

    Player player =(Player) event.getEntity();

    you need to check if it is an instanceof Player
     
  30. Offline

    GreatMinerZ

    L33m4n123 won't give me any errors anymore but it looks like the entity's cannot hit me anymore..

    Code:java
    1. @EventHandler
    2. public void onFallDamage(EntityDamageEvent event) {
    3. Entity entity = event.getEntity();
    4. if(entity instanceof Player) {
    5. Player player = (Player) event.getEntity();
    6.  
    7. if (entity.getType() == EntityType.PLAYER) {
    8. if(fall.contains(player.getName())) {
    9. if(event.getCause() == DamageCause.FALL) {
    10. //code
    11. }
    12. }
    13. event.setCancelled(true);
    14. //to remove
    15. fall.remove(player.getName());
    16. }
    17. }
    18. }
     
Thread Status:
Not open for further replies.

Share This Page