테스트

aion-server 4.8

Gitteol
최고관리자 · 1 · 💬 0 클론/새로받기
 4.8 61f661d · 1 commits 새로받기(Pull)
game-server/data/handlers/instance/DragonLordsRefugeInstance.java
package instance;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

import com.aionemu.commons.utils.Rnd;
import com.aionemu.gameserver.ai.AIActions;
import com.aionemu.gameserver.instance.handlers.GeneralInstanceHandler;
import com.aionemu.gameserver.instance.handlers.InstanceID;
import com.aionemu.gameserver.model.CreatureType;
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.gameobjects.player.Player;
import com.aionemu.gameserver.network.aion.serverpackets.SM_QUEST_ACTION;
import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE;
import com.aionemu.gameserver.services.player.PlayerReviveService;
import com.aionemu.gameserver.services.teleport.TeleportService;
import com.aionemu.gameserver.skillengine.SkillEngine;
import com.aionemu.gameserver.skillengine.model.Effect;
import com.aionemu.gameserver.utils.PacketSendUtility;
import com.aionemu.gameserver.utils.ThreadPoolManager;
import com.aionemu.gameserver.world.WorldMapInstance;
import com.aionemu.gameserver.world.WorldPosition;

/**
 * @author bobobear, Luzien, Estrayl
 */
@InstanceID(300520000)
public class DragonLordsRefugeInstance extends GeneralInstanceHandler {

	private final List<WorldPosition> respawnLocations = new ArrayList<>();
	protected final AtomicInteger raceId = new AtomicInteger(10);
	protected final AtomicInteger incarnationKills = new AtomicInteger();
	protected final AtomicInteger progress = new AtomicInteger();
	protected Future<?> failTask;

	public DragonLordsRefugeInstance(WorldMapInstance instance) {
		super(instance);
		// Retail positions
		respawnLocations.add(new WorldPosition(300520000, 493.72f, 507.67f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 497.52f, 526.03f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 513.02f, 524.57f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 499.57f, 510.19f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 513.22f, 508.36f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 505.05f, 525.03f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 498.65f, 519.93f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 511.44f, 515.36f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 495.27f, 517.07f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 492.62f, 525.37f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 507.56f, 520.36f, 240.5f, (byte) 0));
		respawnLocations.add(new WorldPosition(300520000, 508.20f, 506.85f, 240.5f, (byte) 0));
	}

	@Override
	public void onSpawn(VisibleObject object) {
		if (object instanceof Npc) {
			switch (((Npc) object).getNpcId()) {
				case 219361: // Tiamat Dragon
					ThreadPoolManager.getInstance().schedule(() -> {
						spawn(730673, 459.548f, 456.849f, 417.405f, (byte) 21);
						spawn(730674, 547.909f, 456.568f, 417.405f, (byte) 45);
						spawn(730675, 460.082f, 571.978f, 417.405f, (byte) 98);
						spawn(730676, 547.822f, 571.876f, 417.405f, (byte) 74);
					}, 60000);
					break;
				case 219362: // Tiamat Weakened Dragon
					sendMsg(SM_SYSTEM_MESSAGE.IDTIAMAT_TIAMAT_COUNTDOWN_START(), 2000);
					PacketSendUtility.broadcastToMap(instance, new SM_QUEST_ACTION(0, 1800));
					failTask = ThreadPoolManager.getInstance().schedule(() -> {
						Npc tiamat = getNpc(219362);
						if (tiamat != null && !tiamat.isDead()) {
							endInstance(Arrays.asList(730625, 730633, 730634, 730635, 730636));
							sendMsg(SM_SYSTEM_MESSAGE.IDTIAMAT_TIAMAT_COUNTDOWN_OVER());
						}
					}, 1800000); // 30'
					break;
				case 219488: // Kaisinel 1st Phase
					sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_TIAMAT_2PHASE_START_LIGHT(), 20000);
					break;
				case 219489: // Kaisinel 2nd Phase
					sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_KAISINEL_2PHASE_DEADLYATK(), 3000);
					break;
				case 219490: // Kaisinel 3rd Phase
					sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_KAISINEL_2PHASE_GROGGY(), 15000);
					break;
				case 219491: // Marchutan 1st Phase
					sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_TIAMAT_2PHASE_START_DARK(), 20000);
					break;
				case 219492: // Marchutan 2nd Phase
					sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_MARCHUTAN_2PHASE_DEADLYATK(), 3000);
					break;
				case 219493: // Marchutan 3rd Phase
					sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_MARCHUTAN_2PHASE_GROGGY(), 15000);
					break;
				case 283140:
					sendMsg(SM_SYSTEM_MESSAGE.STR_IDTIAMAT_TIAMAT_SPAWN_BLACKHOLE(), 2500);
					break;
				case 730673:
					ThreadPoolManager.getInstance().schedule(() -> {
						spawn(283163, 463f, 568f, 417.405f, (byte) 105);
						spawn(283164, 545f, 568f, 417.405f, (byte) 78);
						spawn(283165, 545f, 461f, 417.405f, (byte) 46);
						spawn(283166, 463f, 461f, 417.405f, (byte) 17);
					}, 10000);
					break;
				case 730695: // Surkana
					sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_KALYNDI_SURKANA_SPAWN(), 2500);
					break;
			}
		}
	}

	@Override
	public void onStartEffect(Effect effect) {
		switch (effect.getSkillId()) {
			case 20918:
				PacketSendUtility.broadcastMessage(getNpc(800341), 1500612);
				break;
			case 20920:
				if (progress.compareAndSet(1, 2)) {
					ThreadPoolManager.getInstance().schedule(() -> spawn(219488 + raceId.get() * 3, 504f, 515f, 417.405f, (byte) 60), 6000);
					spawn(219532, 469f, 563f, 417.41f, (byte) 103);
					spawn(219535, 466f, 560f, 417.41f, (byte) 103);
					spawn(219533, 542f, 559f, 417.41f, (byte) 79);
					spawn(219538, 538f, 562f, 417.41f, (byte) 79);
					spawn(219534, 537f, 466f, 417.41f, (byte) 42);
					spawn(219537, 541f, 469f, 417.41f, (byte) 42);
					spawn(219536, 466f, 471f, 417.41f, (byte) 18);
					spawn(219539, 470f, 467f, 417.41f, (byte) 18);
				}
				break;
			case 20993:
			case 20994:
			case 20995:
			case 20996:
				sendMsg(SM_SYSTEM_MESSAGE.IDTIAMAT_TIAMAT_DRAKAN_ON_DIE());
				break;
		}
	}

	@Override
	public void onEndEffect(Effect effect) {
		switch (effect.getSkillId()) {
			case 20975:
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_TIAMAT_2PHASE_CLOSE_CRACK());
				break;
			case 20976:
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_TIAMAT_2PHASE_CLOSE_RAGE());
				break;
			case 20977:
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_TIAMAT_2PHASE_CLOSE_GRAVITY());
				break;
			case 20978:
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_TIAMAT_2PHASE_CLOSE_CRYSTAL());
				break;
			case 20983:
				if (((Npc) effect.getEffector()).getNpcId() == 219361)
					endInstance(Arrays.asList(730625, 730633, 730634, 730635, 730636));
				break;
		}
	}

	private void endInstance(List<Integer> despawnExceptions) {
		instance.forEachNpc(npc -> {
			if (!despawnExceptions.contains(npc.getNpcId()))
				npc.getController().delete();
		});
		spawn(730630, 548.18683f, 514.54523f, 420f, (byte) 0, 23);
	}

	@Override
	public void onDie(Npc npc) {
		super.onDie(npc);
		switch (npc.getNpcId()) {
			case 219359: // Calindi Flamelord
				deleteAliveNpcs(730695, 730696); // Surkana
				ThreadPoolManager.getInstance().schedule(() -> AIActions.useSkill(getNpc(219360).getAi(), 20919), 4000);
				ThreadPoolManager.getInstance().schedule(() -> deleteAliveNpcs(730694), 6000); // Aetheric field
				break;
			case 219361: // Tiamat Dragon - killed by Empyrean Lord
				getNpc(730699).getController().die(); // Animates roof destruction
				getNpc(730700).getController().die();
				spawn(283134, 451.97f, 514.55f, 417.40436f, (byte) 0);
				spawn(219362, 451.97f, 514.55f, 417.40436f, (byte) 0);
				spawn(730704, 437.541f, 513.487f, 415.824f, (byte) 0, 17); // Collapsed Debris impaling Tiamat
				break;
			case 219362:
				failTask.cancel(true);
				PacketSendUtility.broadcastToMap(instance, new SM_QUEST_ACTION(0, 0));
				// TODO: play movie
				endInstance(Arrays.asList(219490, 219493, 219362, 730625, 730633, 730634, 730635, 730636));
				spawn(701542, 480f, 514f, 417.405f, (byte) 0); // Treasure Chest
				spawn(800430, 506.8f, 511.4f, 417.405f, (byte) 60); // Kahrun
				spawn(800350 + raceId.get() * 6, 506.7f, 518.4f, 417.405f, (byte) 60); // human Kaisinel/Marchutan
				spawn(800464, 544.964f, 517.898f, 417.405f, (byte) 113);
				spawn(800465, 545.605f, 510.325f, 417.405f, (byte) 17);
				break;
			case 219365: // Incarnations
			case 219366:
			case 219367:
			case 219368:
				if (incarnationKills.incrementAndGet() == 4)
					handlePhaseProgress();
				SkillEngine.getInstance().applyEffectDirectly(npc.getNpcId() - 198386, npc, getNpc(219361)); // 20979 - 20982
				break;
			case 283163: // Balaur Spiritualist
			case 283164:
			case 283165:
			case 283166:
				Npc empyreanLord = getNpc(219488 + raceId.get() * 3);
				if (empyreanLord != null)
					SkillEngine.getInstance().applyEffectDirectly(npc.getNpcId() - 262170, npc, empyreanLord); // 20993 - 20996
				break;
			case 219488: // Kaisinel 1st Phase
			case 219491: // Marchutan 1st Phase
				if (incarnationKills.get() == 4) // in rare cases the empyrean lord dies while the instance have to wait for progress
					return;
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_TIAMAT_DEADLYHOWLING());
				for (int i = 219365; i <= 219368; i++) {
					Npc incarnation = getNpc(i);
					if (incarnation != null)
						AIActions.useSkill(incarnation.getAi(), 20983);
				}
				AIActions.useSkill(getNpc(219361).getAi(), 20983);
				ThreadPoolManager.getInstance().schedule(() -> endInstance(Arrays.asList(730625, 730633, 730634, 730635, 730636, 730699, 730700)), 5000);
				break;
		}
	}

	private void handlePhaseProgress() {
		sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDTIAMAT_TIAMAT_2PHASE_CLOSE_ALL());

		int empyreanLordId = 219488 + raceId.get() * 3;
		getNpc(219361).getEffectController().removeEffect(20984); // Dispel Unbreakable Wing

		// schedule spawn of empyrean lords for final attack to tiamat before became exhausted
		ThreadPoolManager.getInstance().schedule(() -> {
			deleteAliveNpcs(empyreanLordId);
			spawn(219489 + raceId.get() * 3, 516.285f, 514.84f, 417.405f, (byte) 60);
		}, 30000);
	}

	/**
	 * Smalltalk between Tiamat and Kahrun
	 */
	private void handleDialogueEvent(Npc tiamat) {
		Npc kahrun = getNpc(800341);
		AIActions.targetCreature(tiamat.getAi(), kahrun);
		PacketSendUtility.broadcastMessage(tiamat, 1500613, 5000);
		PacketSendUtility.broadcastMessage(kahrun, 1500609, 10000);
		PacketSendUtility.broadcastMessage(tiamat, 1500614, 15000);
		PacketSendUtility.broadcastMessage(kahrun, 1500610, 20000);
		PacketSendUtility.broadcastMessage(tiamat, 1500615, 26500);
		PacketSendUtility.broadcastMessage(kahrun, 1500611, 31500);
		ThreadPoolManager.getInstance().schedule(() -> AIActions.useSkill(kahrun.getAi(), 20597), 35500);
		PacketSendUtility.broadcastMessage(tiamat, 1500616, 40000);
		ThreadPoolManager.getInstance().schedule(() -> AIActions.useSkill(tiamat.getAi(), 20918), 49000);
		PacketSendUtility.broadcastMessage(tiamat, 1500617, 44500);
		ThreadPoolManager.getInstance().schedule(() -> {
			kahrun.getController().delete();
			tiamat.getController().delete();
			spawnTiamat();
			spawnCalindi();
		}, 54500);
	}

	protected void spawnTiamat() {
		spawn(219360, 452, 514, 432, (byte) 0);
	}

	protected void spawnCalindi() {
		spawn(219359, 483.463f, 514.519f, 417.404f, (byte) 0);
	}

	@Override
	public void onEnterInstance(Player player) {
		raceId.compareAndSet(10, player.getRace().getRaceId());
	}

	@Override
	public void onCreatureDetected(Npc detector, Creature detected) {
		if (detector.getNpcId() == 219360 && detected instanceof Player && progress.compareAndSet(0, 1))
			handleDialogueEvent(detector);
	}

	@Override
	public void handleUseItemFinish(Player player, Npc npc) {
		switch (npc.getNpcId()) {
			case 730625:
				float distance = Rnd.get(250, 450) * 0.1f;
				double radian = Math.toRadians(Rnd.get(-45, 60));
				float x = (float) (Math.cos(radian) * distance);
				float y = (float) (Math.sin(radian) * distance);
				TeleportService.teleportTo(player, instance.getMapId(), 503.389f + x, 514.661f + y, 417.404f);
				Npc tiamat = getNpc(219360);
				if (tiamat != null)
					tiamat.overrideNpcType(CreatureType.PEACE);
				break;
			case 730630: // Exit
				TeleportService.moveToInstanceExit(player, mapId, player.getRace());
				break;
			case 730673:
				TeleportService.teleportTo(player, instance.getMapId(), 217.144f, 195.616f, 246.0712f);
				break;
			case 730674:
				TeleportService.teleportTo(player, instance.getMapId(), 785.866f, 197.713f, 246.0712f);
				break;
			case 730675:
				TeleportService.teleportTo(player, instance.getMapId(), 217.947f, 832.552f, 246.0712f);
				break;
			case 730676:
				TeleportService.teleportTo(player, instance.getMapId(), 779.178f, 833.055f, 246.0712f);
				break;
			case 730633:
				TeleportService.teleportTo(player, instance.getMapId(), 461.493f, 459.308f, 417.405f);
				break;
			case 730634:
				TeleportService.teleportTo(player, instance.getMapId(), 546f, 458.934f, 417.405f);
				break;
			case 730635:
				TeleportService.teleportTo(player, instance.getMapId(), 462.188f, 568.913f, 417.405f);
				break;
			case 730636:
				TeleportService.teleportTo(player, instance.getMapId(), 545.773f, 569.225f, 417.405f);
				break;
		}
	}

	@Override
	public void onInstanceDestroy() {
		if (failTask != null && !failTask.isCancelled())
			failTask.cancel(true);
	}

	@Override
	public boolean onReviveEvent(Player player) {
		PlayerReviveService.revive(player, 25, 25, true, 0);
		player.getGameStats().updateStatsAndSpeedVisually();
		PacketSendUtility.sendPacket(player, SM_SYSTEM_MESSAGE.STR_REBIRTH_MASSAGE_ME());
		WorldPosition p = Rnd.get(respawnLocations);
		TeleportService.teleportTo(player, instance, p.getX(), p.getY(), p.getZ(), p.getHeading());
		return true;
	}
}

📎 첨부파일

댓글 작성 권한이 없습니다.
🏆 포인트 랭킹 TOP 10
순위 닉네임 포인트
1 no_profile 타키야겐지쪽지보내기 자기소개 아이디로 검색 전체게시물 100,792
2 no_profile 동가리쪽지보내기 자기소개 아이디로 검색 전체게시물 58,079
3 no_profile 라프텔쪽지보내기 자기소개 아이디로 검색 전체게시물 51,771
4 no_profile 불멸의행복쪽지보내기 자기소개 아이디로 검색 전체게시물 36,923
5 서번트쪽지보내기 자기소개 아이디로 검색 전체게시물 35,011
6 no_profile 보거스쪽지보내기 자기소개 아이디로 검색 전체게시물 29,969
7 no_profile 닥터스쪽지보내기 자기소개 아이디로 검색 전체게시물 29,470
8 no_profile 검은고양이쪽지보내기 자기소개 아이디로 검색 전체게시물 29,077
9 no_profile Revolution쪽지보내기 자기소개 아이디로 검색 전체게시물 28,199
10 no_profile 호롤롤로쪽지보내기 자기소개 아이디로 검색 전체게시물 17,020
알림 0