- Баллы
- 173
Java:
Vector v = p.getVelocity();
if ((v.getX()==0) && (v.getY()==0) && (v.getZ()==0)) // Стоит
p.setExp(1 / 18.0F);
else // Идёт
p.setExp(4 / 18.0F);
Следуйте инструкциям в видео ниже, чтобы узнать, как установить наш сайт как веб-приложение на главный экран вашего устройства.
Примечание: Эта функция может быть недоступна в некоторых браузерах.
Vector v = p.getVelocity();
if ((v.getX()==0) && (v.getY()==0) && (v.getZ()==0)) // Стоит
p.setExp(1 / 18.0F);
else // Идёт
p.setExp(4 / 18.0F);
Тем более что эвентом нельзя отловить прыжок или убавление шума, а надо их как-то ссуммировать (то что в PME и то что в Scheduler, а они оба будут работать в разное время и полоскаPlayerMoveEvent не предлагать, т.к. с его помощью нельзя узнать когда он остановился, а не по прежнему топает дальше.
private void doVisibility(Player p) {
Vector v = p.getVelocity();
if (p.isSneaking()) {
p.setExp(1 / 18.0F);
} else if (p.isSprinting()) {
p.setExp(14 / 18.0F);
} else {
if ((v.getX()==0) && (v.getY()==0) && (v.getZ()==0))
p.setExp(1 / 18.0F);
else
p.setExp(4 / 18.0F);
}
if (!((Entity) p).isOnGround()) p.setExp(p.getExp() + 4 / 18.0F);
if ((p.getEquipment().getHelmet() != null) && (p.getEquipment().getHelmet().isSimilar(new ItemStack(397, 1, (short) 2)))) {
p.setExp(p.getExp() - 5 / 18.0F);
}
attractZombies(p);
}
Шедулер с репитом раз, или даже 2 в тик обеспечит достаточную точность для чего угодноНе думаю что получится обойтись вообще без Move эвента. Иначе будет неточность, как минимум.
Тем более что эвентом нельзя отловить прыжок
package ru.hilgert.events.Events;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class PlayerJumpEvent extends Event{
private static final HandlerList handlers = new HandlerList();
private Player p;
private Location toLoc;
private Location fromLoc;
public PlayerJumpEvent(Player p, Location toLoc, Location fromLoc){
this.toLoc = toLoc;
this.fromLoc = fromLoc;
this.p = p;
}
public void setCancelled(boolean status){
if(status){
p.teleport(this.fromLoc);
}
}
public Player getPlayer(){
return this.p;
}
public Location getTo(){
return this.toLoc;
}
public Location getFrom(){
return this.fromLoc;
}
public Location getLocation(){
return this.p.getLocation();
}
public void setLocation(Location loc){
p.teleport(loc);
}
public HandlerList getHandlers(){
return handlers;
}
public static HandlerList getHandlerList(){
return handlers;
}
}
@EventHandler
public void onMove(PlayerMoveEvent e){
if(e.getFrom().getY() < e.getTo().getY()) {
Bukkit.getPluginManager().callEvent(new PlayerJumpEvent(e.getPlayer(), e.getTo(), e.getFrom()));
}
}

А тут игрок РАЗ и начал подниматься по лестнице.JavaScript:package ru.hilgert.events.Events; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; public class PlayerJumpEvent extends Event{ private static final HandlerList handlers = new HandlerList(); private Player p; private Location toLoc; private Location fromLoc; public PlayerJumpEvent(Player p, Location toLoc, Location fromLoc){ this.toLoc = toLoc; this.fromLoc = fromLoc; this.p = p; } public void setCancelled(boolean status){ if(status){ p.teleport(this.fromLoc); } } public Player getPlayer(){ return this.p; } public Location getTo(){ return this.toLoc; } public Location getFrom(){ return this.fromLoc; } public Location getLocation(){ return this.p.getLocation(); } public void setLocation(Location loc){ p.teleport(loc); } public HandlerList getHandlers(){ return handlers; } public static HandlerList getHandlerList(){ return handlers; } }
И не говорите что евент лишний, и вместо строки вызова евента, можно писать свой кодJavaScript:@EventHandler public void onMove(PlayerMoveEvent e){ if(e.getFrom().getY() < e.getTo().getY()) { Bukkit.getPluginManager().callEvent(new PlayerJumpEvent(e.getPlayer(), e.getTo(), e.getFrom())); } }![]()
if(e.getPlayer().getTo().getBlock() != null){А тут игрок РАЗ и начал подниматься по лестнице.


Прыжок не решает, я написал для примера. Из кода видно, что на "видимость" влияет и эвенты, и шедуллер. В первом посте объяснил ущербность использования эвентов в моём случае. Как эвентом отоавливать осановку игрока, тобиш когда он перестаёт идти?if(e.getPlayer().getTo().getBlock() != null){
//....
}
или
if(e.getPlayer().getTo().getBlock().getType() != Material.LADDER_BLOCK){ //Точно не помню какой там Material
//....
}
Шедулером, в котором раз в секунду будут записываться данные о локации игрока, и его ник, если локация одна и та же == игрок стоит, если нет == ходит, логично жеПрыжок не решает, я написал для примера. Из кода видно, что на "видимость" влияет и эвенты, и шедуллер. В первом посте объяснил ущербность использования эвентов в моём случае. Как эвентом отоавливать осановку игрока, тобиш когда он перестаёт идти?
В майнкрафте игрок останавливается как только перестаёт слать пакеты. То бишь через тик после мув эвента игрок уже стоит на месте. Собственно поэтому Velocity игрока и не работает никогда почти. Ибо в большинстве случаев она отсылается сервером чтобы пнуть игрока и тут же забывается.Прыжок не решает, я написал для примера. Из кода видно, что на "видимость" влияет и эвенты, и шедуллер. В первом посте объяснил ущербность использования эвентов в моём случае. Как эвентом отоавливать осановку игрока, тобиш когда он перестаёт идти?
И как это сделать с технической стороны?В майнкрафте игрок останавливается как только перестаёт слать пакеты. То бишь через тик после мув эвента игрок уже стоит на месте. Собственно поэтому Velocity игрока и не работает никогда почти. Ибо в большинстве случаев она отсылается сервером чтобы пнуть игрока и тут же забывается.
А ты сам подумай. Тут куча вариантов.И как это сделать с технической стороны?
Ну я не настолько туп… Мне надо отловить именно остановку игрока, а не начало движения.Можно посмотреть как реализована проверка на AFK в том же Essentials...
Я порылся в одном плагине… Видимо щедулер надо ставить с задержкой в один тик? И по 20 раз в секунду чекать velocity. А то у меня задержка 20 тиков (1 с), наверное поэтому и не работает.А ты сам подумай. Тут куча вариантов.
Самый простой - шедулер и запись тика последнего движения.
можно и 2-3-4 тика, точности будет достаточно, а ресурсов сэкономлено будет прилично.Ну я не настолько туп… Мне надо отловить именно остановку игрока, а не начало движения.
Я порылся в одном плагине… Видимо щедулер надо ставить с задержкой в один тик? И по 20 раз в секунду чекать velocity. А то у меня задержка 20 тиков (1 с), наверное поэтому и не работает.
private HashMap<String, Location> locs = new HashMap<String, Location>();
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
@Override
public void run() {
for(Player p : Bukkit.getOnlinePlayers()){
Location l = p.getLocation();
Location ll = locs.get(p.getName());
if(ll == null){
locs.put(p.getName(), l);
continue;
}
if(l.getBlockX() == ll.getBlockX() && l.getBlockY() == ll.getBlockY() && l.getBlockZ() == ll.getBlockZ()){
p.sendMessage("Нельзя останавливаться.");
} else {
locs.put(p.getName(), l);
}
}
}
}, 0L, 8L);
package ru.simsonic.utilities;
import java.util.HashSet;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
public class MovingPlayersCatcher implements Listener
{
private final HashSet<Player> movedPlayers = new HashSet<>();
// Выдаёт Set игроков, которые "двинулись" с момента последнего опроса.
public synchronized HashSet<Player> getMovedPlayersAsync()
{
HashSet<Player> result = new HashSet<>(movedPlayers);
movedPlayers.clear();
return result;
}
@org.bukkit.event.EventHandler
protected synchronized void onPlayerJoin(PlayerJoinEvent event)
{
movedPlayers.add(event.getPlayer());
}
@org.bukkit.event.EventHandler
protected synchronized void onPlayerMove(PlayerMoveEvent event)
{
movedPlayers.add(event.getPlayer());
}
@org.bukkit.event.EventHandler
protected synchronized void onPlayerTeleport(PlayerTeleportEvent event)
{
movedPlayers.add(event.getPlayer());
}
@org.bukkit.event.EventHandler
protected synchronized void onPlayerChangedWorld(PlayerChangedWorldEvent event)
{
movedPlayers.add(event.getPlayer());
}
}