Last active
August 29, 2015 14:10
-
-
Save Pandragon/e074311a082ea46008cd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2004-2015 L2J DataPack | |
* | |
* This file is part of L2J DataPack. | |
* | |
* L2J DataPack is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation, either version 3 of the License, or | |
* (at your option) any later version. | |
* | |
* L2J DataPack is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
* General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
package ai.fantasy_isle; | |
import java.text.SimpleDateFormat; | |
import java.util.concurrent.CopyOnWriteArrayList; | |
import java.util.concurrent.ScheduledFuture; | |
import ai.npc.AbstractNpcAI; | |
import com.l2jserver.gameserver.GameTimeController; | |
import com.l2jserver.gameserver.ThreadPoolManager; | |
import com.l2jserver.gameserver.ai.CtrlIntention; | |
import com.l2jserver.gameserver.model.Location; | |
import com.l2jserver.gameserver.model.actor.L2Npc; | |
/** | |
* Fantasy Isle Parade | |
* @author JOJO, Pandragon | |
*/ | |
public class Parade extends AbstractNpcAI | |
{ | |
// @formatter:off | |
protected final int[] ACTORS = | |
{ | |
32379, 0, 32379, | |
32379, 0, 32379, | |
32379, 0, 32379, | |
0, 0, 0, | |
32380, 0, 32380, | |
32380, 32381, 32380, | |
32380, 0, 32380, | |
32380, 32381, 32380, | |
0, 0, 0, | |
32382, 32382, 32382, | |
32382, 32383, 32382, | |
32383, 32384, 32383, | |
32383, 32384, 32383, | |
0, 0, 0, | |
0, 32385, 0, | |
32385, 0, 32385, | |
0, 32385, 0, | |
0, 0, 0, | |
32412, 0, 32411, | |
0, 0, 0, | |
32421, 0, 32409, | |
32423, 0, 32422, | |
0, 0, 0, | |
32420, 32419, 32417, | |
32418, 0, 32416, | |
0, 0, 0, | |
32414, 0, 32414, | |
0, 32413, 0, | |
32414, 0, 32414, | |
0, 0, 0, | |
32393, 0, 32394, | |
0, 32430, 0, | |
32392, 0, 32391, | |
0, 0, 0, | |
0, 32404, 0, | |
32403, 0, 32401, | |
0, 0, 0, | |
0, 32408, 0, | |
32406, 0, 32407, | |
0, 32405, 0, | |
0, 0, 0, | |
32390, 32389, 32387, | |
32388, 0, 32386, | |
0, 0, 0, | |
0, 32400, 0, | |
32397, 32398, 32396, | |
0, 0, 0, | |
0, 32450, 0, | |
32448, 32449, 32447, | |
0, 0, 0, | |
32380, 0, 32380, | |
32380, 32381, 32380, | |
32380, 0, 32380, | |
32380, 32381, 32380, | |
0, 0, 0, | |
32379, 0, 32379, | |
32379, 0, 32379, | |
32379, 0, 32379, | |
0, 0, 0, | |
0, 32415, 0 | |
}; | |
//(Northbound 270 degrees) Route 1 | |
private final int[][] START1 = {{-54780, -56810, -2015, 49152},{-54860, -56810, -2015, 49152},{-54940, -56810, -2015, 49152}}; | |
private final int[][] GOAL1 = {{-54780, -57965, -2015, 49152},{-54860, -57965, -2015, 49152},{-54940, -57965, -2015, 49152}}; | |
//(Westbound 180 degrees) Route 2 | |
private final int[][] START2 = {{-55715, -58900, -2015, 32768},{-55715, -58820, -2015, 32768},{-55715, -58740, -2015, 32768}}; | |
private final int[][] GOAL2 = {{-60850, -58900, -2015, 32768},{-60850, -58820, -2015, 32768},{-60850, -58740, -2015, 32768}}; | |
//(Southbound 90 degrees) Route 3 | |
private final int[][] START3 = {{-61790, -57965, -2015, 16384},{-61710, -57965, -2015, 16384},{-61630, -57965, -2015, 16384}}; | |
private final int[][] GOAL3 = {{-61790, -53890, -2116, 16384},{-61710, -53890, -2116, 16384},{-61630, -53890, -2116, 16384}}; | |
//(Eastbound 0 degrees) Route 4 | |
private final int[][] START4 = {{-60840, -52990, -2108, 0},{-60840, -53070, -2108, 0},{-60840, -53150, -2108, 0}}; | |
private final int[][] GOAL4 = {{-58620, -52990, -2015, 0},{-58620, -53070, -2015, 0},{-58620, -53150, -2015, 0}}; | |
//(To 315 degrees northeast) Route 5 | |
private final int[][] START5 = {{-57233, -53554, -2015, 57344},{-57290, -53610, -2015, 57344},{-57346, -53667, -2015, 57344}}; | |
private final int[][] GOAL5 = {{-55338, -55435, -2015, 57344},{-55395, -55491, -2015, 57344},{-55451, -55547, -2015, 57344}}; | |
final int[][][] START = {START1, START2, START3, START4, START5}; | |
final int[][][] GOAL = {GOAL1, GOAL2, GOAL3, GOAL4, GOAL5}; | |
// @formatter:on | |
int npcIndex; | |
CopyOnWriteArrayList<L2Npc> spawns; | |
ScheduledFuture<?> spawnTask; | |
ScheduledFuture<?> deleteTask; | |
ScheduledFuture<?> cleanTask; | |
public Parade() | |
{ | |
super(Parade.class.getSimpleName(), "ai/fantasy_isle"); | |
// Starts at 8:00 and repeats every 6 hours. | |
final long diff = timeLeftMilli(8, 0, 0), cycle = 3600000L; | |
ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Start(), diff, cycle); | |
// Test - Starts 3 minutes after server startup and repeats every 20 minutes. | |
// final long diff = timeLeftMilli(8, 0, 0), cycle = 600000L; | |
// ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Start(), 180000L, cycle); | |
final SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm"); | |
_log.info("Fantasy Isle: Parade starting at " + format.format(System.currentTimeMillis() + diff) + " and is scheduled each next " + (cycle / 3600000) + " hours."); | |
} | |
protected void load() | |
{ | |
npcIndex = 0; | |
spawns = new CopyOnWriteArrayList<>(); | |
} | |
protected void clean() | |
{ | |
if (spawns != null) | |
{ | |
spawns.forEach(L2Npc::deleteMe); | |
} | |
spawns = null; | |
} | |
private long timeLeftMilli(int hh, int mm, int ss) | |
{ | |
int now = (GameTimeController.getInstance().getGameTicks() * 60) / 100; | |
int dd = ((hh * 3600) + (mm * 60) + ss) - (now % 86400); | |
if (dd < 0) | |
{ | |
dd += 86400; | |
} | |
return (dd * 1000L) / 6L; | |
} | |
protected class Start implements Runnable | |
{ | |
@Override | |
public void run() | |
{ | |
load(); | |
spawnTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Spawn(), 0, 5000); | |
deleteTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new Delete(), 10000, 1000); | |
cleanTask = ThreadPoolManager.getInstance().scheduleGeneral(new Clean(), 420000); | |
} | |
} | |
protected class Spawn implements Runnable | |
{ | |
@Override | |
public void run() | |
{ | |
for (int i = 0; i < 3; ++i) | |
{ | |
if (npcIndex >= ACTORS.length) | |
{ | |
spawnTask.cancel(false); | |
break; | |
} | |
int npcId = ACTORS[npcIndex++]; | |
if (npcId == 0) | |
{ | |
continue; | |
} | |
for (int route = 0; route < 5; ++route) | |
{ | |
int[] start = START[route][i]; | |
int[] goal = GOAL[route][i]; | |
L2Npc actor = addSpawn(npcId, start[0], start[1], start[2], start[3], false, 0); | |
actor.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(goal[0], goal[1], goal[2], goal[3])); | |
spawns.add(actor); | |
} | |
} | |
} | |
} | |
protected class Delete implements Runnable | |
{ | |
@Override | |
public void run() | |
{ | |
if (spawns.size() > 0) | |
{ | |
for (L2Npc actor : spawns) | |
{ | |
if (actor != null) | |
{ | |
if (actor.calculateDistance(actor.getXdestination(), actor.getYdestination(), 0, false, true) < (100 * 100)) | |
{ | |
actor.deleteMe(); | |
spawns.remove(actor); | |
} | |
else if (!actor.isMoving()) | |
{ | |
actor.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(actor.getXdestination(), actor.getYdestination(), actor.getZdestination(), actor.getHeading())); | |
} | |
} | |
} | |
if (spawns.size() == 0) | |
{ | |
deleteTask.cancel(false); | |
} | |
} | |
} | |
} | |
protected class Clean implements Runnable | |
{ | |
@Override | |
public void run() | |
{ | |
spawnTask.cancel(false); | |
spawnTask = null; | |
deleteTask.cancel(false); | |
deleteTask = null; | |
cleanTask.cancel(false); | |
cleanTask = null; | |
clean(); | |
} | |
} | |
public static void main(String[] args) | |
{ | |
new Parade(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment