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,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;
}
/**

View File

@ -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()
{

View File

@ -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());

View File

@ -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;
}
/**

View File

@ -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()
{

View File

@ -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());

View File

@ -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;
}
/**

View File

@ -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()
{

View File

@ -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());

View File

@ -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;
}
/**

View File

@ -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()
{

View File

@ -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());