if(getType() == ZoneType.epic)
{
((Player)actor).updatePvPFlag(0);
actor.sendMessage("You have leave the PVP Zone");
}
@Override
public void startPvPFlag(Creature target)
{
if(_karma > 0)
return;
if(isOnSiegeField())
return;
long startTime = System.currentTimeMillis();
if(target != null && target.getPvpFlag() != 0)
startTime -= Config.PVP_TIME / 2;
if(_pvpFlag != 0 && _lastPvpAttack > startTime)
return;
_lastPvpAttack = startTime;
updatePvPFlag(1);
if(_PvPRegTask == null)
_PvPRegTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(new PvPFlagTask(this), 1000, 1000);
}
public void stopPvPFlag()
{
if(_PvPRegTask != null)
{
_PvPRegTask.cancel(false);
_PvPRegTask = null;
}
updatePvPFlag(0);
}
сюда смотрите.PvPFlagTask
Спасибо за ответ, но я сделал по другому, так как изначально я вносил правки в zone.java а там ругалось на ( player. / target. ) и не знал как исправить. Так я добавил новую зону epic в compass,playable,player и все заработало только с побочными эффектами на все комбат зоны =)сюда смотрите.
Каждую секунду когда чар в ПВП выполняется этот фрагмент
Я не кодер и не учил ява, но вы верно сказали, логично будет добавить в лисинер нужной зоны. Еще что подумал у меня уже есть обработка ПВП флага, можна же зделать на подобии осады, когда выходиш из зоны то получаеш флаг. Типа обработчик есть нужно только его прикрутить в нужном месте. Може быть так или всетаки в лисинер в зонелив установить флаг 2 и запускать таск время и установка флага 0 можно даже кастомноеЯ правильно понял что необходимо сделать чтобы при выходе из определенных зон, через N секунд скидывало флаг пвп?
Если да то решение элементарное - листенер на нужные зоны и в onLeave в них запуск таска на снятие флага, с нужной задержкой, ну или просто корректировка времени до окнчания статуса флаганого до нужного значения.
package l2s.gameserver.listener.zone.impl;
import l2s.gameserver.Config;
import l2s.gameserver.listener.zone.OnZoneEnterLeaveListener;
import l2s.gameserver.model.Creature;
import l2s.gameserver.model.Player;
import l2s.gameserver.model.Zone;
import l2s.gameserver.network.l2.components.CustomMessage;
import l2s.gameserver.utils.Location;
public class EpicZoneListener implements OnZoneEnterLeaveListener
{
public static final OnZoneEnterLeaveListener STATIC = new EpicZoneListener();
@Override
public void onZoneEnter(Zone zone, Creature cha)
{
if(cha.isPlayable() && !cha.getPlayer().isGM())
{
if(cha.getLevel() > zone.getParams().getInteger("levelLimit", Integer.MAX_VALUE))
{
if(cha.isPlayer())
cha.getPlayer().sendMessage(new CustomMessage("scripts.zones.epic.banishMsg", cha.getPlayer()));
cha.teleToLocation(Location.parseLoc(zone.getParams().getString("tele")));
}
else
{
if(!Config.ALT_USE_TRANSFORM_IN_EPIC_ZONE)
{
if(cha.isPlayer())
{
Player player = cha.getPlayer();
if(player.getTransformation() > 0 && player.getTransformationTemplate() > 0 && !player.isCursedWeaponEquipped())
{
// TODO: Нужно ли тут какое-то сообщение?
player.setTransformation(0);
player.updatePvPFlag(1);
}
}
}
}
}
}
@Override
public void onZoneLeave(Zone zone, Creature cha)
{
if(cha.isPlayer())
{
Player player = cha.getPlayer();
if (player.getPvpFlag())
{
long startTime = System.currentTimeMillis();
if(player != null && player.getPvpFlag() != 0)
startTime -= Config.PVP_TIME / 2;
if(_pvpFlag != 0 > startTime)
return;
if(_PvPRegTask == null)
_PvPRegTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(new PvPFlagTask(this), 1000, 1000);
}
}
}
}
private ScheduledFuture _PvPRegTask;
if (player.getPvpFlag())
if (player.getPvpFlag() > 0)
if(_pvpFlag != 0 > startTime)
package l2s.gameserver.listener.zone.impl;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import l2s.gameserver.Config;
import l2s.gameserver.listener.zone.OnZoneEnterLeaveListener;
import l2s.gameserver.model.Creature;
import l2s.gameserver.model.Player;
import l2s.gameserver.model.Zone;
import l2s.gameserver.network.l2.components.CustomMessage;
import l2s.gameserver.utils.Location;
import l2s.gameserver.ThreadPoolManager;
import l2s.gameserver.model.GameObjectTasks.PvPFlagTask;
public class EpicZoneListener implements OnZoneEnterLeaveListener
{
public static final OnZoneEnterLeaveListener STATIC = new EpicZoneListener();
@Override
public void onZoneEnter(Zone zone, Creature cha)
{
if(cha.isPlayable() && !cha.getPlayer().isGM())
{
if(cha.getLevel() > zone.getParams().getInteger("levelLimit", Integer.MAX_VALUE))
{
if(cha.isPlayer())
cha.getPlayer().sendMessage(new CustomMessage("scripts.zones.epic.banishMsg", cha.getPlayer()));
cha.teleToLocation(Location.parseLoc(zone.getParams().getString("tele")));
}
else
{
if(!Config.ALT_USE_TRANSFORM_IN_EPIC_ZONE)
{
if(cha.isPlayer())
{
Player player = cha.getPlayer();
if(player.getTransformation() > 0 && player.getTransformationTemplate() > 0 && !player.isCursedWeaponEquipped())
{
// TODO: Нужно ли тут какое-то сообщение?
player.setTransformation(0);
player.updatePvPFlag(1);
}
}
}
}
}
}
private Future<?> _PvPRegTask;
@Override
public void onZoneLeave(Zone zone, Creature cha)
{
if(cha.isPlayer())
{
Player player = cha.getPlayer();
if (player.getPvpFlag() > 0)
{
long startTime = System.currentTimeMillis();
if(player != null && player.getPvpFlag() != 0)
startTime -= Config.PVP_TIME / 2;
if(_PvPRegTask == null)
_PvPRegTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(new PvPFlagTask(this), 1000, 1000);
}
}
}
}
if(_pvpFlag != 0 > startTime)
private ScheduledFuture _PvPRegTask;
private Future<?> _PvPRegTask;
да можно и оставить, так как ScheduledFuture по сути расширяется классом Futureи думаю оставить так, если оно уже так написано =)
public interface ScheduledFuture<V> extends Delayed, Future<V> {
}
_PvPRegTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(new GameObjectTasks.PvPFlagTask(player), 1000, 1000);
поставить логирование в методах onZoneEnter и onZoneLeave перед всеми проверками, и смотреть запускается ли слушатель (при входы в/выходе из зоны)Так то компил работает: BUILD SUCCESSFUL
Осталось понять почему лисинер EpicZone вообще не делает то что я ему прописал.
Но если что +- рабочий вариант есть, воткну в другом месте. Где-то в Zone.java там точно работало updatePvpFlag
Я проверил работу таймера.поставить логирование в методах onZoneEnter и onZoneLeave перед всеми проверками, и смотреть запускается ли слушатель (при входы в/выходе из зоны)
private Future<?> _PvPRegTask;
@Override
public void onZoneLeave(Zone zone, Creature cha)
{
if(cha.isPlayer())
{
Player player = cha.getPlayer();
if (player.getPvpFlag() > 0)
{
long startTime = System.currentTimeMillis();
startTime -= Config.PVP_TIME / 2;
if(_PvPRegTask == null)
_PvPRegTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(new GameObjectTasks.PvPFlagTask(player), 1000, 1000);
}
}
}
if(getType() == ZoneType.epic)
{
((Player)actor).updatePvPFlag(1);
actor.sendMessage("You have entered the PVP Zone");
}
стоит разобраться в особенностях работы методов scheduleAtFixedRate, scheduleAtFixedDelay и schedule класса ThreadPoolManagerИ тут самое интересное что в public void onZoneLeave должен по идеи обрабатывать только когда вышел из зоны. А по факту захожу в зону получаю флаг и через 1-2 сек пропадает флаг не зависимо от того вышел из зоны или нет.
_PvPRegTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(new GameObjectTasks.PvPFlagTask(player), 1000, 1000);
long startTime = System.currentTimeMillis();
startTime -= Config.PVP_TIME / 2;
if(getType() == ZoneType.epic)
{
((Player)actor).updatePvPFlag(2);
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
((Player)actor).updatePvPFlag(0);
}
},
20000
);
actor.sendMessage("You have leave the PVP Zone");
}
public static class PvPFlagTask extends RunnableImpl
{
private final HardReference<Player> _playerRef;
public PvPFlagTask(Player player)
{
_playerRef = player.getRef();
}
@Override
public void runImpl()
{
Player player = _playerRef.get();
if(player == null)
return;
long diff = Math.abs(System.currentTimeMillis() - player.getlastPvpAttack());
if(diff > Config.PVP_TIME)
player.stopPvPFlag();
else if(diff > Config.PVP_TIME - 20000)
player.updatePvPFlag(2);
else
player.updatePvPFlag(1);
}
}
public void stopPvPFlag()
{
if(_PvPRegTask != null)
{
_PvPRegTask.cancel(false);
_PvPRegTask = null;
}
updatePvPFlag(0);
}
и снова запускается.
стоит разобраться в особенностях работы методов scheduleAtFixedRate, scheduleAtFixedDelay и schedule класса ThreadPoolManager
ну не знаю как еще тебе помочь)в данном случае через секунду и потом каждую секунду будет запущена задача PvPFlagTask
_PvPRegTask = ThreadPoolManager.getInstance().schedule(new GameObjectTasks.PvPFlagTask(player), 1000);
if ( _PvPRegTask == null || _PvPRegTask.isDone() )
И на этом огромное спасибо, я не ищу исполнителя мне просто интересно свободное время потратить впустую =) хочу немного узнать java. Сейчас почитаю scheduleAtFixedRate, scheduleAtFixedDelay и schedule класса ThreadPoolManagerну не знаю как еще тебе помочь)
вот если так?
1000 - через сколько миллисекунд будет запущена задача PvPFlagTask после выхода из зоныJava:_PvPRegTask = ThreadPoolManager.getInstance().schedule(new GameObjectTasks.PvPFlagTask(player), 1000);
и по идеи после определения _PvPRegTask уже будет не null, и при следующем выходе из зоны новая задача не будет запущена
может как то проверять ее состояние, например так
или как-то по другомуJava:if ( _PvPRegTask == null || _PvPRegTask.isDone() )
если самому не допрет как сделать, советую раздел Ищу исполнителя
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?