Можно переделать по своему вкусу. Писал для инстов но чет не зашел. ЯДРО Код: /* * M.O.G. Devs Team * www.mmorpg-onlinegames.ru * Teg's {/aiononline, /eveonline} * * Mission Generator Service 5.0.6 */ package com.mog.gameserver.services.dlc.missionGenerator; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.Future; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mog.gameserver.controllers.PlayerController; import com.mog.gameserver.instance.handlers.theKatalam.IDVritraBaseInstance; import com.mog.gameserver.model.gameobjects.VisibleObject; import com.mog.gameserver.model.gameobjects.player.Player; import com.mog.gameserver.model.team2.group.PlayerFilters.SameInstanceFilter; import com.mog.gameserver.network.aion.serverpackets.SM_QUEST_ACTION; import com.mog.gameserver.services.dlc.stalker.StalkerService; import com.mog.gameserver.spawnengine.SpawnEngine; import com.mog.gameserver.utils.PacketSendUtility; import com.mog.gameserver.utils.ThreadPoolManager; import com.mog.gameserver.utils.commons.utils.Rnd; import com.mog.gameserver.world.WorldMapInstance; import com.mog.gameserver.world.knownlist.Visitor; import javolution.util.FastList; import javolution.util.FastMap; /** * @author Dision */ public class MissionGeneratorService { private static final Logger log = LoggerFactory.getLogger(MissionGeneratorService.class); private FastMap<Integer, VisibleObject> spawns = FastMap.newInstance(); private FastList<Future<?>> tasks = FastList.newInstance(); private Map<Integer, MissionTargetList> missions = new HashMap<>(); private boolean isMission = false; private int timer = 0; private boolean isTimer = false; private int missionId = 0; private int worldId = 0; private int keySpawn = 0; private int keyMission = 0; private int couter = 0; private MissionTargetList mtl; public void missionStart(final WorldMapInstance instance) { if (isMission) return; else isMission = true; ThreadPoolManager.getInstance().schedule(new Runnable() { @Override public void run() { generatorMission(instance); log.info("M.O.G. Console: MissionGeneratorService missionStart"); } }, 60000); } public void missionEnd(WorldMapInstance instance) { missionEnd(instance, false); } public void missionEnd(WorldMapInstance instance, boolean isFail) { if (isMission && !isFail) generatorReward(instance); else { for (Entry<Integer, MissionTargetList> entry : missions.entrySet()) { messenger(instance, entry.getValue().getMission(), 2, "- Миссия провалена.", 0); } } timerInstance(instance, 0, true); isMission = false; timer = 0; isTimer = false; missionId = 0; worldId = 0; keySpawn = 0; keyMission = 0; couter = 0; missions.clear(); for (VisibleObject spawn : spawns.values()) { spawn.getController().onDelete(); } spawns.clear(); stopTasks(); log.info("M.O.G. Console: MissionGeneratorService missionEnd"); } private void generatorMission(WorldMapInstance instance) { int missionId = Rnd.get(1, 4); this.setMissionId(missionId); this.setWorldId(instance.getMapId()); generatorType(instance, missionId, instance.getMapId()); log.info("M.O.G. Console: MissionGeneratorService generatorMission [missionId = " + this.getMissionId() + "] [mapId = " + this.getWorldId() + "]"); } private void generatorType(WorldMapInstance instance, int id, int worldId) { switch (MissionType.getMissionType(id)) { case SEARCHES: mtl = new MissionTargetList(25, "Зачистка", Rnd.get(167010274, 167010279), 186000389, 50000000l); missions.put(keyMission++, mtl); if (!isTimer) { isTimer = true; timerInstance(instance, 900, true); } spawnType(instance, worldId, 1); break; case DEFENSE: mtl = new MissionTargetList(20, "Оборона", Rnd.get(167010274, 167010279), 186000389, 150000000l); missions.put(keyMission++, mtl); couter = 5; if (!isTimer) { isTimer = true; timerInstance(instance, 1800, true); } spawnType(instance, worldId, 2); break; case DEFENSE_MOBILE: mtl = new MissionTargetList(45, "Мобильная оборона", Rnd.get(167010280, 167010285), 166022000, 50000000l); missions.put(keyMission++, mtl); couter = 9; if (!isTimer) { isTimer = true; timerInstance(instance, 1800, true); } spawnType(instance, worldId, 3); break; case ASSASSINATION: mtl = new MissionTargetList(1, "Убийство", Rnd.get(167010280, 167010285), 166022000, 25000000l); missions.put(keyMission++, mtl); if (!isTimer) { isTimer = true; timerInstance(instance, 1800, true); } spawnType(instance, worldId, 4); break; default: break; } for (Entry<Integer, MissionTargetList> entry : missions.entrySet()) { messenger(instance, entry.getValue().getMission(), 2, "- миссия активна.", 0); } } private void spawnType(final WorldMapInstance instance, final int worldId, int type) { IDVritraBaseInstance vritraBase = (IDVritraBaseInstance) instance.getInstanceHandler(); switch (type) { case 1: tasks.add(ThreadPoolManager.getInstance().scheduleAtFixedRate(new Runnable() { @Override public void run() { instance.doOnAllPlayers(new Visitor<Player>() { @Override public void visit(final Player player) { if (vritraBase != null) { if (!vritraBase.isStalker()) { vritraBase.setStalker(true); StalkerService.getInstance().noviceStalker(player, true); } } tasks.add(ThreadPoolManager.getInstance().schedule(new Runnable() { @Override public void run() { if (vritraBase.isStalker()) vritraBase.setStalker(false); } }, 30000)); } }); } }, 60000, 60000)); break; case 2: switch (worldId) { case 301130000: // ID Vritra Base switch (Rnd.get(1, 3)) { case 1: sp(worldId, instance.getInstanceId(), 884030, 640.27f, 354.26f, 202.89f); // 1 break; case 2: sp(worldId, instance.getInstanceId(), 884030, 593.04f, 485.51f, 191.03f); // 1 break; case 3: sp(worldId, instance.getInstanceId(), 884030, 451.83f, 454.63f, 182.20f); // 1 break; } break; } break; case 3: switch (worldId) { case 301130000: // ID Vritra Base sp(worldId, instance.getInstanceId(), 884030, 640.27f, 354.26f, 202.89f); // 1 sp(worldId, instance.getInstanceId(), 884030, 593.04f, 485.51f, 191.03f); // 2 sp(worldId, instance.getInstanceId(), 884030, 451.83f, 454.63f, 182.20f); // 3 break; } break; case 4: instance.doOnAllPlayers(new Visitor<Player>() { @Override public void visit(final Player player) { if (vritraBase != null) { if (!vritraBase.isStalker()) { vritraBase.setStalker(true); StalkerService.getInstance().stalkerSpawn(player, true); } } } }); break; } } public void targetCounter(WorldMapInstance instance) { if (!isMission && missions == null) return; for (Entry<Integer, MissionTargetList> entry : missions.entrySet()) { int targetCount = entry.getValue().getTargetCount(); entry.getValue().setTargetCount(targetCount - 1); messenger(instance, entry.getValue().getMission(), 2, "Целей до завершения миссии: " + entry.getValue().getTargetCount(), 0); if (entry.getValue().getTargetCount() < 1) { messenger(instance, entry.getValue().getMission(), 2, "- Миссия выполнена.", 0); missionEnd(instance); } } } private void generatorReward(final WorldMapInstance instance) { instance.doOnAllPlayers(new Visitor<Player>() { @Override public void visit(final Player player) { for (Entry<Integer, MissionTargetList> entry : missions.entrySet()) { PlayerController.sendMail("Система", player.getName(), "Награда миссии", entry.getValue().getMission() + ": Миссия выполнена. Опыта за миссию: " + entry.getValue().getRewardExp(), entry.getValue().getRewardItemId1(), 1l, 0l); PlayerController.sendMail("Система", player.getName(), "Награда миссии", entry.getValue().getMission() + ": Миссия выполнена. Опыта за миссию: " + entry.getValue().getRewardExp(), entry.getValue().getRewardItemId2(), 1l, 0l); if (player.getLevel() >= 65) player.getCommonData().setExp(player.getCommonData().getExp() + entry.getValue().getRewardExp()); else messenger(instance, entry.getValue().getMission(), 1, "Вы не получили опыт за миссию. Уровень слишком мал.", 0); } } }); } public void messenger(WorldMapInstance instance, final String missionName, final int type, final String msg, int delay) { ThreadPoolManager.getInstance().schedule(new MessengerRunnable(instance, type, "[color:Мисс;0 255 0][color:ия;0 255 0]: " + missionName + " " + msg), delay); } public void missionInfo(Player player) { if (!isMission && missions == null) { PacketSendUtility.sendMessage(player, "[color:Мисс;0 255 0][color:ия;0 255 0] Нет активных миссий."); return; } for (Entry<Integer, MissionTargetList> entry : missions.entrySet()) { String rewardName1 = ""; String rewardName2 = ""; switch (entry.getValue().getRewardItemId1()) { case 167010274: rewardName1 = "Маг. камень: Сила +4"; break; case 167010275: rewardName1 = "Маг. камень: Здоровье +4"; break; case 167010276: rewardName1 = "Маг. камень: Сноровка +4"; break; case 167010277: rewardName1 = "Маг. камень: Ловкость +4"; break; case 167010278: rewardName1 = "Маг. камень: Интеллект +4"; break; case 167010279: rewardName1 = "Маг. камень: Воля +4"; break; case 167010280: rewardName1 = "Маг. камень: Сила +5"; break; case 167010281: rewardName1 = "Маг. камень: Здоровье +5"; break; case 167010282: rewardName1 = "Маг. камень: Сноровка +5"; break; case 167010283: rewardName1 = "Маг. камень: Ловкость +5"; break; case 167010284: rewardName1 = "Маг. камень: Интеллект +5"; break; case 167010285: rewardName1 = "Маг. камень: Воля +5"; break; } switch (entry.getValue().getRewardItemId2()) { case 186000389: rewardName2 = "Монета удачи"; break; case 166022000: rewardName2 = "Сияющий волшебный камень"; break; } PacketSendUtility.sendMessage(player, "[color:Мисс;0 255 0][color:ия;0 255 0]: " + entry.getValue().getMission()); PacketSendUtility.sendMessage(player, "Целей до завершения: " + entry.getValue().getTargetCount()); PacketSendUtility.sendMessage(player, "Награда #1: " + rewardName1); PacketSendUtility.sendMessage(player, "Награда #2: " + rewardName2); PacketSendUtility.sendMessage(player, "Опыт: " + entry.getValue().getRewardExp()); } } public void timerInstance(final WorldMapInstance instance, final int time, final boolean type) { instance.doOnAllPlayers(new Visitor<Player>() { @Override public void visit(final Player player) { generatorTimer(instance, player, time, type); } }); } public void generatorTimer(final WorldMapInstance instance, Player player, int time, boolean type) { System.currentTimeMillis(); // Minuts if (type) this.setTimer(time); if (player.isInTeam()) { player.getCurrentTeam().sendPacket(new SM_QUEST_ACTION(0, this.getTimer()), new SameInstanceFilter(player)); } else { PacketSendUtility.sendPacket(player, new SM_QUEST_ACTION(0, this.getTimer())); } int delay = 0; switch (this.getTimer()) { case 900: delay = 60000 * 15; break; case 1800: delay = 60000 * 30; break; default: return; } tasks.add(ThreadPoolManager.getInstance().schedule(new Runnable() { @Override public void run() { isMission = false; isTimer = false; missionEnd(instance); } }, delay)); log.info("M.O.G. Console: MissionGeneratorService generatorTimer [time = " + this.getTimer() + "]"); } private void stopTasks() { for (FastList.Node<Future<?>> n = tasks.head(), end = tasks.tail(); (n = n.getNext()) != end;) { if (n.getValue() != null) { n.getValue().cancel(true); } } } public void sp(int worldId, int instanceId, int npcId, float x, float y, float z) { spawns.put(keySpawn++, SpawnEngine.spawnObject(SpawnEngine.addNewSingleTimeSpawn(worldId, npcId, x, y, z, (byte) 0), instanceId)); log.info("M.O.G. Console: MissionGeneratorService sp [key = " + keySpawn + "]"); } public int getTimer() { return timer; } public void setTimer(int timer) { this.timer = timer; } public int getMissionId() { return missionId; } public void setMissionId(int missionId) { this.missionId = missionId; } public int getWorldId() { return worldId; } public void setWorldId(int worldId) { this.worldId = worldId; } public int getCouter() { return couter; } public void setCouter(int couter) { this.couter = couter; } public Map<Integer, MissionTargetList> getMissions() { return missions; } public static MissionGeneratorService getInstance() { return MissionGeneratorService.SingletonHolder.instance; } private static class SingletonHolder { protected static final MissionGeneratorService instance = new MissionGeneratorService(); } } Код: /* * M.O.G. Devs Team * www.mmorpg-onlinegames.ru * Teg's {/aiononline, /eveonline} */ package com.mog.gameserver.services.dlc.missionGenerator; import com.mog.gameserver.model.gameobjects.player.Player; import com.mog.gameserver.utils.PacketSendUtility; import com.mog.gameserver.world.WorldMapInstance; import com.mog.gameserver.world.knownlist.Visitor; /** * @author Dision */ public class MessengerRunnable implements Runnable { private WorldMapInstance instance; private int type; private String msg; public MessengerRunnable(WorldMapInstance instance, int type, String msg) { this.instance = instance; this.type = type; this.msg = msg; } @Override public void run() { instance.doOnAllPlayers(new Visitor<Player>() { @Override public void visit(final Player player) { switch (type) { case 1: PacketSendUtility.sendMessage(player, msg); // chat break; case 2: PacketSendUtility.sendYellowLightMessageOnCenter(player, msg); // center break; } } }); } } Код: /* * M.O.G. Devs Team * www.mmorpg-onlinegames.ru * Teg's {/aiononline, /eveonline} */ package com.mog.gameserver.services.dlc.missionGenerator; /** * @author Dision */ public class MissionTargetList { private int targetCount = 0; private String mission = ""; private int rewardItemId1 = 0; private int rewardItemId2 = 0; private long rewardExp = 0; public MissionTargetList(int targetCount, String mission, int rewardItemId1, int rewardItemId2, long rewardExp) { this.targetCount = targetCount; this.mission = mission; this.rewardItemId1 = rewardItemId1; this.rewardItemId2 = rewardItemId2; this.rewardExp = rewardExp; } public int getTargetCount() { return targetCount; } public void setTargetCount(int targetCount) { this.targetCount = targetCount; } public String getMission() { return mission; } public void setMission(String mission) { this.mission = mission; } public int getRewardItemId1() { return rewardItemId1; } public void setRewardItemId1(int rewardItemId1) { this.rewardItemId1 = rewardItemId1; } public int getRewardItemId2() { return rewardItemId2; } public void setRewardItemId2(int rewardItemId2) { this.rewardItemId2 = rewardItemId2; } public long getRewardExp() { return rewardExp; } public void setRewardExp(long rewardExp) { this.rewardExp = rewardExp; } } Код: /* * M.O.G. Devs Team * www.mmorpg-onlinegames.ru * Teg's {/aiononline, /eveonline} */ package com.mog.gameserver.services.dlc.missionGenerator; /** * @author M.O.G. Dision */ public enum MissionType { NONE(0), // Нет SEARCHES(1), // Зачистка DEFENSE(2), // Оборона DEFENSE_MOBILE(3), // Мобильная оборона ASSASSINATION(4); // Убийство private int id; private MissionType(int id) { this.id = id; } public int getId() { return id; } public static MissionType getMissionType(int id) { for (MissionType type : values()) { if (id == type.getId()) { return type; } } return MissionType.NONE; } } АИ Код: /* * Mission attacker */ package com.mog.gameserver.ai2.handlers.dlc; import java.util.concurrent.Future; import com.mog.gameserver.ai2.AIName; import com.mog.gameserver.ai2.handlers.worlds.greatInvasion.TheBuffAI2; import com.mog.gameserver.model.gameobjects.Creature; import com.mog.gameserver.model.gameobjects.Npc; import com.mog.gameserver.services.dlc.missionGenerator.MissionGeneratorService; import com.mog.gameserver.utils.ThreadPoolManager; /** * @author Dision */ @AIName("dlc_mission_attack") public class DLCMissionAttackerAI2 extends TheBuffAI2 { private Npc aggroNpc; private Future<?> delayTask; @Override protected void handleSpawned() { delayReagressive(); super.handleSpawned(); } @Override protected void handleAttack(Creature creature) { super.handleAttack(creature); } private void addHate() { aggroNpc = getNpc(884030); if (aggroNpc != null && !aggroNpc.getLifeStats().isAlreadyDead()) { getOwner().getAggroList().addHate(aggroNpc, 50000); } } /** * Reagressive */ private void delayReagressive() { delayTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(new Runnable() { @Override public void run() { if (isAlreadyDead()) cancelTask(); else { if (getOwner().getTarget() == null) { addHate(); } } } }, 0, 15000); } public void cancelTask() { if (delayTask != null && !delayTask.isCancelled()) { delayTask.cancel(true); } } @Override protected void handleDespawned() { cancelTask(); super.handleDespawned(); } @Override protected void handleDied() { cancelTask(); MissionGeneratorService.getInstance().targetCounter(getPosition().getWorldMapInstance()); super.handleDied(); } } Код: /* * Mission defense */ package com.mog.gameserver.ai2.handlers.dlc; import java.util.Map.Entry; import java.util.concurrent.Future; import com.mog.gameserver.ai2.AIName; import com.mog.gameserver.ai2.NpcAI2; import com.mog.gameserver.ai2.handlers.general.AggressiveNpcAI2; import com.mog.gameserver.ai2.poll.AIAnswer; import com.mog.gameserver.ai2.poll.AIAnswers; import com.mog.gameserver.ai2.poll.AIQuestion; import com.mog.gameserver.model.Race; import com.mog.gameserver.model.gameobjects.Creature; import com.mog.gameserver.model.gameobjects.player.Player; import com.mog.gameserver.services.dlc.missionGenerator.MissionGeneratorService; import com.mog.gameserver.services.dlc.missionGenerator.MissionTargetList; import com.mog.gameserver.utils.MathUtil; import com.mog.gameserver.utils.ThreadPoolManager; import com.mog.gameserver.utils.commons.utils.Rnd; import javolution.util.FastList; /** * @author Dision */ @AIName("dlc_mission_def") public class DLCMissionDefenseAI2 extends AggressiveNpcAI2 { private boolean isActive = false; private FastList<Future<?>> tasks = FastList.newInstance(); private int counter = 0; @Override public boolean canThink() { return false; } @Override protected void handleCreatureSee(Creature creature) { checkDistance(this, creature); } @Override protected void handleCreatureMoved(Creature creature) { checkDistance(this, creature); } private void checkDistance(NpcAI2 ai, final Creature creature) { if (creature instanceof Player) { if (MathUtil.isIn3dRange(getOwner(), creature, 15) && !isActive) { isActive = true; tasks.add(ThreadPoolManager.getInstance().scheduleAtFixedRate(new Runnable() { @Override public void run() { if (isAlreadyDead() || counter == 15) stopTask(); else { if (counter == MissionGeneratorService.getInstance().getCouter()) { for (Entry<Integer, MissionTargetList> entry : MissionGeneratorService.getInstance().getMissions().entrySet()) { MissionGeneratorService.getInstance().messenger(getPosition().getWorldMapInstance(), entry.getValue().getMission(), 2, " \u043e\u0431\u043e\u0440\u043e\u043d\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430", 0); } getOwner().getController().onDie(getOwner()); return; } counter++; for (Entry<Integer, MissionTargetList> entry : MissionGeneratorService.getInstance().getMissions().entrySet()) { MissionGeneratorService.getInstance().messenger(getPosition().getWorldMapInstance(), entry.getValue().getMission(), 2, " \u043e\u0431\u043e\u0440\u043e\u043d\u0430 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0441\u044f", 0); } for (int i = 0; i < 5; i++) { spawn(!creature.getRace().equals(Race.ASMODIANS) ? 855979 : 855986, getOwner().getX() + Rnd.get(2, 8), getOwner().getY() + Rnd.get(2, 8), getOwner().getZ(), (byte) 0); } } } }, 0, 40000)); } } } private void stopTask() { for (FastList.Node<Future<?>> n = tasks.head(), end = tasks.tail(); (n = n.getNext()) != end;) { if (n.getValue() != null) { n.getValue().cancel(true); } } tasks.clear(); getOwner().getController().onDelete(); } @Override protected void handleDespawned() { stopTask(); counter = 0; super.handleDespawned(); } @Override public void handleBackHome() { return; } @Override public int modifyDamage(int damage) { return 1; } @Override protected void handleDied() { stopTask(); counter = 0; MissionGeneratorService.getInstance().missionEnd(getPosition().getWorldMapInstance(), true); super.handleDied(); } @Override protected AIAnswer pollInstance(AIQuestion question) { switch (question) { case SHOULD_DECAY: return AIAnswers.NEGATIVE; case SHOULD_RESPAWN: return AIAnswers.NEGATIVE; case SHOULD_REWARD: return AIAnswers.NEGATIVE; default: return null; } } }