Search code examples
javapluginsminecraft

How could I make a force field effect on a player?


I want to make a player Invunerable to damage and all knockback for a certain period of time (except for fall damage). My rpoblem is that the bukkit runable is not wroking as intended:

  public class WeaponEvents implements Listener {
private Elemental_weapons plugin;
ArrayList<UUID> forceFieldArray = new ArrayList<UUID>();

@EventHandler
public void onplayercrouchevent(PlayerToggleSneakEvent event) {
    boolean issneaking = event.isSneaking();
    Player player = event.getPlayer();
    if (issneaking==true) {

        if (player.getInventory().getChestplate().equals(Weapons.chestplate)) {

            forceFieldArray.add(player.getUniqueId());
            Bukkit.broadcastMessage(String.valueOf(forceFieldArray));
            new BukkitRunnable() {
                @Override
                public void run() {
                    Bukkit.broadcastMessage("no more");
                    forceFieldArray.remove(player.getUniqueId());
                }
            }.runTaskLater( plugin, 200L);
            while (forceFieldArray.contains(player.getUniqueId())) {

            }
        }
    }
}

Solution

  • I'd do this by having an array, say

    ArrayList<UUID> forceFieldArray = new ArrayList<UUID>();

    then whenever you want to activate your player's forcefield use a BukkitRunnable to set a delayed task.

    forceFieldArray.add(player.getUniqueId());
    new BukkitRunnable() {
        @Override
        public void run() {
            forceFieldArray.remove(player.getUniqueId());
        }
    }.runTaskLater(plugin, 200L);
    

    Just remember that the '200L' in there is ticks, 20 ticks to a second so 200L is 10 seconds. This adds the player to the array, then in ten seconds it'll remove the player. Using this you can now use that array to check if players have the force field active.

    public void onPlayerDamage(EntityDamageEvent e) {
        //Check if entity is player
        //Create player variable
        if(e.getCause() == DamageCause./*[Damage type you want to cancel]*/) {
            if(forceFieldArray.contains(player.getUniqueId())) {
                e.setCancelled(true);
            }
        }
    }
    

    This way you could even make a config with a list in there, have all the types of damage you want the forcefield to block then just above the ifs bring that data into an Array and say if(configArray.contains(e.getCause()) { //Do stuff

    Hope this helped!