Spawn system rework.

Thanks Sdw.
Author: UnAfraid, ?
This commit is contained in:
MobiusDev 2017-09-14 12:20:53 +00:00
parent fbd1109bd5
commit 021766a8c5
12 changed files with 632 additions and 416 deletions

View File

@ -159,41 +159,24 @@ public class DBSpawnManager
} }
} }
private class SpawnSchedule implements Runnable private void scheduleSpawn(int npcId)
{ {
private final Logger LOGGER = Logger.getLogger(SpawnSchedule.class.getName()); final L2Npc npc = _spawns.get(npcId).doSpawn();
if (npc != null)
private final int _npcId;
/**
* Instantiates a new spawn schedule.
* @param npcId the npc id
*/
public SpawnSchedule(int npcId)
{ {
_npcId = npcId; npc.setDBStatus(DBStatusType.ALIVE);
final StatsSet info = new StatsSet();
info.set("currentHP", npc.getCurrentHp());
info.set("currentMP", npc.getCurrentMp());
info.set("respawnTime", 0L);
_storedInfo.put(npcId, info);
_npcs.put(npcId, npc);
LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName());
} }
@Override _schedules.remove(npcId);
public void run()
{
final L2Npc npc = _spawns.get(_npcId).doSpawn();
if (npc != null)
{
npc.setDBStatus(DBStatusType.ALIVE);
final StatsSet info = new StatsSet();
info.set("currentHP", npc.getCurrentHp());
info.set("currentMP", npc.getCurrentMp());
info.set("respawnTime", 0L);
_storedInfo.put(_npcId, info);
_npcs.put(_npcId, npc);
LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName());
}
_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")); 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(); updateDb();
} }
} }
@ -287,7 +270,7 @@ public class DBSpawnManager
else else
{ {
final long spawnTime = respawnTime - System.currentTimeMillis(); 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); _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) if (spawn == null)
{ {
return; return null;
} }
final int npcId = spawn.getId(); 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); 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); LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Could not store npc #" + npcId + " in the DB: ", e);
} }
} }
return npc;
} }
/** /**

View File

@ -93,6 +93,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
_spawnAnimation = set.getBoolean("spawnAnimation", false); _spawnAnimation = set.getBoolean("spawnAnimation", false);
_saveInDB = set.getBoolean("dbSave", false); _saveInDB = set.getBoolean("dbSave", false);
_dbName = set.getString("dbName", null); _dbName = set.getString("dbName", null);
_parameters = mergeParameters(spawnTemplate, group);
final int x = set.getInt("x", Integer.MAX_VALUE); final int x = set.getInt("x", Integer.MAX_VALUE);
final int y = set.getInt("y", 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; _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) public void addSpawnLocation(ChanceLocation loc)
@ -188,7 +214,14 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
@Override @Override
public void setParameters(StatsSet parameters) public void setParameters(StatsSet parameters)
{ {
_parameters = parameters; if (_parameters == null)
{
_parameters = parameters;
}
else
{
_parameters.merge(parameters);
}
} }
public boolean hasSpawnAnimation() public boolean hasSpawnAnimation()
@ -233,8 +266,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
float cumulativeChance = 0; float cumulativeChance = 0;
for (ChanceLocation loc : _locations) for (ChanceLocation loc : _locations)
{ {
cumulativeChance += loc.getChance(); if (locRandom <= (cumulativeChance += loc.getChance()))
if (locRandom <= cumulativeChance)
{ {
return loc; return loc;
} }
@ -285,70 +317,21 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
try try
{ {
final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id); final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id);
if (npcTemplate != null) if (npcTemplate == null)
{ {
if (npcTemplate.isType("L2Defender")) LOGGER.warning("Attempting to spawn unexisting npc id: " + _id + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName());
{ return;
LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); }
return;
}
final L2Spawn spawn = new L2Spawn(npcTemplate); if (npcTemplate.isType("L2Defender"))
final Location loc = getSpawnLocation(); {
if (loc == null) LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName());
{ return;
LOGGER.warning("Couldn't initialize new spawn, no location found!"); }
return;
}
spawn.setInstanceId(instance != null ? instance.getId() : 0); for (int i = 0; i < _count; i++)
spawn.setXYZ(loc); {
spawn.setHeading(loc.getHeading()); spawnNpc(npcTemplate, instance);
spawn.setAmount(_count);
spawn.setLocation(loc);
int respawn = 0, respawnRandom = 0;
if (_respawnTime != null)
{
respawn = (int) _respawnTime.getSeconds();
}
if (_respawnTimeRandom != null)
{
respawnRandom = (int) _respawnTimeRandom.getSeconds();
}
if (respawn > 0)
{
spawn.setRespawnDelay(respawn, respawnRandom);
spawn.startRespawn();
}
else
{
spawn.stopRespawn();
}
spawn.setSpawnTemplate(this);
if (_saveInDB)
{
if (!DBSpawnManager.getInstance().isDefined(_id))
{
DBSpawnManager.getInstance().addNewSpawn(spawn, true);
}
}
else
{
for (int i = 0; i < spawn.getAmount(); i++)
{
final L2Npc npc = spawn.doSpawn(_spawnAnimation);
if (npc.isMonster() && (_minions != null))
{
((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(npc);
}
SpawnTable.getInstance().addNewSpawn(spawn, false);
}
} }
} }
catch (Exception e) catch (Exception e)
@ -357,6 +340,77 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
} }
} }
/**
* @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)
{
LOGGER.warning("Couldn't initialize new spawn, no location found!");
return;
}
spawn.setInstanceId(instance != null ? instance.getId() : 0);
spawn.setAmount(1);
spawn.setXYZ(loc);
spawn.setHeading(loc.getHeading());
spawn.setLocation(loc);
int respawn = 0, respawnRandom = 0;
if (_respawnTime != null)
{
respawn = (int) _respawnTime.getSeconds();
}
if (_respawnTimeRandom != null)
{
respawnRandom = (int) _respawnTimeRandom.getSeconds();
}
if (respawn > 0)
{
spawn.setRespawnDelay(respawn, respawnRandom);
spawn.startRespawn();
}
else
{
spawn.stopRespawn();
}
spawn.setSpawnTemplate(this);
if (_saveInDB)
{
if (!DBSpawnManager.getInstance().isDefined(_id))
{
final L2Npc spawnedNpc = DBSpawnManager.getInstance().addNewSpawn(spawn, true);
if ((spawnedNpc != null) && spawnedNpc.isMonster() && (_minions != null))
{
((L2MonsterInstance) spawnedNpc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(spawnedNpc);
}
}
else
{
final L2Npc npc = spawn.doSpawn(_spawnAnimation);
if (npc.isMonster() && (_minions != null))
{
((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(npc);
SpawnTable.getInstance().addNewSpawn(spawn, false);
}
}
public void despawn() public void despawn()
{ {
_spawnedNpcs.forEach(npc -> _spawnedNpcs.forEach(npc ->

View File

@ -23,6 +23,7 @@ import java.util.stream.Collectors;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.instancezone.Instance; 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.interfaces.ITerritorized;
import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory; import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory;
import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory;
@ -30,13 +31,14 @@ import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory;
/** /**
* @author UnAfraid * @author UnAfraid
*/ */
public class SpawnGroup implements Cloneable, ITerritorized public class SpawnGroup implements Cloneable, ITerritorized, IParameterized<StatsSet>
{ {
private final String _name; private final String _name;
private final boolean _spawnByDefault; private final boolean _spawnByDefault;
private List<L2SpawnTerritory> _territories; private List<L2SpawnTerritory> _territories;
private List<L2BannedSpawnTerritory> _bannedTerritories; private List<L2BannedSpawnTerritory> _bannedTerritories;
private final List<NpcSpawnTemplate> _spawns = new ArrayList<>(); private final List<NpcSpawnTemplate> _spawns = new ArrayList<>();
private StatsSet _parameters;
public SpawnGroup(StatsSet set) public SpawnGroup(StatsSet set)
{ {
@ -101,6 +103,18 @@ public class SpawnGroup implements Cloneable, ITerritorized
return _bannedTerritories != null ? _bannedTerritories : Collections.emptyList(); 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) public List<NpcSpawnTemplate> getSpawnsById(int id)
{ {
return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList()); return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList());

View File

@ -159,41 +159,24 @@ public class DBSpawnManager
} }
} }
private class SpawnSchedule implements Runnable private void scheduleSpawn(int npcId)
{ {
private final Logger LOGGER = Logger.getLogger(SpawnSchedule.class.getName()); final L2Npc npc = _spawns.get(npcId).doSpawn();
if (npc != null)
private final int _npcId;
/**
* Instantiates a new spawn schedule.
* @param npcId the npc id
*/
public SpawnSchedule(int npcId)
{ {
_npcId = npcId; npc.setDBStatus(DBStatusType.ALIVE);
final StatsSet info = new StatsSet();
info.set("currentHP", npc.getCurrentHp());
info.set("currentMP", npc.getCurrentMp());
info.set("respawnTime", 0L);
_storedInfo.put(npcId, info);
_npcs.put(npcId, npc);
LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName());
} }
@Override _schedules.remove(npcId);
public void run()
{
final L2Npc npc = _spawns.get(_npcId).doSpawn();
if (npc != null)
{
npc.setDBStatus(DBStatusType.ALIVE);
final StatsSet info = new StatsSet();
info.set("currentHP", npc.getCurrentHp());
info.set("currentMP", npc.getCurrentMp());
info.set("respawnTime", 0L);
_storedInfo.put(_npcId, info);
_npcs.put(_npcId, npc);
LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName());
}
_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")); 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(); updateDb();
} }
} }
@ -287,7 +270,7 @@ public class DBSpawnManager
else else
{ {
final long spawnTime = respawnTime - System.currentTimeMillis(); 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); _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) if (spawn == null)
{ {
return; return null;
} }
final int npcId = spawn.getId(); 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); 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); LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Could not store npc #" + npcId + " in the DB: ", e);
} }
} }
return npc;
} }
/** /**

View File

@ -93,6 +93,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
_spawnAnimation = set.getBoolean("spawnAnimation", false); _spawnAnimation = set.getBoolean("spawnAnimation", false);
_saveInDB = set.getBoolean("dbSave", false); _saveInDB = set.getBoolean("dbSave", false);
_dbName = set.getString("dbName", null); _dbName = set.getString("dbName", null);
_parameters = mergeParameters(spawnTemplate, group);
final int x = set.getInt("x", Integer.MAX_VALUE); final int x = set.getInt("x", Integer.MAX_VALUE);
final int y = set.getInt("y", 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; _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) public void addSpawnLocation(ChanceLocation loc)
@ -188,7 +214,14 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
@Override @Override
public void setParameters(StatsSet parameters) public void setParameters(StatsSet parameters)
{ {
_parameters = parameters; if (_parameters == null)
{
_parameters = parameters;
}
else
{
_parameters.merge(parameters);
}
} }
public boolean hasSpawnAnimation() public boolean hasSpawnAnimation()
@ -233,8 +266,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
float cumulativeChance = 0; float cumulativeChance = 0;
for (ChanceLocation loc : _locations) for (ChanceLocation loc : _locations)
{ {
cumulativeChance += loc.getChance(); if (locRandom <= (cumulativeChance += loc.getChance()))
if (locRandom <= cumulativeChance)
{ {
return loc; return loc;
} }
@ -285,70 +317,21 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
try try
{ {
final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id); final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id);
if (npcTemplate != null) if (npcTemplate == null)
{ {
if (npcTemplate.isType("L2Defender")) LOGGER.warning("Attempting to spawn unexisting npc id: " + _id + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName());
{ return;
LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); }
return;
}
final L2Spawn spawn = new L2Spawn(npcTemplate); if (npcTemplate.isType("L2Defender"))
final Location loc = getSpawnLocation(); {
if (loc == null) LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName());
{ return;
LOGGER.warning("Couldn't initialize new spawn, no location found!"); }
return;
}
spawn.setInstanceId(instance != null ? instance.getId() : 0); for (int i = 0; i < _count; i++)
spawn.setXYZ(loc); {
spawn.setHeading(loc.getHeading()); spawnNpc(npcTemplate, instance);
spawn.setAmount(_count);
spawn.setLocation(loc);
int respawn = 0, respawnRandom = 0;
if (_respawnTime != null)
{
respawn = (int) _respawnTime.getSeconds();
}
if (_respawnTimeRandom != null)
{
respawnRandom = (int) _respawnTimeRandom.getSeconds();
}
if (respawn > 0)
{
spawn.setRespawnDelay(respawn, respawnRandom);
spawn.startRespawn();
}
else
{
spawn.stopRespawn();
}
spawn.setSpawnTemplate(this);
if (_saveInDB)
{
if (!DBSpawnManager.getInstance().isDefined(_id))
{
DBSpawnManager.getInstance().addNewSpawn(spawn, true);
}
}
else
{
for (int i = 0; i < spawn.getAmount(); i++)
{
final L2Npc npc = spawn.doSpawn(_spawnAnimation);
if (npc.isMonster() && (_minions != null))
{
((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(npc);
}
SpawnTable.getInstance().addNewSpawn(spawn, false);
}
} }
} }
catch (Exception e) catch (Exception e)
@ -357,6 +340,77 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
} }
} }
/**
* @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)
{
LOGGER.warning("Couldn't initialize new spawn, no location found!");
return;
}
spawn.setInstanceId(instance != null ? instance.getId() : 0);
spawn.setAmount(1);
spawn.setXYZ(loc);
spawn.setHeading(loc.getHeading());
spawn.setLocation(loc);
int respawn = 0, respawnRandom = 0;
if (_respawnTime != null)
{
respawn = (int) _respawnTime.getSeconds();
}
if (_respawnTimeRandom != null)
{
respawnRandom = (int) _respawnTimeRandom.getSeconds();
}
if (respawn > 0)
{
spawn.setRespawnDelay(respawn, respawnRandom);
spawn.startRespawn();
}
else
{
spawn.stopRespawn();
}
spawn.setSpawnTemplate(this);
if (_saveInDB)
{
if (!DBSpawnManager.getInstance().isDefined(_id))
{
final L2Npc spawnedNpc = DBSpawnManager.getInstance().addNewSpawn(spawn, true);
if ((spawnedNpc != null) && spawnedNpc.isMonster() && (_minions != null))
{
((L2MonsterInstance) spawnedNpc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(spawnedNpc);
}
}
else
{
final L2Npc npc = spawn.doSpawn(_spawnAnimation);
if (npc.isMonster() && (_minions != null))
{
((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(npc);
SpawnTable.getInstance().addNewSpawn(spawn, false);
}
}
public void despawn() public void despawn()
{ {
_spawnedNpcs.forEach(npc -> _spawnedNpcs.forEach(npc ->

View File

@ -23,6 +23,7 @@ import java.util.stream.Collectors;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.instancezone.Instance; 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.interfaces.ITerritorized;
import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory; import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory;
import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory;
@ -30,13 +31,14 @@ import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory;
/** /**
* @author UnAfraid * @author UnAfraid
*/ */
public class SpawnGroup implements Cloneable, ITerritorized public class SpawnGroup implements Cloneable, ITerritorized, IParameterized<StatsSet>
{ {
private final String _name; private final String _name;
private final boolean _spawnByDefault; private final boolean _spawnByDefault;
private List<L2SpawnTerritory> _territories; private List<L2SpawnTerritory> _territories;
private List<L2BannedSpawnTerritory> _bannedTerritories; private List<L2BannedSpawnTerritory> _bannedTerritories;
private final List<NpcSpawnTemplate> _spawns = new ArrayList<>(); private final List<NpcSpawnTemplate> _spawns = new ArrayList<>();
private StatsSet _parameters;
public SpawnGroup(StatsSet set) public SpawnGroup(StatsSet set)
{ {
@ -101,6 +103,18 @@ public class SpawnGroup implements Cloneable, ITerritorized
return _bannedTerritories != null ? _bannedTerritories : Collections.emptyList(); 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) public List<NpcSpawnTemplate> getSpawnsById(int id)
{ {
return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList()); return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList());

View File

@ -159,41 +159,24 @@ public class DBSpawnManager
} }
} }
private class SpawnSchedule implements Runnable private void scheduleSpawn(int npcId)
{ {
private final Logger LOGGER = Logger.getLogger(SpawnSchedule.class.getName()); final L2Npc npc = _spawns.get(npcId).doSpawn();
if (npc != null)
private final int _npcId;
/**
* Instantiates a new spawn schedule.
* @param npcId the npc id
*/
public SpawnSchedule(int npcId)
{ {
_npcId = npcId; npc.setDBStatus(DBStatusType.ALIVE);
final StatsSet info = new StatsSet();
info.set("currentHP", npc.getCurrentHp());
info.set("currentMP", npc.getCurrentMp());
info.set("respawnTime", 0L);
_storedInfo.put(npcId, info);
_npcs.put(npcId, npc);
LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName());
} }
@Override _schedules.remove(npcId);
public void run()
{
final L2Npc npc = _spawns.get(_npcId).doSpawn();
if (npc != null)
{
npc.setDBStatus(DBStatusType.ALIVE);
final StatsSet info = new StatsSet();
info.set("currentHP", npc.getCurrentHp());
info.set("currentMP", npc.getCurrentMp());
info.set("respawnTime", 0L);
_storedInfo.put(_npcId, info);
_npcs.put(_npcId, npc);
LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName());
}
_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")); 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(); updateDb();
} }
} }
@ -287,7 +270,7 @@ public class DBSpawnManager
else else
{ {
final long spawnTime = respawnTime - System.currentTimeMillis(); 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); _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) if (spawn == null)
{ {
return; return null;
} }
final int npcId = spawn.getId(); 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); 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); LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Could not store npc #" + npcId + " in the DB: ", e);
} }
} }
return npc;
} }
/** /**

View File

@ -93,6 +93,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
_spawnAnimation = set.getBoolean("spawnAnimation", false); _spawnAnimation = set.getBoolean("spawnAnimation", false);
_saveInDB = set.getBoolean("dbSave", false); _saveInDB = set.getBoolean("dbSave", false);
_dbName = set.getString("dbName", null); _dbName = set.getString("dbName", null);
_parameters = mergeParameters(spawnTemplate, group);
final int x = set.getInt("x", Integer.MAX_VALUE); final int x = set.getInt("x", Integer.MAX_VALUE);
final int y = set.getInt("y", 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; _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) public void addSpawnLocation(ChanceLocation loc)
@ -188,7 +214,14 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
@Override @Override
public void setParameters(StatsSet parameters) public void setParameters(StatsSet parameters)
{ {
_parameters = parameters; if (_parameters == null)
{
_parameters = parameters;
}
else
{
_parameters.merge(parameters);
}
} }
public boolean hasSpawnAnimation() public boolean hasSpawnAnimation()
@ -233,8 +266,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
float cumulativeChance = 0; float cumulativeChance = 0;
for (ChanceLocation loc : _locations) for (ChanceLocation loc : _locations)
{ {
cumulativeChance += loc.getChance(); if (locRandom <= (cumulativeChance += loc.getChance()))
if (locRandom <= cumulativeChance)
{ {
return loc; return loc;
} }
@ -285,70 +317,21 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
try try
{ {
final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id); final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id);
if (npcTemplate != null) if (npcTemplate == null)
{ {
if (npcTemplate.isType("L2Defender")) LOGGER.warning("Attempting to spawn unexisting npc id: " + _id + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName());
{ return;
LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); }
return;
}
final L2Spawn spawn = new L2Spawn(npcTemplate); if (npcTemplate.isType("L2Defender"))
final Location loc = getSpawnLocation(); {
if (loc == null) LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName());
{ return;
LOGGER.warning("Couldn't initialize new spawn, no location found!"); }
return;
}
spawn.setInstanceId(instance != null ? instance.getId() : 0); for (int i = 0; i < _count; i++)
spawn.setXYZ(loc); {
spawn.setHeading(loc.getHeading()); spawnNpc(npcTemplate, instance);
spawn.setAmount(_count);
spawn.setLocation(loc);
int respawn = 0, respawnRandom = 0;
if (_respawnTime != null)
{
respawn = (int) _respawnTime.getSeconds();
}
if (_respawnTimeRandom != null)
{
respawnRandom = (int) _respawnTimeRandom.getSeconds();
}
if (respawn > 0)
{
spawn.setRespawnDelay(respawn, respawnRandom);
spawn.startRespawn();
}
else
{
spawn.stopRespawn();
}
spawn.setSpawnTemplate(this);
if (_saveInDB)
{
if (!DBSpawnManager.getInstance().isDefined(_id))
{
DBSpawnManager.getInstance().addNewSpawn(spawn, true);
}
}
else
{
for (int i = 0; i < spawn.getAmount(); i++)
{
final L2Npc npc = spawn.doSpawn(_spawnAnimation);
if (npc.isMonster() && (_minions != null))
{
((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(npc);
}
SpawnTable.getInstance().addNewSpawn(spawn, false);
}
} }
} }
catch (Exception e) catch (Exception e)
@ -357,6 +340,77 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
} }
} }
/**
* @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)
{
LOGGER.warning("Couldn't initialize new spawn, no location found!");
return;
}
spawn.setInstanceId(instance != null ? instance.getId() : 0);
spawn.setAmount(1);
spawn.setXYZ(loc);
spawn.setHeading(loc.getHeading());
spawn.setLocation(loc);
int respawn = 0, respawnRandom = 0;
if (_respawnTime != null)
{
respawn = (int) _respawnTime.getSeconds();
}
if (_respawnTimeRandom != null)
{
respawnRandom = (int) _respawnTimeRandom.getSeconds();
}
if (respawn > 0)
{
spawn.setRespawnDelay(respawn, respawnRandom);
spawn.startRespawn();
}
else
{
spawn.stopRespawn();
}
spawn.setSpawnTemplate(this);
if (_saveInDB)
{
if (!DBSpawnManager.getInstance().isDefined(_id))
{
final L2Npc spawnedNpc = DBSpawnManager.getInstance().addNewSpawn(spawn, true);
if ((spawnedNpc != null) && spawnedNpc.isMonster() && (_minions != null))
{
((L2MonsterInstance) spawnedNpc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(spawnedNpc);
}
}
else
{
final L2Npc npc = spawn.doSpawn(_spawnAnimation);
if (npc.isMonster() && (_minions != null))
{
((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(npc);
SpawnTable.getInstance().addNewSpawn(spawn, false);
}
}
public void despawn() public void despawn()
{ {
_spawnedNpcs.forEach(npc -> _spawnedNpcs.forEach(npc ->

View File

@ -23,6 +23,7 @@ import java.util.stream.Collectors;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.instancezone.Instance; 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.interfaces.ITerritorized;
import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory; import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory;
import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory;
@ -30,13 +31,14 @@ import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory;
/** /**
* @author UnAfraid * @author UnAfraid
*/ */
public class SpawnGroup implements Cloneable, ITerritorized public class SpawnGroup implements Cloneable, ITerritorized, IParameterized<StatsSet>
{ {
private final String _name; private final String _name;
private final boolean _spawnByDefault; private final boolean _spawnByDefault;
private List<L2SpawnTerritory> _territories; private List<L2SpawnTerritory> _territories;
private List<L2BannedSpawnTerritory> _bannedTerritories; private List<L2BannedSpawnTerritory> _bannedTerritories;
private final List<NpcSpawnTemplate> _spawns = new ArrayList<>(); private final List<NpcSpawnTemplate> _spawns = new ArrayList<>();
private StatsSet _parameters;
public SpawnGroup(StatsSet set) public SpawnGroup(StatsSet set)
{ {
@ -101,6 +103,18 @@ public class SpawnGroup implements Cloneable, ITerritorized
return _bannedTerritories != null ? _bannedTerritories : Collections.emptyList(); 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) public List<NpcSpawnTemplate> getSpawnsById(int id)
{ {
return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList()); return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList());

View File

@ -159,41 +159,24 @@ public class DBSpawnManager
} }
} }
private class SpawnSchedule implements Runnable private void scheduleSpawn(int npcId)
{ {
private final Logger LOGGER = Logger.getLogger(SpawnSchedule.class.getName()); final L2Npc npc = _spawns.get(npcId).doSpawn();
if (npc != null)
private final int _npcId;
/**
* Instantiates a new spawn schedule.
* @param npcId the npc id
*/
public SpawnSchedule(int npcId)
{ {
_npcId = npcId; npc.setDBStatus(DBStatusType.ALIVE);
final StatsSet info = new StatsSet();
info.set("currentHP", npc.getCurrentHp());
info.set("currentMP", npc.getCurrentMp());
info.set("respawnTime", 0L);
_storedInfo.put(npcId, info);
_npcs.put(npcId, npc);
LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName());
} }
@Override _schedules.remove(npcId);
public void run()
{
final L2Npc npc = _spawns.get(_npcId).doSpawn();
if (npc != null)
{
npc.setDBStatus(DBStatusType.ALIVE);
final StatsSet info = new StatsSet();
info.set("currentHP", npc.getCurrentHp());
info.set("currentMP", npc.getCurrentMp());
info.set("respawnTime", 0L);
_storedInfo.put(_npcId, info);
_npcs.put(_npcId, npc);
LOGGER.info(getClass().getSimpleName() + ": Spawning NPC " + npc.getName());
}
_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")); 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(); updateDb();
} }
} }
@ -287,7 +270,7 @@ public class DBSpawnManager
else else
{ {
final long spawnTime = respawnTime - System.currentTimeMillis(); 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); _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) if (spawn == null)
{ {
return; return null;
} }
final int npcId = spawn.getId(); 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); 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); LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Could not store npc #" + npcId + " in the DB: ", e);
} }
} }
return npc;
} }
/** /**

View File

@ -93,6 +93,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
_spawnAnimation = set.getBoolean("spawnAnimation", false); _spawnAnimation = set.getBoolean("spawnAnimation", false);
_saveInDB = set.getBoolean("dbSave", false); _saveInDB = set.getBoolean("dbSave", false);
_dbName = set.getString("dbName", null); _dbName = set.getString("dbName", null);
_parameters = mergeParameters(spawnTemplate, group);
final int x = set.getInt("x", Integer.MAX_VALUE); final int x = set.getInt("x", Integer.MAX_VALUE);
final int y = set.getInt("y", 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; _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) public void addSpawnLocation(ChanceLocation loc)
@ -188,7 +214,14 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
@Override @Override
public void setParameters(StatsSet parameters) public void setParameters(StatsSet parameters)
{ {
_parameters = parameters; if (_parameters == null)
{
_parameters = parameters;
}
else
{
_parameters.merge(parameters);
}
} }
public boolean hasSpawnAnimation() public boolean hasSpawnAnimation()
@ -233,8 +266,7 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
float cumulativeChance = 0; float cumulativeChance = 0;
for (ChanceLocation loc : _locations) for (ChanceLocation loc : _locations)
{ {
cumulativeChance += loc.getChance(); if (locRandom <= (cumulativeChance += loc.getChance()))
if (locRandom <= cumulativeChance)
{ {
return loc; return loc;
} }
@ -285,70 +317,21 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
try try
{ {
final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id); final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(_id);
if (npcTemplate != null) if (npcTemplate == null)
{ {
if (npcTemplate.isType("L2Defender")) LOGGER.warning("Attempting to spawn unexisting npc id: " + _id + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName());
{ return;
LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName()); }
return;
}
final L2Spawn spawn = new L2Spawn(npcTemplate); if (npcTemplate.isType("L2Defender"))
final Location loc = getSpawnLocation(); {
if (loc == null) LOGGER.warning("Attempting to spawn npc id: " + _id + " type: " + npcTemplate.getType() + " file: " + _spawnTemplate.getFile().getName() + " spawn: " + _spawnTemplate.getName() + " group: " + _group.getName());
{ return;
LOGGER.warning("Couldn't initialize new spawn, no location found!"); }
return;
}
spawn.setInstanceId(instance != null ? instance.getId() : 0); for (int i = 0; i < _count; i++)
spawn.setXYZ(loc); {
spawn.setHeading(loc.getHeading()); spawnNpc(npcTemplate, instance);
spawn.setAmount(_count);
spawn.setLocation(loc);
int respawn = 0, respawnRandom = 0;
if (_respawnTime != null)
{
respawn = (int) _respawnTime.getSeconds();
}
if (_respawnTimeRandom != null)
{
respawnRandom = (int) _respawnTimeRandom.getSeconds();
}
if (respawn > 0)
{
spawn.setRespawnDelay(respawn, respawnRandom);
spawn.startRespawn();
}
else
{
spawn.stopRespawn();
}
spawn.setSpawnTemplate(this);
if (_saveInDB)
{
if (!DBSpawnManager.getInstance().isDefined(_id))
{
DBSpawnManager.getInstance().addNewSpawn(spawn, true);
}
}
else
{
for (int i = 0; i < spawn.getAmount(); i++)
{
final L2Npc npc = spawn.doSpawn(_spawnAnimation);
if (npc.isMonster() && (_minions != null))
{
((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(npc);
}
SpawnTable.getInstance().addNewSpawn(spawn, false);
}
} }
} }
catch (Exception e) catch (Exception e)
@ -357,6 +340,77 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
} }
} }
/**
* @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)
{
LOGGER.warning("Couldn't initialize new spawn, no location found!");
return;
}
spawn.setInstanceId(instance != null ? instance.getId() : 0);
spawn.setAmount(1);
spawn.setXYZ(loc);
spawn.setHeading(loc.getHeading());
spawn.setLocation(loc);
int respawn = 0, respawnRandom = 0;
if (_respawnTime != null)
{
respawn = (int) _respawnTime.getSeconds();
}
if (_respawnTimeRandom != null)
{
respawnRandom = (int) _respawnTimeRandom.getSeconds();
}
if (respawn > 0)
{
spawn.setRespawnDelay(respawn, respawnRandom);
spawn.startRespawn();
}
else
{
spawn.stopRespawn();
}
spawn.setSpawnTemplate(this);
if (_saveInDB)
{
if (!DBSpawnManager.getInstance().isDefined(_id))
{
final L2Npc spawnedNpc = DBSpawnManager.getInstance().addNewSpawn(spawn, true);
if ((spawnedNpc != null) && spawnedNpc.isMonster() && (_minions != null))
{
((L2MonsterInstance) spawnedNpc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(spawnedNpc);
}
}
else
{
final L2Npc npc = spawn.doSpawn(_spawnAnimation);
if (npc.isMonster() && (_minions != null))
{
((L2MonsterInstance) npc).getMinionList().spawnMinions(_minions);
}
_spawnedNpcs.add(npc);
SpawnTable.getInstance().addNewSpawn(spawn, false);
}
}
public void despawn() public void despawn()
{ {
_spawnedNpcs.forEach(npc -> _spawnedNpcs.forEach(npc ->

View File

@ -23,6 +23,7 @@ import java.util.stream.Collectors;
import com.l2jmobius.gameserver.model.StatsSet; import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.instancezone.Instance; 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.interfaces.ITerritorized;
import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory; import com.l2jmobius.gameserver.model.zone.type.L2BannedSpawnTerritory;
import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory; import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory;
@ -30,13 +31,14 @@ import com.l2jmobius.gameserver.model.zone.type.L2SpawnTerritory;
/** /**
* @author UnAfraid * @author UnAfraid
*/ */
public class SpawnGroup implements Cloneable, ITerritorized public class SpawnGroup implements Cloneable, ITerritorized, IParameterized<StatsSet>
{ {
private final String _name; private final String _name;
private final boolean _spawnByDefault; private final boolean _spawnByDefault;
private List<L2SpawnTerritory> _territories; private List<L2SpawnTerritory> _territories;
private List<L2BannedSpawnTerritory> _bannedTerritories; private List<L2BannedSpawnTerritory> _bannedTerritories;
private final List<NpcSpawnTemplate> _spawns = new ArrayList<>(); private final List<NpcSpawnTemplate> _spawns = new ArrayList<>();
private StatsSet _parameters;
public SpawnGroup(StatsSet set) public SpawnGroup(StatsSet set)
{ {
@ -101,6 +103,18 @@ public class SpawnGroup implements Cloneable, ITerritorized
return _bannedTerritories != null ? _bannedTerritories : Collections.emptyList(); 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) public List<NpcSpawnTemplate> getSpawnsById(int id)
{ {
return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList()); return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList());