Существующая зона случайного PVP

  • Автор темы Автор темы barao45
  • Дата начала Дата начала

barao45

Свой человек
Пользователь
Старожил I степени
Сообщения
25
Розыгрыши
0
Репутация
0
Реакции
0
Баллы
533
Хроники
  1. Fafurion
Исходники
Отсутствуют
Сборка
NN
Всем привет! Мне нужна помощь. Я хочу создать планируемое событие, например, TVT, которое берёт существующую зону из файла zones.xml (например, город Гиран) и делает её PvP-зоной на определённое время. Я пробовал это сделать, но зона глючит и остаётся PvP-зоной независимо от того, активно событие или нет. Я использую L2jMobius Essence.
 
ты зону одного типа меняешь на другую или что?

логично объявить отдельную зону нужного типа, изначально в выключенном состоянии, а в эвенте ее просто находишь по имени и включаешь/выключаешь её когда надо через метод setEnabled.
 
Если ты хочешь сделать ивент - максимально правильно бы сделать под него отдельный рефлекшен, а не использовать мейн. Внутри зоны при старте движа активируешь зону, которая заранее указана, как пвп
 
ты зону одного типа меняешь на другую или что?

логично объявить отдельную зону нужного типа, изначально в выключенном состоянии, а в эвенте ее просто находишь по имени и включаешь/выключаешь её когда надо через метод setEnabled.
Хорошо. Значит, когда событие начнётся, мне нужно деактивировать зону без PvP и активировать PvP, а когда событие закончится, заново активировать мирную зону, верно?
 
ну да
но вобще, как вон выше уже написали, пвп-эвенты лучше проводить в отдельном инстансе, чтобы не мешать игрокам которые находятся в месте проведения, но не участвуют в эвенте
 
Запрещено публиковать исходный код без BB-кода — CODE
package custom.events.RandomZoneEvent;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ScheduledFuture;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import org.l2jmobius.commons.threads.ThreadPool;
import org.l2jmobius.commons.time.SchedulingPattern;
import org.l2jmobius.commons.time.TimeUtil;
import org.l2jmobius.commons.util.IXmlReader;
import org.l2jmobius.gameserver.managers.ZoneManager;
import org.l2jmobius.gameserver.model.StatSet;
import org.l2jmobius.gameserver.model.actor.Creature;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.Player;
import org.l2jmobius.gameserver.model.quest.Event;
import org.l2jmobius.gameserver.model.zone.ZoneId;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.model.zone.type.RandomZone;
import org.l2jmobius.gameserver.util.Broadcast;

/**
* Random Zone Event - Activates one random PvP zone temporarily.
* Does not modify the zone class at runtime: it works by changing flags for players who enter/leave while the event is active.
* @author Juan (adapted)
*/
public class RandomZoneEvent extends Event
{
private static final String CONFIG_FILE = "data/scripts/custom/events/RandomZoneEvent/config.xml";

private static int EVENT_DURATION_MINUTES = 15;

private static boolean _isActive = false;
private ScheduledFuture<?> _eventTask = null;

private final List<ZoneType> _availableZones = new ArrayList<>();
private ZoneType _activeZone = null;

private RandomZoneEvent()
{
loadConfig();
loadZones();
}

private void loadConfig()
{
new IXmlReader()
{
@Override
public void load()
{
parseDatapackFile(CONFIG_FILE);
}

@Override
public void parseDocument(Document doc, File file)
{
forEach(doc, "event", eventNode ->
{
final StatSet att = new StatSet(parseAttributes(eventNode));
final String name = att.getString("name");

for (Node node = eventNode.getFirstChild(); node != null; node = node.getNextSibling())
{
if ("schedule".equals(node.getNodeName()))
{
final StatSet attributes = new StatSet(parseAttributes(node));
final String pattern = attributes.getString("pattern");
final SchedulingPattern schedulingPattern = new SchedulingPattern(pattern);

final StatSet params = new StatSet();
params.set("Name", name);
params.set("SchedulingPattern", pattern);

final long delay = schedulingPattern.getDelayToNextFromNow();
getTimers().addTimer("Schedule_" + name, params, delay + 5000, null, null);
LOGGER.info("[RandomZoneEvent] Event " + name + " scheduled at " + TimeUtil.getDateTimeString(System.currentTimeMillis() + delay));
}
}
});
}
}.load();
}

private void loadZones()
{
for (ZoneType zone : ZoneManager.getInstance().getAllZones(RandomZone.class))
{
if ((zone.getName() != null) && zone.getName().toLowerCase().startsWith("random_zone"))
{
if (!_availableZones.contains(zone))
{
_availableZones.add(zone);
LOGGER.info("[RandomZoneEvent] Loaded zone: " + zone.getName() + " (id=" + zone.getId() + ")");
}
}
}
LOGGER.info("[RandomZoneEvent] ✅ Total loaded: " + _availableZones.size());
}

@Override
public void onTimerEvent(String event, StatSet params, Npc npc, Player player)
{
if (event.startsWith("Schedule_"))
{
eventStart(null);
final SchedulingPattern schedulingPattern = new SchedulingPattern(params.getString("SchedulingPattern"));
final long delay = schedulingPattern.getDelayToNextFromNow();
getTimers().addTimer(event, params, delay + 5000, null, null);
LOGGER.info("[RandomZoneEvent] Rescheduled for " + TimeUtil.getDateTimeString(System.currentTimeMillis() + delay));
}
}

@Override
public boolean eventStart(Player eventMaker)
{
if (_isActive)
{
if (eventMaker != null)
{
eventMaker.sendMessage("RandomZoneEvent is already active.");
}
return false;
}

if (_availableZones.isEmpty())
{
Broadcast.toAllOnlinePlayers("[RandomZoneEvent] No zones configured.");
return false;
}

_isActive = true;
Broadcast.toAllOnlinePlayers("⚔️ Random Zone Event has started! Preparing a PvP zone...");

_eventTask = ThreadPool.schedule(this::activateRandomZone, 5_000);
return true;
}

private void activateRandomZone()
{
final ZoneType selected = _availableZones.get(new Random().nextInt(_availableZones.size()));
_activeZone = selected;

_activeZone.setEnabled(true);

// broadcast
Broadcast.toAllOnlinePlayers("🔥 Random Zone Event: " + _activeZone.getName() + " is now PvP for " + EVENT_DURATION_MINUTES + " minutes!");

_eventTask = ThreadPool.schedule(this::eventStop, EVENT_DURATION_MINUTES * 60 * 1000L);
}

@Override
public boolean eventStop()
{
if (!_isActive)
{
return false;
}

_isActive = false;

if (_eventTask != null)
{
_eventTask.cancel(true);
_eventTask = null;
}

if (_activeZone != null)
{
Broadcast.toAllOnlinePlayers("🏁 The Random Zone Event has ended. " + _activeZone.getName() + " has returned to normal.");
_activeZone = null;
}
else
{
Broadcast.toAllOnlinePlayers("🏁 The Random Zone Event has ended.");
}

return true;
}

@Override
public void onEnterZone(Creature creature, ZoneType zone)
{
if (!_isActive || (_activeZone == null))
{
return;
}

if ((zone == _activeZone) && creature.isPlayable())
{
creature.setInsideZone(ZoneId.PEACE, false);
creature.setInsideZone(ZoneId.SIEGE, true);

if (creature.isPlayer())
{
creature.sendMessage("This zone is temporarily in PvP mode.");
}
}
}

@Override
public void onExitZone(Creature creature, ZoneType zone)
{
if (!_isActive || (_activeZone == null))
{
return;
}

if ((zone == _activeZone) && creature.isPlayable())
{
creature.setInsideZone(ZoneId.PEACE, true);
creature.setInsideZone(ZoneId.SIEGE, false);
if (creature.isPlayer())
{
creature.sendMessage("The zone is no longer in PvP mode.");
}
}
}

@Override
public boolean eventBypass(Player player, String bypass)
{
return true;
}

@Override
public String onEvent(String event, Npc npc, Player player)
{
return event;
}

@Override
public String onFirstTalk(Npc npc, Player player)
{
return null;
}

public static void main(String[] args)
{
new RandomZoneEvent();
}
}

Я работал с этим классом события, он пока не функционален, но это была общая идея того, что я хотел сделать.
Когда ты говоришь «новый экземпляр», ты имеешь в виду экземпляр класса?
Извини за вопрос, у меня не так много знаний в этой области.
В этом коде мне, кажется, нужно взять зону по её ID, установить active = false и активировать зону как случайную (Random), в которой возможно PvP, насколько я понимаю.
 
Назад
Сверху Снизу