public class TeleporterInstance extends MerchantInstance {
private static final String DATA_PATH = "data/spawn/";
private static ScheduledFuture<?> zoneRotationTask;
private static List<NpcInstance> activeNpcs = new ArrayList<>();
// Constructor for TeleporterInstance
public TeleporterInstance(int objectId, NpcTemplate template) {
super(objectId, template);
startAutoZoneRotation(); // Automatically start zone rotation when NPC is created
}
// Automatically schedules zone rotation every day at midnight
public static void startAutoZoneRotation() {
runZoneRotation(); // Perform an immediate rotation
long timeUntilNextDay = calculateTimeUntilMidnight();
// Schedule daily zone rotation at 00:00
zoneRotationTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(TeleporterInstance::runZoneRotation,
timeUntilNextDay,
86400000); // 24 hours
}
// Run the zone rotation logic (spawn/despawn NPCs)
public static void runZoneRotation() {
// Get the current day of the week to determine the active zone
DayOfWeek currentDay = LocalDate.now().getDayOfWeek();
String dayName = currentDay.name().toLowerCase(); // Get day in lowercase (e.g., "monday")
// Load NPCs from XML based on the day of the week
loadNpcsForDay(dayName);
}
// Load NPCs for the current day from XML files
public static void loadNpcsForDay(String dayName) {
// Define zone names for each day and load respective XML files
String[] zones = {"devilsisle", "cruma_marshlands", "pagan_temple", "ruins_of_despair"};
// Despawn current NPCs, if any
despawnNpcs();
// Load and spawn NPCs for each zone
for (String zone : zones) {
String filename = DATA_PATH + dayName + "_" + zone + ".xml";
spawnNpcsFromXml(filename);
}
// Announce the new active zone to players
Announcements.getInstance().announceByCustomMessage("CustomZonesEvent.ZoneActive." + dayName, null);
}
// Spawn NPCs from the given XML file
private static void spawnNpcsFromXml(String filename) {
try {
// Initialize the XML parser
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File(filename));
NodeList spawnList = doc.getElementsByTagName("spawn");
for (int i = 0; i < spawnList.getLength(); i++) {
Node spawnNode = spawnList.item(i);
if (spawnNode.getNodeType() == Node.ELEMENT_NODE) {
Element spawnElement = (Element) spawnNode;
// Get the <npc> element inside <spawn>
NodeList npcList = spawnElement.getElementsByTagName("npc");
for (int j = 0; j < npcList.getLength(); j++) {
Element npcElement = (Element) npcList.item(j);
// Extract npc attributes
int npcId = Integer.parseInt(npcElement.getAttribute("id"));
int respawnTime = Integer.parseInt(npcElement.getAttribute("respawn"));
// Extract the position from the 'pos' attribute
String pos = npcElement.getAttribute("pos");
String[] positionData = pos.split(" ");
int x = Integer.parseInt(positionData[0]);
int y = Integer.parseInt(positionData[1]);
int z = Integer.parseInt(positionData[2]);
int heading = Integer.parseInt(positionData[3]); // Optional, for future use
// Spawn the NPC and set respawn timer
spawnAndRespawnNpc(npcId, x, y, z, respawnTime);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
// Method to spawn and respawn an NPC after a certain delay
private static void spawnAndRespawnNpc(int npcId, int x, int y, int z, int respawnTime) {
Location spawnLocation = new Location(x, y, z);
NpcInstance npc = NpcHolder.getInstance().getTemplate(npcId).getNewInstance();
// Spawn the NPC at the specified location
npc.spawnMe(spawnLocation);
// Prevent the NPC from walking (set AI to idle)
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Add to the active NPC list
activeNpcs.add(npc);
// Schedule the NPC to respawn after the specified time
ThreadPoolManager.getInstance().schedule(() -> {
// Despawn the NPC and respawn it after the delay
if (!npc.isDeleted()) {
npc.deleteMe();
activeNpcs.remove(npc);
}
spawnAndRespawnNpc(npcId, x, y, z, respawnTime); // Recursively respawn the NPC
}, respawnTime * 1000L); // Convert respawn time to milliseconds
}