Dropped reused minion references.
This commit is contained in:
@@ -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
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user