Spawn system rework.
Thanks Sdw. Author: UnAfraid, ?
This commit is contained in:
		| @@ -159,25 +159,9 @@ public class DBSpawnManager | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	private class SpawnSchedule implements Runnable | ||||
| 	private void scheduleSpawn(int npcId) | ||||
| 	{ | ||||
| 		private final Logger LOGGER = Logger.getLogger(SpawnSchedule.class.getName()); | ||||
| 		 | ||||
| 		private final int _npcId; | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Instantiates a new spawn schedule. | ||||
| 		 * @param npcId the npc id | ||||
| 		 */ | ||||
| 		public SpawnSchedule(int npcId) | ||||
| 		{ | ||||
| 			_npcId = npcId; | ||||
| 		} | ||||
| 		 | ||||
| 		@Override | ||||
| 		public void run() | ||||
| 		{ | ||||
| 			final L2Npc npc = _spawns.get(_npcId).doSpawn(); | ||||
| 		final L2Npc npc = _spawns.get(npcId).doSpawn(); | ||||
| 		if (npc != null) | ||||
| 		{ | ||||
| 			npc.setDBStatus(DBStatusType.ALIVE); | ||||
| @@ -187,13 +171,12 @@ public class DBSpawnManager | ||||
| 			info.set("currentMP", npc.getCurrentMp()); | ||||
| 			info.set("respawnTime", 0L); | ||||
| 			 | ||||
| 				_storedInfo.put(_npcId, info); | ||||
| 				_npcs.put(_npcId, npc); | ||||
| 			_storedInfo.put(npcId, info); | ||||
| 			_npcs.put(npcId, npc); | ||||
| 			LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName()); | ||||
| 		} | ||||
| 		 | ||||
| 			_schedules.remove(_npcId); | ||||
| 		} | ||||
| 		_schedules.remove(npcId); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| @@ -226,7 +209,7 @@ public class DBSpawnManager | ||||
| 			{ | ||||
| 				LOGGER.info(getClass().getSimpleName() + ": Updated " + npc.getName() + " respawn time to " + Util.formatDate(new Date(respawnTime), "dd.MM.yyyy HH:mm")); | ||||
| 				 | ||||
| 				_schedules.put(npc.getId(), ThreadPoolManager.schedule(new SpawnSchedule(npc.getId()), respawnDelay)); | ||||
| 				_schedules.put(npc.getId(), ThreadPoolManager.schedule(() -> scheduleSpawn(npc.getId()), respawnDelay)); | ||||
| 				updateDb(); | ||||
| 			} | ||||
| 		} | ||||
| @@ -287,7 +270,7 @@ public class DBSpawnManager | ||||
| 		else | ||||
| 		{ | ||||
| 			final long spawnTime = respawnTime - System.currentTimeMillis(); | ||||
| 			_schedules.put(npcId, ThreadPoolManager.schedule(new SpawnSchedule(npcId), spawnTime)); | ||||
| 			_schedules.put(npcId, ThreadPoolManager.schedule(() -> scheduleSpawn(npcId), spawnTime)); | ||||
| 		} | ||||
| 		 | ||||
| 		_spawns.put(npcId, spawn); | ||||
| @@ -315,17 +298,18 @@ public class DBSpawnManager | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public void addNewSpawn(L2Spawn spawn, boolean storeInDb) | ||||
| 	public L2Npc addNewSpawn(L2Spawn spawn, boolean storeInDb) | ||||
| 	{ | ||||
| 		if (spawn == null) | ||||
| 		{ | ||||
| 			return; | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		final int npcId = spawn.getId(); | ||||
| 		if (_spawns.containsKey(npcId)) | ||||
| 		final L2Spawn existingSpawn = _spawns.get(npcId); | ||||
| 		if (existingSpawn != null) | ||||
| 		{ | ||||
| 			return; | ||||
| 			return existingSpawn.getLastSpawn(); | ||||
| 		} | ||||
| 		 | ||||
| 		SpawnTable.getInstance().addNewSpawn(spawn, false); | ||||
| @@ -368,6 +352,8 @@ public class DBSpawnManager | ||||
| 				LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Could not store npc #" + npcId + " in the DB: ", e); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		return npc; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
|   | ||||
| @@ -93,6 +93,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		_spawnAnimation = set.getBoolean("spawnAnimation", false); | ||||
| 		_saveInDB = set.getBoolean("dbSave", false); | ||||
| 		_dbName = set.getString("dbName", null); | ||||
| 		_parameters = mergeParameters(spawnTemplate, group); | ||||
| 		 | ||||
| 		final int x = set.getInt("x", Integer.MAX_VALUE); | ||||
| 		final int y = set.getInt("y", Integer.MAX_VALUE); | ||||
| @@ -123,6 +124,31 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 				_zone = zone; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		mergeParameters(spawnTemplate, group); | ||||
| 	} | ||||
| 	 | ||||
| 	private StatsSet mergeParameters(SpawnTemplate spawnTemplate, SpawnGroup group) | ||||
| 	{ | ||||
| 		if ((_parameters == null) && (spawnTemplate.getParameters() == null) && (group.getParameters() == null)) | ||||
| 		{ | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		final StatsSet set = new StatsSet(); | ||||
| 		if (spawnTemplate.getParameters() != null) | ||||
| 		{ | ||||
| 			set.merge(spawnTemplate.getParameters()); | ||||
| 		} | ||||
| 		if (group.getParameters() != null) | ||||
| 		{ | ||||
| 			set.merge(group.getParameters()); | ||||
| 		} | ||||
| 		if (_parameters != null) | ||||
| 		{ | ||||
| 			set.merge(_parameters); | ||||
| 		} | ||||
| 		return set; | ||||
| 	} | ||||
| 	 | ||||
| 	public void addSpawnLocation(ChanceLocation loc) | ||||
| @@ -187,9 +213,16 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void setParameters(StatsSet parameters) | ||||
| 	{ | ||||
| 		if (_parameters == null) | ||||
| 		{ | ||||
| 			_parameters = parameters; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			_parameters.merge(parameters); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean hasSpawnAnimation() | ||||
| 	{ | ||||
| @@ -233,8 +266,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 			float cumulativeChance = 0; | ||||
| 			for (ChanceLocation loc : _locations) | ||||
| 			{ | ||||
| 				cumulativeChance += loc.getChance(); | ||||
| 				if (locRandom <= cumulativeChance) | ||||
| 				if (locRandom <= (cumulativeChance += loc.getChance())) | ||||
| 				{ | ||||
| 					return loc; | ||||
| 				} | ||||
| @@ -285,14 +317,39 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		try | ||||
| 		{ | ||||
| 			final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id); | ||||
| 			if (npcTemplate != null) | ||||
| 			if (npcTemplate == null) | ||||
| 			{ | ||||
| 				LOGGER.warning("Attempting to spawn unexisting npc id: " + _id + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); | ||||
| 				return; | ||||
| 			} | ||||
| 			 | ||||
| 			if (npcTemplate.isType("L2Defender")) | ||||
| 			{ | ||||
| 				LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); | ||||
| 				return; | ||||
| 			} | ||||
| 			 | ||||
| 			for (int i = 0; i < _count; i++) | ||||
| 			{ | ||||
| 				spawnNpc(npcTemplate, instance); | ||||
| 			} | ||||
| 		} | ||||
| 		catch (Exception e) | ||||
| 		{ | ||||
| 			LOGGER.log(Level.WARNING, "Couldn't spawn npc " + _id, e); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * @param npcTemplate | ||||
| 	 * @param instance | ||||
| 	 * @throws ClassCastException | ||||
| 	 * @throws NoSuchMethodException | ||||
| 	 * @throws ClassNotFoundException | ||||
| 	 * @throws SecurityException | ||||
| 	 */ | ||||
| 	private void spawnNpc(L2NpcTemplate npcTemplate, Instance instance) throws SecurityException, ClassNotFoundException, NoSuchMethodException, ClassCastException | ||||
| 	{ | ||||
| 		final L2Spawn spawn = new L2Spawn(npcTemplate); | ||||
| 		final Location loc = getSpawnLocation(); | ||||
| 		if (loc == null) | ||||
| @@ -302,9 +359,9 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		} | ||||
| 		 | ||||
| 		spawn.setInstanceId(instance != null ? instance.getId() : 0); | ||||
| 		spawn.setAmount(1); | ||||
| 		spawn.setXYZ(loc); | ||||
| 		spawn.setHeading(loc.getHeading()); | ||||
| 				spawn.setAmount(_count); | ||||
| 		spawn.setLocation(loc); | ||||
| 		int respawn = 0, respawnRandom = 0; | ||||
| 		if (_respawnTime != null) | ||||
| @@ -332,12 +389,16 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		{ | ||||
| 			if (!DBSpawnManager.getInstance().isDefined(_id)) | ||||
| 			{ | ||||
| 						DBSpawnManager.getInstance().addNewSpawn(spawn, true); | ||||
| 				final L2Npc spawnedNpc = DBSpawnManager.getInstance().addNewSpawn(spawn, true); | ||||
| 				if ((spawnedNpc != null) && spawnedNpc.isMonster() && (_minions != null)) | ||||
| 				{ | ||||
| 					((L2MonsterInstance) spawnedNpc).getMinionList().spawnMinions(_minions); | ||||
| 				} | ||||
| 				 | ||||
| 				_spawnedNpcs.add(spawnedNpc); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 				{ | ||||
| 					for (int i = 0; i < spawn.getAmount(); i++) | ||||
| 		{ | ||||
| 			final L2Npc npc = spawn.doSpawn(_spawnAnimation); | ||||
| 			if (npc.isMonster() && (_minions != null)) | ||||
| @@ -345,17 +406,10 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 				((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions); | ||||
| 			} | ||||
| 			_spawnedNpcs.add(npc); | ||||
| 					} | ||||
| 			 | ||||
| 			SpawnTable.getInstance().addNewSpawn(spawn, false); | ||||
| 		} | ||||
| 	} | ||||
| 		} | ||||
| 		catch (Exception e) | ||||
| 		{ | ||||
| 			LOGGER.log(Level.WARNING, "Couldn't spawn npc " + _id, e); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public void despawn() | ||||
| 	{ | ||||
|   | ||||
| @@ -23,6 +23,7 @@ import java.util.stream.Collectors; | ||||
|  | ||||
| import com.l2jmobius.gameserver.model.StatsSet; | ||||
| import com.l2jmobius.gameserver.model.instancezone.Instance; | ||||
| import com.l2jmobius.gameserver.model.interfaces.IParameterized; | ||||
| import com.l2jmobius.gameserver.model.interfaces.ITerritorized; | ||||
| import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory; | ||||
| import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; | ||||
| @@ -30,13 +31,14 @@ import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; | ||||
| /** | ||||
|  * @author UnAfraid | ||||
|  */ | ||||
| public class SpawnGroup implements Cloneable, ITerritorized | ||||
| public class SpawnGroup implements Cloneable, ITerritorized, IParameterized<StatsSet> | ||||
| { | ||||
| 	private final String _name; | ||||
| 	private final boolean _spawnByDefault; | ||||
| 	private List<L2SpawnTerritory> _territories; | ||||
| 	private List<L2BannedSpawnTerritory> _bannedTerritories; | ||||
| 	private final List<NpcSpawnTemplate> _spawns = new ArrayList<>(); | ||||
| 	private StatsSet _parameters; | ||||
| 	 | ||||
| 	public SpawnGroup(StatsSet set) | ||||
| 	{ | ||||
| @@ -101,6 +103,18 @@ public class SpawnGroup implements Cloneable, ITerritorized | ||||
| 		return _bannedTerritories != null ? _bannedTerritories : Collections.emptyList(); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public StatsSet getParameters() | ||||
| 	{ | ||||
| 		return _parameters; | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void setParameters(StatsSet parameters) | ||||
| 	{ | ||||
| 		_parameters = parameters; | ||||
| 	} | ||||
| 	 | ||||
| 	public List<NpcSpawnTemplate> getSpawnsById(int id) | ||||
| 	{ | ||||
| 		return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList()); | ||||
|   | ||||
| @@ -159,25 +159,9 @@ public class DBSpawnManager | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	private class SpawnSchedule implements Runnable | ||||
| 	private void scheduleSpawn(int npcId) | ||||
| 	{ | ||||
| 		private final Logger LOGGER = Logger.getLogger(SpawnSchedule.class.getName()); | ||||
| 		 | ||||
| 		private final int _npcId; | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Instantiates a new spawn schedule. | ||||
| 		 * @param npcId the npc id | ||||
| 		 */ | ||||
| 		public SpawnSchedule(int npcId) | ||||
| 		{ | ||||
| 			_npcId = npcId; | ||||
| 		} | ||||
| 		 | ||||
| 		@Override | ||||
| 		public void run() | ||||
| 		{ | ||||
| 			final L2Npc npc = _spawns.get(_npcId).doSpawn(); | ||||
| 		final L2Npc npc = _spawns.get(npcId).doSpawn(); | ||||
| 		if (npc != null) | ||||
| 		{ | ||||
| 			npc.setDBStatus(DBStatusType.ALIVE); | ||||
| @@ -187,13 +171,12 @@ public class DBSpawnManager | ||||
| 			info.set("currentMP", npc.getCurrentMp()); | ||||
| 			info.set("respawnTime", 0L); | ||||
| 			 | ||||
| 				_storedInfo.put(_npcId, info); | ||||
| 				_npcs.put(_npcId, npc); | ||||
| 			_storedInfo.put(npcId, info); | ||||
| 			_npcs.put(npcId, npc); | ||||
| 			LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName()); | ||||
| 		} | ||||
| 		 | ||||
| 			_schedules.remove(_npcId); | ||||
| 		} | ||||
| 		_schedules.remove(npcId); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| @@ -226,7 +209,7 @@ public class DBSpawnManager | ||||
| 			{ | ||||
| 				LOGGER.info(getClass().getSimpleName() + ": Updated " + npc.getName() + " respawn time to " + Util.formatDate(new Date(respawnTime), "dd.MM.yyyy HH:mm")); | ||||
| 				 | ||||
| 				_schedules.put(npc.getId(), ThreadPoolManager.schedule(new SpawnSchedule(npc.getId()), respawnDelay)); | ||||
| 				_schedules.put(npc.getId(), ThreadPoolManager.schedule(() -> scheduleSpawn(npc.getId()), respawnDelay)); | ||||
| 				updateDb(); | ||||
| 			} | ||||
| 		} | ||||
| @@ -287,7 +270,7 @@ public class DBSpawnManager | ||||
| 		else | ||||
| 		{ | ||||
| 			final long spawnTime = respawnTime - System.currentTimeMillis(); | ||||
| 			_schedules.put(npcId, ThreadPoolManager.schedule(new SpawnSchedule(npcId), spawnTime)); | ||||
| 			_schedules.put(npcId, ThreadPoolManager.schedule(() -> scheduleSpawn(npcId), spawnTime)); | ||||
| 		} | ||||
| 		 | ||||
| 		_spawns.put(npcId, spawn); | ||||
| @@ -315,17 +298,18 @@ public class DBSpawnManager | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public void addNewSpawn(L2Spawn spawn, boolean storeInDb) | ||||
| 	public L2Npc addNewSpawn(L2Spawn spawn, boolean storeInDb) | ||||
| 	{ | ||||
| 		if (spawn == null) | ||||
| 		{ | ||||
| 			return; | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		final int npcId = spawn.getId(); | ||||
| 		if (_spawns.containsKey(npcId)) | ||||
| 		final L2Spawn existingSpawn = _spawns.get(npcId); | ||||
| 		if (existingSpawn != null) | ||||
| 		{ | ||||
| 			return; | ||||
| 			return existingSpawn.getLastSpawn(); | ||||
| 		} | ||||
| 		 | ||||
| 		SpawnTable.getInstance().addNewSpawn(spawn, false); | ||||
| @@ -368,6 +352,8 @@ public class DBSpawnManager | ||||
| 				LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Could not store npc #" + npcId + " in the DB: ", e); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		return npc; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
|   | ||||
| @@ -93,6 +93,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		_spawnAnimation = set.getBoolean("spawnAnimation", false); | ||||
| 		_saveInDB = set.getBoolean("dbSave", false); | ||||
| 		_dbName = set.getString("dbName", null); | ||||
| 		_parameters = mergeParameters(spawnTemplate, group); | ||||
| 		 | ||||
| 		final int x = set.getInt("x", Integer.MAX_VALUE); | ||||
| 		final int y = set.getInt("y", Integer.MAX_VALUE); | ||||
| @@ -123,6 +124,31 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 				_zone = zone; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		mergeParameters(spawnTemplate, group); | ||||
| 	} | ||||
| 	 | ||||
| 	private StatsSet mergeParameters(SpawnTemplate spawnTemplate, SpawnGroup group) | ||||
| 	{ | ||||
| 		if ((_parameters == null) && (spawnTemplate.getParameters() == null) && (group.getParameters() == null)) | ||||
| 		{ | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		final StatsSet set = new StatsSet(); | ||||
| 		if (spawnTemplate.getParameters() != null) | ||||
| 		{ | ||||
| 			set.merge(spawnTemplate.getParameters()); | ||||
| 		} | ||||
| 		if (group.getParameters() != null) | ||||
| 		{ | ||||
| 			set.merge(group.getParameters()); | ||||
| 		} | ||||
| 		if (_parameters != null) | ||||
| 		{ | ||||
| 			set.merge(_parameters); | ||||
| 		} | ||||
| 		return set; | ||||
| 	} | ||||
| 	 | ||||
| 	public void addSpawnLocation(ChanceLocation loc) | ||||
| @@ -187,9 +213,16 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void setParameters(StatsSet parameters) | ||||
| 	{ | ||||
| 		if (_parameters == null) | ||||
| 		{ | ||||
| 			_parameters = parameters; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			_parameters.merge(parameters); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean hasSpawnAnimation() | ||||
| 	{ | ||||
| @@ -233,8 +266,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 			float cumulativeChance = 0; | ||||
| 			for (ChanceLocation loc : _locations) | ||||
| 			{ | ||||
| 				cumulativeChance += loc.getChance(); | ||||
| 				if (locRandom <= cumulativeChance) | ||||
| 				if (locRandom <= (cumulativeChance += loc.getChance())) | ||||
| 				{ | ||||
| 					return loc; | ||||
| 				} | ||||
| @@ -285,14 +317,39 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		try | ||||
| 		{ | ||||
| 			final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id); | ||||
| 			if (npcTemplate != null) | ||||
| 			if (npcTemplate == null) | ||||
| 			{ | ||||
| 				LOGGER.warning("Attempting to spawn unexisting npc id: " + _id + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); | ||||
| 				return; | ||||
| 			} | ||||
| 			 | ||||
| 			if (npcTemplate.isType("L2Defender")) | ||||
| 			{ | ||||
| 				LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); | ||||
| 				return; | ||||
| 			} | ||||
| 			 | ||||
| 			for (int i = 0; i < _count; i++) | ||||
| 			{ | ||||
| 				spawnNpc(npcTemplate, instance); | ||||
| 			} | ||||
| 		} | ||||
| 		catch (Exception e) | ||||
| 		{ | ||||
| 			LOGGER.log(Level.WARNING, "Couldn't spawn npc " + _id, e); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * @param npcTemplate | ||||
| 	 * @param instance | ||||
| 	 * @throws ClassCastException | ||||
| 	 * @throws NoSuchMethodException | ||||
| 	 * @throws ClassNotFoundException | ||||
| 	 * @throws SecurityException | ||||
| 	 */ | ||||
| 	private void spawnNpc(L2NpcTemplate npcTemplate, Instance instance) throws SecurityException, ClassNotFoundException, NoSuchMethodException, ClassCastException | ||||
| 	{ | ||||
| 		final L2Spawn spawn = new L2Spawn(npcTemplate); | ||||
| 		final Location loc = getSpawnLocation(); | ||||
| 		if (loc == null) | ||||
| @@ -302,9 +359,9 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		} | ||||
| 		 | ||||
| 		spawn.setInstanceId(instance != null ? instance.getId() : 0); | ||||
| 		spawn.setAmount(1); | ||||
| 		spawn.setXYZ(loc); | ||||
| 		spawn.setHeading(loc.getHeading()); | ||||
| 				spawn.setAmount(_count); | ||||
| 		spawn.setLocation(loc); | ||||
| 		int respawn = 0, respawnRandom = 0; | ||||
| 		if (_respawnTime != null) | ||||
| @@ -332,12 +389,16 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		{ | ||||
| 			if (!DBSpawnManager.getInstance().isDefined(_id)) | ||||
| 			{ | ||||
| 						DBSpawnManager.getInstance().addNewSpawn(spawn, true); | ||||
| 				final L2Npc spawnedNpc = DBSpawnManager.getInstance().addNewSpawn(spawn, true); | ||||
| 				if ((spawnedNpc != null) && spawnedNpc.isMonster() && (_minions != null)) | ||||
| 				{ | ||||
| 					((L2MonsterInstance) spawnedNpc).getMinionList().spawnMinions(_minions); | ||||
| 				} | ||||
| 				 | ||||
| 				_spawnedNpcs.add(spawnedNpc); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 				{ | ||||
| 					for (int i = 0; i < spawn.getAmount(); i++) | ||||
| 		{ | ||||
| 			final L2Npc npc = spawn.doSpawn(_spawnAnimation); | ||||
| 			if (npc.isMonster() && (_minions != null)) | ||||
| @@ -345,17 +406,10 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 				((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions); | ||||
| 			} | ||||
| 			_spawnedNpcs.add(npc); | ||||
| 					} | ||||
| 			 | ||||
| 			SpawnTable.getInstance().addNewSpawn(spawn, false); | ||||
| 		} | ||||
| 	} | ||||
| 		} | ||||
| 		catch (Exception e) | ||||
| 		{ | ||||
| 			LOGGER.log(Level.WARNING, "Couldn't spawn npc " + _id, e); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public void despawn() | ||||
| 	{ | ||||
|   | ||||
| @@ -23,6 +23,7 @@ import java.util.stream.Collectors; | ||||
|  | ||||
| import com.l2jmobius.gameserver.model.StatsSet; | ||||
| import com.l2jmobius.gameserver.model.instancezone.Instance; | ||||
| import com.l2jmobius.gameserver.model.interfaces.IParameterized; | ||||
| import com.l2jmobius.gameserver.model.interfaces.ITerritorized; | ||||
| import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory; | ||||
| import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; | ||||
| @@ -30,13 +31,14 @@ import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; | ||||
| /** | ||||
|  * @author UnAfraid | ||||
|  */ | ||||
| public class SpawnGroup implements Cloneable, ITerritorized | ||||
| public class SpawnGroup implements Cloneable, ITerritorized, IParameterized<StatsSet> | ||||
| { | ||||
| 	private final String _name; | ||||
| 	private final boolean _spawnByDefault; | ||||
| 	private List<L2SpawnTerritory> _territories; | ||||
| 	private List<L2BannedSpawnTerritory> _bannedTerritories; | ||||
| 	private final List<NpcSpawnTemplate> _spawns = new ArrayList<>(); | ||||
| 	private StatsSet _parameters; | ||||
| 	 | ||||
| 	public SpawnGroup(StatsSet set) | ||||
| 	{ | ||||
| @@ -101,6 +103,18 @@ public class SpawnGroup implements Cloneable, ITerritorized | ||||
| 		return _bannedTerritories != null ? _bannedTerritories : Collections.emptyList(); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public StatsSet getParameters() | ||||
| 	{ | ||||
| 		return _parameters; | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void setParameters(StatsSet parameters) | ||||
| 	{ | ||||
| 		_parameters = parameters; | ||||
| 	} | ||||
| 	 | ||||
| 	public List<NpcSpawnTemplate> getSpawnsById(int id) | ||||
| 	{ | ||||
| 		return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList()); | ||||
|   | ||||
| @@ -159,25 +159,9 @@ public class DBSpawnManager | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	private class SpawnSchedule implements Runnable | ||||
| 	private void scheduleSpawn(int npcId) | ||||
| 	{ | ||||
| 		private final Logger LOGGER = Logger.getLogger(SpawnSchedule.class.getName()); | ||||
| 		 | ||||
| 		private final int _npcId; | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Instantiates a new spawn schedule. | ||||
| 		 * @param npcId the npc id | ||||
| 		 */ | ||||
| 		public SpawnSchedule(int npcId) | ||||
| 		{ | ||||
| 			_npcId = npcId; | ||||
| 		} | ||||
| 		 | ||||
| 		@Override | ||||
| 		public void run() | ||||
| 		{ | ||||
| 			final L2Npc npc = _spawns.get(_npcId).doSpawn(); | ||||
| 		final L2Npc npc = _spawns.get(npcId).doSpawn(); | ||||
| 		if (npc != null) | ||||
| 		{ | ||||
| 			npc.setDBStatus(DBStatusType.ALIVE); | ||||
| @@ -187,13 +171,12 @@ public class DBSpawnManager | ||||
| 			info.set("currentMP", npc.getCurrentMp()); | ||||
| 			info.set("respawnTime", 0L); | ||||
| 			 | ||||
| 				_storedInfo.put(_npcId, info); | ||||
| 				_npcs.put(_npcId, npc); | ||||
| 			_storedInfo.put(npcId, info); | ||||
| 			_npcs.put(npcId, npc); | ||||
| 			LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName()); | ||||
| 		} | ||||
| 		 | ||||
| 			_schedules.remove(_npcId); | ||||
| 		} | ||||
| 		_schedules.remove(npcId); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| @@ -226,7 +209,7 @@ public class DBSpawnManager | ||||
| 			{ | ||||
| 				LOGGER.info(getClass().getSimpleName() + ": Updated " + npc.getName() + " respawn time to " + Util.formatDate(new Date(respawnTime), "dd.MM.yyyy HH:mm")); | ||||
| 				 | ||||
| 				_schedules.put(npc.getId(), ThreadPoolManager.schedule(new SpawnSchedule(npc.getId()), respawnDelay)); | ||||
| 				_schedules.put(npc.getId(), ThreadPoolManager.schedule(() -> scheduleSpawn(npc.getId()), respawnDelay)); | ||||
| 				updateDb(); | ||||
| 			} | ||||
| 		} | ||||
| @@ -287,7 +270,7 @@ public class DBSpawnManager | ||||
| 		else | ||||
| 		{ | ||||
| 			final long spawnTime = respawnTime - System.currentTimeMillis(); | ||||
| 			_schedules.put(npcId, ThreadPoolManager.schedule(new SpawnSchedule(npcId), spawnTime)); | ||||
| 			_schedules.put(npcId, ThreadPoolManager.schedule(() -> scheduleSpawn(npcId), spawnTime)); | ||||
| 		} | ||||
| 		 | ||||
| 		_spawns.put(npcId, spawn); | ||||
| @@ -315,17 +298,18 @@ public class DBSpawnManager | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public void addNewSpawn(L2Spawn spawn, boolean storeInDb) | ||||
| 	public L2Npc addNewSpawn(L2Spawn spawn, boolean storeInDb) | ||||
| 	{ | ||||
| 		if (spawn == null) | ||||
| 		{ | ||||
| 			return; | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		final int npcId = spawn.getId(); | ||||
| 		if (_spawns.containsKey(npcId)) | ||||
| 		final L2Spawn existingSpawn = _spawns.get(npcId); | ||||
| 		if (existingSpawn != null) | ||||
| 		{ | ||||
| 			return; | ||||
| 			return existingSpawn.getLastSpawn(); | ||||
| 		} | ||||
| 		 | ||||
| 		SpawnTable.getInstance().addNewSpawn(spawn, false); | ||||
| @@ -368,6 +352,8 @@ public class DBSpawnManager | ||||
| 				LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Could not store npc #" + npcId + " in the DB: ", e); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		return npc; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
|   | ||||
| @@ -93,6 +93,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		_spawnAnimation = set.getBoolean("spawnAnimation", false); | ||||
| 		_saveInDB = set.getBoolean("dbSave", false); | ||||
| 		_dbName = set.getString("dbName", null); | ||||
| 		_parameters = mergeParameters(spawnTemplate, group); | ||||
| 		 | ||||
| 		final int x = set.getInt("x", Integer.MAX_VALUE); | ||||
| 		final int y = set.getInt("y", Integer.MAX_VALUE); | ||||
| @@ -123,6 +124,31 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 				_zone = zone; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		mergeParameters(spawnTemplate, group); | ||||
| 	} | ||||
| 	 | ||||
| 	private StatsSet mergeParameters(SpawnTemplate spawnTemplate, SpawnGroup group) | ||||
| 	{ | ||||
| 		if ((_parameters == null) && (spawnTemplate.getParameters() == null) && (group.getParameters() == null)) | ||||
| 		{ | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		final StatsSet set = new StatsSet(); | ||||
| 		if (spawnTemplate.getParameters() != null) | ||||
| 		{ | ||||
| 			set.merge(spawnTemplate.getParameters()); | ||||
| 		} | ||||
| 		if (group.getParameters() != null) | ||||
| 		{ | ||||
| 			set.merge(group.getParameters()); | ||||
| 		} | ||||
| 		if (_parameters != null) | ||||
| 		{ | ||||
| 			set.merge(_parameters); | ||||
| 		} | ||||
| 		return set; | ||||
| 	} | ||||
| 	 | ||||
| 	public void addSpawnLocation(ChanceLocation loc) | ||||
| @@ -187,9 +213,16 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void setParameters(StatsSet parameters) | ||||
| 	{ | ||||
| 		if (_parameters == null) | ||||
| 		{ | ||||
| 			_parameters = parameters; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			_parameters.merge(parameters); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean hasSpawnAnimation() | ||||
| 	{ | ||||
| @@ -233,8 +266,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 			float cumulativeChance = 0; | ||||
| 			for (ChanceLocation loc : _locations) | ||||
| 			{ | ||||
| 				cumulativeChance += loc.getChance(); | ||||
| 				if (locRandom <= cumulativeChance) | ||||
| 				if (locRandom <= (cumulativeChance += loc.getChance())) | ||||
| 				{ | ||||
| 					return loc; | ||||
| 				} | ||||
| @@ -285,14 +317,39 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		try | ||||
| 		{ | ||||
| 			final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id); | ||||
| 			if (npcTemplate != null) | ||||
| 			if (npcTemplate == null) | ||||
| 			{ | ||||
| 				LOGGER.warning("Attempting to spawn unexisting npc id: " + _id + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); | ||||
| 				return; | ||||
| 			} | ||||
| 			 | ||||
| 			if (npcTemplate.isType("L2Defender")) | ||||
| 			{ | ||||
| 				LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); | ||||
| 				return; | ||||
| 			} | ||||
| 			 | ||||
| 			for (int i = 0; i < _count; i++) | ||||
| 			{ | ||||
| 				spawnNpc(npcTemplate, instance); | ||||
| 			} | ||||
| 		} | ||||
| 		catch (Exception e) | ||||
| 		{ | ||||
| 			LOGGER.log(Level.WARNING, "Couldn't spawn npc " + _id, e); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * @param npcTemplate | ||||
| 	 * @param instance | ||||
| 	 * @throws ClassCastException | ||||
| 	 * @throws NoSuchMethodException | ||||
| 	 * @throws ClassNotFoundException | ||||
| 	 * @throws SecurityException | ||||
| 	 */ | ||||
| 	private void spawnNpc(L2NpcTemplate npcTemplate, Instance instance) throws SecurityException, ClassNotFoundException, NoSuchMethodException, ClassCastException | ||||
| 	{ | ||||
| 		final L2Spawn spawn = new L2Spawn(npcTemplate); | ||||
| 		final Location loc = getSpawnLocation(); | ||||
| 		if (loc == null) | ||||
| @@ -302,9 +359,9 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		} | ||||
| 		 | ||||
| 		spawn.setInstanceId(instance != null ? instance.getId() : 0); | ||||
| 		spawn.setAmount(1); | ||||
| 		spawn.setXYZ(loc); | ||||
| 		spawn.setHeading(loc.getHeading()); | ||||
| 				spawn.setAmount(_count); | ||||
| 		spawn.setLocation(loc); | ||||
| 		int respawn = 0, respawnRandom = 0; | ||||
| 		if (_respawnTime != null) | ||||
| @@ -332,12 +389,16 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		{ | ||||
| 			if (!DBSpawnManager.getInstance().isDefined(_id)) | ||||
| 			{ | ||||
| 						DBSpawnManager.getInstance().addNewSpawn(spawn, true); | ||||
| 				final L2Npc spawnedNpc = DBSpawnManager.getInstance().addNewSpawn(spawn, true); | ||||
| 				if ((spawnedNpc != null) && spawnedNpc.isMonster() && (_minions != null)) | ||||
| 				{ | ||||
| 					((L2MonsterInstance) spawnedNpc).getMinionList().spawnMinions(_minions); | ||||
| 				} | ||||
| 				 | ||||
| 				_spawnedNpcs.add(spawnedNpc); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 				{ | ||||
| 					for (int i = 0; i < spawn.getAmount(); i++) | ||||
| 		{ | ||||
| 			final L2Npc npc = spawn.doSpawn(_spawnAnimation); | ||||
| 			if (npc.isMonster() && (_minions != null)) | ||||
| @@ -345,17 +406,10 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 				((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions); | ||||
| 			} | ||||
| 			_spawnedNpcs.add(npc); | ||||
| 					} | ||||
| 			 | ||||
| 			SpawnTable.getInstance().addNewSpawn(spawn, false); | ||||
| 		} | ||||
| 	} | ||||
| 		} | ||||
| 		catch (Exception e) | ||||
| 		{ | ||||
| 			LOGGER.log(Level.WARNING, "Couldn't spawn npc " + _id, e); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public void despawn() | ||||
| 	{ | ||||
|   | ||||
| @@ -23,6 +23,7 @@ import java.util.stream.Collectors; | ||||
|  | ||||
| import com.l2jmobius.gameserver.model.StatsSet; | ||||
| import com.l2jmobius.gameserver.model.instancezone.Instance; | ||||
| import com.l2jmobius.gameserver.model.interfaces.IParameterized; | ||||
| import com.l2jmobius.gameserver.model.interfaces.ITerritorized; | ||||
| import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory; | ||||
| import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; | ||||
| @@ -30,13 +31,14 @@ import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; | ||||
| /** | ||||
|  * @author UnAfraid | ||||
|  */ | ||||
| public class SpawnGroup implements Cloneable, ITerritorized | ||||
| public class SpawnGroup implements Cloneable, ITerritorized, IParameterized<StatsSet> | ||||
| { | ||||
| 	private final String _name; | ||||
| 	private final boolean _spawnByDefault; | ||||
| 	private List<L2SpawnTerritory> _territories; | ||||
| 	private List<L2BannedSpawnTerritory> _bannedTerritories; | ||||
| 	private final List<NpcSpawnTemplate> _spawns = new ArrayList<>(); | ||||
| 	private StatsSet _parameters; | ||||
| 	 | ||||
| 	public SpawnGroup(StatsSet set) | ||||
| 	{ | ||||
| @@ -101,6 +103,18 @@ public class SpawnGroup implements Cloneable, ITerritorized | ||||
| 		return _bannedTerritories != null ? _bannedTerritories : Collections.emptyList(); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public StatsSet getParameters() | ||||
| 	{ | ||||
| 		return _parameters; | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void setParameters(StatsSet parameters) | ||||
| 	{ | ||||
| 		_parameters = parameters; | ||||
| 	} | ||||
| 	 | ||||
| 	public List<NpcSpawnTemplate> getSpawnsById(int id) | ||||
| 	{ | ||||
| 		return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList()); | ||||
|   | ||||
| @@ -159,25 +159,9 @@ public class DBSpawnManager | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	private class SpawnSchedule implements Runnable | ||||
| 	private void scheduleSpawn(int npcId) | ||||
| 	{ | ||||
| 		private final Logger LOGGER = Logger.getLogger(SpawnSchedule.class.getName()); | ||||
| 		 | ||||
| 		private final int _npcId; | ||||
| 		 | ||||
| 		/** | ||||
| 		 * Instantiates a new spawn schedule. | ||||
| 		 * @param npcId the npc id | ||||
| 		 */ | ||||
| 		public SpawnSchedule(int npcId) | ||||
| 		{ | ||||
| 			_npcId = npcId; | ||||
| 		} | ||||
| 		 | ||||
| 		@Override | ||||
| 		public void run() | ||||
| 		{ | ||||
| 			final L2Npc npc = _spawns.get(_npcId).doSpawn(); | ||||
| 		final L2Npc npc = _spawns.get(npcId).doSpawn(); | ||||
| 		if (npc != null) | ||||
| 		{ | ||||
| 			npc.setDBStatus(DBStatusType.ALIVE); | ||||
| @@ -187,13 +171,12 @@ public class DBSpawnManager | ||||
| 			info.set("currentMP", npc.getCurrentMp()); | ||||
| 			info.set("respawnTime", 0L); | ||||
| 			 | ||||
| 				_storedInfo.put(_npcId, info); | ||||
| 				_npcs.put(_npcId, npc); | ||||
| 			_storedInfo.put(npcId, info); | ||||
| 			_npcs.put(npcId, npc); | ||||
| 			LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName()); | ||||
| 		} | ||||
| 		 | ||||
| 			_schedules.remove(_npcId); | ||||
| 		} | ||||
| 		_schedules.remove(npcId); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| @@ -226,7 +209,7 @@ public class DBSpawnManager | ||||
| 			{ | ||||
| 				LOGGER.info(getClass().getSimpleName() + ": Updated " + npc.getName() + " respawn time to " + Util.formatDate(new Date(respawnTime), "dd.MM.yyyy HH:mm")); | ||||
| 				 | ||||
| 				_schedules.put(npc.getId(), ThreadPoolManager.schedule(new SpawnSchedule(npc.getId()), respawnDelay)); | ||||
| 				_schedules.put(npc.getId(), ThreadPoolManager.schedule(() -> scheduleSpawn(npc.getId()), respawnDelay)); | ||||
| 				updateDb(); | ||||
| 			} | ||||
| 		} | ||||
| @@ -287,7 +270,7 @@ public class DBSpawnManager | ||||
| 		else | ||||
| 		{ | ||||
| 			final long spawnTime = respawnTime - System.currentTimeMillis(); | ||||
| 			_schedules.put(npcId, ThreadPoolManager.schedule(new SpawnSchedule(npcId), spawnTime)); | ||||
| 			_schedules.put(npcId, ThreadPoolManager.schedule(() -> scheduleSpawn(npcId), spawnTime)); | ||||
| 		} | ||||
| 		 | ||||
| 		_spawns.put(npcId, spawn); | ||||
| @@ -315,17 +298,18 @@ public class DBSpawnManager | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public void addNewSpawn(L2Spawn spawn, boolean storeInDb) | ||||
| 	public L2Npc addNewSpawn(L2Spawn spawn, boolean storeInDb) | ||||
| 	{ | ||||
| 		if (spawn == null) | ||||
| 		{ | ||||
| 			return; | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		final int npcId = spawn.getId(); | ||||
| 		if (_spawns.containsKey(npcId)) | ||||
| 		final L2Spawn existingSpawn = _spawns.get(npcId); | ||||
| 		if (existingSpawn != null) | ||||
| 		{ | ||||
| 			return; | ||||
| 			return existingSpawn.getLastSpawn(); | ||||
| 		} | ||||
| 		 | ||||
| 		SpawnTable.getInstance().addNewSpawn(spawn, false); | ||||
| @@ -368,6 +352,8 @@ public class DBSpawnManager | ||||
| 				LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Could not store npc #" + npcId + " in the DB: ", e); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		return npc; | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
|   | ||||
| @@ -93,6 +93,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		_spawnAnimation = set.getBoolean("spawnAnimation", false); | ||||
| 		_saveInDB = set.getBoolean("dbSave", false); | ||||
| 		_dbName = set.getString("dbName", null); | ||||
| 		_parameters = mergeParameters(spawnTemplate, group); | ||||
| 		 | ||||
| 		final int x = set.getInt("x", Integer.MAX_VALUE); | ||||
| 		final int y = set.getInt("y", Integer.MAX_VALUE); | ||||
| @@ -123,6 +124,31 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 				_zone = zone; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		mergeParameters(spawnTemplate, group); | ||||
| 	} | ||||
| 	 | ||||
| 	private StatsSet mergeParameters(SpawnTemplate spawnTemplate, SpawnGroup group) | ||||
| 	{ | ||||
| 		if ((_parameters == null) && (spawnTemplate.getParameters() == null) && (group.getParameters() == null)) | ||||
| 		{ | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		final StatsSet set = new StatsSet(); | ||||
| 		if (spawnTemplate.getParameters() != null) | ||||
| 		{ | ||||
| 			set.merge(spawnTemplate.getParameters()); | ||||
| 		} | ||||
| 		if (group.getParameters() != null) | ||||
| 		{ | ||||
| 			set.merge(group.getParameters()); | ||||
| 		} | ||||
| 		if (_parameters != null) | ||||
| 		{ | ||||
| 			set.merge(_parameters); | ||||
| 		} | ||||
| 		return set; | ||||
| 	} | ||||
| 	 | ||||
| 	public void addSpawnLocation(ChanceLocation loc) | ||||
| @@ -187,9 +213,16 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void setParameters(StatsSet parameters) | ||||
| 	{ | ||||
| 		if (_parameters == null) | ||||
| 		{ | ||||
| 			_parameters = parameters; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			_parameters.merge(parameters); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean hasSpawnAnimation() | ||||
| 	{ | ||||
| @@ -233,8 +266,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 			float cumulativeChance = 0; | ||||
| 			for (ChanceLocation loc : _locations) | ||||
| 			{ | ||||
| 				cumulativeChance += loc.getChance(); | ||||
| 				if (locRandom <= cumulativeChance) | ||||
| 				if (locRandom <= (cumulativeChance += loc.getChance())) | ||||
| 				{ | ||||
| 					return loc; | ||||
| 				} | ||||
| @@ -285,14 +317,39 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		try | ||||
| 		{ | ||||
| 			final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id); | ||||
| 			if (npcTemplate != null) | ||||
| 			if (npcTemplate == null) | ||||
| 			{ | ||||
| 				LOGGER.warning("Attempting to spawn unexisting npc id: " + _id + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); | ||||
| 				return; | ||||
| 			} | ||||
| 			 | ||||
| 			if (npcTemplate.isType("L2Defender")) | ||||
| 			{ | ||||
| 				LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); | ||||
| 				return; | ||||
| 			} | ||||
| 			 | ||||
| 			for (int i = 0; i < _count; i++) | ||||
| 			{ | ||||
| 				spawnNpc(npcTemplate, instance); | ||||
| 			} | ||||
| 		} | ||||
| 		catch (Exception e) | ||||
| 		{ | ||||
| 			LOGGER.log(Level.WARNING, "Couldn't spawn npc " + _id, e); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * @param npcTemplate | ||||
| 	 * @param instance | ||||
| 	 * @throws ClassCastException | ||||
| 	 * @throws NoSuchMethodException | ||||
| 	 * @throws ClassNotFoundException | ||||
| 	 * @throws SecurityException | ||||
| 	 */ | ||||
| 	private void spawnNpc(L2NpcTemplate npcTemplate, Instance instance) throws SecurityException, ClassNotFoundException, NoSuchMethodException, ClassCastException | ||||
| 	{ | ||||
| 		final L2Spawn spawn = new L2Spawn(npcTemplate); | ||||
| 		final Location loc = getSpawnLocation(); | ||||
| 		if (loc == null) | ||||
| @@ -302,9 +359,9 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		} | ||||
| 		 | ||||
| 		spawn.setInstanceId(instance != null ? instance.getId() : 0); | ||||
| 		spawn.setAmount(1); | ||||
| 		spawn.setXYZ(loc); | ||||
| 		spawn.setHeading(loc.getHeading()); | ||||
| 				spawn.setAmount(_count); | ||||
| 		spawn.setLocation(loc); | ||||
| 		int respawn = 0, respawnRandom = 0; | ||||
| 		if (_respawnTime != null) | ||||
| @@ -332,12 +389,16 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 		{ | ||||
| 			if (!DBSpawnManager.getInstance().isDefined(_id)) | ||||
| 			{ | ||||
| 						DBSpawnManager.getInstance().addNewSpawn(spawn, true); | ||||
| 				final L2Npc spawnedNpc = DBSpawnManager.getInstance().addNewSpawn(spawn, true); | ||||
| 				if ((spawnedNpc != null) && spawnedNpc.isMonster() && (_minions != null)) | ||||
| 				{ | ||||
| 					((L2MonsterInstance) spawnedNpc).getMinionList().spawnMinions(_minions); | ||||
| 				} | ||||
| 				 | ||||
| 				_spawnedNpcs.add(spawnedNpc); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 				{ | ||||
| 					for (int i = 0; i < spawn.getAmount(); i++) | ||||
| 		{ | ||||
| 			final L2Npc npc = spawn.doSpawn(_spawnAnimation); | ||||
| 			if (npc.isMonster() && (_minions != null)) | ||||
| @@ -345,17 +406,10 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet> | ||||
| 				((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions); | ||||
| 			} | ||||
| 			_spawnedNpcs.add(npc); | ||||
| 					} | ||||
| 			 | ||||
| 			SpawnTable.getInstance().addNewSpawn(spawn, false); | ||||
| 		} | ||||
| 	} | ||||
| 		} | ||||
| 		catch (Exception e) | ||||
| 		{ | ||||
| 			LOGGER.log(Level.WARNING, "Couldn't spawn npc " + _id, e); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public void despawn() | ||||
| 	{ | ||||
|   | ||||
| @@ -23,6 +23,7 @@ import java.util.stream.Collectors; | ||||
|  | ||||
| import com.l2jmobius.gameserver.model.StatsSet; | ||||
| import com.l2jmobius.gameserver.model.instancezone.Instance; | ||||
| import com.l2jmobius.gameserver.model.interfaces.IParameterized; | ||||
| import com.l2jmobius.gameserver.model.interfaces.ITerritorized; | ||||
| import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory; | ||||
| import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; | ||||
| @@ -30,13 +31,14 @@ import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; | ||||
| /** | ||||
|  * @author UnAfraid | ||||
|  */ | ||||
| public class SpawnGroup implements Cloneable, ITerritorized | ||||
| public class SpawnGroup implements Cloneable, ITerritorized, IParameterized<StatsSet> | ||||
| { | ||||
| 	private final String _name; | ||||
| 	private final boolean _spawnByDefault; | ||||
| 	private List<L2SpawnTerritory> _territories; | ||||
| 	private List<L2BannedSpawnTerritory> _bannedTerritories; | ||||
| 	private final List<NpcSpawnTemplate> _spawns = new ArrayList<>(); | ||||
| 	private StatsSet _parameters; | ||||
| 	 | ||||
| 	public SpawnGroup(StatsSet set) | ||||
| 	{ | ||||
| @@ -101,6 +103,18 @@ public class SpawnGroup implements Cloneable, ITerritorized | ||||
| 		return _bannedTerritories != null ? _bannedTerritories : Collections.emptyList(); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public StatsSet getParameters() | ||||
| 	{ | ||||
| 		return _parameters; | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public void setParameters(StatsSet parameters) | ||||
| 	{ | ||||
| 		_parameters = parameters; | ||||
| 	} | ||||
| 	 | ||||
| 	public List<NpcSpawnTemplate> getSpawnsById(int id) | ||||
| 	{ | ||||
| 		return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList()); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 MobiusDev
					MobiusDev