테스트

aion-server 4.8

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

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import com.aionemu.commons.utils.Rnd;
import com.aionemu.gameserver.dataholders.DataManager;
import com.aionemu.gameserver.instance.handlers.GeneralInstanceHandler;
import com.aionemu.gameserver.instance.handlers.InstanceID;
import com.aionemu.gameserver.model.Race;
import com.aionemu.gameserver.model.gameobjects.Npc;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.geometry.Point3D;
import com.aionemu.gameserver.model.instance.InstanceProgressionType;
import com.aionemu.gameserver.model.instance.instancescore.NormalScore;
import com.aionemu.gameserver.network.aion.instanceinfo.EternalBastionScoreWriter;
import com.aionemu.gameserver.network.aion.serverpackets.SM_INSTANCE_SCORE;
import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE;
import com.aionemu.gameserver.services.abyss.AbyssPointsService;
import com.aionemu.gameserver.services.item.ItemService;
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;

/**
 * Remaining Online Information:<br>
 * Summarized guide: <a href="https://web.archive.org/web/20160918063923/http://aion.mouseclic.com:80/wiki/instance/bastion?lang=us">Link</a><br>
 * Guide based on interview: <a href="https://web.archive.org/web/20150215111653/http://aion.mouseclic.com:80/instances/bastion.php">Link</a><br>
 * Rewards: <<a href="https://aionpowerbook.com/powerbook/index.php?title=Steel_Wall_Bastion_-_Drop&setlang=en&aionclassic=0">Link</a><br>
 * Quick Summary:
 * Players need to defend the fortress commander while also progressing the instance and accumulating additional points by killing the surrounding
 * camp commanders. The first three phases are progressed by killing three specific commanders, whereas the fourth phase will be completed if all
 * five siege towers are killed.<br>
 * Killing a specific barricade or dredgion signal tower or activating the siege cannon will result in additional assault pod spawns.
 * Every two minutes an assault wave will spawn. It's strength, i.e. assaulter count, increases over time. Additional waves can spawn from
 * assault pods, siege towers or broken wall/gate.<br>
 * Players can skip specific waves by killing enough commanders and thus reducing the assault strength. They can also use the cannons or tank to
 * make defending/attacking easier.
 *
 * @author Cheatkiller, Estrayl
 */
@InstanceID(300540000)
public class EternalBastionInstance extends GeneralInstanceHandler {

	private static final int START_DELAY = 180 * 1000;
	private final AtomicInteger assaultPower = new AtomicInteger(12); // Retail
	private final AtomicInteger progressionKills = new AtomicInteger();
	private final AtomicBoolean isRaceSet = new AtomicBoolean();
	private final List<Future<?>> spawnTasks = new ArrayList<>();
	private Future<?> instanceTimerTask, assaultWaveTask;
	private int waveCount;
	private long startTime;
	private NormalScore instanceReward;

	public EternalBastionInstance(WorldMapInstance instance) {
		super(instance);
	}

	@Override
	public void onDie(Npc npc) {
		super.onDie(npc);
		switch (npc.getNpcId()) {
			case 231168: // Pashid Scout Commander Azute
			case 231169: // Pashid Scout Commander Zest
			case 231170: // Pashid Scout Commander Sartas
			case 231171: // Pashid Infantry Commander Matuk
			case 231172: // Pashid Assault Commander Badute
			case 231173: // Pashid Assault Commander Katsu
			case 231174: // Pashid Artillery Commander Murat
			case 231175: // Pashid Artillery Commander Kaimdu
			case 231176: // Pashid Artillery Commander Nirta
				addPoints(npc, 1880);
				checkProgress(progressionKills.incrementAndGet());
				break;
			case 231143: // Pashid Siege Tower
			case 231152: // Pashid Siege Tower
			case 231153: // Pashid Siege Tower
			case 231154: // Pashid Siege Tower
			case 231155: // Pashid Siege Tower
				addPoints(npc, 334);
				checkProgress(progressionKills.incrementAndGet());
				break;
			case 231177: // Deathbringer Tariksha
				addPoints(npc, 1880);
				break;
			case 231178: // Commander Hakunta
			case 231179: // Commander Rakunta
				addPoints(npc, 1880);
				assaultPower.addAndGet(-2); // Retail
				break;
			case 230784: // Pashid Snare Turret
			case 230785: // Pashid Assault Flamethrower
			case 231137: // Pashid Danuar Turret
			case 231138: // Pashid Danuar Turret
			case 231140: // Pashid Assault Pod
			case 231141: // Pashid Siege Drop Pod
			case 231144: // Pashid Siege Cannon
			case 231156: // Pashid Assault Pod
			case 231157: // Pashid Assault Pod
			case 231158: // Pashid Assault Pod
			case 231159: // Pashid Assault Pod
			case 231160: // Pashid Assault Pod
			case 231162: // Pashid Assault Pod
			case 231163: // Pashid Siege Drop Pod
			case 231164: // Pashid Siege Drop Pod
			case 231165: // Pashid Siege Drop Pod
			case 231167: // Pashid Siege Drop Pod
			case 231180: // Dredgion Signal Tower
				addPoints(npc, 334);
				break;
			case 231148: // Dredgion Signal Tower
				addPoints(npc, 334);
				PacketSendUtility.broadcastToMap(npc, SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_AddWave_03());
				spawnWithDelay(231157, 778.845f, 323.282f, 253.434f, (byte) 40, 30000);
				spawnWithDelay(231159, 697.564f, 305.424f, 249.303f, (byte) 100, 30000);
				break;
			case 231149: // Pashid Army Barricade
				addPoints(npc, 266);
				PacketSendUtility.broadcastToMap(npc, SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_AddWave_02());
				spawnWithDelay(231164, 667.350f, 281.046f, 225.698f, (byte) 33, 30000); // Pashid Assault Pod
				spawnWithDelay(231165, 721.498f, 358.172f, 230.940f, (byte) 0, 30000);
			case 231181: // Pashid Army Barricade
				addPoints(npc, 266);
				break;
			case 230746: // Pashid Assault Tribuni Sentry
			case 230753: // Pashid Assault Rider
			case 230754: // Pashid Assault Gunner
			case 230756: // Pashid Assault Supply Officer
			case 230757: // Pashid Assault Dragon
				addPoints(npc, 1002);
				assaultPower.decrementAndGet();
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_Notice_06());
				break;
			case 230744: // Pashid Assault Tribuni Combatant
			case 230745: // Pashid Assault Tribuni Protector
			case 230749: // Pashid Assault Tribuni Marksman
			case 231131: // Pashid Siege Dragon
			case 231132: // Pashid Siege Dragon
			case 231133: // Pashid Siege Dragon
			case 231134: // Pashid Siege Dragon
				addPoints(npc, 1002);
				break;
			case 831333: // Castle Wall
				addPoints(npc, -150);
				deleteAliveNpcs(831332); // Right Castle Gate
				deleteAliveNpcs(231150); // Drill
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_Notice_04());
				break;
			case 831335: // Inner Water Gate
				addPoints(npc, -150);
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_Notice_02());
				break;
			case 209516: // Commander Lysander
			case 209517: // Commander Granir
				addPoints(npc, -100000); // Retail
				endInstance();
				break;
			case 209555: // Lysander's Disciple
			case 209557: // Granir's Disciple
				addPoints(npc, -50);
				break;
			case 231130: // Grand Commander Pashid
				addPoints(npc, 24000);
				endInstance();
				break;
			case 231117: // Pashid Elite Siege Combatant
			case 231118: // Pashid Elite Siege Protector
			case 231119: // Pashid Elite Siege Ambusher
			case 231120: // Pashid Elite Siege Troublemaker
			case 231122: // Pashid Elite Siege Marksman
			case 231123: // Pashid Elite Siege Rampager
			case 231124: // Pashid Elite Siege Magus
			case 231125: // Pashid Elite Siege Summoner
			case 231126: // Pashid Elite Siege Cavalry
			case 231127: // Pashid Elite Siege Striker
			case 231128: // Pashid Elite Siege Medic
			case 233310: // Pashid Siege Cavalry
			case 233311: // Pashid Siege Engineer
				addPoints(npc, 42);
				break;
			case 233312: // Pashid Siege Healer
			case 233314: // Pashid Elite Siege Defender
			case 233315: // Pashid Elite Siege Gunner
				addPoints(npc, 36);
				break;
			case 231115: // Pashid Siege Soldier
			case 231116: // Pashid Siege Mage
			case 233309: // Pashid Siege Ambusher
				addPoints(npc, 33);
				break;
			case 233313:
				addPoints(npc, 20);
				break;
		}
	}

	private void checkProgress(int progressionKills) {
		switch (progressionKills) {
			case 3 -> {
				Npc outerWaterGate = getNpc(831334);
				if (outerWaterGate != null)
					outerWaterGate.getController().deleteIfAliveOrCancelRespawn();
				spawn(233314, 575.858f, 146.753f, 221.351f, (byte) 33); // Pashid Elite Siege Defender
				spawn(233314, 587.445f, 152.020f, 218.004f, (byte) 63);
				spawn(233314, 609.691f, 187.747f, 216.455f, (byte) 87);
				spawn(233314, 630.440f, 192.271f, 219.763f, (byte) 40);
				spawn(233315, 598.051f, 160.956f, 216.754f, (byte) 100); // Pashid Elite Siege Gunner
				spawn(233315, 609.099f, 150.973f, 216.063f, (byte) 57);
				spawn(233315, 637.820f, 203.284f, 222.032f, (byte) 77);
				spawn(233315, 641.959f, 197.833f, 221.788f, (byte) 77);

				spawnTasks.add(ThreadPoolManager.getInstance().schedule(() -> {
					sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_MainWave_02());
					spawn(231171, 655.755f, 212.606f, 223.931f, (byte) 80); // Pashid Infantry Commander Matuk
					spawnWithWalker(231142, 604.397f, 170.492f, 216.042f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_D1"); // Pashid Siege Volatile
					spawnWithWalker(231142, 605.397f, 171.492f, 216.092f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_D1");
					spawnWithWalker(231142, 603.397f, 171.492f, 216.085f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_D1");
					spawnWithWalker(231173, 657.052f, 465.173f, 225.052f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_B2F2"); // Pashid Assault Commander Katsu
					spawnWithWalker(233313, 659.052f, 467.173f, 225.000f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_B2F2");
					spawnWithWalker(233313, 655.052f, 467.173f, 225.133f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_B2F2");
					spawnWithWalker(231172, 604.429f, 413.910f, 223.782f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_B1F2"); // Pashid Assault Commander Badute
					spawnWithWalker(233313, 606.429f, 411.910f, 224.027f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_B1F2");
					spawnWithWalker(233313, 602.429f, 411.910f, 223.756f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_B1F2");
				}, 90, TimeUnit.SECONDS));
			}
			case 6 -> spawnTasks.add(ThreadPoolManager.getInstance().schedule(() -> {
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_MainWave_03());
				spawn(233313, 572.428f, 368.118f, 226.464f, (byte) 113); // Pashid Siege Combatant
				spawn(233313, 577.691f, 374.779f, 226.077f, (byte) 110);
				spawn(233313, 583.372f, 380.359f, 225.562f, (byte) 107);
				spawn(233313, 590.788f, 386.729f, 224.273f, (byte) 100);
				spawn(233313, 652.680f, 456.840f, 225.698f, (byte) 110);
				spawn(233313, 660.402f, 469.521f, 225.095f, (byte) 113);
				spawn(233313, 670.701f, 477.320f, 225.120f, (byte) 100);
				spawn(233313, 681.626f, 481.653f, 224.853f, (byte) 100);
				spawn(231137, 569.389f, 374.023f, 228.221f, (byte) 110); // Pashid Danuar Turret
				spawn(231137, 576.424f, 381.682f, 226.099f, (byte) 107);
				spawn(231137, 584.247f, 388.219f, 225.080f, (byte) 103);
				spawn(231138, 650.886f, 466.252f, 225.282f, (byte) 110);
				spawn(231138, 661.941f, 478.229f, 226.286f, (byte) 103);
				spawn(231138, 673.506f, 486.307f, 225.869f, (byte) 100);
				spawn(231140, 635.426f, 243.117f, 238.075f, (byte) 33); // Pashid Assault Pods
				spawn(231141, 666.361f, 294.435f, 225.698f, (byte) 20);
				spawn(231158, 768.339f, 390.709f, 243.356f, (byte) 40);
				spawn(231174, 669.851f, 468.267f, 225.250f, (byte) 107); // Pashid Artillery Commander Murat
				spawn(231175, 583.830f, 373.812f, 225.280f, (byte) 107); // Pashid Artillery Commander Kaimdu
				spawn(231176, 760.219f, 392.471f, 243.354f, (byte) 50); // Pashid Infantry Commander Nirta
			}, 90, TimeUnit.SECONDS));
			case 9 -> spawnTasks.add(ThreadPoolManager.getInstance().schedule(() -> {
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_MainWave_04());
				spawn(231143, 613.231f, 262.163f, 227.255f, (byte) 3);
				spawn(231152, 608.371f, 303.514f, 226.295f, (byte) 113);
				spawn(231153, 625.244f, 352.624f, 226.295f, (byte) 113);
				spawn(231154, 668.864f, 405.970f, 228.500f, (byte) 83);
				spawn(231155, 691.536f, 409.367f, 231.720f, (byte) 98);
			}, 90, TimeUnit.SECONDS));
			case 14 -> spawnTasks.add(ThreadPoolManager.getInstance().schedule(() -> {
				sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_MainWave_05());
				spawn(231130, 740.668f, 298.082f, 233.889f, (byte) 100); // Commander Pashid
				spawn(231131, 686.574f, 358.216f, 243.386f, (byte) 100); // Pashid Siege Dragons
				spawn(231131, 655.856f, 351.118f, 241.595f, (byte) 20);
				spawn(231131, 732.982f, 371.320f, 230.942f, (byte) 106);
				spawn(231132, 582.631f, 376.172f, 225.461f, (byte) 100);
				spawn(231133, 745.820f, 322.916f, 249.287f, (byte) 86);
				spawn(231133, 713.242f, 289.971f, 249.285f, (byte) 0);
				spawn(231134, 668.732f, 473.705f, 225.159f, (byte) 100);
				spawn(231156, 641.551f, 339.264f, 238.075f, (byte) 20); // Pashid Assault Pods
				spawn(231163, 727.175f, 364.431f, 230.941f, (byte) 7);
			}, 90, TimeUnit.SECONDS));
		}
	}

	@Override
	public void onEnterInstance(Player player) {
		if (!instanceReward.isRewarded())
			sendPacket();
		if (isRaceSet.compareAndSet(false, true)) {
			spawnRaceGuards(player.getRace());
			if (Rnd.nextBoolean()) {
				spawn(231177, 821.146f, 607.305f, 239.703f, (byte) 73); // Deathbringer Tariksha
				spawn(230746, 551.146f, 412.105f, 222.760f, (byte) 30); // Pashid Assault Tribuni Sentry
				spawn(231149, 702.116f, 552.614f, 232.423f, (byte) 110); // Pashid Army Barricade (Assault Pod Trigger)
				spawn(231181, 564.414f, 250.835f, 233.198f, (byte) 110); // Pashid Army Barricade
			} else {
				spawn(230746, 821.146f, 607.305f, 239.703f, (byte) 73); // Pashid Assault Tribuni Sentry
				spawn(231177, 551.146f, 412.105f, 222.760f, (byte) 30); // Deathbringer Tariksha
				spawn(231181, 702.116f, 552.614f, 232.423f, (byte) 110); // Pashid Army Barricade
				spawn(231149, 564.414f, 250.835f, 233.198f, (byte) 110); // Pashid Army Barricade (Assault Pod Trigger)
			}
		}
	}

	private void spawnRaceGuards(Race race) {
		int guardId = race == Race.ELYOS ? 209555 : 209557;
		spawn(race == Race.ELYOS ? 209516 : 209517, 750.205f, 285.880f, 233.752f, (byte) 40); // Commander
		spawn(race == Race.ELYOS ? 701923 : 701924, 744.174f, 292.949f, 233.698f, (byte) 40); // Flag
		spawn(race == Race.ELYOS ? 701625 : 701922, 640.862f, 412.784f, 243.940f, (byte) 40); // Siege Cannon
		spawn(guardId, 595.476f, 284.680f, 226.375f, (byte) 40);
		spawn(guardId, 598.868f, 284.201f, 226.424f, (byte) 40);
		spawn(guardId, 602.328f, 340.964f, 225.794f, (byte) 40);
		spawn(guardId, 605.731f, 343.153f, 225.448f, (byte) 40);
		spawn(guardId, 607.450f, 387.642f, 223.353f, (byte) 40);
		spawn(guardId, 611.817f, 388.865f, 223.500f, (byte) 40);
		spawn(guardId, 681.742f, 444.580f, 226.818f, (byte) 40);
		spawn(guardId, 684.437f, 447.848f, 226.787f, (byte) 40);
		spawn(guardId, 690.046f, 351.800f, 244.744f, (byte) 40);
		spawn(guardId, 690.220f, 341.532f, 228.674f, (byte) 40);
		spawn(guardId, 692.778f, 337.952f, 228.674f, (byte) 40);
		spawn(guardId, 693.082f, 354.432f, 244.733f, (byte) 40);
		spawn(guardId, 715.405f, 427.312f, 230.025f, (byte) 40);
		spawn(guardId, 719.378f, 428.101f, 230.112f, (byte) 40);
		spawn(guardId, 748.146f, 361.345f, 230.945f, (byte) 40);
		spawn(guardId, 749.389f, 364.988f, 230.945f, (byte) 40);
		if (race == Race.ELYOS) {
			spawn(701596, 617.501f, 248.196f, 235.740f, (byte) 60); // Cannons
			spawn(701597, 612.806f, 275.206f, 235.740f, (byte) 67);
			spawn(701598, 616.159f, 313.939f, 235.740f, (byte) 53);
			spawn(701599, 625.603f, 339.608f, 235.734f, (byte) 53);
			spawn(701600, 650.914f, 372.932f, 238.607f, (byte) 53);
			spawn(701601, 677.853f, 396.203f, 238.632f, (byte) 40);
			spawn(701602, 710.145f, 410.661f, 241.014f, (byte) 30);
			spawn(701603, 736.803f, 414.121f, 241.017f, (byte) 40);
			spawn(701604, 772.961f, 410.834f, 241.014f, (byte) 20);
			spawn(701605, 798.383f, 401.605f, 241.015f, (byte) 30);
			spawn(701606, 709.602f, 313.531f, 254.216f, (byte) 40);
			spawn(701607, 726.757f, 327.932f, 254.216f, (byte) 50);
		} else {
			spawn(701610, 617.501f, 248.196f, 235.740f, (byte) 60); // Cannons
			spawn(701611, 612.806f, 275.206f, 235.740f, (byte) 67);
			spawn(701612, 616.159f, 313.939f, 235.740f, (byte) 53);
			spawn(701613, 625.603f, 339.608f, 235.734f, (byte) 53);
			spawn(701614, 650.914f, 372.932f, 238.607f, (byte) 53);
			spawn(701615, 677.853f, 396.203f, 238.632f, (byte) 40);
			spawn(701616, 710.145f, 410.661f, 241.014f, (byte) 30);
			spawn(701617, 736.803f, 414.121f, 241.017f, (byte) 40);
			spawn(701618, 772.961f, 410.834f, 241.014f, (byte) 20);
			spawn(701619, 798.383f, 401.605f, 241.015f, (byte) 30);
			spawn(701620, 709.602f, 313.531f, 254.216f, (byte) 40);
			spawn(701621, 726.757f, 327.932f, 254.216f, (byte) 50);
		}
	}

	@Override
	public void onInstanceCreate() {
		instanceReward = new NormalScore();
		instanceReward.setInstanceProgressionType(InstanceProgressionType.PREPARING);
		instanceReward.setPoints(20000);
		startTime = System.currentTimeMillis();
		instanceTimerTask = ThreadPoolManager.getInstance().schedule(this::onStart, START_DELAY);
	}

	private void onStart() {
		startTime = System.currentTimeMillis();
		instanceReward.setInstanceProgressionType(InstanceProgressionType.START_PROGRESS);
		sendPacket();
		instance.forEachDoor(door -> door.setOpen(true));
		assaultWaveTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(this::spawnAssaultWave, 60000, 60000);
		instanceTimerTask = ThreadPoolManager.getInstance().schedule(this::onTimeOut, 30, TimeUnit.MINUTES);

		sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_MainWave_01());
		spawn(233313, 584.013f, 371.221f, 225.374f, (byte) 110); // Pashid Siege Fighter
		spawn(233313, 588.725f, 377.543f, 225.221f, (byte) 110);
		spawn(233313, 655.190f, 454.515f, 225.936f, (byte) 110);
		spawn(233313, 659.293f, 461.406f, 225.449f, (byte) 110);
		spawn(233313, 795.178f, 462.909f, 225.853f, (byte) 118);
		spawn(233313, 804.449f, 461.860f, 227.897f, (byte) 58);
		spawn(233315, 572.093f, 377.641f, 227.147f, (byte) 110); // Pashid Elite Siege Gunner
		spawn(233315, 580.561f, 387.814f, 225.668f, (byte) 110);
		spawn(233315, 646.597f, 458.471f, 225.575f, (byte) 117);
		spawn(233315, 652.617f, 467.432f, 225.265f, (byte) 113);
		spawn(233315, 794.179f, 474.019f, 225.361f, (byte) 88);
		spawn(233315, 806.574f, 473.837f, 227.837f, (byte) 98);
		spawn(231168, 652.191f, 461.264f, 225.095f, (byte) 110); // Pashid Scout Commander Azute
		spawn(231169, 581.777f, 377.664f, 225.528f, (byte) 110); // Pashid Scout Commander Zest
		spawn(231170, 800.515f, 469.416f, 228.586f, (byte) 88); // Pashid Scout Commander Sartas
		spawn(831334, 569.772f, 162.763f, 220.048f, (byte) 53, 271); // Outer Water Gate
		spawnWithDelay(231167, 735.282f, 295.307f, 233.752f, (byte) 115, 9000); // Pashid Assault Pods
		spawnWithDelay(231162, 747.273f, 300.182f, 233.752f, (byte) 97, 6000);
	}

	private void spawnAssaultWave() {
		switch (++waveCount) {
			case 1, 5, 13, 17, 25 -> spawnAssaultPodWave();
			case 2 -> spawnEasternWaveOne();
			case 4 -> {
				spawnEasternWaveOne();
				spawnNorthernWaveOne();
			}
			case 6 -> {
				spawnEasternWaveOne();
				spawnNorthernWaveOne();
				spawnEasternWaveTwo();
				spawnCanalWave();
				spawnSiegeTowerWave();
			}
			case 8 -> {
				spawnEasternWaveOne();
				spawnNorthernWaveOne();
				spawnEasternWaveTwo();
				spawnWesternWave();
			}
			case 9, 21 -> {
				spawnAssaultPodWave();
				spawnSiegeTowerWave();
			}
			case 10 -> {
				spawnEasternWaveOne();
				spawnNorthernWaveOne();
				spawnEasternWaveTwo();
				spawnWesternWave();
				spawnNorthernWaveTwo();
				spawnCanalWave();
				if (assaultPower.get() >= 8) {
					spawnWithWalker(231142, 795.579f, 478.629f, 225.086f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S38"); // Pashid Siege Volatile
					spawnWithWalker(231142, 798.579f, 479.629f, 225.221f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S38");
					spawnWithWalker(231142, 792.579f, 479.629f, 224.934f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S38");
					spawnWithWalker(231142, 801.579f, 481.629f, 225.845f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S38");
					spawnWithWalker(231142, 789.579f, 481.629f, 224.622f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S38");
				}
			}
			case 12 -> {
				spawnEasternWaveOne();
				spawnNorthernWaveOne();
				spawnEasternWaveTwo();
				spawnWesternWave();
				spawnNorthernWaveTwo();
				spawnEasternWaveThree();
				spawnSiegeTowerWave();
			}
			case 14 -> {
				spawnEasternWaveOne();
				spawnNorthernWaveOne();
				spawnEasternWaveTwo();
				spawnWesternWave();
				spawnNorthernWaveTwo();
				spawnEasternWaveThree();
				spawnCanalWave();
			}
			case 15 -> {
				spawnCanalWave();
				spawnSiegeTowerWave();
				if (assaultPower.get() >= 7 && getNpc(831333) != null)
					spawnWithWalker(231150, 798.563f, 477.952f, 225.231f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S73"); // Pashid Siege Ram
			}
			case 16 -> {
				if (assaultPower.get() >= 11)
					spawnEasternWaveOne();
				spawnNorthernWaveOne();
				spawnEasternWaveTwo();
				if (assaultPower.get() >= 12)
					spawnWesternWave();
				spawnNorthernWaveTwo();
				spawnEasternWaveThree();
			}
			case 18 -> {
				spawnEasternWaveOne();
				spawnNorthernWaveOne();
				if (assaultPower.get() >= 10)
					spawnEasternWaveTwo();
				spawnWesternWave();
				if (assaultPower.get() >= 9)
					spawnNorthernWaveTwo();
				spawnEasternWaveThree();
				spawnCanalWave();
				spawnSouthernWave();
				spawnSiegeTowerWave();
			}
			case 20 -> {
				spawnEasternWaveOne();
				spawnNorthernWaveOne();
				spawnEasternWaveTwo();
				spawnWesternWave();
				spawnNorthernWaveTwo();
				spawnEasternWaveThree();
			}
			case 22 -> {
				spawnEasternWaveOne();
				spawnNorthernWaveOne();
				spawnEasternWaveTwo();
				spawnWesternWave();
				spawnNorthernWaveTwo();
				spawnEasternWaveThree();
				spawnCanalWave();
				spawnSouthernWave();
			}
			case 24 -> {
				if (assaultPower.get() >= 5)
					spawnEasternWaveOne();
				spawnNorthernWaveOne();
				spawnEasternWaveTwo();
				if (assaultPower.get() >= 6)
					spawnWesternWave();
				spawnNorthernWaveTwo();
				spawnEasternWaveThree();
				spawnSiegeTowerWave();
			}
			case 26 -> {
				spawnEasternWaveOne();
				if (assaultPower.get() >= 3)
					spawnNorthernWaveOne();
				spawnEasternWaveTwo();
				spawnWesternWave();
				spawnNorthernWaveTwo();
				if (assaultPower.get() >= 4)
					spawnEasternWaveThree();
				spawnCanalWave();
				spawnSouthernWave();
			}
			case 28 -> {
				spawnEasternWaveOne();
				spawnNorthernWaveOne();
				if (assaultPower.get() >= 1)
					spawnEasternWaveTwo();
				spawnWesternWave();
				if (assaultPower.get() >= 2)
					spawnNorthernWaveTwo();
				spawnEasternWaveThree();
			}
		}
	}

	private void spawnEasternWaveOne() {
		spawnWithWalker(231113, 652.071f, 475.738f, 226.125f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S46"); // East 1
		spawnWithWalker(231110, 655.071f, 478.738f, 226.125f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S46");
		spawnWithWalker(231110, 649.071f, 478.738f, 226.125f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S46");
	}

	private void spawnEasternWaveTwo() {
		spawnWithWalker(231114, 671.857f, 480.417f, 225.195f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S32"); // East 2
		spawnWithWalker(231112, 674.857f, 483.417f, 225.337f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S32");
		spawnWithWalker(231112, 668.857f, 483.417f, 226.457f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S32");
	}

	private void spawnEasternWaveThree() {
		spawnWithWalker(231113, 632.525f, 451.311f, 223.422f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S34"); // East 3
		spawnWithWalker(231111, 635.525f, 454.311f, 223.193f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S34");
		spawnWithWalker(231111, 629.525f, 454.311f, 220.445f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S34");
	}

	private void spawnNorthernWaveOne() {
		spawnWithWalker(231113, 598.026f, 411.715f, 223.784f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S71"); // North 1
		spawnWithWalker(231110, 601.026f, 414.715f, 223.519f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S71");
		spawnWithWalker(231110, 595.026f, 414.715f, 223.552f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S71");
	}

	private void spawnNorthernWaveTwo() {
		spawnWithWalker(231113, 569.237f, 387.007f, 227.533f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S36"); // North 2
		spawnWithWalker(231111, 572.237f, 390.007f, 227.905f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S36");
		spawnWithWalker(231111, 566.237f, 390.007f, 228.194f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S36");
	}

	private void spawnWesternWave() {
		spawnWithWalker(231114, 587.952f, 239.621f, 229.530f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S44"); // West
		spawnWithWalker(231112, 590.952f, 242.621f, 229.152f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S44");
		spawnWithWalker(231112, 584.952f, 242.621f, 229.822f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S44");
	}

	private void spawnSouthernWave() {
		if (getNpc(831333) == null) {
			spawnWithWalker(231113, 794.134f, 483.021f, 224.756f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S39"); // South Wall
			spawnWithWalker(231113, 796.134f, 481.021f, 225.008f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S39");
			spawnWithWalker(231113, 792.134f, 481.021f, 224.820f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_S39");
		}
	}

	private void spawnCanalWave() {
		if (getNpc(831335) == null) {
			spawnWithWalker(231110, 610.571f, 189.724f, 216.509f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_T1"); // Canal
			spawnWithWalker(231108, 612.571f, 191.724f, 216.589f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_T1");
			spawnWithWalker(231108, 608.571f, 187.724f, 216.574f, (byte) 100, "NPCPathIDLDF5b_TD_Mob_Z1_S2_T1");
		}
	}

	private void spawnAssaultPodWave() {
		if (getNpc(231140) != null) {
			spawnWithWalker(231106, 633.457f, 245.792f, 238.075f, (byte) 33, "NPCPathIDLDF5b_TD_Mob_Z1_S3_POD01");
			spawnWithWalker(231108, 635.457f, 247.792f, 238.075f, (byte) 33, "NPCPathIDLDF5b_TD_Mob_Z1_S3_POD01");
			spawnWithWalker(231108, 631.457f, 247.792f, 238.075f, (byte) 33, "NPCPathIDLDF5b_TD_Mob_Z1_S3_POD01");
		}
		if (getNpc(231156) != null) {
			spawnWithWalker(231106, 642.871f, 343.420f, 238.075f, (byte) 20, "NPCPathIDLDF5b_TD_Z1_S5_POD01");
			spawnWithWalker(231108, 644.871f, 345.420f, 238.075f, (byte) 20, "NPCPathIDLDF5b_TD_Z1_S5_POD01");
			spawnWithWalker(231108, 640.871f, 345.420f, 238.075f, (byte) 20, "NPCPathIDLDF5b_TD_Z1_S5_POD01");
		}
		if (getNpc(231157) != null) {
			spawnWithWalker(231106, 776.242f, 326.041f, 253.434f, (byte) 40, "NPCPathIDLDF5b_TD_Z4_POD02");
			spawnWithWalker(231108, 778.242f, 328.041f, 253.434f, (byte) 40, "NPCPathIDLDF5b_TD_Z4_POD02");
			spawnWithWalker(231108, 774.242f, 328.041f, 253.434f, (byte) 40, "NPCPathIDLDF5b_TD_Z4_POD02");
		}
		if (getNpc(231158) != null) {
			spawnWithWalker(231106, 765.481f, 393.614f, 243.354f, (byte) 40, "NPCPathIDLDF5b_TD_Mob_Z1_S3_POD3");
			spawnWithWalker(231108, 767.481f, 395.614f, 243.354f, (byte) 40, "NPCPathIDLDF5b_TD_Mob_Z1_S3_POD3");
			spawnWithWalker(231108, 763.481f, 395.614f, 243.354f, (byte) 40, "NPCPathIDLDF5b_TD_Mob_Z1_S3_POD3");
		}
		if (getNpc(231141) != null) {
			spawnWithWalker(231105, 667.631f, 297.565f, 225.700f, (byte) 20, "NPCPathIDLDF5b_TD_Mob_Z1_S3_POD2");
			spawnWithWalker(231107, 669.631f, 299.565f, 225.700f, (byte) 20, "NPCPathIDLDF5b_TD_Mob_Z1_S3_POD2");
			spawnWithWalker(231107, 665.631f, 299.565f, 225.700f, (byte) 20, "NPCPathIDLDF5b_TD_Mob_Z1_S3_POD2");
		}
		if (getNpc(231163) != null) {
			spawnWithWalker(231105, 731.089f, 365.461f, 230.941f, (byte) 7, "NPCPathIDLDF5b_TD_Z1_S5_POD02");
			spawnWithWalker(231107, 731.089f, 365.461f, 230.941f, (byte) 7, "NPCPathIDLDF5b_TD_Z1_S5_POD02");
			spawnWithWalker(231107, 731.089f, 365.461f, 230.941f, (byte) 7, "NPCPathIDLDF5b_TD_Z1_S5_POD02");
		}
		if (getNpc(231159) != null) {
			spawnWithWalker(231106, 699.760f, 302.938f, 249.303f, (byte) 100, "NPCPathIDLDF5b_TD_Z4_POD01");
			spawnWithWalker(231108, 701.760f, 304.938f, 249.303f, (byte) 100, "NPCPathIDLDF5b_TD_Z4_POD01");
			spawnWithWalker(231108, 697.760f, 304.938f, 249.303f, (byte) 100, "NPCPathIDLDF5b_TD_Z4_POD01");
		}
		if (getNpc(231162) != null) { // Could be a bug on retail, but anyway
			spawnWithWalker(231106, 724.927f, 359.346f, 230.941f, (byte) 0, "NPCPathIDLDF5b_TD_Z3_POD02");
			spawnWithWalker(231108, 726.927f, 361.346f, 230.941f, (byte) 0, "NPCPathIDLDF5b_TD_Z3_POD02");
			spawnWithWalker(231108, 722.927f, 361.346f, 230.941f, (byte) 0, "NPCPathIDLDF5b_TD_Z3_POD02");
		}
		if (getNpc(231164) != null) {
			spawnWithWalker(231106, 724.927f, 359.346f, 230.941f, (byte) 0, "NPCPathIDLDF5b_TD_Z3_POD02");
			spawnWithWalker(231108, 726.927f, 361.346f, 230.941f, (byte) 0, "NPCPathIDLDF5b_TD_Z3_POD02");
			spawnWithWalker(231108, 722.927f, 361.346f, 230.941f, (byte) 0, "NPCPathIDLDF5b_TD_Z3_POD02");
		}
		if (getNpc(231165) != null) {
			spawnWithWalker(231106, 724.927f, 359.346f, 230.941f, (byte) 0, "NPCPathIDLDF5b_TD_Z3_POD02");
			spawnWithWalker(231108, 726.927f, 361.346f, 230.941f, (byte) 0, "NPCPathIDLDF5b_TD_Z3_POD02");
			spawnWithWalker(231108, 722.927f, 361.346f, 230.941f, (byte) 0, "NPCPathIDLDF5b_TD_Z3_POD02");
		}
	}

	private void spawnSiegeTowerWave() {
		if (getNpc(230783) != null) {
			spawnWithWalker(231107, 623.235f, 263.392f, 238.484f, (byte) 3, "NPCPathIDLDF5b_TD_Z1_S4_T1");
			spawnWithWalker(231105, 625.235f, 265.392f, 238.484f, (byte) 3, "NPCPathIDLDF5b_TD_Z1_S4_T1");
			spawnWithWalker(231105, 621.235f, 265.392f, 238.484f, (byte) 3, "NPCPathIDLDF5b_TD_Z1_S4_T1");
		}
		if (getNpc(231152) != null) {
			spawnWithWalker(231107, 621.920f, 298.179f, 238.075f, (byte) 113, "NPCPathIDLDF5b_TD_Z1_S4_T2");
			spawnWithWalker(231105, 623.920f, 300.179f, 238.075f, (byte) 113, "NPCPathIDLDF5b_TD_Z1_S4_T2");
			spawnWithWalker(231105, 619.920f, 300.179f, 238.075f, (byte) 113, "NPCPathIDLDF5b_TD_Z1_S4_T2");
		}
		if (getNpc(231153) != null) {
			spawnWithWalker(231107, 644.089f, 351.522f, 239.764f, (byte) 113, "NPCPathIDLDF5b_TD_Z1_S4_T3");
			spawnWithWalker(231105, 646.089f, 353.522f, 241.151f, (byte) 113, "NPCPathIDLDF5b_TD_Z1_S4_T3");
			spawnWithWalker(231105, 642.089f, 353.522f, 239.809f, (byte) 113, "NPCPathIDLDF5b_TD_Z1_S4_T3");
		}
		if (getNpc(231154) != null) {
			spawnWithWalker(231107, 664.091f, 394.303f, 240.223f, (byte) 83, "NPCPathIDLDF5b_TD_Z1_S4_T4");
			spawnWithWalker(231105, 666.091f, 396.303f, 240.223f, (byte) 83, "NPCPathIDLDF5b_TD_Z1_S4_T4");
			spawnWithWalker(231105, 662.091f, 396.303f, 240.223f, (byte) 83, "NPCPathIDLDF5b_TD_Z1_S4_T4");
		}
		if (getNpc(231155) != null) {
			spawnWithWalker(231107, 692.867f, 396.708f, 241.594f, (byte) 85, "NPCPathIDLDF5b_TD_Z1_S4_T5");
			spawnWithWalker(231105, 694.867f, 398.708f, 242.018f, (byte) 85, "NPCPathIDLDF5b_TD_Z1_S4_T5");
			spawnWithWalker(231105, 690.867f, 398.708f, 241.594f, (byte) 85, "NPCPathIDLDF5b_TD_Z1_S4_T5");
		}
	}

	private void onTimeOut() {
		sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_MainWave_06());
		endInstance();
	}

	/*
	 * Original points for ranks:
	 * 92,000 = S-Rank
	 * 84,000 = A-Rank
	 * 76,000 = B-Rank
	 * 50,000 = C-Rank
	 * 10,000 = D-Rank
	 */
	private void endInstance() {
		cancelTasks();
		instanceReward.setInstanceProgressionType(InstanceProgressionType.END_PROGRESS);

		int rank = getFinalRank();
		switch (rank) {
			case 1 -> {
				instanceReward.setFinalAp(35000);
				instanceReward.setRewardItem1(186000242); // Ceramium Medal
				instanceReward.setRewardItem1Count(4);
				instanceReward.setRewardItem2(188052596); // Highest Grade Material Support Bundle
				instanceReward.setRewardItem2Count(1);
				instanceReward.setRewardItem3(188052594); // Highest Grade Material Box
				instanceReward.setRewardItem3Count(1);
			}
			case 2 -> {
				instanceReward.setFinalAp(25000);
				instanceReward.setRewardItem1(186000242); // Ceramium Medal
				instanceReward.setRewardItem1Count(2);
				instanceReward.setRewardItem2(188052594); // Highest Grade Material Box
				instanceReward.setRewardItem2Count(1);
				instanceReward.setRewardItem3(188052597); // High Grade Material Support Bundle
				instanceReward.setRewardItem3Count(1);
			}
			case 3 -> { // B-Rank
				instanceReward.setFinalAp(15000);
				instanceReward.setRewardItem1(186000242); // Ceramium Medal
				instanceReward.setRewardItem1Count(1);
				instanceReward.setRewardItem2(188052595); // High Grade Material Box
				instanceReward.setRewardItem2Count(1);
				instanceReward.setRewardItem3(188052598); // Low Grade Material Support Bundle
				instanceReward.setRewardItem3Count(1);
			}
			case 4 -> { // C-Rank
				instanceReward.setFinalAp(11000);
				instanceReward.setRewardItem1(188052598); // Low Grade Material Support Bundle
				instanceReward.setRewardItem1Count(1);
			}
			case 5 -> instanceReward.setFinalAp(7000); // D-Rank
		}
		instanceReward.setInstanceProgressionType(InstanceProgressionType.END_PROGRESS);
		instanceReward.setRank(rank);
		instance.forEachNpc(npc -> npc.getController().delete());
		sendPacket();
		instance.forEachPlayer(this::distributeRewards);
		spawnFinalChest(rank);
		spawn(730871, 766.458f, 263.157f, 233.498f, (byte) 100); // Exit
		log.info("[{}] Instance completed with {} points resulting in {}-Rank. Player(s) in instance: {}",
			DataManager.WORLD_MAPS_DATA.getTemplate(mapId).getName(), instanceReward.getPoints(), getRankNameById(rank),
			instance.getPlayersInside().stream().map(p -> String.format("%s (ID:%d)", p.getName(), p.getObjectId())).collect(Collectors.joining(", ")));
	}

	private int getFinalRank() {
		if (instanceReward.getPoints() >= 90000) { // S-Rank
			return 1;
		} else if (instanceReward.getPoints() >= 82000) { // A-Rank
			return 2;
		} else if (instanceReward.getPoints() >= 60000) { // B-Rank
			return 3;
		} else if (instanceReward.getPoints() >= 30000) { // C-Rank
			return 4;
		} else if (instanceReward.getPoints() >= 5000) { // D-Rank
			return 5;
		} else {
			return 8;
		}
	}

	private void spawnFinalChest(int rank) {
		switch (rank) {
			case 1 -> spawn(701913, 744.167f, 292.860f, 233.702f, (byte) 100); // Biggest in model size
			case 2 -> spawn(701914, 744.167f, 292.860f, 233.702f, (byte) 100);
			case 3 -> spawn(701915, 744.167f, 292.860f, 233.702f, (byte) 100);
			case 4 -> spawn(701916, 744.167f, 292.860f, 233.702f, (byte) 100);
			case 5 -> spawn(701917, 744.167f, 292.860f, 233.702f, (byte) 100); // Smallest in model size
		}
	}

	private void distributeRewards(Player player) {
		AbyssPointsService.addAp(player, instanceReward.getFinalAp());
		if (instanceReward.getRewardItem1() > 0)
			ItemService.addItem(player, instanceReward.getRewardItem1(), instanceReward.getRewardItem1Count(), true);
		if (instanceReward.getRewardItem2() > 0)
			ItemService.addItem(player, instanceReward.getRewardItem2(), instanceReward.getRewardItem2Count(), true);
		if (instanceReward.getRewardItem3() > 0)
			ItemService.addItem(player, instanceReward.getRewardItem3(), instanceReward.getRewardItem3Count(), true);
		if (instanceReward.getRewardItem4() > 0)
			ItemService.addItem(player, instanceReward.getRewardItem4(), instanceReward.getRewardItem4Count(), true);
	}

	@Override
	public void handleUseItemFinish(Player player, Npc npc) {
		if (npc.getNpcId() == 701625 || npc.getNpcId() == 701922) {
			SkillEngine.getInstance().getSkill(npc, 21069, 1, npc).useSkill();
			ThreadPoolManager.getInstance().schedule(() -> npc.getController().delete(), 3000);
			sendMsg(SM_SYSTEM_MESSAGE.STR_MSG_IDLDF5b_TD_AddWave_01(), 3000);
			spawnWithDelay(231160, 707.703f, 259.173f, 253.038f, (byte) 40, 33000); // Assault Pod
		}
	}

	@Override
	public void onEndEffect(Effect effect) {
		if (effect.getEffected()instanceof Player player && !player.isDead() && !player.getLifeStats().isAboutToDie()) {
			switch (effect.getSkillId()) {
				case 21138, 21139 -> { // Cannons respawn if not killed
					Point3D pos = new Point3D(player.getX(), player.getY(), player.getZ());
					Race race = player.getRace();
					spawnTasks.add(ThreadPoolManager.getInstance().schedule(() -> {
						if (instanceReward.getInstanceProgressionType() == InstanceProgressionType.START_PROGRESS)
							spawn(race == Race.ELYOS ? 701596 : 701610, pos.getX(), pos.getY(), pos.getZ(), (byte) 50);
					}, 10, TimeUnit.SECONDS));
				}
			}
		}
	}

	@Override
	public void onInstanceDestroy() {
		cancelTasks();
	}

	@Override
	public boolean onReviveEvent(Player player) {
		PlayerReviveService.revive(player, 100, 100, false, 0);
		player.getGameStats().updateStatsAndSpeedVisually();
		TeleportService.teleportTo(player, instance, 449.581f, 448.846f, 270.747f, (byte) 70);
		return true;
	}

	private void cancelTasks() {
		spawnTasks.forEach(task -> {
			if (task != null && !task.isDone())
				task.cancel(false);
		});
		if (instanceTimerTask != null && !instanceTimerTask.isCancelled())
			instanceTimerTask.cancel(false);
		if (assaultWaveTask != null && !assaultWaveTask.isCancelled())
			assaultWaveTask.cancel(false);
	}

	private void spawnWithDelay(int npcId, float x, float y, float z, byte h, int delay) {
		spawnTasks.add(ThreadPoolManager.getInstance().schedule(() -> spawn(npcId, x, y, z, h), delay));
	}

	private void spawnWithWalker(int npcId, float x, float y, float z, byte h, final String walker) {
		spawn(npcId, x, y, z, h).getSpawn().setWalkerId(walker);
	}

	private void addPoints(Npc npc, int points) {
		if (instanceReward.getInstanceProgressionType() == InstanceProgressionType.START_PROGRESS) {
			instanceReward.addPoints(points);
			PacketSendUtility.broadcastToMap(instance, SM_SYSTEM_MESSAGE.STR_MSG_GET_SCORE(npc.getObjectTemplate().getL10n(), points));
			sendPacket();
		}
	}

	private int getTime() {
		int current = (int) (System.currentTimeMillis() - startTime);
		return instanceReward.getInstanceProgressionType() == InstanceProgressionType.PREPARING ? 180000 - current : Math.max(1800000 - current, 0);
	}

	private void sendPacket() {
		PacketSendUtility.broadcastToMap(instance, new SM_INSTANCE_SCORE(instance.getMapId(), new EternalBastionScoreWriter(instanceReward), getTime()));
	}

	@Override
	public void leaveInstance(Player player) {
		if (instanceReward.getInstanceProgressionType() == InstanceProgressionType.END_PROGRESS)
			TeleportService.moveToInstanceExit(player, mapId, player.getRace());
	}

	private String getRankNameById(int rank) {
		return switch (rank) {
			case 1 -> "S";
			case 2 -> "A";
			case 3 -> "B";
			case 4 -> "C";
			case 5 -> "D";
			default -> "F";
		};
	}

	@Override
	public boolean isBoss(Npc npc) {
		return switch (npc.getNpcId()) {
			case 209516, 209517, 231168, 231169, 231170, 231171, 231172, 231173, 231174, 231175, 231176, 231130 -> true;
			default -> false;
		};
	}
}

📎 첨부파일

댓글 작성 권한이 없습니다.
🏆 포인트 랭킹 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