package ai; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.aionemu.commons.utils.Rnd; import com.aionemu.gameserver.ai.AIActions; import com.aionemu.gameserver.ai.AIName; import com.aionemu.gameserver.ai.AIState; import com.aionemu.gameserver.dataholders.DataManager; import com.aionemu.gameserver.model.gameobjects.Creature; import com.aionemu.gameserver.model.gameobjects.Npc; import com.aionemu.gameserver.model.gameobjects.VisibleObject; import com.aionemu.gameserver.model.templates.ai.Percentage; import com.aionemu.gameserver.model.templates.ai.SummonGroup; import com.aionemu.gameserver.utils.ThreadPoolManager; import com.aionemu.gameserver.world.World; /** * @author xTz */ @AIName("summoner") public class SummonerAI extends AggressiveNpcAI { private final List spawnedNpc = new ArrayList<>(); private List percentage = Collections.emptyList(); private volatile int spawnedPercent = 0; public SummonerAI(Npc owner) { super(owner); } @Override protected void handleAttack(Creature creature) { super.handleAttack(creature); checkPercentage(getLifeStats().getHpPercentage()); } @Override protected void handleDespawned() { super.handleDespawned(); removeAndResetHelperSpawns(); percentage.clear(); } @Override protected void handleBackHome() { super.handleBackHome(); removeAndResetHelperSpawns(); } @Override protected void handleNotAtHome() { super.handleNotAtHome(); if (getState() == AIState.WALKING) removeAndResetHelperSpawns(); } @Override protected void handleSpawned() { super.handleSpawned(); percentage = new ArrayList<>(DataManager.AI_DATA.getAiTemplate(getNpcId()).getSummons().getPercentage()); } @Override protected void handleDied() { super.handleDied(); removeAndResetHelperSpawns(); percentage.clear(); } private void removeAndResetHelperSpawns() { synchronized (spawnedNpc) { for (Integer object : spawnedNpc) { VisibleObject npc = World.getInstance().findVisibleObject(object); if (npc != null && npc.isSpawned()) { npc.getController().delete(); } } spawnedNpc.clear(); } spawnedPercent = 0; } protected void addHelpersSpawn(int objId) { synchronized (spawnedNpc) { spawnedNpc.add(objId); } } private void checkPercentage(int hpPercentage) { for (Percentage percent : percentage) { if (spawnedPercent != 0 && spawnedPercent <= percent.getPercent()) { continue; } if (hpPercentage <= percent.getPercent()) { int skill = percent.getSkillId(); if (skill != 0) AIActions.useSkill(this, skill); if (percent.isIndividual()) { handleIndividualSpawnedSummons(percent); } else if (percent.getSummons() != null) { handleBeforeSpawn(percent); for (SummonGroup summonGroup : percent.getSummons()) { final SummonGroup sg = summonGroup; ThreadPoolManager.getInstance().schedule(() -> spawnHelpers(sg), summonGroup.getSchedule()); } } spawnedPercent = percent.getPercent(); } } } protected void spawnHelpers(SummonGroup summonGroup) { if (!isDead() && checkBeforeSpawn()) { int count = Rnd.get(summonGroup.getMinCount(), summonGroup.getMaxCount()); for (int i = 0; i < count; i++) { VisibleObject npc; if (summonGroup.getDistance() != 0) npc = rndSpawnInRange(summonGroup.getNpcId(), summonGroup.getDistance()); else npc = spawn(summonGroup.getNpcId(), summonGroup.getX(), summonGroup.getY(), summonGroup.getZ(), summonGroup.getH()); addHelpersSpawn(npc.getObjectId()); } handleSpawnFinished(summonGroup); } } protected boolean checkBeforeSpawn() { return true; } protected void handleBeforeSpawn(Percentage percent) { } protected void handleSpawnFinished(SummonGroup summonGroup) { } protected void handleIndividualSpawnedSummons(Percentage percent) { } }