MinionList related rework.
This commit is contained in:
		| @@ -19,8 +19,8 @@ package org.l2jmobius.gameserver.model.actor; | ||||
| import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.HashMap; | ||||
| import java.util.Iterator; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| @@ -3332,13 +3332,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder | ||||
| 	 */ | ||||
| 	private List<Effect> effectQueueInsert(Effect newStackedEffect, List<Effect> stackQueue) | ||||
| 	{ | ||||
| 		// Create an Iterator to go through the list of stacked effects in progress on the Creature | ||||
| 		final Iterator<Effect> queueIterator = stackQueue.iterator(); | ||||
| 		// Go through the list of stacked effects in progress on the Creature. | ||||
| 		int i = 0; | ||||
| 		while (queueIterator.hasNext()) | ||||
| 		for (Effect effect : stackQueue) | ||||
| 		{ | ||||
| 			final Effect cur = queueIterator.next(); | ||||
| 			if (newStackedEffect.getStackOrder() < cur.getStackOrder()) | ||||
| 			if (newStackedEffect.getStackOrder() < effect.getStackOrder()) | ||||
| 			{ | ||||
| 				i++; | ||||
| 			} | ||||
| @@ -6280,17 +6278,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder | ||||
| 					 | ||||
| 					if (target instanceof MinionInstance) | ||||
| 					{ | ||||
| 						((MinionInstance) target).getLeader().stopHating(this); | ||||
| 						 | ||||
| 						final List<MinionInstance> spawnedMinions = ((MinionInstance) target).getLeader().getSpawnedMinions(); | ||||
| 						if ((spawnedMinions != null) && !spawnedMinions.isEmpty()) | ||||
| 						final MonsterInstance leader = ((MinionInstance) target).getLeader(); | ||||
| 						leader.stopHating(this); | ||||
| 						if (leader.hasMinions()) | ||||
| 						{ | ||||
| 							final Iterator<MinionInstance> itr = spawnedMinions.iterator(); | ||||
| 							MinionInstance minion; | ||||
| 							while (itr.hasNext()) | ||||
| 							for (MinionInstance minion : leader.getSpawnedMinions()) | ||||
| 							{ | ||||
| 								minion = itr.next(); | ||||
| 								if (((MinionInstance) target).getLeader().getMostHated() == null) | ||||
| 								if (leader.getMostHated() == null) | ||||
| 								{ | ||||
| 									((AttackableAI) minion.getAI()).setGlobalAggro(-25); | ||||
| 									minion.clearAggroList(); | ||||
| @@ -6302,7 +6296,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder | ||||
| 									((AttackableAI) minion.getAI()).setGlobalAggro(-25); | ||||
| 									minion.clearAggroList(); | ||||
| 									minion.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE); | ||||
| 									minion.addDamage(((MinionInstance) target).getLeader().getMostHated(), 100); | ||||
| 									minion.addDamage(leader.getMostHated(), 100); | ||||
| 								} | ||||
| 							} | ||||
| 						} | ||||
| @@ -6310,14 +6304,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder | ||||
| 					else | ||||
| 					{ | ||||
| 						((Attackable) target).stopHating(this); | ||||
| 						final List<MinionInstance> spawnedMinions = ((MonsterInstance) target).getSpawnedMinions(); | ||||
| 						final Collection<MinionInstance> spawnedMinions = ((MonsterInstance) target).getSpawnedMinions(); | ||||
| 						if ((spawnedMinions != null) && !spawnedMinions.isEmpty()) | ||||
| 						{ | ||||
| 							final Iterator<MinionInstance> itr = spawnedMinions.iterator(); | ||||
| 							MinionInstance minion; | ||||
| 							while (itr.hasNext()) | ||||
| 							for (MinionInstance minion : spawnedMinions) | ||||
| 							{ | ||||
| 								minion = itr.next(); | ||||
| 								if (((Attackable) target).getMostHated() == null) | ||||
| 								{ | ||||
| 									((AttackableAI) minion.getAI()).setGlobalAggro(-25); | ||||
| @@ -8051,16 +8042,13 @@ public abstract class Creature extends WorldObject implements ISkillsHolder | ||||
| 								 | ||||
| 								if (creature instanceof MinionInstance) | ||||
| 								{ | ||||
| 									((MinionInstance) creature).getLeader().stopHating(this); | ||||
| 									final List<MinionInstance> spawnedMinions = ((MonsterInstance) creature).getSpawnedMinions(); | ||||
| 									if ((spawnedMinions != null) && !spawnedMinions.isEmpty()) | ||||
| 									final MonsterInstance leader = ((MinionInstance) creature).getLeader(); | ||||
| 									leader.stopHating(this); | ||||
| 									if (leader.hasMinions()) | ||||
| 									{ | ||||
| 										final Iterator<MinionInstance> itr = spawnedMinions.iterator(); | ||||
| 										MinionInstance minion; | ||||
| 										while (itr.hasNext()) | ||||
| 										for (MinionInstance minion : leader.getSpawnedMinions()) | ||||
| 										{ | ||||
| 											minion = itr.next(); | ||||
| 											if (((Attackable) creature).getMostHated() == null) | ||||
| 											if (leader.getMostHated() == null) | ||||
| 											{ | ||||
| 												((AttackableAI) minion.getAI()).setGlobalAggro(-25); | ||||
| 												minion.clearAggroList(); | ||||
| @@ -8080,14 +8068,11 @@ public abstract class Creature extends WorldObject implements ISkillsHolder | ||||
| 								else | ||||
| 								{ | ||||
| 									((Attackable) creature).stopHating(this); | ||||
| 									final List<MinionInstance> spawnedMinions = ((MonsterInstance) creature).getSpawnedMinions(); | ||||
| 									final Collection<MinionInstance> spawnedMinions = ((MonsterInstance) creature).getSpawnedMinions(); | ||||
| 									if ((spawnedMinions != null) && !spawnedMinions.isEmpty()) | ||||
| 									{ | ||||
| 										final Iterator<MinionInstance> itr = spawnedMinions.iterator(); | ||||
| 										MinionInstance minion; | ||||
| 										while (itr.hasNext()) | ||||
| 										for (MinionInstance minion : spawnedMinions) | ||||
| 										{ | ||||
| 											minion = itr.next(); | ||||
| 											if (((Attackable) creature).getMostHated() == null) | ||||
| 											{ | ||||
| 												((AttackableAI) minion.getAI()).setGlobalAggro(-25); | ||||
|   | ||||
| @@ -16,8 +16,7 @@ | ||||
|  */ | ||||
| package org.l2jmobius.gameserver.model.actor.instance; | ||||
|  | ||||
| import java.util.Iterator; | ||||
| import java.util.List; | ||||
| import java.util.Collection; | ||||
| import java.util.concurrent.ScheduledFuture; | ||||
|  | ||||
| import org.l2jmobius.Config; | ||||
| @@ -28,7 +27,6 @@ import org.l2jmobius.gameserver.model.actor.Creature; | ||||
| import org.l2jmobius.gameserver.model.actor.knownlist.MonsterKnownList; | ||||
| import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate; | ||||
| import org.l2jmobius.gameserver.model.spawn.Spawn; | ||||
| import org.l2jmobius.gameserver.network.serverpackets.SocialAction; | ||||
| import org.l2jmobius.gameserver.util.MinionList; | ||||
|  | ||||
| /** | ||||
| @@ -114,32 +112,8 @@ public class MonsterInstance extends Attackable | ||||
| 		 | ||||
| 		if (getTemplate().getMinionData() != null) | ||||
| 		{ | ||||
| 			try | ||||
| 			{ | ||||
| 				for (MinionInstance minion : _minionList.getSpawnedMinions()) | ||||
| 				{ | ||||
| 					if (minion == null) | ||||
| 					{ | ||||
| 						continue; | ||||
| 					} | ||||
| 					_minionList.getSpawnedMinions().remove(minion); | ||||
| 					minion.deleteMe(); | ||||
| 				} | ||||
| 				_minionList.clearRespawnList(); | ||||
| 				 | ||||
| 				manageMinions(); | ||||
| 			} | ||||
| 			catch (NullPointerException e) | ||||
| 			{ | ||||
| 			} | ||||
| 			 | ||||
| 			switch (getTemplate().getNpcId()) | ||||
| 			{ | ||||
| 				case 12372: // baium | ||||
| 				{ | ||||
| 					broadcastPacket(new SocialAction(getObjectId(), 2)); | ||||
| 				} | ||||
| 			} | ||||
| 			_minionList.clearRespawnList(); | ||||
| 			manageMinions(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| @@ -193,25 +167,18 @@ public class MonsterInstance extends Attackable | ||||
| 	{ | ||||
| 		if (_minionList.hasMinions()) | ||||
| 		{ | ||||
| 			final List<MinionInstance> spawnedMinions = _minionList.getSpawnedMinions(); | ||||
| 			if ((spawnedMinions != null) && !spawnedMinions.isEmpty()) | ||||
| 			for (MinionInstance minion : _minionList.getSpawnedMinions()) | ||||
| 			{ | ||||
| 				final Iterator<MinionInstance> itr = spawnedMinions.iterator(); | ||||
| 				MinionInstance minion; | ||||
| 				while (itr.hasNext()) | ||||
| 				// Trigger the aggro condition of the minion | ||||
| 				if ((minion != null) && !minion.isDead()) | ||||
| 				{ | ||||
| 					minion = itr.next(); | ||||
| 					// Trigger the aggro condition of the minion | ||||
| 					if ((minion != null) && !minion.isDead()) | ||||
| 					if (this instanceof RaidBossInstance) | ||||
| 					{ | ||||
| 						if (this instanceof RaidBossInstance) | ||||
| 						{ | ||||
| 							minion.addDamage(attacker, 100); | ||||
| 						} | ||||
| 						else | ||||
| 						{ | ||||
| 							minion.addDamage(attacker, 1); | ||||
| 						} | ||||
| 						minion.addDamage(attacker, 100); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						minion.addDamage(attacker, 1); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| @@ -242,7 +209,7 @@ public class MonsterInstance extends Attackable | ||||
| 	 * Gets the spawned minions. | ||||
| 	 * @return the spawned minions | ||||
| 	 */ | ||||
| 	public List<MinionInstance> getSpawnedMinions() | ||||
| 	public Collection<MinionInstance> getSpawnedMinions() | ||||
| 	{ | ||||
| 		return _minionList.getSpawnedMinions(); | ||||
| 	} | ||||
| @@ -321,17 +288,6 @@ public class MonsterInstance extends Attackable | ||||
| 	 */ | ||||
| 	public void deleteSpawnedMinions() | ||||
| 	{ | ||||
| 		for (MinionInstance minion : _minionList.getSpawnedMinions()) | ||||
| 		{ | ||||
| 			if (minion == null) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 			minion.abortAttack(); | ||||
| 			minion.abortCast(); | ||||
| 			minion.deleteMe(); | ||||
| 			_minionList.getSpawnedMinions().remove(minion); | ||||
| 		} | ||||
| 		_minionList.clearRespawnList(); | ||||
| 	} | ||||
| 	 | ||||
|   | ||||
| @@ -16,9 +16,8 @@ | ||||
|  */ | ||||
| package org.l2jmobius.gameserver.util; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Map.Entry; | ||||
| import java.util.Set; | ||||
| @@ -35,40 +34,32 @@ import org.l2jmobius.gameserver.model.actor.instance.MonsterInstance; | ||||
| import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate; | ||||
|  | ||||
| /** | ||||
|  * @version $Revision: 1.2 $ $Date: 2004/06/27 08:12:59 $ | ||||
|  * @author luisantonioa, Mobius | ||||
|  */ | ||||
| public class MinionList | ||||
| { | ||||
| 	/** List containing the current spawned minions for this MonsterInstance */ | ||||
| 	private final List<MinionInstance> minionReferences; | ||||
| 	protected Map<Long, Integer> _respawnTasks = new ConcurrentHashMap<>(); | ||||
| 	private final MonsterInstance master; | ||||
| 	private final Set<MinionInstance> _spawnedMinions = ConcurrentHashMap.newKeySet(); | ||||
| 	private final Map<Long, Integer> _respawnTasks = new ConcurrentHashMap<>(); | ||||
| 	private final MonsterInstance _master; | ||||
| 	 | ||||
| 	public MinionList(MonsterInstance pMaster) | ||||
| 	public MinionList(MonsterInstance master) | ||||
| 	{ | ||||
| 		minionReferences = new ArrayList<>(); | ||||
| 		master = pMaster; | ||||
| 		_master = master; | ||||
| 	} | ||||
| 	 | ||||
| 	public int countSpawnedMinions() | ||||
| 	{ | ||||
| 		synchronized (minionReferences) | ||||
| 		{ | ||||
| 			return minionReferences.size(); | ||||
| 		} | ||||
| 		return _spawnedMinions.size(); | ||||
| 	} | ||||
| 	 | ||||
| 	public int countSpawnedMinionsById(int minionId) | ||||
| 	{ | ||||
| 		int count = 0; | ||||
| 		synchronized (minionReferences) | ||||
| 		for (MinionInstance minion : _spawnedMinions) | ||||
| 		{ | ||||
| 			for (MinionInstance minion : minionReferences) | ||||
| 			if (minion.getNpcId() == minionId) | ||||
| 			{ | ||||
| 				if (minion.getNpcId() == minionId) | ||||
| 				{ | ||||
| 					count++; | ||||
| 				} | ||||
| 				count++; | ||||
| 			} | ||||
| 		} | ||||
| 		return count; | ||||
| @@ -76,26 +67,23 @@ public class MinionList | ||||
| 	 | ||||
| 	public boolean hasMinions() | ||||
| 	{ | ||||
| 		return !minionReferences.isEmpty(); | ||||
| 		return !_spawnedMinions.isEmpty(); | ||||
| 	} | ||||
| 	 | ||||
| 	public List<MinionInstance> getSpawnedMinions() | ||||
| 	public Collection<MinionInstance> getSpawnedMinions() | ||||
| 	{ | ||||
| 		return minionReferences; | ||||
| 		return _spawnedMinions; | ||||
| 	} | ||||
| 	 | ||||
| 	public void addSpawnedMinion(MinionInstance minion) | ||||
| 	{ | ||||
| 		synchronized (minionReferences) | ||||
| 		{ | ||||
| 			minionReferences.add(minion); | ||||
| 		} | ||||
| 		_spawnedMinions.add(minion); | ||||
| 	} | ||||
| 	 | ||||
| 	public int lazyCountSpawnedMinionsGroups() | ||||
| 	{ | ||||
| 		final Set<Integer> seenGroups = new HashSet<>(); | ||||
| 		for (MinionInstance minion : minionReferences) | ||||
| 		for (MinionInstance minion : _spawnedMinions) | ||||
| 		{ | ||||
| 			seenGroups.add(minion.getNpcId()); | ||||
| 		} | ||||
| @@ -104,32 +92,25 @@ public class MinionList | ||||
| 	 | ||||
| 	public void removeSpawnedMinion(MinionInstance minion) | ||||
| 	{ | ||||
| 		synchronized (minionReferences) | ||||
| 		{ | ||||
| 			minionReferences.remove(minion); | ||||
| 		} | ||||
| 		_spawnedMinions.remove(minion); | ||||
| 	} | ||||
| 	 | ||||
| 	public void moveMinionToRespawnList(MinionInstance minion) | ||||
| 	{ | ||||
| 		final Long current = System.currentTimeMillis(); | ||||
| 		synchronized (minionReferences) | ||||
| 		_spawnedMinions.remove(minion); | ||||
| 		if (_respawnTasks.get(current) == null) | ||||
| 		{ | ||||
| 			minionReferences.remove(minion); | ||||
| 			if (_respawnTasks.get(current) == null) | ||||
| 			_respawnTasks.put(current, minion.getNpcId()); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			for (int i = 1; i < 30; i++) | ||||
| 			{ | ||||
| 				_respawnTasks.put(current, minion.getNpcId()); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				// nice AoE | ||||
| 				for (int i = 1; i < 30; i++) | ||||
| 				if (_respawnTasks.get(current + i) == null) | ||||
| 				{ | ||||
| 					if (_respawnTasks.get(current + i) == null) | ||||
| 					{ | ||||
| 						_respawnTasks.put(current + i, minion.getNpcId()); | ||||
| 						break; | ||||
| 					} | ||||
| 					_respawnTasks.put(current + i, minion.getNpcId()); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -137,6 +118,19 @@ public class MinionList | ||||
| 	 | ||||
| 	public void clearRespawnList() | ||||
| 	{ | ||||
| 		for (MinionInstance minion : _spawnedMinions) | ||||
| 		{ | ||||
| 			if (minion == null) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 			 | ||||
| 			minion.abortAttack(); | ||||
| 			minion.abortCast(); | ||||
| 			minion.deleteMe(); | ||||
| 		} | ||||
| 		 | ||||
| 		_spawnedMinions.clear(); | ||||
| 		_respawnTasks.clear(); | ||||
| 	} | ||||
| 	 | ||||
| @@ -145,7 +139,7 @@ public class MinionList | ||||
| 	 */ | ||||
| 	public void maintainMinions() | ||||
| 	{ | ||||
| 		if ((master == null) || master.isAlikeDead()) | ||||
| 		if ((_master == null) || _master.isAlikeDead()) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| @@ -175,27 +169,22 @@ public class MinionList | ||||
| 	 */ | ||||
| 	public void spawnMinions() | ||||
| 	{ | ||||
| 		if ((master == null) || master.isAlikeDead()) | ||||
| 		if ((_master == null) || _master.isAlikeDead()) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		final List<MinionData> minions = master.getTemplate().getMinionData(); | ||||
| 		 | ||||
| 		synchronized (minionReferences) | ||||
| 		int minionCount; | ||||
| 		int minionId; | ||||
| 		int minionsToSpawn; | ||||
| 		for (MinionData minion : _master.getTemplate().getMinionData()) | ||||
| 		{ | ||||
| 			int minionCount; | ||||
| 			int minionId; | ||||
| 			int minionsToSpawn; | ||||
| 			for (MinionData minion : minions) | ||||
| 			minionCount = minion.getAmount(); | ||||
| 			minionId = minion.getMinionId(); | ||||
| 			minionsToSpawn = minionCount - countSpawnedMinionsById(minionId); | ||||
| 			for (int i = 0; i < minionsToSpawn; i++) | ||||
| 			{ | ||||
| 				minionCount = minion.getAmount(); | ||||
| 				minionId = minion.getMinionId(); | ||||
| 				minionsToSpawn = minionCount - countSpawnedMinionsById(minionId); | ||||
| 				for (int i = 0; i < minionsToSpawn; i++) | ||||
| 				{ | ||||
| 					spawnSingleMinion(minionId); | ||||
| 				} | ||||
| 				spawnSingleMinion(minionId); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -221,10 +210,10 @@ public class MinionList | ||||
| 		 | ||||
| 		// Set the Minion HP, MP and Heading | ||||
| 		monster.setCurrentHpMp(monster.getMaxHp(), monster.getMaxMp()); | ||||
| 		monster.setHeading(master.getHeading()); | ||||
| 		monster.setHeading(_master.getHeading()); | ||||
| 		 | ||||
| 		// Set the Minion leader to this RaidBoss | ||||
| 		monster.setLeader(master); | ||||
| 		monster.setLeader(_master); | ||||
| 		 | ||||
| 		// Init the position of the Minion and add it in the world as a visible object | ||||
| 		int spawnConstant; | ||||
| @@ -237,7 +226,7 @@ public class MinionList | ||||
| 			spawnConstant *= -1; | ||||
| 		} | ||||
| 		 | ||||
| 		final int newX = master.getX() + spawnConstant; | ||||
| 		final int newX = _master.getX() + spawnConstant; | ||||
| 		spawnConstant = Rnd.get(randSpawnLim); | ||||
| 		randPlusMin = Rnd.get(2); | ||||
| 		if (randPlusMin == 1) | ||||
| @@ -245,13 +234,13 @@ public class MinionList | ||||
| 			spawnConstant *= -1; | ||||
| 		} | ||||
| 		 | ||||
| 		final int newY = master.getY() + spawnConstant; | ||||
| 		monster.spawnMe(newX, newY, master.getZ()); | ||||
| 		final int newY = _master.getY() + spawnConstant; | ||||
| 		monster.spawnMe(newX, newY, _master.getZ()); | ||||
| 		 | ||||
| 		// Assist master | ||||
| 		if (!master.getAggroList().isEmpty()) | ||||
| 		if (!_master.getAggroList().isEmpty()) | ||||
| 		{ | ||||
| 			monster.getAggroList().putAll(master.getAggroList()); | ||||
| 			monster.getAggroList().putAll(_master.getAggroList()); | ||||
| 			monster.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, monster.getAggroList().keySet().stream().findFirst().get()); | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 MobiusDevelopment
					MobiusDevelopment