Index: C:/java/net/sf/l2j/gameserver/model/RandomSpawnHandler.java =================================================================== --- C:/java/net/sf/l2j/gameserver/model/RandomSpawnHandler.java (revision 1674) +++ C:/java/net/sf/l2j/gameserver/model/RandomSpawnHandler.java (working copy) @@ -1,207 +1,277 @@ -/* - * This program 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 2, or (at your option) - * any later version. - * - * This program 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * http://www.gnu.org/copyleft/gpl.html - */ package net.sf.l2j.gameserver.model; import java.util.List; -import java.util.Map; -import java.util.Random; import java.util.logging.Logger; -import javolution.util.FastList; -import javolution.util.FastMap; - import net.sf.l2j.Config; import net.sf.l2j.gameserver.ClientScheduler; +import net.sf.l2j.gameserver.idfactory.IdFactory; +import net.sf.l2j.gameserver.lib.Rnd; +import net.sf.l2j.gameserver.model.L2Spawn; import net.sf.l2j.gameserver.NpcTable; -import net.sf.l2j.gameserver.SpawnTable; import net.sf.l2j.gameserver.templates.L2NpcTemplate; -/** - * Random Spawn Handler - * - * Allows random spawning of a NPC object based on a timer. - * (From the official idea used for the Merchant and Blacksmith of Mammon) - * - * @author Tempy - * - */ -public class RandomSpawnHandler { +import javolution.util.FastList; + +public class RandomSpawnHandler +{ protected static Logger _log = Logger.getLogger(RandomSpawnHandler.class.getName()); - private static RandomSpawnHandler _instance; - - public static final int DEFAULT_RESPAWN = 3600000; //1 hour in millisecs - public static final int DEFAULT_DESPAWN = 3600000; //1 hour in millisecs - - protected List _npcIds; - protected List _resDelay; - protected List _desDelay; - protected Map _spawnLocs; - - public RandomSpawnHandler() - { - _npcIds = new FastList(); - _resDelay = new FastList(); - _desDelay = new FastList(); - _spawnLocs = new FastMap(); - } - - public static RandomSpawnHandler getInstance() - { - if (_instance == null) - { - _instance = new RandomSpawnHandler(); - } - - return _instance; - } - - public final int size() - { - return _npcIds.size(); - } - - public void start() - { - for (int i = 0; i < _npcIds.size(); i++) - { - RandomSpawner rs = new RandomSpawner(i, null, -1); - ClientScheduler.getInstance().scheduleLow(rs, 30000); // Initial spawn after 30 secs - } - } - - public void registerSpawn(int npcId, int[][] spawnPoints, int respawnDelay, int despawnDelay) - { - _npcIds.add(npcId); - _spawnLocs.put(npcId, spawnPoints); - - if (respawnDelay < 1) - respawnDelay = DEFAULT_RESPAWN; - - if (despawnDelay < 0) - despawnDelay = DEFAULT_DESPAWN; - - _resDelay.add(respawnDelay); - _desDelay.add(despawnDelay); - - if (Config.DEBUG) - _log.config("RandomSpawnHandler: Registered random spawn for NPC ID " + npcId); - } - - public final boolean removeSpawn(int npcId) - { - for (int i = 0; i < _npcIds.size(); i++) { - if (_npcIds.get(i) == npcId) { - _npcIds.remove(i); - _spawnLocs.remove(npcId); - _resDelay.remove(i); - _desDelay.remove(i); - if (Config.DEBUG) - _log.config("RandomSpawnHandler: Removed random spawn for NPC ID " + npcId); - - return true; - } - } - return false; - } - - - private class RandomSpawner implements Runnable - { - private int _npcIndex = 0; - private L2NpcInstance _npcInst; - private int _lastSpawnIndex; // Prevents spawning in same place twice! - - public RandomSpawner(int npcIndex, L2NpcInstance npcInst, int lastSpawnIndex) { - _npcIndex = npcIndex; - _npcInst = npcInst; - _lastSpawnIndex = lastSpawnIndex; // -1 = has no last spawn index. - } - - public void run() - { - try - { - int npcId = _npcIds.get(_npcIndex); - int[][] _spawns = _spawnLocs.get(npcId); - - Random rnd = new Random(); - int spawnIndex = rnd.nextInt(_spawns.length); - - if (_lastSpawnIndex != -1) - while (spawnIndex == _lastSpawnIndex) - spawnIndex = rnd.nextInt(_spawns.length); - - int _x = _spawns[spawnIndex][0]; - int _y = _spawns[spawnIndex][1]; - int _z = _spawns[spawnIndex][2]; - - if (_npcInst == null) - { - L2NpcTemplate npcTemplate = NpcTable.getInstance().getTemplate(npcId); - L2Spawn randomSpawn = new L2Spawn(npcTemplate); - - randomSpawn.setLocx(_x); - randomSpawn.setLocy(_y); - randomSpawn.setLocz(_z); - randomSpawn.setAmount(1); - SpawnTable.getInstance().addNewSpawn(randomSpawn, false); - _npcInst = randomSpawn.doSpawn(); - } - else { - _npcInst.spawnMe(_x, _y, _z); - } - - //if (Config.DEBUG) It may be useful to know where the spawn is! :) - _log.info("RandomSpawnHandler: Spawned NPC ID " + npcId + - " at " + _x + ", " + _y + ", " + _z + " for " + (_desDelay.get(_npcIndex) / 1000 / 60) + " mins."); - - RandomSpawner rs = new RandomSpawner(_npcIndex, _npcInst, spawnIndex); - ClientScheduler.getInstance().scheduleLow(rs, _resDelay.get(_npcIndex)); - - // If no despawn time, do not despawn this NPC instance. - if (_desDelay.get(_npcIndex) > 0) { - RandomDespawner rd = new RandomDespawner(_npcInst); - ClientScheduler.getInstance().scheduleLow(rd, _desDelay.get(_npcIndex)); - } - } - catch (Exception e) { - _log.warning("RandomSpawnHandler: An error occurred while spawning NPC ID " + _npcIds.get(_npcIndex) + ": " + e); - } - } - } - - private class RandomDespawner implements Runnable - { - private L2NpcInstance _npcInst; - - public RandomDespawner (L2NpcInstance npcInst) { - _npcInst = npcInst; - } - - public void run() - { - if (Config.DEBUG) - _log.info("RandomSpawnHandler: Hidden NPC ID " + _npcInst.getNpcId() + - " (Obj ID " + _npcInst.getObjectId() + ") at " + _npcInst.getX() + ", " + _npcInst.getY() + ", " + _npcInst.getZ() + "."); - - _npcInst.toggleVisible(); - } - } + // ========================================================================================== + // Shared + // ========================================================= + // Data Field + private static RandomSpawnHandler _instance; + + // ========================================================= + // Method - Public + // ========================================================= + // Method - Private + // ========================================================= + // Proeprty + public static RandomSpawnHandler getInstance() + { + if (_instance == null) + _instance = new RandomSpawnHandler(); + + return _instance; + } + + // ========================================================================================== + // Instance + public class RandomSpawnInstance + { + // ========================================================= + // Schedule Task + public class DeSpawnTask implements Runnable + { + public void run() + { + if (this == null || _Spawns.size() <= 0) + return; + + try + { + for (int i = 0; i < _Spawns.size(); i++) + { + if (_Spawns.get(i).getLastSpawn() == null) + continue; + + if (_Spawns.get(i).getLastSpawn().isVisible()) + _Spawns.get(i).getLastSpawn().decayMe(); + } + + if (_IsActive == true) // Respawn only if active + ClientScheduler.getInstance().scheduleLow(new SpawnTask(), _SpawnDelay); // Prepare auto spawn task + } catch (Throwable t){} + } + } + + public class SpawnTask implements Runnable + { + public void run() + { + if (this == null || _Spawns.size() <= 0) + return; + + try + { + int[] spawnLoc = _SpawnLocs.get(Rnd.get(_SpawnLocs.size())); + for (int i = 0; i < _Spawns.size(); i++) + { + if (_Spawns.get(i).getLastSpawn() == null) + continue; + + if (_Spawns.get(i).getLastSpawn().isVisible()) + _Spawns.get(i).getLastSpawn().decayMe(); + + _Spawns.get(i).getLastSpawn().spawnMe(Rnd.get(spawnLoc[0] - 200, spawnLoc[0] + 200), Rnd.get(spawnLoc[1] - 200, spawnLoc[1] + 200), spawnLoc[2] + 20); + + if (Config.DEBUG) + _log.info("RandomSpawnHandler: Spawned NPC ID " + _Spawns.get(i).getLastSpawn().getNpcId() + + " at " + _Spawns.get(i).getLastSpawn().getX() + + ", " + _Spawns.get(i).getLastSpawn().getY() + + ", " + _Spawns.get(i).getLastSpawn().getZ() + + " for " + (_RandomSpawn / 1000 / 60) + " mins."); + } + ClientScheduler.getInstance().scheduleLow(new SpawnTask(), _RandomSpawn); // Prepare auto despawn task + }catch (Throwable t){} + } + } + + // ========================================================= + // Data Field + private boolean _IsActive = true; + private int _ObjectId; + private int _RandomSpawn; + private List _Spawns = new FastList(); + private int _SpawnDelay; + private List _SpawnLocs = new FastList(); + private L2NpcTemplate _Template; + + // ========================================================= + // Constructor + public RandomSpawnInstance(int npcId, int count, int[][] spawnLocs, int randomSpawn, int spawnDelay) + { + _Template = NpcTable.getInstance().getTemplate(npcId); + if (_Template == null) + { + return; + } + + try + { + for (int i = 0; i < count; i++) + { + _Spawns.add(new L2Spawn(_Template)); + _Spawns.get(_Spawns.size() - 1).setLocx(0); + _Spawns.get(_Spawns.size() - 1).setId(IdFactory.getInstance().getNextId()); + _Spawns.get(_Spawns.size() - 1).setLocx(1); + _Spawns.get(_Spawns.size() - 1).setLocy(1); + _Spawns.get(_Spawns.size() - 1).setLocz(1); + _Spawns.get(_Spawns.size() - 1).stopRespawn(); + L2World.getInstance().storeObject(_Spawns.get(_Spawns.size() - 1).spawnOne()); + _Spawns.get(_Spawns.size() - 1).getLastSpawn().decayMe(); + } + }catch (Throwable t){} + + _ObjectId = IdFactory.getInstance().getNextId(); + _RandomSpawn = randomSpawn; + _SpawnDelay = spawnDelay; + + for (int i = 0; i < spawnLocs.length; i++) + { + _SpawnLocs.add(spawnLocs[i]); + } + } + + // ========================================================= + // Method - Public + public void start() + { + _IsActive = true; + ClientScheduler.getInstance().scheduleLow(new SpawnTask(), 0); + } + + public void stop() + { + _IsActive = false; + ClientScheduler.getInstance().scheduleLow(new DeSpawnTask(), 0); + } + + // ========================================================= + // Proeprty + public final int getCount() + { + return _Spawns.size(); + } + + public final boolean getIsActive() + { + return _IsActive; + } + + public final int getNpcId() + { + return _Template.npcId; + } + + public final int getObjectId() + { + return _ObjectId; + } + + public final int getRandomSpawn() + { + return _RandomSpawn; + } + + public final int getSpawnDelay() + { + return _SpawnDelay; + } + } + // =============================================================== + // Schedule task + + // ========================================================= + // Data Field + private List _RandomSpawns = new FastList(); + + // ========================================================= + // Constructor + public RandomSpawnHandler() + { + } + + // ========================================================= + // Method - Public + public RandomSpawnInstance registerSpawn(int npcId, int[][] spawnPoints, int randomSpawnDelay, int spawnDelay) + { + return registerSpawn(npcId, 1, spawnPoints, randomSpawnDelay, spawnDelay); + } + + public RandomSpawnInstance registerSpawn(int npcId, int count, int[][] spawnPoints, int randomSpawnDelay, int spawnDelay) + { + if (randomSpawnDelay < 1) + randomSpawnDelay = 3600000; //1 hour in millisecs; + + if (spawnDelay < 0) + spawnDelay = 0; + + _RandomSpawns.add(new RandomSpawnInstance(npcId, count, spawnPoints, randomSpawnDelay, spawnDelay)); + + if (Config.DEBUG) + _log.config("RandomSpawnHandler: Registered random spawn for NPC ID " + npcId); + + return _RandomSpawns.get(_RandomSpawns.size() - 1); + } + + public void start() + { + for (int i = 0; i < _RandomSpawns.size(); i++) + { + if (_RandomSpawns.get(i).getIsActive()) + _RandomSpawns.get(i).start(); + } + } + + public void stop() + { + for (int i = 0; i < _RandomSpawns.size(); i++) + { + if (_RandomSpawns.get(i).getIsActive()) + _RandomSpawns.get(i).stop(); + } + } + + public void unregisterSpawn(int objectId) + { + for (int i = 0; i < _RandomSpawns.size(); i++) + { + if (_RandomSpawns.get(i).getObjectId() == objectId) + { + _RandomSpawns.remove(i); + return; + } + } + } + + public void unregisterSpawn(RandomSpawnInstance randomSpawn) + { + unregisterSpawn(randomSpawn.getObjectId()); + } + + // ========================================================= + // Method - Private + + // ========================================================= + // Proeprty + public final int size() + { + if (_RandomSpawns == null) + _RandomSpawns = new FastList(); + return _RandomSpawns.size(); + } + } \ No newline at end of file Index: C:/java/net/sf/l2j/gameserver/SevenSigns.java =================================================================== --- C:/java/net/sf/l2j/gameserver/SevenSigns.java (revision 1674) +++ C:/java/net/sf/l2j/gameserver/SevenSigns.java (working copy) @@ -25,6 +25,7 @@ import net.sf.l2j.gameserver.model.L2Spawn; import net.sf.l2j.gameserver.model.L2World; import net.sf.l2j.gameserver.model.RandomSpawnHandler; +import net.sf.l2j.gameserver.model.RandomSpawnHandler.RandomSpawnInstance; import net.sf.l2j.gameserver.serverpackets.SignsSky; import net.sf.l2j.gameserver.serverpackets.SystemMessage; import net.sf.l2j.gameserver.templates.L2NpcTemplate; @@ -97,6 +98,7 @@ private static final int MAXIMUM_PLAYER_CONTRIB = 300000; // NPC Related Constants \\ + private static RandomSpawnInstance _MerchantSpawn; private static final int [][] merchantSpawns = { {172323, -17828, -4927}, // Disciples {83120, 209006, -5465}, // Saints @@ -108,6 +110,7 @@ {-41357, 209809, -5113}, // Sacrifice }; + private static RandomSpawnInstance _BlacksmithSpawn; private static final int [][] blacksmithSpawns = { {113988, 84335, -6541}, // Forbidden Path {-19430, 13271, -4927}, // Dark Omens @@ -600,8 +603,8 @@ L2NpcTemplate npcTemplate = null; // Register the random spawns of the Mammon NPCs - RandomSpawnHandler.getInstance().registerSpawn(8113, merchantSpawns, RandomSpawnHandler.DEFAULT_RESPAWN, -1); - RandomSpawnHandler.getInstance().registerSpawn(8126, blacksmithSpawns, RandomSpawnHandler.DEFAULT_RESPAWN, -1); + _BlacksmithSpawn = RandomSpawnHandler.getInstance().registerSpawn(8126, blacksmithSpawns, 3600000, -1); + _MerchantSpawn = RandomSpawnHandler.getInstance().registerSpawn(8113, merchantSpawns, 3600000, -1); /* Set up the spawning and required auto chats. */ // First, do this for the Preachers of Doom @@ -721,8 +724,8 @@ protected void removeSevenSignsNPCs() { // Remove the random spawns of Mammon NPCs - RandomSpawnHandler.getInstance().removeSpawn(8113); - RandomSpawnHandler.getInstance().removeSpawn(8126); + RandomSpawnHandler.getInstance().unregisterSpawn(_BlacksmithSpawn); + RandomSpawnHandler.getInstance().unregisterSpawn(_MerchantSpawn); // Remove the auto chats of Seven Signs NPCs and hide them AutoChatHandler.getInstance().removeChat(8093);