在PlayerMoveEvent中只执行一次p.sendMessage

时间:2015-08-29 08:52:25

标签: java bukkit

当playerMoveEvent执行时,每次走路时都会发送取消消息。是否可以只发送一次?

这是主要课程:

package me.mortadelle2.togglePVP;

import java.util.ArrayList;
import java.util.HashMap;

import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

public class PVP extends JavaPlugin{

    public int turnOn;
    public int turnOff;

    ArrayList<String> noPVP = new ArrayList<String>();

    HashMap<String, Integer> stepCounter = new HashMap<String, Integer>();

    public void onEnable(){
        new MainEvents(this);
        getLogger().info("You may now toggle PVP!");
    }

    public void onDisable(){
        getLogger().info("You may no longer toggle PVP ;(");
    }

    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {

    final Player p = (Player) sender;

        if (cmd.getName().equalsIgnoreCase("pvp") && p.hasPermission("togglepvp.toggle")){

            if (args.length == 0){
                p.sendMessage(ChatColor.RED + "Invalid usage! /pvp [on or off]");
                return true;
            }

            if (args.length == 1){

                if (args[0].equalsIgnoreCase("on")){

                    stepCounter.put(p.getName(), 0);

                    p.sendMessage(ChatColor.RED + "PVP " + ChatColor.YELLOW + "will be turned on in 5 seconds! Don't move!");

                    turnOn = this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {



                        @Override
                        public void run() {

                            noPVP.remove(p.getName());
                            p.sendMessage(ChatColor.RED + "PVP" + ChatColor.YELLOW + " has been turned on!");

                        }
                    }, 100L);
                    return true;
                }

                if (args[0].equalsIgnoreCase("off") && p.hasPermission("togglepvp.toggle")) {

                    stepCounter.put(p.getName(), 0);

                    p.sendMessage(ChatColor.RED + "PVP " + ChatColor.YELLOW
                            + "will be turned off in 5 seconds! Don't move!");

                    turnOff = this.getServer().getScheduler()
                            .scheduleSyncDelayedTask(this, new Runnable() {

                                @Override
                                public void run() {

                                    noPVP.add(p.getName());
                                    p.sendMessage(ChatColor.RED + "PVP"
                                            + ChatColor.YELLOW
                                            + " has been turned off!");

                                }
                            }, 100L);
                    return true;
                }

            }

        }


        return false;
    }

}

和Listener类:

package me.mortadelle2.togglePVP;

import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerMoveEvent;

public class MainEvents implements Listener {

    PVP getter;

    public MainEvents(PVP plugin){

        plugin.getServer().getPluginManager().registerEvents(this, plugin);

        this.getter = plugin;

    }

    @EventHandler
    public void playerDamagesWhenToggledOff(EntityDamageByEntityEvent e){

        Player victim = (Player) e.getEntity();
        Player damager = (Player) e.getDamager();

        if (getter.noPVP.contains(victim) || getter.noPVP.contains(damager)){
            e.setCancelled(true);
        }

    }

    @EventHandler
    public void playerMovesSoCancelsTask(PlayerMoveEvent e){
        Player p = e.getPlayer();

        getter.stepCounter.put(p.getName(), 1);

        if (getter.stepCounter.get(p.getName()) == 1){

        if (e.getTo().getBlockX() != e.getFrom().getBlockX() || e.getTo().getBlockY() != e.getFrom().getBlockY()
                || e.getTo().getBlockZ() != e.getFrom().getBlockZ()){

            getter.getServer().getScheduler().cancelTask(getter.turnOn);
            getter.getServer().getScheduler().cancelTask(getter.turnOff);
            p.sendMessage(ChatColor.RED + "You moved so the action was cancelled!");

            getter.stepCounter.put(p.getName(), 0);
        }
        }

    }

}

我试着计算他的步数并在他走路时递增,但这不起作用,所以我无法想象会发生什么。

1 个答案:

答案 0 :(得分:3)

您可以先删除所有的全局变量,然后创建一个公共静态ArrayList,用于保存所有已启用pvp保护的播放器,以及一个等待更改状态的播放器。

public static ArrayList<String> noPVP = new ArrayList<String>();//Holds players that have pvp protection enabled
public static ArrayList<String> playersWaiting = new ArrayList<String>();//Holds players waiting to change states

static修饰符将创建一个可以在整个类中访问的对象,而无需使用“getter”。通过PVP实现主类的实例。[var]。您可以删除所有其他全局变量,现在由于这些变量是静态的,您可以删除侦听器类中的getter。

要解决您的问题,您需要修改命令,以便在执行命令时将玩家置于地图中

if (args[0].equalsIgnoreCase("on")) {
    player.sendMessage(ChatColor.YELLOW + "PVP will be turned on in 5 seconds! Don't move!");
    playersWaiting.add(player.getName());

    Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {

        @Override
        public void run() {
            if (playersWaiting.contains(player.getName())) {
                playersWaiting.remove(player.getName());
                noPVP.remove(player.getName());
                player.sendMessage(ChatColor.YELLOW + "You have turned PVP on!");
            }
        }
    }, 100L);
    return true;
} else if (args[0].equalsIgnoreCase("off")) {
    player.sendMessage(ChatColor.YELLOW + "PVP will be turned off in 5 seconds. Don't move!");
    playersWaiting.add(player.getName());

    this.getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {

        @Override
        public void run() {
            if (playersWaiting.contains(player.getName())) {
                playersWaiting.remove(player.getName());
                noPVP.add(player.getName());
                player.sendMessage(ChatColor.YELLOW + "You have turned PVP off!");
            }
        }
    }, 100L);
    return true;
}

如果玩家改变位置,您的玩家移动事件应该完全从地图中删除玩家:

@EventHandler
public void playerMovesSoCancelsTask(PlayerMoveEvent e) {
    Player player = e.getPlayer();//Get the player

    //Check if the player is moving to a new block
    if (e.getTo().getBlockX() != e.getFrom().getBlockX() || e.getTo().getBlockY() != e.getFrom().getBlockY() || e.getTo().getBlockZ() != e.getFrom().getBlockZ()) {

        //Check if the player is waiting to turn on/off pvp
        if (PVP.playersWaiting.contains(player.getName())) {
            player.sendMessage(ChatColor.RED + "You moved so the action was cancelled!");
            PVP.playersWaiting.remove(player.getName()); //Remove the player from the waiting list
        }
    }
}

我注意到的其他一些问题:

1)您将CommandSender投射到播放器而不进行任何检查。尝试从控制台执行命令,看看会发生什么。谷歌搜索应该告诉你如何解决这个问题。

2)在你的playerDamagesWhenToggledOff听众的方法中,你要检查玩家本身,而不是他们的名字。请务必使用他们的名字:if (Main.noPVP.containsKey(victim.getName())) { e.setCancelled() }

3)你永远不会从变量中删除玩家,确保你创建一个新的PlayerQuitEvent并从所有全局变量中删除玩家。