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. No modifica la clase de la zona: usa flags PvP en runtime.
* @author Juan
*/
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;
public RandomZoneEvent()
{
loadConfig();
loadZones();
registerZoneListeners();
}
/**
* Registra listeners a TODAS LAS ZONAS random
*/
private void registerZoneListeners()
{
for (ZoneType zone : _availableZones)
{
addEnterZoneId(zone.getId());
addExitZoneId(zone.getId());
LOGGER.info("[RandomZoneEvent] Registered listener for zone: " + zone.getName());
}
}
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"))
{
_availableZones.add(zone);
LOGGER.info("[RandomZoneEvent] Loaded zone: " + zone.getName() + " (id=" + zone.getId() + ")");
}
}
LOGGER.info("[RandomZoneEvent] Total random zones 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 already active.");
}
return false;
}
if (_availableZones.isEmpty())
{
Broadcast.toAllOnlinePlayers("[RandomZoneEvent] No zones configured.");
return false;
}
_isActive = true;
Broadcast.toAllOnlinePlayers(" Random Zone Event has started!");
_eventTask = ThreadPool.schedule(this::activateRandomZone, 5_000);
return true;
}
private void activateRandomZone()
{
_activeZone = _availableZones.get(new Random().nextInt(_availableZones.size()));
_activeZone.setEnabled(true);
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)
{
_activeZone.setEnabled(false);
Broadcast.toAllOnlinePlayers(" Random Zone Event ended. " + _activeZone.getName() + " is back to normal.");
_activeZone = null;
}
else
{
Broadcast.toAllOnlinePlayers(" Random Zone Event ended.");
}
return true;
}
@Override
public void onEnterZone(Creature creature, ZoneType zone)
{
if (!_isActive || (_activeZone == null))
{
return;
}
if ((zone == _activeZone) && creature.isPlayable())
{
creature.setInsideZone(ZoneId.PVP, true);
if (creature.isPlayer())
{
creature.sendMessage("Esta zona está en modo PvP temporalmente.");
}
}
}
@Override
public void onExitZone(Creature creature, ZoneType zone)
{
if (!_isActive || (_activeZone == null))
{
return;
}
if ((zone == _activeZone) && creature.isPlayable())
{
creature.setInsideZone(ZoneId.PVP, false);
if (creature.isPlayer())
{
creature.sendMessage("Abandonaste la zona PvP temporal.");
}
}
}
@Override
public boolean eventBypass(Player player, String bypass)
{
return true;
}
@Override
public String onEvent(String event, Npc npc, Player player)
{
return super.onEvent(event, npc, player);
}
@Override
public String onFirstTalk(Npc npc, Player player)
{
return null;
}
public static void main(String[] args)
{
new RandomZoneEvent();
}
}
i have this but its not working