Expulsion of Evil Spirit raidboss additions.
Contributed by pecanha.
This commit is contained in:
		| @@ -19,11 +19,23 @@ package quests.Q00311_ExpulsionOfEvilSpirits; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| import org.l2jmobius.commons.concurrent.ThreadPool; | ||||
| import org.l2jmobius.commons.util.Rnd; | ||||
| import org.l2jmobius.gameserver.ai.CtrlIntention; | ||||
| import org.l2jmobius.gameserver.data.xml.impl.SkillData; | ||||
| import org.l2jmobius.gameserver.enums.QuestSound; | ||||
| import org.l2jmobius.gameserver.instancemanager.GlobalVariablesManager; | ||||
| import org.l2jmobius.gameserver.instancemanager.ZoneManager; | ||||
| import org.l2jmobius.gameserver.model.actor.Attackable; | ||||
| import org.l2jmobius.gameserver.model.actor.Creature; | ||||
| import org.l2jmobius.gameserver.model.actor.Npc; | ||||
| import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; | ||||
| import org.l2jmobius.gameserver.model.quest.Quest; | ||||
| import org.l2jmobius.gameserver.model.quest.QuestState; | ||||
| import org.l2jmobius.gameserver.model.skills.BuffInfo; | ||||
| import org.l2jmobius.gameserver.model.zone.ZoneType; | ||||
| import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUse; | ||||
| import org.l2jmobius.gameserver.util.Util; | ||||
|  | ||||
| /** | ||||
|  * Expulsion of Evil Spirits (311) | ||||
| @@ -31,17 +43,14 @@ import org.l2jmobius.gameserver.model.quest.QuestState; | ||||
|  */ | ||||
| public class Q00311_ExpulsionOfEvilSpirits extends Quest | ||||
| { | ||||
| 	// NPC | ||||
| 	// NPCs | ||||
| 	private static final int CHAIREN = 32655; | ||||
| 	private final static int ALTAR = 18811; | ||||
| 	private final static int VARANGKA = 18808; | ||||
| 	// Items | ||||
| 	private static final int PROTECTION_SOULS_PENDANT = 14848; | ||||
| 	private static final int SOUL_CORE_CONTAINING_EVIL_SPIRIT = 14881; | ||||
| 	private static final int RAGNA_ORCS_AMULET = 14882; | ||||
| 	// Misc | ||||
| 	private static final int MIN_LEVEL = 80; | ||||
| 	private static final int SOUL_CORE_COUNT = 10; | ||||
| 	private static final int RAGNA_ORCS_KILLS_COUNT = 100; | ||||
| 	private static final int RAGNA_ORCS_AMULET_COUNT = 10; | ||||
| 	// Monsters | ||||
| 	private static final Map<Integer, Double> MONSTERS = new HashMap<>(); | ||||
| 	static | ||||
| @@ -57,7 +66,21 @@ public class Q00311_ExpulsionOfEvilSpirits extends Quest | ||||
| 		MONSTERS.put(22699, 0.752); // Ragna Orc Sniper | ||||
| 		MONSTERS.put(22701, 0.716); // Varangka's Dre Vanul | ||||
| 		MONSTERS.put(22702, 0.662); // Varangka's Destroyer | ||||
| 		MONSTERS.put(18808, 0.7); | ||||
| 		MONSTERS.put(18809, 0.694); | ||||
| 		MONSTERS.put(18810, 0.694); | ||||
| 	} | ||||
| 	// Misc | ||||
| 	private static final int MIN_LEVEL = 80; | ||||
| 	private static final int SOUL_CORE_COUNT = 10; | ||||
| 	private static final int RAGNA_ORCS_KILLS_COUNT = 100; | ||||
| 	private static final int RAGNA_ORCS_AMULET_COUNT = 10; | ||||
| 	private static final ZoneType ALTARZONE = ZoneManager.getInstance().getZoneById(20201); | ||||
| 	private static long respawnTime = 0; | ||||
| 	private static Npc _altar; | ||||
| 	private static Npc _varangka; | ||||
| 	private static Npc _varangkaMinion1; | ||||
| 	private static Npc _varangkaMinion2; | ||||
| 	 | ||||
| 	public Q00311_ExpulsionOfEvilSpirits() | ||||
| 	{ | ||||
| @@ -66,11 +89,68 @@ public class Q00311_ExpulsionOfEvilSpirits extends Quest | ||||
| 		addTalkId(CHAIREN); | ||||
| 		addKillId(MONSTERS.keySet()); | ||||
| 		registerQuestItems(SOUL_CORE_CONTAINING_EVIL_SPIRIT, RAGNA_ORCS_AMULET); | ||||
| 		addEnterZoneId(ALTARZONE.getId()); | ||||
| 		addAttackId(ALTAR); | ||||
| 		 | ||||
| 		try | ||||
| 		{ | ||||
| 			respawnTime = GlobalVariablesManager.getInstance().getLong("VarangkaRespawn", 0); | ||||
| 		} | ||||
| 		catch (Exception e) | ||||
| 		{ | ||||
| 			 | ||||
| 		} | ||||
| 		GlobalVariablesManager.getInstance().set("VarangkaRespawn", respawnTime); | ||||
| 		if ((respawnTime == 0) || ((respawnTime - System.currentTimeMillis()) < 0)) | ||||
| 		{ | ||||
| 			startQuestTimer("altarSpawn", 5000, null, null); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			startQuestTimer("altarSpawn", respawnTime - System.currentTimeMillis(), null, null); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAdvEvent(String event, Npc npc, PlayerInstance player) | ||||
| 	{ | ||||
| 		if (event.equalsIgnoreCase("altarSpawn")) | ||||
| 		{ | ||||
| 			if (!checkIfSpawned(ALTAR)) | ||||
| 			{ | ||||
| 				_altar = addSpawn(ALTAR, 74120, -101920, -960, 32760, false, 0); | ||||
| 				_altar.setInvul(true); | ||||
| 				GlobalVariablesManager.getInstance().set("VarangkaRespawn", 0); | ||||
| 				if (Util.checkIfInRange(1200, npc, player, true)) | ||||
| 				{ | ||||
| 					ThreadPool.schedule(new zoneCheck(player), 1000); | ||||
| 				} | ||||
| 			} | ||||
| 			return null; | ||||
| 		} | ||||
| 		else if (event.equalsIgnoreCase("minion1") && checkIfSpawned(VARANGKA)) | ||||
| 		{ | ||||
| 			if (!checkIfSpawned(VARANGKA + 1) && checkIfSpawned(VARANGKA)) | ||||
| 			{ | ||||
| 				_varangkaMinion1 = addSpawn(VARANGKA + 1, player.getX() + Rnd.get(10, 50), player.getY() + Rnd.get(10, 50), -967, 0, false, 0); | ||||
| 				_varangkaMinion1.setRunning(); | ||||
| 				((Attackable) _varangkaMinion1).addDamageHate(_varangka.getTarget().getActingPlayer(), 1, 99999); | ||||
| 				_varangkaMinion1.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, _varangka.getTarget().getActingPlayer()); | ||||
| 			} | ||||
| 			return null; | ||||
| 		} | ||||
| 		else if (event.equalsIgnoreCase("minion2")) | ||||
| 		{ | ||||
| 			if (!checkIfSpawned(VARANGKA + 2) && checkIfSpawned(VARANGKA)) | ||||
| 			{ | ||||
| 				_varangkaMinion2 = addSpawn(VARANGKA + 2, player.getX() + Rnd.get(10, 50), player.getY() + Rnd.get(10, 50), -967, 0, false, 0); | ||||
| 				_varangkaMinion2.setRunning(); | ||||
| 				((Attackable) _varangkaMinion2).addDamageHate(_varangka.getTarget().getActingPlayer(), 1, 99999); | ||||
| 				_varangkaMinion2.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, _varangka.getTarget().getActingPlayer()); | ||||
| 			} | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		final QuestState qs = getQuestState(player, false); | ||||
| 		if (qs == null) | ||||
| 		{ | ||||
| @@ -134,19 +214,63 @@ public class Q00311_ExpulsionOfEvilSpirits extends Quest | ||||
| 		final QuestState qs = getRandomPartyMemberState(killer, 1, 2, npc); | ||||
| 		if (qs != null) | ||||
| 		{ | ||||
| 			final PlayerInstance member = qs.getPlayer(); | ||||
| 			if (npc.getId() == VARANGKA) | ||||
| 			{ | ||||
| 				if ((qs.getInt("cond") != 1)) | ||||
| 				{ | ||||
| 					return null; | ||||
| 				} | ||||
| 				_altar.doDie(killer); | ||||
| 				_altar = null; | ||||
| 				_varangka = null; | ||||
| 				if (checkIfSpawned(VARANGKA + 1)) | ||||
| 				{ | ||||
| 					_varangkaMinion1.doDie(killer); | ||||
| 				} | ||||
| 				if (checkIfSpawned(VARANGKA + 2)) | ||||
| 				{ | ||||
| 					_varangkaMinion2.doDie(killer); | ||||
| 				} | ||||
| 				cancelQuestTimers("minion1"); | ||||
| 				cancelQuestTimers("minion2"); | ||||
| 				_varangkaMinion1 = null; | ||||
| 				_varangkaMinion2 = null; | ||||
| 				final long respawn = Rnd.get(14400000, 28800000); | ||||
| 				GlobalVariablesManager.getInstance().set("VarangkaRespawn", System.currentTimeMillis() + respawn); | ||||
| 				startQuestTimer("altarSpawn", respawn, null, null); | ||||
| 				takeItems(member, PROTECTION_SOULS_PENDANT, 1); | ||||
| 				return super.onKill(npc, killer, isSummon); | ||||
| 			} | ||||
| 			else if (npc.getId() == (VARANGKA + 1)) | ||||
| 			{ | ||||
| 				_varangkaMinion1 = null; | ||||
| 				startQuestTimer("minion1", Rnd.get(60000, 120000), npc, killer); | ||||
| 				return super.onKill(npc, killer, isSummon); | ||||
| 			} | ||||
| 			else if (npc.getId() == (VARANGKA + 2)) | ||||
| 			{ | ||||
| 				_varangkaMinion2 = null; | ||||
| 				startQuestTimer("minion2", Rnd.get(60000, 120000), npc, killer); | ||||
| 				return super.onKill(npc, killer, isSummon); | ||||
| 			} | ||||
| 			 | ||||
| 			final int count = qs.getMemoStateEx(1) + 1; | ||||
| 			if ((count >= RAGNA_ORCS_KILLS_COUNT) && (getRandom(20) < ((count % 100) + 1))) | ||||
| 			{ | ||||
| 				qs.setMemoStateEx(1, 0); | ||||
| 				giveItems(killer, SOUL_CORE_CONTAINING_EVIL_SPIRIT, 1); | ||||
| 				playSound(killer, QuestSound.ITEMSOUND_QUEST_ITEMGET); | ||||
| 				giveItems(member, SOUL_CORE_CONTAINING_EVIL_SPIRIT, 1); | ||||
| 				playSound(member, QuestSound.ITEMSOUND_QUEST_ITEMGET); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				qs.setMemoStateEx(1, count); | ||||
| 			} | ||||
| 			 | ||||
| 			giveItemRandomly(killer, npc, RAGNA_ORCS_AMULET, 1, 0, MONSTERS.get(npc.getId()), true); | ||||
| 			if (MONSTERS.get(npc.getId()) < Rnd.get(1d)) | ||||
| 			{ | ||||
| 				giveItems(member, RAGNA_ORCS_AMULET, 1); | ||||
| 			} | ||||
| 		} | ||||
| 		return super.onKill(npc, killer, isSummon); | ||||
| 	} | ||||
| @@ -166,4 +290,112 @@ public class Q00311_ExpulsionOfEvilSpirits extends Quest | ||||
| 		} | ||||
| 		return htmltext; | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAttack(Npc npc, PlayerInstance player, int damage, boolean isPet) | ||||
| 	{ | ||||
| 		QuestState qs = player.getQuestState(Q00311_ExpulsionOfEvilSpirits.class.getSimpleName()); | ||||
| 		if (qs == null) | ||||
| 		{ | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		if (hasQuestItems(player, PROTECTION_SOULS_PENDANT) && (Rnd.get(100) < 20)) | ||||
| 		{ | ||||
| 			if ((_varangka == null) && !checkIfSpawned(VARANGKA)) | ||||
| 			{ | ||||
| 				_varangka = addSpawn(VARANGKA, 74914, -101922, -967, 0, false, 0); | ||||
| 				if ((_varangkaMinion1 == null) && !checkIfSpawned(VARANGKA + 1)) | ||||
| 				{ | ||||
| 					_varangkaMinion1 = addSpawn(VARANGKA + 1, 74914 + Rnd.get(10, 50), -101922 + Rnd.get(10, 50), -967, 0, false, 0); | ||||
| 				} | ||||
| 				if ((_varangkaMinion2 == null) && !checkIfSpawned(VARANGKA + 2)) | ||||
| 				{ | ||||
| 					_varangkaMinion2 = addSpawn(VARANGKA + 2, 74914 + Rnd.get(10, 50), -101922 + Rnd.get(10, 50), -967, 0, false, 0); | ||||
| 				} | ||||
| 				 | ||||
| 				for (Creature creature : ALTARZONE.getCharactersInside()) | ||||
| 				{ | ||||
| 					if ((creature instanceof Attackable) && (creature.getId() >= VARANGKA) && (creature.getId() <= (VARANGKA + 2))) | ||||
| 					{ | ||||
| 						creature.setRunning(); | ||||
| 						((Attackable) creature).addDamageHate(player, 1, 99999); | ||||
| 						creature.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		else if (!hasQuestItems(player, PROTECTION_SOULS_PENDANT)) | ||||
| 		{ | ||||
| 			ThreadPool.schedule(new zoneCheck(player), 1000); | ||||
| 		} | ||||
| 		return super.onAttack(npc, player, damage, isPet); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onEnterZone(Creature creature, ZoneType zone) | ||||
| 	{ | ||||
| 		if (creature.isPlayer()) | ||||
| 		{ | ||||
| 			ThreadPool.schedule(new zoneCheck(creature.getActingPlayer()), 1000); | ||||
| 		} | ||||
| 		return super.onEnterZone(creature, zone); | ||||
| 	} | ||||
| 	 | ||||
| 	private class zoneCheck implements Runnable | ||||
| 	{ | ||||
| 		private final static int DEBUFF_SKILL_ID = 6148; | ||||
| 		private final static int DEBUFF_SKILL_LEVEL = 1; | ||||
| 		 | ||||
| 		private final PlayerInstance _player; | ||||
| 		 | ||||
| 		protected zoneCheck(PlayerInstance player) | ||||
| 		{ | ||||
| 			_player = player; | ||||
| 		} | ||||
| 		 | ||||
| 		@Override | ||||
| 		public void run() | ||||
| 		{ | ||||
| 			if ((_altar != null) && ALTARZONE.isCharacterInZone(_player)) | ||||
| 			{ | ||||
| 				final QuestState qs = _player.getQuestState(Q00311_ExpulsionOfEvilSpirits.class.getSimpleName()); | ||||
| 				if (qs == null) | ||||
| 				{ | ||||
| 					castDebuff(_player); | ||||
| 					ThreadPool.schedule(new zoneCheck(_player), 3000); | ||||
| 				} | ||||
| 				else if (!hasQuestItems(_player, PROTECTION_SOULS_PENDANT)) | ||||
| 				{ | ||||
| 					castDebuff(_player); | ||||
| 					ThreadPool.schedule(new zoneCheck(_player), 3000); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		private void castDebuff(PlayerInstance player) | ||||
| 		{ | ||||
| 			for (BuffInfo info : player.getEffectList().getDebuffs()) | ||||
| 			{ | ||||
| 				if (info.getSkill().getId() == DEBUFF_SKILL_ID) | ||||
| 				{ | ||||
| 					info.getEffected().getEffectList().stopSkillEffects(true, DEBUFF_SKILL_ID); | ||||
| 				} | ||||
| 			} | ||||
| 			_altar.broadcastPacket(new MagicSkillUse(_altar, player, DEBUFF_SKILL_ID, DEBUFF_SKILL_LEVEL, 1000, 0)); | ||||
| 			SkillData.getInstance().getSkill(DEBUFF_SKILL_ID, 1).applyEffects(_altar, player); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	private boolean checkIfSpawned(int npcId) | ||||
| 	{ | ||||
| 		for (Creature creature : ALTARZONE.getCharactersInside()) | ||||
| 		{ | ||||
| 			if (creature.getId() == npcId) | ||||
| 			{ | ||||
| 				return true; | ||||
| 			} | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -307,4 +307,8 @@ | ||||
| 		<node X="109830" Y="-39550" /> | ||||
| 		<node X="110457" Y="-39540" /> | ||||
| 	</zone> | ||||
| 	<zone name="Vangara" id="20201" type="ScriptZone" shape="Cuboid" minZ="-7660" maxZ="7340"> | ||||
| 		<node X="73241" Y="-102671" /> | ||||
| 		<node X="75229" Y="-101174" /> | ||||
| 	</zone> | ||||
| </list> | ||||
		Reference in New Issue
	
	Block a user
	 MobiusDevelopment
					MobiusDevelopment