Dropped reused minion references.

This commit is contained in:
MobiusDev
2018-01-19 06:46:02 +00:00
parent 4e3a5d92c6
commit 078a59d2c4
18 changed files with 134 additions and 556 deletions

View File

@@ -509,13 +509,6 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
{ {
npc.clearAggroList(); npc.clearAggroList();
npc.getAttackByList().clear(); npc.getAttackByList().clear();
if (npc.isMonster())
{
if (((L2MonsterInstance) npc).hasMinions())
{
((L2MonsterInstance) npc).getMinionList().deleteReusedMinions();
}
}
} }
// Check if the mob should not return to spawn point // Check if the mob should not return to spawn point

View File

@@ -115,12 +115,6 @@ public class L2MonsterInstance extends L2Attackable
getLeader().getMinionList().onMinionSpawn(this); getLeader().getMinionList().onMinionSpawn(this);
} }
// delete spawned minions before dynamic minions spawned by script
if (hasMinions())
{
getMinionList().onMasterSpawn();
}
startMaintenanceTask(); startMaintenanceTask();
} }

View File

@@ -30,15 +30,12 @@ import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.holders.MinionHolder; import com.l2jmobius.gameserver.model.holders.MinionHolder;
/** /**
* @author luisantonioa, DS * @author luisantonioa, DS, Mobius
*/ */
public class MinionList public class MinionList
{ {
protected final L2MonsterInstance _master; protected final L2MonsterInstance _master;
/** List containing the current spawned minions */ private final List<L2MonsterInstance> _spawnedMinions = new CopyOnWriteArrayList<>();
private final List<L2MonsterInstance> _minionReferences = new CopyOnWriteArrayList<>();
/** List containing the cached deleted minions for reuse */
protected List<L2MonsterInstance> _reusedMinionReferences = null;
public MinionList(L2MonsterInstance pMaster) public MinionList(L2MonsterInstance pMaster)
{ {
@@ -54,7 +51,7 @@ public class MinionList
*/ */
public List<L2MonsterInstance> getSpawnedMinions() public List<L2MonsterInstance> getSpawnedMinions()
{ {
return _minionReferences; return _spawnedMinions;
} }
/** /**
@@ -69,13 +66,7 @@ public class MinionList
*/ */
public final void spawnMinions(List<MinionHolder> minions) public final void spawnMinions(List<MinionHolder> minions)
{ {
if (_master.isAlikeDead()) if (_master.isAlikeDead() || (minions == null))
{
return;
}
// List<MinionHolder> minions = _master.getParameters().getMinionList("Privates");
if (minions == null)
{ {
return; return;
} }
@@ -95,8 +86,6 @@ public class MinionList
} }
} }
} }
// remove non-needed minions
deleteReusedMinions();
} }
/** /**
@@ -104,48 +93,17 @@ public class MinionList
*/ */
public void deleteSpawnedMinions() public void deleteSpawnedMinions()
{ {
if (!_minionReferences.isEmpty()) if (!_spawnedMinions.isEmpty())
{ {
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if (minion != null) if (minion != null)
{ {
minion.setLeader(null); minion.setLeader(null);
minion.deleteMe(); minion.deleteMe();
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
} }
} }
_minionReferences.clear(); _spawnedMinions.clear();
}
}
/**
* Delete all reused minions to prevent memory leaks.
*/
public void deleteReusedMinions()
{
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.clear();
}
}
// hooks
/**
* Called on the master spawn Old minions (from previous spawn) are deleted. If master can respawn - enabled reuse of the killed minions.
*/
public void onMasterSpawn()
{
deleteSpawnedMinions();
// if master has spawn and can respawn - try to reuse minions
if ((_reusedMinionReferences == null) && (_master.getParameters().getSet().get("SummonPrivateRate") == null) && !_master.getParameters().getMinionList("Privates").isEmpty() && (_master.getSpawn() != null) && _master.getSpawn().isRespawnEnabled())
{
_reusedMinionReferences = new CopyOnWriteArrayList<>();
} }
} }
@@ -155,7 +113,7 @@ public class MinionList
*/ */
public void onMinionSpawn(L2MonsterInstance minion) public void onMinionSpawn(L2MonsterInstance minion)
{ {
_minionReferences.add(minion); _spawnedMinions.add(minion);
} }
/** /**
@@ -178,11 +136,7 @@ public class MinionList
public void onMinionDie(L2MonsterInstance minion, int respawnTime) public void onMinionDie(L2MonsterInstance minion, int respawnTime)
{ {
minion.setLeader(null); // prevent memory leaks minion.setLeader(null); // prevent memory leaks
_minionReferences.remove(minion); _spawnedMinions.remove(minion);
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime; final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime;
if ((time > 0) && !_master.isAlikeDead()) if ((time > 0) && !_master.isAlikeDead())
@@ -215,7 +169,7 @@ public class MinionList
aggro *= 10; aggro *= 10;
} }
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat())) if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat()))
{ {
@@ -232,7 +186,7 @@ public class MinionList
final int offset = 200; final int offset = 200;
final int minRadius = (int) _master.getCollisionRadius() + 30; final int minRadius = (int) _master.getCollisionRadius() + 30;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled()) if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled())
{ {
@@ -267,20 +221,6 @@ public class MinionList
{ {
return; return;
} }
// searching in reused minions
if (_reusedMinionReferences != null)
{
final L2MonsterInstance minion = _reusedMinionReferences.stream().filter(m -> (m.getId() == minionId)).findFirst().orElse(null);
if (minion != null)
{
_reusedMinionReferences.remove(minion);
minion.refreshID();
initializeNpcInstance(_master, minion);
return;
}
}
// not found in cache
spawnMinion(_master, minionId); spawnMinion(_master, minionId);
} }
@@ -301,11 +241,6 @@ public class MinionList
// minion can be already spawned or deleted // minion can be already spawned or deleted
if (!_minion.isSpawned()) if (!_minion.isSpawned())
{ {
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.remove(_minion);
}
_minion.refreshID(); _minion.refreshID();
initializeNpcInstance(_master, _minion); initializeNpcInstance(_master, _minion);
} }
@@ -390,7 +325,7 @@ public class MinionList
private final int countSpawnedMinionsById(int minionId) private final int countSpawnedMinionsById(int minionId)
{ {
int count = 0; int count = 0;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && (minion.getId() == minionId)) if ((minion != null) && (minion.getId() == minionId))
{ {
@@ -402,11 +337,11 @@ public class MinionList
public final int countSpawnedMinions() public final int countSpawnedMinions()
{ {
return _minionReferences.size(); return _spawnedMinions.size();
} }
public final long lazyCountSpawnedMinionsGroups() public final long lazyCountSpawnedMinionsGroups()
{ {
return _minionReferences.stream().distinct().count(); return _spawnedMinions.stream().distinct().count();
} }
} }

View File

@@ -509,13 +509,6 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
{ {
npc.clearAggroList(); npc.clearAggroList();
npc.getAttackByList().clear(); npc.getAttackByList().clear();
if (npc.isMonster())
{
if (((L2MonsterInstance) npc).hasMinions())
{
((L2MonsterInstance) npc).getMinionList().deleteReusedMinions();
}
}
} }
// Check if the mob should not return to spawn point // Check if the mob should not return to spawn point

View File

@@ -115,12 +115,6 @@ public class L2MonsterInstance extends L2Attackable
getLeader().getMinionList().onMinionSpawn(this); getLeader().getMinionList().onMinionSpawn(this);
} }
// delete spawned minions before dynamic minions spawned by script
if (hasMinions())
{
getMinionList().onMasterSpawn();
}
startMaintenanceTask(); startMaintenanceTask();
} }

View File

@@ -30,15 +30,12 @@ import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.holders.MinionHolder; import com.l2jmobius.gameserver.model.holders.MinionHolder;
/** /**
* @author luisantonioa, DS * @author luisantonioa, DS, Mobius
*/ */
public class MinionList public class MinionList
{ {
protected final L2MonsterInstance _master; protected final L2MonsterInstance _master;
/** List containing the current spawned minions */ private final List<L2MonsterInstance> _spawnedMinions = new CopyOnWriteArrayList<>();
private final List<L2MonsterInstance> _minionReferences = new CopyOnWriteArrayList<>();
/** List containing the cached deleted minions for reuse */
protected List<L2MonsterInstance> _reusedMinionReferences = null;
public MinionList(L2MonsterInstance pMaster) public MinionList(L2MonsterInstance pMaster)
{ {
@@ -54,7 +51,7 @@ public class MinionList
*/ */
public List<L2MonsterInstance> getSpawnedMinions() public List<L2MonsterInstance> getSpawnedMinions()
{ {
return _minionReferences; return _spawnedMinions;
} }
/** /**
@@ -69,13 +66,7 @@ public class MinionList
*/ */
public final void spawnMinions(List<MinionHolder> minions) public final void spawnMinions(List<MinionHolder> minions)
{ {
if (_master.isAlikeDead()) if (_master.isAlikeDead() || (minions == null))
{
return;
}
// List<MinionHolder> minions = _master.getParameters().getMinionList("Privates");
if (minions == null)
{ {
return; return;
} }
@@ -95,8 +86,6 @@ public class MinionList
} }
} }
} }
// remove non-needed minions
deleteReusedMinions();
} }
/** /**
@@ -104,48 +93,17 @@ public class MinionList
*/ */
public void deleteSpawnedMinions() public void deleteSpawnedMinions()
{ {
if (!_minionReferences.isEmpty()) if (!_spawnedMinions.isEmpty())
{ {
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if (minion != null) if (minion != null)
{ {
minion.setLeader(null); minion.setLeader(null);
minion.deleteMe(); minion.deleteMe();
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
} }
} }
_minionReferences.clear(); _spawnedMinions.clear();
}
}
/**
* Delete all reused minions to prevent memory leaks.
*/
public void deleteReusedMinions()
{
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.clear();
}
}
// hooks
/**
* Called on the master spawn Old minions (from previous spawn) are deleted. If master can respawn - enabled reuse of the killed minions.
*/
public void onMasterSpawn()
{
deleteSpawnedMinions();
// if master has spawn and can respawn - try to reuse minions
if ((_reusedMinionReferences == null) && (_master.getParameters().getSet().get("SummonPrivateRate") == null) && !_master.getParameters().getMinionList("Privates").isEmpty() && (_master.getSpawn() != null) && _master.getSpawn().isRespawnEnabled())
{
_reusedMinionReferences = new CopyOnWriteArrayList<>();
} }
} }
@@ -155,7 +113,7 @@ public class MinionList
*/ */
public void onMinionSpawn(L2MonsterInstance minion) public void onMinionSpawn(L2MonsterInstance minion)
{ {
_minionReferences.add(minion); _spawnedMinions.add(minion);
} }
/** /**
@@ -178,11 +136,7 @@ public class MinionList
public void onMinionDie(L2MonsterInstance minion, int respawnTime) public void onMinionDie(L2MonsterInstance minion, int respawnTime)
{ {
minion.setLeader(null); // prevent memory leaks minion.setLeader(null); // prevent memory leaks
_minionReferences.remove(minion); _spawnedMinions.remove(minion);
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime; final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime;
if ((time > 0) && !_master.isAlikeDead()) if ((time > 0) && !_master.isAlikeDead())
@@ -215,7 +169,7 @@ public class MinionList
aggro *= 10; aggro *= 10;
} }
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat())) if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat()))
{ {
@@ -232,7 +186,7 @@ public class MinionList
final int offset = 200; final int offset = 200;
final int minRadius = (int) _master.getCollisionRadius() + 30; final int minRadius = (int) _master.getCollisionRadius() + 30;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled()) if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled())
{ {
@@ -267,20 +221,6 @@ public class MinionList
{ {
return; return;
} }
// searching in reused minions
if (_reusedMinionReferences != null)
{
final L2MonsterInstance minion = _reusedMinionReferences.stream().filter(m -> (m.getId() == minionId)).findFirst().orElse(null);
if (minion != null)
{
_reusedMinionReferences.remove(minion);
minion.refreshID();
initializeNpcInstance(_master, minion);
return;
}
}
// not found in cache
spawnMinion(_master, minionId); spawnMinion(_master, minionId);
} }
@@ -301,11 +241,6 @@ public class MinionList
// minion can be already spawned or deleted // minion can be already spawned or deleted
if (!_minion.isSpawned()) if (!_minion.isSpawned())
{ {
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.remove(_minion);
}
_minion.refreshID(); _minion.refreshID();
initializeNpcInstance(_master, _minion); initializeNpcInstance(_master, _minion);
} }
@@ -390,7 +325,7 @@ public class MinionList
private final int countSpawnedMinionsById(int minionId) private final int countSpawnedMinionsById(int minionId)
{ {
int count = 0; int count = 0;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && (minion.getId() == minionId)) if ((minion != null) && (minion.getId() == minionId))
{ {
@@ -402,11 +337,11 @@ public class MinionList
public final int countSpawnedMinions() public final int countSpawnedMinions()
{ {
return _minionReferences.size(); return _spawnedMinions.size();
} }
public final long lazyCountSpawnedMinionsGroups() public final long lazyCountSpawnedMinionsGroups()
{ {
return _minionReferences.stream().distinct().count(); return _spawnedMinions.stream().distinct().count();
} }
} }

View File

@@ -509,13 +509,6 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
{ {
npc.clearAggroList(); npc.clearAggroList();
npc.getAttackByList().clear(); npc.getAttackByList().clear();
if (npc.isMonster())
{
if (((L2MonsterInstance) npc).hasMinions())
{
((L2MonsterInstance) npc).getMinionList().deleteReusedMinions();
}
}
} }
// Check if the mob should not return to spawn point // Check if the mob should not return to spawn point

View File

@@ -115,12 +115,6 @@ public class L2MonsterInstance extends L2Attackable
getLeader().getMinionList().onMinionSpawn(this); getLeader().getMinionList().onMinionSpawn(this);
} }
// delete spawned minions before dynamic minions spawned by script
if (hasMinions())
{
getMinionList().onMasterSpawn();
}
startMaintenanceTask(); startMaintenanceTask();
} }

View File

@@ -30,15 +30,12 @@ import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.holders.MinionHolder; import com.l2jmobius.gameserver.model.holders.MinionHolder;
/** /**
* @author luisantonioa, DS * @author luisantonioa, DS, Mobius
*/ */
public class MinionList public class MinionList
{ {
protected final L2MonsterInstance _master; protected final L2MonsterInstance _master;
/** List containing the current spawned minions */ private final List<L2MonsterInstance> _spawnedMinions = new CopyOnWriteArrayList<>();
private final List<L2MonsterInstance> _minionReferences = new CopyOnWriteArrayList<>();
/** List containing the cached deleted minions for reuse */
protected List<L2MonsterInstance> _reusedMinionReferences = null;
public MinionList(L2MonsterInstance pMaster) public MinionList(L2MonsterInstance pMaster)
{ {
@@ -54,7 +51,7 @@ public class MinionList
*/ */
public List<L2MonsterInstance> getSpawnedMinions() public List<L2MonsterInstance> getSpawnedMinions()
{ {
return _minionReferences; return _spawnedMinions;
} }
/** /**
@@ -69,13 +66,7 @@ public class MinionList
*/ */
public final void spawnMinions(List<MinionHolder> minions) public final void spawnMinions(List<MinionHolder> minions)
{ {
if (_master.isAlikeDead()) if (_master.isAlikeDead() || (minions == null))
{
return;
}
// List<MinionHolder> minions = _master.getParameters().getMinionList("Privates");
if (minions == null)
{ {
return; return;
} }
@@ -95,8 +86,6 @@ public class MinionList
} }
} }
} }
// remove non-needed minions
deleteReusedMinions();
} }
/** /**
@@ -104,48 +93,17 @@ public class MinionList
*/ */
public void deleteSpawnedMinions() public void deleteSpawnedMinions()
{ {
if (!_minionReferences.isEmpty()) if (!_spawnedMinions.isEmpty())
{ {
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if (minion != null) if (minion != null)
{ {
minion.setLeader(null); minion.setLeader(null);
minion.deleteMe(); minion.deleteMe();
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
} }
} }
_minionReferences.clear(); _spawnedMinions.clear();
}
}
/**
* Delete all reused minions to prevent memory leaks.
*/
public void deleteReusedMinions()
{
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.clear();
}
}
// hooks
/**
* Called on the master spawn Old minions (from previous spawn) are deleted. If master can respawn - enabled reuse of the killed minions.
*/
public void onMasterSpawn()
{
deleteSpawnedMinions();
// if master has spawn and can respawn - try to reuse minions
if ((_reusedMinionReferences == null) && (_master.getParameters().getSet().get("SummonPrivateRate") == null) && !_master.getParameters().getMinionList("Privates").isEmpty() && (_master.getSpawn() != null) && _master.getSpawn().isRespawnEnabled())
{
_reusedMinionReferences = new CopyOnWriteArrayList<>();
} }
} }
@@ -155,7 +113,7 @@ public class MinionList
*/ */
public void onMinionSpawn(L2MonsterInstance minion) public void onMinionSpawn(L2MonsterInstance minion)
{ {
_minionReferences.add(minion); _spawnedMinions.add(minion);
} }
/** /**
@@ -178,11 +136,7 @@ public class MinionList
public void onMinionDie(L2MonsterInstance minion, int respawnTime) public void onMinionDie(L2MonsterInstance minion, int respawnTime)
{ {
minion.setLeader(null); // prevent memory leaks minion.setLeader(null); // prevent memory leaks
_minionReferences.remove(minion); _spawnedMinions.remove(minion);
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime; final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime;
if ((time > 0) && !_master.isAlikeDead()) if ((time > 0) && !_master.isAlikeDead())
@@ -215,7 +169,7 @@ public class MinionList
aggro *= 10; aggro *= 10;
} }
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat())) if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat()))
{ {
@@ -232,7 +186,7 @@ public class MinionList
final int offset = 200; final int offset = 200;
final int minRadius = (int) _master.getCollisionRadius() + 30; final int minRadius = (int) _master.getCollisionRadius() + 30;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled()) if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled())
{ {
@@ -267,20 +221,6 @@ public class MinionList
{ {
return; return;
} }
// searching in reused minions
if (_reusedMinionReferences != null)
{
final L2MonsterInstance minion = _reusedMinionReferences.stream().filter(m -> (m.getId() == minionId)).findFirst().orElse(null);
if (minion != null)
{
_reusedMinionReferences.remove(minion);
minion.refreshID();
initializeNpcInstance(_master, minion);
return;
}
}
// not found in cache
spawnMinion(_master, minionId); spawnMinion(_master, minionId);
} }
@@ -301,11 +241,6 @@ public class MinionList
// minion can be already spawned or deleted // minion can be already spawned or deleted
if (!_minion.isSpawned()) if (!_minion.isSpawned())
{ {
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.remove(_minion);
}
_minion.refreshID(); _minion.refreshID();
initializeNpcInstance(_master, _minion); initializeNpcInstance(_master, _minion);
} }
@@ -390,7 +325,7 @@ public class MinionList
private final int countSpawnedMinionsById(int minionId) private final int countSpawnedMinionsById(int minionId)
{ {
int count = 0; int count = 0;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && (minion.getId() == minionId)) if ((minion != null) && (minion.getId() == minionId))
{ {
@@ -402,11 +337,11 @@ public class MinionList
public final int countSpawnedMinions() public final int countSpawnedMinions()
{ {
return _minionReferences.size(); return _spawnedMinions.size();
} }
public final long lazyCountSpawnedMinionsGroups() public final long lazyCountSpawnedMinionsGroups()
{ {
return _minionReferences.stream().distinct().count(); return _spawnedMinions.stream().distinct().count();
} }
} }

View File

@@ -509,13 +509,6 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
{ {
npc.clearAggroList(); npc.clearAggroList();
npc.getAttackByList().clear(); npc.getAttackByList().clear();
if (npc.isMonster())
{
if (((L2MonsterInstance) npc).hasMinions())
{
((L2MonsterInstance) npc).getMinionList().deleteReusedMinions();
}
}
} }
// Check if the mob should not return to spawn point // Check if the mob should not return to spawn point

View File

@@ -115,12 +115,6 @@ public class L2MonsterInstance extends L2Attackable
getLeader().getMinionList().onMinionSpawn(this); getLeader().getMinionList().onMinionSpawn(this);
} }
// delete spawned minions before dynamic minions spawned by script
if (hasMinions())
{
getMinionList().onMasterSpawn();
}
startMaintenanceTask(); startMaintenanceTask();
} }

View File

@@ -30,15 +30,12 @@ import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.holders.MinionHolder; import com.l2jmobius.gameserver.model.holders.MinionHolder;
/** /**
* @author luisantonioa, DS * @author luisantonioa, DS, Mobius
*/ */
public class MinionList public class MinionList
{ {
protected final L2MonsterInstance _master; protected final L2MonsterInstance _master;
/** List containing the current spawned minions */ private final List<L2MonsterInstance> _spawnedMinions = new CopyOnWriteArrayList<>();
private final List<L2MonsterInstance> _minionReferences = new CopyOnWriteArrayList<>();
/** List containing the cached deleted minions for reuse */
protected List<L2MonsterInstance> _reusedMinionReferences = null;
public MinionList(L2MonsterInstance pMaster) public MinionList(L2MonsterInstance pMaster)
{ {
@@ -54,7 +51,7 @@ public class MinionList
*/ */
public List<L2MonsterInstance> getSpawnedMinions() public List<L2MonsterInstance> getSpawnedMinions()
{ {
return _minionReferences; return _spawnedMinions;
} }
/** /**
@@ -69,13 +66,7 @@ public class MinionList
*/ */
public final void spawnMinions(List<MinionHolder> minions) public final void spawnMinions(List<MinionHolder> minions)
{ {
if (_master.isAlikeDead()) if (_master.isAlikeDead() || (minions == null))
{
return;
}
// List<MinionHolder> minions = _master.getParameters().getMinionList("Privates");
if (minions == null)
{ {
return; return;
} }
@@ -95,8 +86,6 @@ public class MinionList
} }
} }
} }
// remove non-needed minions
deleteReusedMinions();
} }
/** /**
@@ -104,48 +93,17 @@ public class MinionList
*/ */
public void deleteSpawnedMinions() public void deleteSpawnedMinions()
{ {
if (!_minionReferences.isEmpty()) if (!_spawnedMinions.isEmpty())
{ {
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if (minion != null) if (minion != null)
{ {
minion.setLeader(null); minion.setLeader(null);
minion.deleteMe(); minion.deleteMe();
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
} }
} }
_minionReferences.clear(); _spawnedMinions.clear();
}
}
/**
* Delete all reused minions to prevent memory leaks.
*/
public void deleteReusedMinions()
{
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.clear();
}
}
// hooks
/**
* Called on the master spawn Old minions (from previous spawn) are deleted. If master can respawn - enabled reuse of the killed minions.
*/
public void onMasterSpawn()
{
deleteSpawnedMinions();
// if master has spawn and can respawn - try to reuse minions
if ((_reusedMinionReferences == null) && (_master.getParameters().getSet().get("SummonPrivateRate") == null) && !_master.getParameters().getMinionList("Privates").isEmpty() && (_master.getSpawn() != null) && _master.getSpawn().isRespawnEnabled())
{
_reusedMinionReferences = new CopyOnWriteArrayList<>();
} }
} }
@@ -155,7 +113,7 @@ public class MinionList
*/ */
public void onMinionSpawn(L2MonsterInstance minion) public void onMinionSpawn(L2MonsterInstance minion)
{ {
_minionReferences.add(minion); _spawnedMinions.add(minion);
} }
/** /**
@@ -178,11 +136,7 @@ public class MinionList
public void onMinionDie(L2MonsterInstance minion, int respawnTime) public void onMinionDie(L2MonsterInstance minion, int respawnTime)
{ {
minion.setLeader(null); // prevent memory leaks minion.setLeader(null); // prevent memory leaks
_minionReferences.remove(minion); _spawnedMinions.remove(minion);
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime; final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime;
if ((time > 0) && !_master.isAlikeDead()) if ((time > 0) && !_master.isAlikeDead())
@@ -215,7 +169,7 @@ public class MinionList
aggro *= 10; aggro *= 10;
} }
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat())) if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat()))
{ {
@@ -232,7 +186,7 @@ public class MinionList
final int offset = 200; final int offset = 200;
final int minRadius = (int) _master.getCollisionRadius() + 30; final int minRadius = (int) _master.getCollisionRadius() + 30;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled()) if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled())
{ {
@@ -267,20 +221,6 @@ public class MinionList
{ {
return; return;
} }
// searching in reused minions
if (_reusedMinionReferences != null)
{
final L2MonsterInstance minion = _reusedMinionReferences.stream().filter(m -> (m.getId() == minionId)).findFirst().orElse(null);
if (minion != null)
{
_reusedMinionReferences.remove(minion);
minion.refreshID();
initializeNpcInstance(_master, minion);
return;
}
}
// not found in cache
spawnMinion(_master, minionId); spawnMinion(_master, minionId);
} }
@@ -301,11 +241,6 @@ public class MinionList
// minion can be already spawned or deleted // minion can be already spawned or deleted
if (!_minion.isSpawned()) if (!_minion.isSpawned())
{ {
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.remove(_minion);
}
_minion.refreshID(); _minion.refreshID();
initializeNpcInstance(_master, _minion); initializeNpcInstance(_master, _minion);
} }
@@ -390,7 +325,7 @@ public class MinionList
private final int countSpawnedMinionsById(int minionId) private final int countSpawnedMinionsById(int minionId)
{ {
int count = 0; int count = 0;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && (minion.getId() == minionId)) if ((minion != null) && (minion.getId() == minionId))
{ {
@@ -402,11 +337,11 @@ public class MinionList
public final int countSpawnedMinions() public final int countSpawnedMinions()
{ {
return _minionReferences.size(); return _spawnedMinions.size();
} }
public final long lazyCountSpawnedMinionsGroups() public final long lazyCountSpawnedMinionsGroups()
{ {
return _minionReferences.stream().distinct().count(); return _spawnedMinions.stream().distinct().count();
} }
} }

View File

@@ -538,10 +538,6 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
{ {
npc.clearAggroList(); npc.clearAggroList();
npc.getAttackByList().clear(); npc.getAttackByList().clear();
if ((npc instanceof L2MonsterInstance) && ((L2MonsterInstance) npc).hasMinions())
{
((L2MonsterInstance) npc).getMinionList().deleteReusedMinions();
}
} }
// Check if the mob should not return to spawn point // Check if the mob should not return to spawn point

View File

@@ -97,12 +97,6 @@ public class L2MonsterInstance extends L2Attackable
getLeader().getMinionList().onMinionSpawn(this); getLeader().getMinionList().onMinionSpawn(this);
} }
// delete spawned minions before dynamic minions spawned by script
if (hasMinions())
{
getMinionList().onMasterSpawn();
}
startMaintenanceTask(); startMaintenanceTask();
} }

View File

@@ -27,19 +27,15 @@ import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance; import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate; import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.holders.MinionHolder; import com.l2jmobius.gameserver.model.holders.MinionHolder;
import com.l2jmobius.gameserver.taskmanager.DecayTaskManager;
import com.l2jmobius.util.Rnd; import com.l2jmobius.util.Rnd;
/** /**
* @author luisantonioa, DS * @author luisantonioa, DS, Mobius
*/ */
public class MinionList public class MinionList
{ {
protected final L2MonsterInstance _master; protected final L2MonsterInstance _master;
/** List containing the current spawned minions */ private final List<L2MonsterInstance> _spawnedMinions = new CopyOnWriteArrayList<>();
private final List<L2MonsterInstance> _minionReferences = new CopyOnWriteArrayList<>();
/** List containing the cached deleted minions for reuse */
protected List<L2MonsterInstance> _reusedMinionReferences = null;
public MinionList(L2MonsterInstance pMaster) public MinionList(L2MonsterInstance pMaster)
{ {
@@ -55,7 +51,7 @@ public class MinionList
*/ */
public List<L2MonsterInstance> getSpawnedMinions() public List<L2MonsterInstance> getSpawnedMinions()
{ {
return _minionReferences; return _spawnedMinions;
} }
/** /**
@@ -75,8 +71,7 @@ public class MinionList
return; return;
} }
int minionCount, minionId; int minionCount, minionId, minionsToSpawn;
long minionsToSpawn;
for (MinionHolder minion : minions) for (MinionHolder minion : minions)
{ {
minionCount = minion.getCount(); minionCount = minion.getCount();
@@ -91,8 +86,6 @@ public class MinionList
} }
} }
} }
// remove non-needed minions
deleteReusedMinions();
} }
/** /**
@@ -100,49 +93,17 @@ public class MinionList
*/ */
public void deleteSpawnedMinions() public void deleteSpawnedMinions()
{ {
if (_minionReferences.isEmpty()) if (!_spawnedMinions.isEmpty())
{ {
return; for (L2MonsterInstance minion : _spawnedMinions)
}
for (L2MonsterInstance minion : _minionReferences)
{
if (minion != null)
{ {
minion.setLeader(null); if (minion != null)
minion.deleteMe();
if (_reusedMinionReferences != null)
{ {
_reusedMinionReferences.add(minion); minion.setLeader(null);
minion.deleteMe();
} }
} }
} _spawnedMinions.clear();
_minionReferences.clear();
}
/**
* Delete all reused minions to prevent memory leaks.
*/
public void deleteReusedMinions()
{
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.clear();
}
}
// hooks
/**
* Called on the master spawn Old minions (from previous spawn) are deleted. If master can respawn - enabled reuse of the killed minions.
*/
public void onMasterSpawn()
{
deleteSpawnedMinions();
// if master has spawn and can respawn - try to reuse minions
if ((_reusedMinionReferences == null) && (_master.getTemplate().getParameters().getSet().get("SummonPrivateRate") == null) && !_master.getTemplate().getParameters().getMinionList("Privates").isEmpty() && (_master.getSpawn() != null) && _master.getSpawn().isRespawnEnabled())
{
_reusedMinionReferences = new CopyOnWriteArrayList<>();
} }
} }
@@ -152,7 +113,7 @@ public class MinionList
*/ */
public void onMinionSpawn(L2MonsterInstance minion) public void onMinionSpawn(L2MonsterInstance minion)
{ {
_minionReferences.add(minion); _spawnedMinions.add(minion);
} }
/** /**
@@ -175,11 +136,7 @@ public class MinionList
public void onMinionDie(L2MonsterInstance minion, int respawnTime) public void onMinionDie(L2MonsterInstance minion, int respawnTime)
{ {
minion.setLeader(null); // prevent memory leaks minion.setLeader(null); // prevent memory leaks
_minionReferences.remove(minion); _spawnedMinions.remove(minion);
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime; final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime;
if ((time > 0) && !_master.isAlikeDead()) if ((time > 0) && !_master.isAlikeDead())
@@ -212,7 +169,7 @@ public class MinionList
aggro *= 10; aggro *= 10;
} }
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat())) if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat()))
{ {
@@ -229,15 +186,29 @@ public class MinionList
final int offset = 200; final int offset = 200;
final int minRadius = (int) _master.getCollisionRadius() + 30; final int minRadius = (int) _master.getCollisionRadius() + 30;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled()) if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled())
{ {
int newX = Rnd.get(minRadius * 2, offset * 2); // x int newX = Rnd.get(minRadius * 2, offset * 2); // x
int newY = Rnd.get(newX, offset * 2); // distance int newY = Rnd.get(newX, offset * 2); // distance
newY = (int) Math.sqrt((newY * newY) - (newX * newX)); // y newY = (int) Math.sqrt((newY * newY) - (newX * newX)); // y
newX = newX > (offset + minRadius) ? (_master.getX() + newX) - offset : (_master.getX() - newX) + minRadius; if (newX > (offset + minRadius))
newY = newY > (offset + minRadius) ? (_master.getY() + newY) - offset : (_master.getY() - newY) + minRadius; {
newX = (_master.getX() + newX) - offset;
}
else
{
newX = (_master.getX() - newX) + minRadius;
}
if (newY > (offset + minRadius))
{
newY = (_master.getY() + newY) - offset;
}
else
{
newY = (_master.getY() - newY) + minRadius;
}
minion.teleToLocation(new Location(newX, newY, _master.getZ())); minion.teleToLocation(new Location(newX, newY, _master.getZ()));
} }
@@ -250,21 +221,6 @@ public class MinionList
{ {
return; return;
} }
// searching in reused minions
if (_reusedMinionReferences != null)
{
final L2MonsterInstance minion = _reusedMinionReferences.stream().filter(m -> (m.getId() == minionId)).findFirst().orElse(null);
if (minion != null)
{
DecayTaskManager.getInstance().cancel(minion);
minion.onDecay();
_reusedMinionReferences.remove(minion);
minion.refreshID();
initializeNpcInstance(_master, minion);
return;
}
}
// not found in cache
spawnMinion(_master, minionId); spawnMinion(_master, minionId);
} }
@@ -285,11 +241,6 @@ public class MinionList
return; return;
} }
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.remove(_minion);
}
_minion.refreshID(); _minion.refreshID();
initializeNpcInstance(_master, _minion); initializeNpcInstance(_master, _minion);
} }
@@ -314,7 +265,12 @@ public class MinionList
{ {
// Get the template of the Minion to spawn // Get the template of the Minion to spawn
final L2NpcTemplate minionTemplate = NpcData.getInstance().getTemplate(minionId); final L2NpcTemplate minionTemplate = NpcData.getInstance().getTemplate(minionId);
return minionTemplate == null ? null : initializeNpcInstance(master, new L2MonsterInstance(minionTemplate)); if (minionTemplate == null)
{
return null;
}
return initializeNpcInstance(master, new L2MonsterInstance(minionTemplate));
} }
protected static L2MonsterInstance initializeNpcInstance(L2MonsterInstance master, L2MonsterInstance minion) protected static L2MonsterInstance initializeNpcInstance(L2MonsterInstance master, L2MonsterInstance minion)
@@ -340,8 +296,22 @@ public class MinionList
int newX = Rnd.get(minRadius * 2, offset * 2); // x int newX = Rnd.get(minRadius * 2, offset * 2); // x
int newY = Rnd.get(newX, offset * 2); // distance int newY = Rnd.get(newX, offset * 2); // distance
newY = (int) Math.sqrt((newY * newY) - (newX * newX)); // y newY = (int) Math.sqrt((newY * newY) - (newX * newX)); // y
newX = newX > (offset + minRadius) ? (master.getX() + newX) - offset : (master.getX() - newX) + minRadius; if (newX > (offset + minRadius))
newY = newY > (offset + minRadius) ? (master.getY() + newY) - offset : (master.getY() - newY) + minRadius; {
newX = (master.getX() + newX) - offset;
}
else
{
newX = (master.getX() - newX) + minRadius;
}
if (newY > (offset + minRadius))
{
newY = (master.getY() + newY) - offset;
}
else
{
newY = (master.getY() - newY) + minRadius;
}
minion.spawnMe(newX, newY, master.getZ()); minion.spawnMe(newX, newY, master.getZ());
@@ -350,18 +320,26 @@ public class MinionList
// Statistics part // Statistics part
private final long countSpawnedMinionsById(int minionId) private final int countSpawnedMinionsById(int minionId)
{ {
return _minionReferences.stream().filter(npc -> npc.getId() == minionId).count(); int count = 0;
for (L2MonsterInstance minion : _spawnedMinions)
{
if ((minion != null) && (minion.getId() == minionId))
{
count++;
}
}
return count;
} }
public final int countSpawnedMinions() public final int countSpawnedMinions()
{ {
return _minionReferences.size(); return _spawnedMinions.size();
} }
public final long lazyCountSpawnedMinionsGroups() public final long lazyCountSpawnedMinionsGroups()
{ {
return _minionReferences.stream().map(L2MonsterInstance::getId).distinct().count(); return _spawnedMinions.stream().distinct().count();
} }
} }

View File

@@ -509,13 +509,6 @@ public class L2AttackableAI extends L2CharacterAI implements Runnable
{ {
npc.clearAggroList(); npc.clearAggroList();
npc.getAttackByList().clear(); npc.getAttackByList().clear();
if (npc.isMonster())
{
if (((L2MonsterInstance) npc).hasMinions())
{
((L2MonsterInstance) npc).getMinionList().deleteReusedMinions();
}
}
} }
// Check if the mob should not return to spawn point // Check if the mob should not return to spawn point

View File

@@ -115,12 +115,6 @@ public class L2MonsterInstance extends L2Attackable
getLeader().getMinionList().onMinionSpawn(this); getLeader().getMinionList().onMinionSpawn(this);
} }
// delete spawned minions before dynamic minions spawned by script
if (hasMinions())
{
getMinionList().onMasterSpawn();
}
startMaintenanceTask(); startMaintenanceTask();
} }

View File

@@ -30,15 +30,12 @@ import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.holders.MinionHolder; import com.l2jmobius.gameserver.model.holders.MinionHolder;
/** /**
* @author luisantonioa, DS * @author luisantonioa, DS, Mobius
*/ */
public class MinionList public class MinionList
{ {
protected final L2MonsterInstance _master; protected final L2MonsterInstance _master;
/** List containing the current spawned minions */ private final List<L2MonsterInstance> _spawnedMinions = new CopyOnWriteArrayList<>();
private final List<L2MonsterInstance> _minionReferences = new CopyOnWriteArrayList<>();
/** List containing the cached deleted minions for reuse */
protected List<L2MonsterInstance> _reusedMinionReferences = null;
public MinionList(L2MonsterInstance pMaster) public MinionList(L2MonsterInstance pMaster)
{ {
@@ -54,7 +51,7 @@ public class MinionList
*/ */
public List<L2MonsterInstance> getSpawnedMinions() public List<L2MonsterInstance> getSpawnedMinions()
{ {
return _minionReferences; return _spawnedMinions;
} }
/** /**
@@ -69,13 +66,7 @@ public class MinionList
*/ */
public final void spawnMinions(List<MinionHolder> minions) public final void spawnMinions(List<MinionHolder> minions)
{ {
if (_master.isAlikeDead()) if (_master.isAlikeDead() || (minions == null))
{
return;
}
// List<MinionHolder> minions = _master.getParameters().getMinionList("Privates");
if (minions == null)
{ {
return; return;
} }
@@ -95,8 +86,6 @@ public class MinionList
} }
} }
} }
// remove non-needed minions
deleteReusedMinions();
} }
/** /**
@@ -104,48 +93,17 @@ public class MinionList
*/ */
public void deleteSpawnedMinions() public void deleteSpawnedMinions()
{ {
if (!_minionReferences.isEmpty()) if (!_spawnedMinions.isEmpty())
{ {
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if (minion != null) if (minion != null)
{ {
minion.setLeader(null); minion.setLeader(null);
minion.deleteMe(); minion.deleteMe();
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
} }
} }
_minionReferences.clear(); _spawnedMinions.clear();
}
}
/**
* Delete all reused minions to prevent memory leaks.
*/
public void deleteReusedMinions()
{
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.clear();
}
}
// hooks
/**
* Called on the master spawn Old minions (from previous spawn) are deleted. If master can respawn - enabled reuse of the killed minions.
*/
public void onMasterSpawn()
{
deleteSpawnedMinions();
// if master has spawn and can respawn - try to reuse minions
if ((_reusedMinionReferences == null) && (_master.getParameters().getSet().get("SummonPrivateRate") == null) && !_master.getParameters().getMinionList("Privates").isEmpty() && (_master.getSpawn() != null) && _master.getSpawn().isRespawnEnabled())
{
_reusedMinionReferences = new CopyOnWriteArrayList<>();
} }
} }
@@ -155,7 +113,7 @@ public class MinionList
*/ */
public void onMinionSpawn(L2MonsterInstance minion) public void onMinionSpawn(L2MonsterInstance minion)
{ {
_minionReferences.add(minion); _spawnedMinions.add(minion);
} }
/** /**
@@ -178,11 +136,7 @@ public class MinionList
public void onMinionDie(L2MonsterInstance minion, int respawnTime) public void onMinionDie(L2MonsterInstance minion, int respawnTime)
{ {
minion.setLeader(null); // prevent memory leaks minion.setLeader(null); // prevent memory leaks
_minionReferences.remove(minion); _spawnedMinions.remove(minion);
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.add(minion);
}
final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime; final int time = respawnTime < 0 ? _master.isRaid() ? (int) Config.RAID_MINION_RESPAWN_TIMER : 0 : respawnTime;
if ((time > 0) && !_master.isAlikeDead()) if ((time > 0) && !_master.isAlikeDead())
@@ -215,7 +169,7 @@ public class MinionList
aggro *= 10; aggro *= 10;
} }
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat())) if ((minion != null) && !minion.isDead() && (callerIsMaster || !minion.isInCombat()))
{ {
@@ -232,7 +186,7 @@ public class MinionList
final int offset = 200; final int offset = 200;
final int minRadius = (int) _master.getCollisionRadius() + 30; final int minRadius = (int) _master.getCollisionRadius() + 30;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled()) if ((minion != null) && !minion.isDead() && !minion.isMovementDisabled())
{ {
@@ -267,20 +221,6 @@ public class MinionList
{ {
return; return;
} }
// searching in reused minions
if (_reusedMinionReferences != null)
{
final L2MonsterInstance minion = _reusedMinionReferences.stream().filter(m -> (m.getId() == minionId)).findFirst().orElse(null);
if (minion != null)
{
_reusedMinionReferences.remove(minion);
minion.refreshID();
initializeNpcInstance(_master, minion);
return;
}
}
// not found in cache
spawnMinion(_master, minionId); spawnMinion(_master, minionId);
} }
@@ -301,11 +241,6 @@ public class MinionList
// minion can be already spawned or deleted // minion can be already spawned or deleted
if (!_minion.isSpawned()) if (!_minion.isSpawned())
{ {
if (_reusedMinionReferences != null)
{
_reusedMinionReferences.remove(_minion);
}
_minion.refreshID(); _minion.refreshID();
initializeNpcInstance(_master, _minion); initializeNpcInstance(_master, _minion);
} }
@@ -390,7 +325,7 @@ public class MinionList
private final int countSpawnedMinionsById(int minionId) private final int countSpawnedMinionsById(int minionId)
{ {
int count = 0; int count = 0;
for (L2MonsterInstance minion : _minionReferences) for (L2MonsterInstance minion : _spawnedMinions)
{ {
if ((minion != null) && (minion.getId() == minionId)) if ((minion != null) && (minion.getId() == minionId))
{ {
@@ -402,11 +337,11 @@ public class MinionList
public final int countSpawnedMinions() public final int countSpawnedMinions()
{ {
return _minionReferences.size(); return _spawnedMinions.size();
} }
public final long lazyCountSpawnedMinionsGroups() public final long lazyCountSpawnedMinionsGroups()
{ {
return _minionReferences.stream().distinct().count(); return _spawnedMinions.stream().distinct().count();
} }
} }