Re-addition of Anakim and Lilith AIs.
Contributed by CostyKiller.
This commit is contained in:
		
							
								
								
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31101-01.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31101-01.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| A human-like voice comes from a glowing blue orb:<br> | ||||
| Someone went in already, and Anakim has disappeared soon after. There is no point in entering right now. | ||||
| </body></html> | ||||
							
								
								
									
										3
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31101-02.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31101-02.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| (A command channel needs at least %min% members to challenge Anakim.) | ||||
| </body></html> | ||||
							
								
								
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31101-03.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31101-03.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br> | ||||
| (The players who belong to an association can only enter through the Association Leader.) | ||||
| </body></html> | ||||
							
								
								
									
										3
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31101-04.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31101-04.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| (A command channel members level must be %minLevel% to challenge Anakim.) | ||||
| </body></html> | ||||
							
								
								
									
										7
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31101.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31101.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| A Human voice seems to emanate from a shining, blue globe:<br> | ||||
| Behold the gateway to the Forbidden Sacred Area! My job is to guard it, and you cannot pass without my permission.<br> | ||||
| <Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Anakim">"I want to teleport."</Button> | ||||
| <Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest OracleTeleport">Enter the Dimensional Rift</Button> | ||||
| <Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button> | ||||
| </body></html> | ||||
							
								
								
									
										5
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31109.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31109.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| <html><body>Gatekeeper Spirit:<br> | ||||
| Behold, the sphere speaks...<br> | ||||
| You must leave this place!<br> | ||||
| <Button ALIGN=LEFT ICON="TELEPORT" action="bypass -h Quest Anakim exist">"Okay. I will teleport."</Button> | ||||
| </body></html> | ||||
							
								
								
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31111.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/31111.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br | ||||
| >A human-like voice comes from a glowing blue orb:<br> | ||||
| <Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest Anakim">"I kinda want to teleport inside."</Button> | ||||
| </body></html> | ||||
							
								
								
									
										369
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/Anakim.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										369
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/Anakim.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,369 @@ | ||||
| /* | ||||
|  * This file is part of the L2J Mobius project. | ||||
|  *  | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  *  | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| package ai.bosses.Anakim; | ||||
|  | ||||
| import java.util.Calendar; | ||||
| import java.util.List; | ||||
|  | ||||
| import org.l2jmobius.Config; | ||||
| import org.l2jmobius.commons.util.CommonUtil; | ||||
| import org.l2jmobius.gameserver.ai.CtrlIntention; | ||||
| import org.l2jmobius.gameserver.enums.TeleportWhereType; | ||||
| import org.l2jmobius.gameserver.instancemanager.GrandBossManager; | ||||
| import org.l2jmobius.gameserver.instancemanager.MapRegionManager; | ||||
| import org.l2jmobius.gameserver.instancemanager.ZoneManager; | ||||
| import org.l2jmobius.gameserver.model.Location; | ||||
| import org.l2jmobius.gameserver.model.Party; | ||||
| import org.l2jmobius.gameserver.model.Spawn; | ||||
| import org.l2jmobius.gameserver.model.StatSet; | ||||
| import org.l2jmobius.gameserver.model.WorldObject; | ||||
| 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.Player; | ||||
| import org.l2jmobius.gameserver.model.actor.instance.GrandBoss; | ||||
| import org.l2jmobius.gameserver.model.quest.QuestTimer; | ||||
| import org.l2jmobius.gameserver.model.skill.AbnormalType; | ||||
| import org.l2jmobius.gameserver.model.skill.Skill; | ||||
| import org.l2jmobius.gameserver.model.zone.ZoneType; | ||||
| import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; | ||||
|  | ||||
| import ai.AbstractNpcAI; | ||||
|  | ||||
| /** | ||||
|  * Anakim AI<br> | ||||
|  * @author LasTravel<br> | ||||
|  * @URL http://boards.lineage2.com/showpost.php?p=3386784&postcount=6<br> | ||||
|  * @video http://www.youtube.com/watch?v=LecymFTJQzQ | ||||
|  */ | ||||
| public class Anakim extends AbstractNpcAI | ||||
| { | ||||
| 	// Status | ||||
| 	private static final int ALIVE = 0; | ||||
| 	private static final int FIGHTING = 1; | ||||
| 	private static final int DEAD = 2; | ||||
| 	// NPCs | ||||
| 	private static final int ANAKIM = 29348; | ||||
| 	private static final int EXIST_CUBIC = 31109; | ||||
| 	private static final int ANAKIM_CUBIC = 31111; | ||||
| 	//@formatter:off | ||||
|     private static final int[] ANAKIM_MINIONS = {29349, 29350, 29351}; | ||||
|     //@formatter:on	 | ||||
| 	private static final int[] ALL_MOBS = | ||||
| 	{ | ||||
| 		ANAKIM, | ||||
| 		ANAKIM_MINIONS[0], | ||||
| 		ANAKIM_MINIONS[1], | ||||
| 		ANAKIM_MINIONS[2], | ||||
| 	}; | ||||
| 	// Misc | ||||
| 	private static final Location ENTER_ANAKIM_LOC = new Location(184569, -12134, -5499); | ||||
| 	private static final ZoneType BOSS_ZONE = ZoneManager.getInstance().getZoneById(12003); | ||||
| 	// Vars | ||||
| 	private static long _lastAction; | ||||
| 	private static Npc _anakimBoss; | ||||
| 	private static GrandBoss _anakimTemp; | ||||
| 	 | ||||
| 	public Anakim() | ||||
| 	{ | ||||
| 		addTalkId(EXIST_CUBIC, ANAKIM_CUBIC); | ||||
| 		addStartNpc(EXIST_CUBIC, ANAKIM_CUBIC); | ||||
| 		addFirstTalkId(EXIST_CUBIC, ANAKIM_CUBIC); | ||||
| 		addAttackId(ALL_MOBS); | ||||
| 		addKillId(ALL_MOBS); | ||||
| 		addSkillSeeId(ALL_MOBS); | ||||
| 		 | ||||
| 		// Unlock | ||||
| 		final StatSet info = GrandBossManager.getInstance().getStatSet(ANAKIM); | ||||
| 		final int status = GrandBossManager.getInstance().getStatus(ANAKIM); | ||||
| 		if (status == DEAD) | ||||
| 		{ | ||||
| 			final long time = info.getLong("respawn_time") - System.currentTimeMillis(); | ||||
| 			if (time > 0) | ||||
| 			{ | ||||
| 				startQuestTimer("unlock_anakim", time, null, null); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				_anakimTemp = (GrandBoss) addSpawn(ANAKIM, -126920, -234182, -15563, 0, false, 0); | ||||
| 				GrandBossManager.getInstance().addBoss(_anakimTemp); | ||||
| 				GrandBossManager.getInstance().setStatus(ANAKIM, ALIVE); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			_anakimTemp = (GrandBoss) addSpawn(ANAKIM, -126920, -234182, -15563, 0, false, 0); | ||||
| 			GrandBossManager.getInstance().addBoss(_anakimTemp); | ||||
| 			GrandBossManager.getInstance().setStatus(ANAKIM, ALIVE); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAdvEvent(String event, Npc npc, Player player) | ||||
| 	{ | ||||
| 		switch (event) | ||||
| 		{ | ||||
| 			case "unlock_anakim": | ||||
| 			{ | ||||
| 				_anakimTemp = (GrandBoss) addSpawn(ANAKIM, -126920, -234182, -15563, 0, false, 0); | ||||
| 				GrandBossManager.getInstance().addBoss(_anakimTemp); | ||||
| 				GrandBossManager.getInstance().setStatus(ANAKIM, ALIVE); | ||||
| 				break; | ||||
| 			} | ||||
| 			case "check_activity_task": | ||||
| 			{ | ||||
| 				if ((_lastAction + 900000) < System.currentTimeMillis()) | ||||
| 				{ | ||||
| 					GrandBossManager.getInstance().setStatus(ANAKIM, ALIVE); | ||||
| 					for (Creature creature : BOSS_ZONE.getCharactersInside()) | ||||
| 					{ | ||||
| 						if (creature != null) | ||||
| 						{ | ||||
| 							if (creature.isNpc()) | ||||
| 							{ | ||||
| 								creature.deleteMe(); | ||||
| 							} | ||||
| 							else if (creature.isPlayer()) | ||||
| 							{ | ||||
| 								creature.teleToLocation(MapRegionManager.getInstance().getTeleToLocation(creature, TeleportWhereType.TOWN)); | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 					startQuestTimer("end_anakim", 2000, null, null); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					startQuestTimer("check_activity_task", 60000, null, null); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 			case "cancel_timers": | ||||
| 			{ | ||||
| 				QuestTimer activityTimer = getQuestTimer("check_activity_task", null, null); | ||||
| 				if (activityTimer != null) | ||||
| 				{ | ||||
| 					activityTimer.cancel(); | ||||
| 				} | ||||
| 				 | ||||
| 				QuestTimer forceEnd = getQuestTimer("end_anakim", null, null); | ||||
| 				if (forceEnd != null) | ||||
| 				{ | ||||
| 					forceEnd.cancel(); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 			case "end_anakim": | ||||
| 			{ | ||||
| 				notifyEvent("cancel_timers", null, null); | ||||
| 				if (_anakimBoss != null) | ||||
| 				{ | ||||
| 					_anakimBoss.deleteMe(); | ||||
| 				} | ||||
| 				BOSS_ZONE.oustAllPlayers(); | ||||
| 				if (GrandBossManager.getInstance().getStatus(ANAKIM) != DEAD) | ||||
| 				{ | ||||
| 					GrandBossManager.getInstance().setStatus(ANAKIM, ALIVE); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 			case "exist": | ||||
| 			{ | ||||
| 				player.teleToLocation(TeleportWhereType.TOWN); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		return super.onAdvEvent(event, npc, player); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onTalk(Npc npc, Player player) | ||||
| 	{ | ||||
| 		if (npc.getId() == ANAKIM_CUBIC) | ||||
| 		{ | ||||
| 			final int _anakimStatus = GrandBossManager.getInstance().getStatus(ANAKIM); | ||||
| 			if (_anakimStatus > ALIVE) | ||||
| 			{ | ||||
| 				return "31101-01.html"; | ||||
| 			} | ||||
| 			if (!player.isInParty()) | ||||
| 			{ | ||||
| 				final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId()); | ||||
| 				packet.setHtml(getHtm(player, "31101-02.html")); | ||||
| 				packet.replace("%min%", Integer.toString(Config.ANAKIM_MIN_PLAYERS)); | ||||
| 				player.sendPacket(packet); | ||||
| 				return null; | ||||
| 			} | ||||
| 			final Party party = player.getParty(); | ||||
| 			final boolean isInCC = party.isInCommandChannel(); | ||||
| 			final List<Player> members = (isInCC) ? party.getCommandChannel().getMembers() : party.getMembers(); | ||||
| 			final boolean isPartyLeader = (isInCC) ? party.getCommandChannel().isLeader(player) : party.isLeader(player); | ||||
| 			if (!isPartyLeader) | ||||
| 			{ | ||||
| 				return "31101-03.html"; | ||||
| 			} | ||||
| 			 | ||||
| 			if ((members.size() < Config.ANAKIM_MIN_PLAYERS) || (members.size() > Config.ANAKIM_MAX_PLAYERS)) | ||||
| 			{ | ||||
| 				final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId()); | ||||
| 				packet.setHtml(getHtm(player, "31101-02.html")); | ||||
| 				packet.replace("%min%", Integer.toString(Config.ANAKIM_MIN_PLAYERS)); | ||||
| 				player.sendPacket(packet); | ||||
| 				return null; | ||||
| 			} | ||||
| 			 | ||||
| 			for (Player member : members) | ||||
| 			{ | ||||
| 				if (member.getLevel() < Config.ANAKIM_MIN_PLAYER_LEVEL) | ||||
| 				{ | ||||
| 					final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId()); | ||||
| 					packet.setHtml(getHtm(player, "31101-04.html")); | ||||
| 					packet.replace("%minLevel%", Integer.toString(Config.ANAKIM_MIN_PLAYER_LEVEL)); | ||||
| 					player.sendPacket(packet); | ||||
| 					return null; | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
| 			for (Player member : members) | ||||
| 			{ | ||||
| 				if (member.isInsideRadius3D(npc, 1000) && (npc.getId() == ANAKIM_CUBIC)) | ||||
| 				{ | ||||
| 					member.teleToLocation(ENTER_ANAKIM_LOC, true); | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
| 			if ((_anakimStatus == ALIVE) && (npc.getId() == ANAKIM_CUBIC)) | ||||
| 			{ | ||||
| 				GrandBossManager.getInstance().setStatus(ANAKIM, FIGHTING); | ||||
| 				// Spawn the rb | ||||
| 				_anakimBoss = addSpawn(ANAKIM, 185080, -12613, -5499, 16550, false, 0); | ||||
| 				GrandBossManager.getInstance().addBoss((GrandBoss) _anakimBoss); | ||||
| 				startQuestTimer("end_anakim", 60 * 60000, null, null); // 1h | ||||
| 			} | ||||
| 		} | ||||
| 		return super.onTalk(npc, player); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onFirstTalk(Npc npc, Player player) | ||||
| 	{ | ||||
| 		return npc.getId() + ".html"; | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAttack(Npc npc, Player attacker, int damage, boolean isPet) | ||||
| 	{ | ||||
| 		_lastAction = System.currentTimeMillis(); | ||||
| 		if (npc.isMinion() || npc.isRaid())// Anakim and minions | ||||
| 		{ | ||||
| 			// Anti BUGGERS | ||||
| 			if (!BOSS_ZONE.isInsideZone(attacker)) // Character attacking out of zone | ||||
| 			{ | ||||
| 				attacker.doDie(null); | ||||
| 			} | ||||
| 			if (!BOSS_ZONE.isInsideZone(npc)) // Npc moved out of the zone | ||||
| 			{ | ||||
| 				Spawn spawn = npc.getSpawn(); | ||||
| 				if (spawn != null) | ||||
| 				{ | ||||
| 					npc.teleToLocation(spawn.getX(), spawn.getY(), spawn.getZ()); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		return super.onAttack(npc, attacker, damage, isPet); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onKill(Npc npc, Player killer, boolean isPet) | ||||
| 	{ | ||||
| 		if (npc.getId() == ANAKIM) | ||||
| 		{ | ||||
| 			notifyEvent("cancel_timers", null, null); | ||||
| 			addSpawn(EXIST_CUBIC, 185082, -12606, -5499, 6133, false, 900000); // 15min | ||||
| 			 | ||||
| 			GrandBossManager.getInstance().setStatus(ANAKIM, DEAD); | ||||
| 			final long respawnTime = getRespawnTime(); | ||||
| 			final StatSet info = GrandBossManager.getInstance().getStatSet(ANAKIM); | ||||
| 			info.set("respawn_time", System.currentTimeMillis() + respawnTime); | ||||
| 			GrandBossManager.getInstance().setStatSet(ANAKIM, info); | ||||
| 			 | ||||
| 			startQuestTimer("unlock_anakim", respawnTime, null, null); | ||||
| 			startQuestTimer("end_anakim", 900000, null, null); | ||||
| 		} | ||||
| 		return super.onKill(npc, killer, isPet); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onSkillSee(Npc npc, Player caster, Skill skill, WorldObject[] targets, boolean isPet) | ||||
| 	{ | ||||
| 		if (CommonUtil.contains(ANAKIM_MINIONS, npc.getId()) && getRandomBoolean()) | ||||
| 		{ | ||||
| 			if (skill.getAbnormalType() == AbnormalType.HP_RECOVER) | ||||
| 			{ | ||||
| 				if (!npc.isCastingNow() && (npc.getTarget() != npc) && (npc.getTarget() != caster) && (npc.getTarget() != _anakimBoss)) // Don't call minions if are healing Anakim | ||||
| 				{ | ||||
| 					((Attackable) npc).clearAggroList(); | ||||
| 					npc.setTarget(caster); | ||||
| 					((Attackable) npc).addDamageHate(caster, 500, 99999); | ||||
| 					npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, caster); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return super.onSkillSee(npc, caster, skill, targets, isPet); | ||||
| 	} | ||||
| 	 | ||||
| 	private int getRespawnTime() | ||||
| 	{ | ||||
| 		return (int) calcReuseFromDays(0, 21, Calendar.TUESDAY, 0, 16, Calendar.SATURDAY); | ||||
| 	} | ||||
| 	 | ||||
| 	private long calcReuseFromDays(int day1Minute, int day1Hour, int day1Day, int day2Minute, int day2Hour, int day2Day) | ||||
| 	{ | ||||
| 		Calendar now = Calendar.getInstance(); | ||||
| 		Calendar day1 = (Calendar) now.clone(); | ||||
| 		day1.set(Calendar.MINUTE, day1Minute); | ||||
| 		day1.set(Calendar.HOUR_OF_DAY, day1Hour); | ||||
| 		day1.set(Calendar.DAY_OF_WEEK, day1Day); | ||||
| 		 | ||||
| 		Calendar day2 = (Calendar) day1.clone(); | ||||
| 		day2.set(Calendar.MINUTE, day2Minute); | ||||
| 		day2.set(Calendar.HOUR_OF_DAY, day2Hour); | ||||
| 		day2.set(Calendar.DAY_OF_WEEK, day2Day); | ||||
| 		 | ||||
| 		if (now.after(day1)) | ||||
| 		{ | ||||
| 			day1.add(Calendar.WEEK_OF_MONTH, 1); | ||||
| 		} | ||||
| 		if (now.after(day2)) | ||||
| 		{ | ||||
| 			day2.add(Calendar.WEEK_OF_MONTH, 1); | ||||
| 		} | ||||
| 		 | ||||
| 		Calendar reenter = day1; | ||||
| 		if (day2.before(day1)) | ||||
| 		{ | ||||
| 			reenter = day2; | ||||
| 		} | ||||
| 		return reenter.getTimeInMillis() - System.currentTimeMillis(); | ||||
| 	} | ||||
| 	 | ||||
| 	public static void main(String[] args) | ||||
| 	{ | ||||
| 		new Anakim(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										220
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/AnakimBoss.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/AnakimBoss.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,220 @@ | ||||
| /* | ||||
|  * This file is part of the L2J Mobius project. | ||||
|  *  | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  *  | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package ai.bosses.Anakim; | ||||
|  | ||||
| import org.l2jmobius.commons.util.CommonUtil; | ||||
| import org.l2jmobius.gameserver.model.actor.Creature; | ||||
| import org.l2jmobius.gameserver.model.actor.Npc; | ||||
| import org.l2jmobius.gameserver.model.actor.Player; | ||||
| import org.l2jmobius.gameserver.model.holders.SkillHolder; | ||||
| import org.l2jmobius.gameserver.model.skill.Skill; | ||||
| import org.l2jmobius.gameserver.model.skill.SkillCaster; | ||||
| import org.l2jmobius.gameserver.model.variables.NpcVariables; | ||||
|  | ||||
| import ai.AbstractNpcAI; | ||||
|  | ||||
| /** | ||||
|  * @author NviX | ||||
|  */ | ||||
| public class AnakimBoss extends AbstractNpcAI | ||||
| { | ||||
| 	// Npc | ||||
| 	private static final int ANAKIM = 29348; | ||||
| 	// Skills | ||||
| 	private static final SkillHolder POWER_STRIKE = new SkillHolder(32566, 1); | ||||
| 	private static final SkillHolder POWER_MULTI_SHOT = new SkillHolder(32567, 1); | ||||
| 	private static final SkillHolder HOLY_VENGEANCE = new SkillHolder(32568, 1); | ||||
| 	private static final SkillHolder HOLY_DIMENSION = new SkillHolder(32569, 1); | ||||
| 	private static final SkillHolder HOLY_SHIELD = new SkillHolder(32570, 1); | ||||
| 	// Others | ||||
| 	private boolean _hp75 = false; | ||||
| 	private boolean _hp50 = false; | ||||
| 	private boolean _hp25 = false; | ||||
| 	 | ||||
| 	private AnakimBoss() | ||||
| 	{ | ||||
| 		registerMobs(ANAKIM); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAdvEvent(String event, Npc npc, Player player) | ||||
| 	{ | ||||
| 		switch (event) | ||||
| 		{ | ||||
| 			case "MANAGE_SKILLS": | ||||
| 			{ | ||||
| 				if (npc != null) | ||||
| 				{ | ||||
| 					manageSkills(npc); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		return super.onAdvEvent(event, npc, player); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAttack(Npc npc, Player attacker, int damage, boolean isSummon, Skill skill) | ||||
| 	{ | ||||
| 		if (npc.getId() == ANAKIM) | ||||
| 		{ | ||||
| 			if (skill == null) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 1000)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, ((damage / 3) * 100)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 20)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 10)); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, ((damage / 3) * 20)); | ||||
| 			} | ||||
| 			manageSkills(npc); | ||||
| 		} | ||||
| 		 | ||||
| 		return super.onAttack(npc, attacker, damage, isSummon); | ||||
| 	} | ||||
| 	 | ||||
| 	private final void refreshAiParams(Creature attacker, Npc npc, int damage) | ||||
| 	{ | ||||
| 		refreshAiParams(attacker, npc, damage, damage); | ||||
| 	} | ||||
| 	 | ||||
| 	private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) | ||||
| 	{ | ||||
| 		final int newAggroVal = damage + getRandom(3000); | ||||
| 		final int aggroVal = aggro + 1000; | ||||
| 		final NpcVariables vars = npc.getVariables(); | ||||
| 		for (int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			if (attacker == vars.getObject("c_quest" + i, Creature.class)) | ||||
| 			{ | ||||
| 				if (vars.getInt("i_quest" + i) < aggroVal) | ||||
| 				{ | ||||
| 					vars.set("i_quest" + i, newAggroVal); | ||||
| 				} | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 		final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); | ||||
| 		vars.set("i_quest" + index, newAggroVal); | ||||
| 		vars.set("c_quest" + index, attacker); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onSpellFinished(Npc npc, Player player, Skill skill) | ||||
| 	{ | ||||
| 		startQuestTimer("MANAGE_SKILLS", 1000, npc, null); | ||||
| 		 | ||||
| 		return super.onSpellFinished(npc, player, skill); | ||||
| 	} | ||||
| 	 | ||||
| 	private void manageSkills(Npc npc) | ||||
| 	{ | ||||
| 		if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		final NpcVariables vars = npc.getVariables(); | ||||
| 		for (int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			final Creature attacker = vars.getObject("c_quest" + i, Creature.class); | ||||
| 			if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) | ||||
| 			{ | ||||
| 				vars.set("i_quest" + i, 0); | ||||
| 			} | ||||
| 		} | ||||
| 		final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); | ||||
| 		final Creature player = vars.getObject("c_quest" + index, Creature.class); | ||||
| 		final int i2 = vars.getInt("i_quest" + index); | ||||
| 		if ((i2 > 0) && (getRandom(100) < 70)) | ||||
| 		{ | ||||
| 			vars.set("i_quest" + index, 500); | ||||
| 		} | ||||
| 		 | ||||
| 		SkillHolder skillToCast = null; | ||||
| 		int chance = getRandom(100); | ||||
| 		if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.75)) && !_hp75) | ||||
| 		{ | ||||
| 			_hp75 = true; | ||||
| 			npc.abortCast(); | ||||
| 			npc.abortAttack(); | ||||
| 			npc.setTarget(npc); | ||||
| 			npc.doCast(HOLY_SHIELD.getSkill()); | ||||
| 			return; | ||||
| 		} | ||||
| 		else if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.50)) && !_hp50) | ||||
| 		{ | ||||
| 			_hp50 = true; | ||||
| 			npc.abortCast(); | ||||
| 			npc.abortAttack(); | ||||
| 			npc.setTarget(npc); | ||||
| 			npc.doCast(HOLY_SHIELD.getSkill()); | ||||
| 			return; | ||||
| 		} | ||||
| 		else if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.25)) && !_hp25) | ||||
| 		{ | ||||
| 			_hp25 = true; | ||||
| 			npc.abortCast(); | ||||
| 			npc.abortAttack(); | ||||
| 			npc.setTarget(npc); | ||||
| 			npc.doCast(HOLY_SHIELD.getSkill()); | ||||
| 			return; | ||||
| 		} | ||||
| 		if ((player != null) && !player.isDead()) | ||||
| 		{ | ||||
| 			if (chance < 15) | ||||
| 			{ | ||||
| 				skillToCast = HOLY_DIMENSION; | ||||
| 			} | ||||
| 			else if (chance < 30) | ||||
| 			{ | ||||
| 				skillToCast = HOLY_VENGEANCE; | ||||
| 			} | ||||
| 			else if (chance < 50) | ||||
| 			{ | ||||
| 				skillToCast = POWER_MULTI_SHOT; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				skillToCast = POWER_STRIKE; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) | ||||
| 		 | ||||
| 		{ | ||||
| 			npc.setTarget(player); | ||||
| 			npc.doCast(skillToCast.getSkill()); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public static void main(String[] args) | ||||
| 	{ | ||||
| 		new AnakimBoss(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										188
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/AnakimElitePriest.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Anakim/AnakimElitePriest.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | ||||
| /* | ||||
|  * This file is part of the L2J Mobius project. | ||||
|  *  | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  *  | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package ai.bosses.Anakim; | ||||
|  | ||||
| import org.l2jmobius.commons.util.CommonUtil; | ||||
| import org.l2jmobius.gameserver.model.actor.Creature; | ||||
| import org.l2jmobius.gameserver.model.actor.Npc; | ||||
| import org.l2jmobius.gameserver.model.actor.Player; | ||||
| import org.l2jmobius.gameserver.model.holders.SkillHolder; | ||||
| import org.l2jmobius.gameserver.model.skill.Skill; | ||||
| import org.l2jmobius.gameserver.model.skill.SkillCaster; | ||||
| import org.l2jmobius.gameserver.model.variables.NpcVariables; | ||||
|  | ||||
| import ai.AbstractNpcAI; | ||||
|  | ||||
| /** | ||||
|  * @author NviX | ||||
|  */ | ||||
| public class AnakimElitePriest extends AbstractNpcAI | ||||
| { | ||||
| 	// Npc | ||||
| 	private static final int ANAKIM_ELITE_PRIEST = 29351; | ||||
| 	// Skills | ||||
| 	private static final SkillHolder ENERGY_SHOT = new SkillHolder(32576, 1); | ||||
| 	private static final SkillHolder MAGIC_BLAST = new SkillHolder(32577, 1); | ||||
| 	private static final SkillHolder LIGHTNING = new SkillHolder(32575, 1); | ||||
| 	private static final SkillHolder BLESS = new SkillHolder(32574, 1); | ||||
| 	 | ||||
| 	private AnakimElitePriest() | ||||
| 	{ | ||||
| 		registerMobs(ANAKIM_ELITE_PRIEST); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAdvEvent(String event, Npc npc, Player player) | ||||
| 	{ | ||||
| 		switch (event) | ||||
| 		{ | ||||
| 			case "MANAGE_SKILLS": | ||||
| 			{ | ||||
| 				if (npc != null) | ||||
| 				{ | ||||
| 					manageSkills(npc); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		return super.onAdvEvent(event, npc, player); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAttack(Npc npc, Player attacker, int damage, boolean isSummon, Skill skill) | ||||
| 	{ | ||||
| 		if (npc.getId() == ANAKIM_ELITE_PRIEST) | ||||
| 		{ | ||||
| 			if (skill == null) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 1000)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, ((damage / 3) * 100)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 20)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 10)); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, ((damage / 3) * 20)); | ||||
| 			} | ||||
| 			manageSkills(npc); | ||||
| 		} | ||||
| 		 | ||||
| 		return super.onAttack(npc, attacker, damage, isSummon); | ||||
| 	} | ||||
| 	 | ||||
| 	private final void refreshAiParams(Creature attacker, Npc npc, int damage) | ||||
| 	{ | ||||
| 		refreshAiParams(attacker, npc, damage, damage); | ||||
| 	} | ||||
| 	 | ||||
| 	private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) | ||||
| 	{ | ||||
| 		final int newAggroVal = damage + getRandom(3000); | ||||
| 		final int aggroVal = aggro + 1000; | ||||
| 		final NpcVariables vars = npc.getVariables(); | ||||
| 		for (int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			if (attacker == vars.getObject("c_quest" + i, Creature.class)) | ||||
| 			{ | ||||
| 				if (vars.getInt("i_quest" + i) < aggroVal) | ||||
| 				{ | ||||
| 					vars.set("i_quest" + i, newAggroVal); | ||||
| 				} | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 		final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); | ||||
| 		vars.set("i_quest" + index, newAggroVal); | ||||
| 		vars.set("c_quest" + index, attacker); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onSpellFinished(Npc npc, Player player, Skill skill) | ||||
| 	{ | ||||
| 		startQuestTimer("MANAGE_SKILLS", 1000, npc, null); | ||||
| 		 | ||||
| 		return super.onSpellFinished(npc, player, skill); | ||||
| 	} | ||||
| 	 | ||||
| 	private void manageSkills(Npc npc) | ||||
| 	{ | ||||
| 		if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		final NpcVariables vars = npc.getVariables(); | ||||
| 		for (int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			final Creature attacker = vars.getObject("c_quest" + i, Creature.class); | ||||
| 			if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) | ||||
| 			{ | ||||
| 				vars.set("i_quest" + i, 0); | ||||
| 			} | ||||
| 		} | ||||
| 		final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); | ||||
| 		final Creature player = vars.getObject("c_quest" + index, Creature.class); | ||||
| 		final int i2 = vars.getInt("i_quest" + index); | ||||
| 		if ((i2 > 0) && (getRandom(100) < 70)) | ||||
| 		{ | ||||
| 			vars.set("i_quest" + index, 500); | ||||
| 		} | ||||
| 		 | ||||
| 		SkillHolder skillToCast = null; | ||||
| 		int chance = getRandom(100); | ||||
| 		if ((player != null) && !player.isDead()) | ||||
| 		{ | ||||
| 			if (chance < 15) | ||||
| 			{ | ||||
| 				skillToCast = BLESS; | ||||
| 			} | ||||
| 			else if (chance < 30) | ||||
| 			{ | ||||
| 				skillToCast = LIGHTNING; | ||||
| 			} | ||||
| 			else if (chance < 50) | ||||
| 			{ | ||||
| 				skillToCast = MAGIC_BLAST; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				skillToCast = ENERGY_SHOT; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) | ||||
| 		 | ||||
| 		{ | ||||
| 			npc.setTarget(player); | ||||
| 			npc.doCast(skillToCast.getSkill()); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public static void main(String[] args) | ||||
| 	{ | ||||
| 		new AnakimElitePriest(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31110.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31110.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br | ||||
| >A human-like voice comes from a glowing blue orb:<br> | ||||
| <Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest Lilith">"I kinda want to teleport inside."</Button> | ||||
| </body></html> | ||||
							
								
								
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31118-01.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31118-01.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| A human-like voice comes from a glowing blue orb:<br> | ||||
| Someone already went in, and Lilith disappeared soon after. There is no point in entering right now. | ||||
| </body></html> | ||||
							
								
								
									
										3
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31118-02.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31118-02.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| (A command channel needs at least %min% members to challenge Lilith.) | ||||
| </body></html> | ||||
							
								
								
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31118-03.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31118-03.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br> | ||||
| (The players who belong to an association can only enter through the Association Leader.) | ||||
| </body></html> | ||||
							
								
								
									
										3
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31118-04.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31118-04.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| (A command channel members level must be %minLevel% to challenge Lilith.) | ||||
| </body></html> | ||||
							
								
								
									
										7
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31118.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31118.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| A human voice seems to emanate from a shining, blue globe:<br> | ||||
| Behold the gateway to the Forbidden Sacred Area! My job is to guard it, and you cannot pass without my permission.<br> | ||||
| <Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest Lilith">Teleport</Button> | ||||
| <Button ALIGN=LEFT ICON="NORMAL" action="bypass -h npc_%objectId%_Quest OracleTeleport">Enter the Dimensional Rift</Button> | ||||
| <Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button> | ||||
| </body></html> | ||||
							
								
								
									
										5
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31124.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/31124.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| <html><body>Gatekeeper Ziggurat:<br> | ||||
| A human voice seems to emanate from a shining, blue globe:<br> | ||||
| Behold the gateway to the Forbidden Sacred Area! My job is to guard it, and you cannot pass without my permission.<br> | ||||
| <Button ALIGN=LEFT ICON="TELEPORT" action="bypass -h Quest Lilith exist">"Okay. I will teleport."</Button> | ||||
| </body></html> | ||||
							
								
								
									
										368
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/Lilith.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										368
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/Lilith.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,368 @@ | ||||
| /* | ||||
|  * This file is part of the L2J Mobius project. | ||||
|  *  | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  *  | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package ai.bosses.Lilith; | ||||
|  | ||||
| import java.util.Calendar; | ||||
| import java.util.List; | ||||
|  | ||||
| import org.l2jmobius.Config; | ||||
| import org.l2jmobius.commons.util.CommonUtil; | ||||
| import org.l2jmobius.gameserver.ai.CtrlIntention; | ||||
| import org.l2jmobius.gameserver.enums.TeleportWhereType; | ||||
| import org.l2jmobius.gameserver.instancemanager.GrandBossManager; | ||||
| import org.l2jmobius.gameserver.instancemanager.MapRegionManager; | ||||
| import org.l2jmobius.gameserver.instancemanager.ZoneManager; | ||||
| import org.l2jmobius.gameserver.model.Location; | ||||
| import org.l2jmobius.gameserver.model.Party; | ||||
| import org.l2jmobius.gameserver.model.Spawn; | ||||
| import org.l2jmobius.gameserver.model.StatSet; | ||||
| import org.l2jmobius.gameserver.model.WorldObject; | ||||
| 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.Player; | ||||
| import org.l2jmobius.gameserver.model.actor.instance.GrandBoss; | ||||
| import org.l2jmobius.gameserver.model.quest.QuestTimer; | ||||
| import org.l2jmobius.gameserver.model.skill.AbnormalType; | ||||
| import org.l2jmobius.gameserver.model.skill.Skill; | ||||
| import org.l2jmobius.gameserver.model.zone.ZoneType; | ||||
| import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage; | ||||
|  | ||||
| import ai.AbstractNpcAI; | ||||
|  | ||||
| /** | ||||
|  * Lilith AI<br> | ||||
|  * @author LasTravel<br> | ||||
|  * @URL http://boards.lineage2.com/showpost.php?p=3386784&postcount=6<br> | ||||
|  * @video https://www.youtube.com/watch?v=H3MuIwUjjD4 | ||||
|  */ | ||||
| public class Lilith extends AbstractNpcAI | ||||
| { | ||||
| 	// Status | ||||
| 	private static final int ALIVE = 0; | ||||
| 	private static final int FIGHTING = 1; | ||||
| 	private static final int DEAD = 2; | ||||
| 	// NPCs | ||||
| 	private static final int LILITH = 29336; | ||||
| 	private static final int EXIST_CUBIC = 31124; | ||||
| 	private static final int LILITH_CUBIC = 31110; | ||||
| 	//@formatter:off | ||||
| 	private static final int[] LILITH_MINIONS = {29337, 29338, 29339}; | ||||
| 	//@formatter:on	 | ||||
| 	private static final int[] ALL_MOBS = | ||||
| 	{ | ||||
| 		LILITH, | ||||
| 		LILITH_MINIONS[0], | ||||
| 		LILITH_MINIONS[1], | ||||
| 	}; | ||||
| 	// Misc | ||||
| 	private static final Location ENTER_LILITH_LOC = new Location(184449, -9032, -5499); | ||||
| 	private static final ZoneType BOSS_ZONE = ZoneManager.getInstance().getZoneById(12005); | ||||
| 	private static final ZoneType PRE_LILITH_ZONE = ZoneManager.getInstance().getZoneById(12006); | ||||
| 	// Others | ||||
| 	private static long _lastAction; | ||||
| 	private static Npc _lilithBoss; | ||||
| 	private GrandBoss _tempLilith = null; | ||||
| 	 | ||||
| 	public Lilith() | ||||
| 	{ | ||||
| 		addTalkId(EXIST_CUBIC, LILITH_CUBIC); | ||||
| 		addStartNpc(EXIST_CUBIC, LILITH_CUBIC); | ||||
| 		addFirstTalkId(EXIST_CUBIC, LILITH_CUBIC); | ||||
| 		addAttackId(ALL_MOBS); | ||||
| 		addKillId(ALL_MOBS); | ||||
| 		addSkillSeeId(ALL_MOBS); | ||||
| 		 | ||||
| 		// Unlock | ||||
| 		final StatSet info = GrandBossManager.getInstance().getStatSet(LILITH); | ||||
| 		final int status = GrandBossManager.getInstance().getStatus(LILITH); | ||||
| 		if (status == DEAD) | ||||
| 		{ | ||||
| 			final long time = info.getLong("respawn_time") - System.currentTimeMillis(); | ||||
| 			if (time > 0) | ||||
| 			{ | ||||
| 				startQuestTimer("unlock_lilith", time, null, null); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				_tempLilith = (GrandBoss) addSpawn(LILITH, -126920, -234182, -15563, 0, false, 0); | ||||
| 				GrandBossManager.getInstance().addBoss(_tempLilith); | ||||
| 				GrandBossManager.getInstance().setStatus(LILITH, ALIVE); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			_tempLilith = (GrandBoss) addSpawn(LILITH, -126920, -234182, -15563, 0, false, 0); | ||||
| 			GrandBossManager.getInstance().addBoss(_tempLilith); | ||||
| 			GrandBossManager.getInstance().setStatus(LILITH, ALIVE); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAdvEvent(String event, Npc npc, Player player) | ||||
| 	{ | ||||
| 		switch (event) | ||||
| 		{ | ||||
| 			case "unlock_lilith": | ||||
| 			{ | ||||
| 				_tempLilith = (GrandBoss) addSpawn(LILITH, -126920, -234182, -15563, 0, false, 0); | ||||
| 				GrandBossManager.getInstance().addBoss(_tempLilith); | ||||
| 				GrandBossManager.getInstance().setStatus(LILITH, ALIVE); | ||||
| 				break; | ||||
| 			} | ||||
| 			case "check_activity_task": | ||||
| 			{ | ||||
| 				if ((_lastAction + 900000) < System.currentTimeMillis()) | ||||
| 				{ | ||||
| 					GrandBossManager.getInstance().setStatus(LILITH, ALIVE); | ||||
| 					for (Creature creature : BOSS_ZONE.getCharactersInside()) | ||||
| 					{ | ||||
| 						if (creature != null) | ||||
| 						{ | ||||
| 							if (creature.isNpc()) | ||||
| 							{ | ||||
| 								creature.deleteMe(); | ||||
| 							} | ||||
| 							else if (creature.isPlayer()) | ||||
| 							{ | ||||
| 								creature.teleToLocation(MapRegionManager.getInstance().getTeleToLocation(creature, TeleportWhereType.TOWN)); | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 					startQuestTimer("end_lilith", 2000, null, null); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					startQuestTimer("check_activity_task", 60000, null, null); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 			case "cancel_timers": | ||||
| 			{ | ||||
| 				QuestTimer activityTimer = getQuestTimer("check_activity_task", null, null); | ||||
| 				if (activityTimer != null) | ||||
| 				{ | ||||
| 					activityTimer.cancel(); | ||||
| 				} | ||||
| 				 | ||||
| 				QuestTimer forceEnd = getQuestTimer("end_lilith", null, null); | ||||
| 				if (forceEnd != null) | ||||
| 				{ | ||||
| 					forceEnd.cancel(); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 			case "end_lilith": | ||||
| 			{ | ||||
| 				notifyEvent("cancel_timers", null, null); | ||||
| 				if (_lilithBoss != null) | ||||
| 				{ | ||||
| 					_lilithBoss.deleteMe(); | ||||
| 				} | ||||
| 				BOSS_ZONE.oustAllPlayers(); | ||||
| 				PRE_LILITH_ZONE.oustAllPlayers(); | ||||
| 				if (GrandBossManager.getInstance().getStatus(LILITH) != DEAD) | ||||
| 				{ | ||||
| 					GrandBossManager.getInstance().setStatus(LILITH, ALIVE); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 			case "exist": | ||||
| 			{ | ||||
| 				player.teleToLocation(TeleportWhereType.TOWN); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		return super.onAdvEvent(event, npc, player); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onTalk(Npc npc, Player player) | ||||
| 	{ | ||||
| 		final int _lilithStatus = GrandBossManager.getInstance().getStatus(LILITH); | ||||
| 		if ((npc.getId() == LILITH_CUBIC) && (_lilithStatus > ALIVE)) | ||||
| 		{ | ||||
| 			return "31118-01.html"; | ||||
| 		} | ||||
| 		if (!player.isInParty()) | ||||
| 		{ | ||||
| 			final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId()); | ||||
| 			packet.setHtml(getHtm(player, "31118-02.html")); | ||||
| 			packet.replace("%min%", Integer.toString(Config.LILITH_MIN_PLAYERS)); | ||||
| 			player.sendPacket(packet); | ||||
| 			return null; | ||||
| 		} | ||||
| 		final Party party = player.getParty(); | ||||
| 		final boolean isInCC = party.isInCommandChannel(); | ||||
| 		final List<Player> members = (isInCC) ? party.getCommandChannel().getMembers() : party.getMembers(); | ||||
| 		final boolean isPartyLeader = (isInCC) ? party.getCommandChannel().isLeader(player) : party.isLeader(player); | ||||
| 		if (!isPartyLeader) | ||||
| 		{ | ||||
| 			return "31118-03.html"; | ||||
| 		} | ||||
| 		 | ||||
| 		if ((members.size() < Config.LILITH_MIN_PLAYERS) || (members.size() > Config.LILITH_MAX_PLAYERS)) | ||||
| 		{ | ||||
| 			final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId()); | ||||
| 			packet.setHtml(getHtm(player, "31118-02.html")); | ||||
| 			packet.replace("%min%", Integer.toString(Config.LILITH_MIN_PLAYERS)); | ||||
| 			player.sendPacket(packet); | ||||
| 			return null; | ||||
| 		} | ||||
| 		 | ||||
| 		for (Player member : members) | ||||
| 		{ | ||||
| 			if (member.getLevel() < Config.LILITH_MIN_PLAYER_LEVEL) | ||||
| 			{ | ||||
| 				final NpcHtmlMessage packet = new NpcHtmlMessage(npc.getObjectId()); | ||||
| 				packet.setHtml(getHtm(player, "31118-04.html")); | ||||
| 				packet.replace("%minLevel%", Integer.toString(Config.LILITH_MIN_PLAYER_LEVEL)); | ||||
| 				player.sendPacket(packet); | ||||
| 				return null; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		for (Player member : members) | ||||
| 		{ | ||||
| 			if (member.isInsideRadius3D(npc, 1000) && (npc.getId() == LILITH_CUBIC)) | ||||
| 			{ | ||||
| 				member.teleToLocation(ENTER_LILITH_LOC, true); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		if ((_lilithStatus == ALIVE) && (npc.getId() == LILITH_CUBIC)) | ||||
| 		{ | ||||
| 			GrandBossManager.getInstance().setStatus(LILITH, FIGHTING); | ||||
| 			// Spawn the rb | ||||
| 			_lilithBoss = addSpawn(LILITH, 185062, -9605, -5499, 15640, false, 0); | ||||
| 			GrandBossManager.getInstance().addBoss((GrandBoss) _lilithBoss); | ||||
| 			_lastAction = System.currentTimeMillis(); | ||||
| 			startQuestTimer("check_activity_task", 60000, null, null, true); | ||||
| 			startQuestTimer("end_lilith", 60 * 60000, null, null); // 1h | ||||
| 		} | ||||
| 		return super.onTalk(npc, player); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAttack(Npc npc, Player attacker, int damage, boolean isPet) | ||||
| 	{ | ||||
| 		_lastAction = System.currentTimeMillis(); | ||||
| 		if (npc.isMinion() || npc.isRaid()) // Lilith and minions | ||||
| 		{ | ||||
| 			// Anti BUGGERS | ||||
| 			if (!BOSS_ZONE.isInsideZone(attacker)) // Character attacking out of zone | ||||
| 			{ | ||||
| 				attacker.doDie(null); | ||||
| 			} | ||||
| 			if (!BOSS_ZONE.isInsideZone(npc)) // Npc moved out of the zone | ||||
| 			{ | ||||
| 				Spawn spawn = npc.getSpawn(); | ||||
| 				if (spawn != null) | ||||
| 				{ | ||||
| 					npc.teleToLocation(spawn.getX(), spawn.getY(), spawn.getZ()); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		return super.onAttack(npc, attacker, damage, isPet); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onKill(Npc npc, Player killer, boolean isPet) | ||||
| 	{ | ||||
| 		if (npc.getId() == LILITH) | ||||
| 		{ | ||||
| 			notifyEvent("cancel_timers", null, null); | ||||
| 			addSpawn(EXIST_CUBIC, 185062, -9605, -5499, 15640, false, 900000); // 15min | ||||
| 			 | ||||
| 			GrandBossManager.getInstance().setStatus(LILITH, DEAD); | ||||
| 			final long respawnTime = getRespawnTime(); | ||||
| 			final StatSet info = GrandBossManager.getInstance().getStatSet(LILITH); | ||||
| 			info.set("respawn_time", System.currentTimeMillis() + respawnTime); | ||||
| 			GrandBossManager.getInstance().setStatSet(LILITH, info); | ||||
| 			 | ||||
| 			startQuestTimer("unlock_lilith", respawnTime, null, null); | ||||
| 			startQuestTimer("end_lilith", 900000, null, null); | ||||
| 		} | ||||
| 		return super.onKill(npc, killer, isPet); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onSkillSee(Npc npc, Player caster, Skill skill, WorldObject[] targets, boolean isPet) | ||||
| 	{ | ||||
| 		if (CommonUtil.contains(LILITH_MINIONS, npc.getId()) && getRandomBoolean()) | ||||
| 		{ | ||||
| 			if (skill.getAbnormalType() == AbnormalType.HP_RECOVER) | ||||
| 			{ | ||||
| 				if (!npc.isCastingNow() && (npc.getTarget() != npc) && (npc.getTarget() != caster) && (npc.getTarget() != _lilithBoss)) | ||||
| 				{ | ||||
| 					((Attackable) npc).clearAggroList(); | ||||
| 					npc.setTarget(caster); | ||||
| 					((Attackable) npc).addDamageHate(caster, 500, 99999); | ||||
| 					npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, caster); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return super.onSkillSee(npc, caster, skill, targets, isPet); | ||||
| 	} | ||||
| 	 | ||||
| 	private int getRespawnTime() | ||||
| 	{ | ||||
| 		return (int) calcReuseFromDays(0, 21, Calendar.THURSDAY, 0, 14, Calendar.SATURDAY); | ||||
| 	} | ||||
| 	 | ||||
| 	private long calcReuseFromDays(int day1Minute, int day1Hour, int day1Day, int day2Minute, int day2Hour, int day2Day) | ||||
| 	{ | ||||
| 		Calendar now = Calendar.getInstance(); | ||||
| 		Calendar day1 = (Calendar) now.clone(); | ||||
| 		day1.set(Calendar.MINUTE, day1Minute); | ||||
| 		day1.set(Calendar.HOUR_OF_DAY, day1Hour); | ||||
| 		day1.set(Calendar.DAY_OF_WEEK, day1Day); | ||||
| 		 | ||||
| 		Calendar day2 = (Calendar) day1.clone(); | ||||
| 		day2.set(Calendar.MINUTE, day2Minute); | ||||
| 		day2.set(Calendar.HOUR_OF_DAY, day2Hour); | ||||
| 		day2.set(Calendar.DAY_OF_WEEK, day2Day); | ||||
| 		 | ||||
| 		if (now.after(day1)) | ||||
| 		{ | ||||
| 			day1.add(Calendar.WEEK_OF_MONTH, 1); | ||||
| 		} | ||||
| 		if (now.after(day2)) | ||||
| 		{ | ||||
| 			day2.add(Calendar.WEEK_OF_MONTH, 1); | ||||
| 		} | ||||
| 		 | ||||
| 		Calendar reenter = day1; | ||||
| 		if (day2.before(day1)) | ||||
| 		{ | ||||
| 			reenter = day2; | ||||
| 		} | ||||
| 		return reenter.getTimeInMillis() - System.currentTimeMillis(); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onFirstTalk(Npc npc, Player player) | ||||
| 	{ | ||||
| 		return npc.getId() + ".html"; | ||||
| 	} | ||||
| 	 | ||||
| 	public static void main(String[] args) | ||||
| 	{ | ||||
| 		new Lilith(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										220
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/LilithBoss.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/LilithBoss.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,220 @@ | ||||
| /* | ||||
|  * This file is part of the L2J Mobius project. | ||||
|  *  | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  *  | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package ai.bosses.Lilith; | ||||
|  | ||||
| import org.l2jmobius.commons.util.CommonUtil; | ||||
| import org.l2jmobius.gameserver.model.actor.Creature; | ||||
| import org.l2jmobius.gameserver.model.actor.Npc; | ||||
| import org.l2jmobius.gameserver.model.actor.Player; | ||||
| import org.l2jmobius.gameserver.model.holders.SkillHolder; | ||||
| import org.l2jmobius.gameserver.model.skill.Skill; | ||||
| import org.l2jmobius.gameserver.model.skill.SkillCaster; | ||||
| import org.l2jmobius.gameserver.model.variables.NpcVariables; | ||||
|  | ||||
| import ai.AbstractNpcAI; | ||||
|  | ||||
| /** | ||||
|  * @author NviX | ||||
|  */ | ||||
| public class LilithBoss extends AbstractNpcAI | ||||
| { | ||||
| 	// Npc | ||||
| 	private static final int LILITH = 29336; | ||||
| 	// Skills | ||||
| 	private static final SkillHolder MAGIC_BOLT = new SkillHolder(32536, 1); | ||||
| 	private static final SkillHolder MAGIC_BLAST = new SkillHolder(32537, 1); | ||||
| 	private static final SkillHolder UNHOLY_VENGEANCE = new SkillHolder(32538, 1); | ||||
| 	private static final SkillHolder UNHOLY_DIMENSION = new SkillHolder(32539, 1); | ||||
| 	private static final SkillHolder UNHOLY_SHIELD = new SkillHolder(32540, 1); | ||||
| 	// Others | ||||
| 	private boolean _hp75 = false; | ||||
| 	private boolean _hp50 = false; | ||||
| 	private boolean _hp25 = false; | ||||
| 	 | ||||
| 	private LilithBoss() | ||||
| 	{ | ||||
| 		registerMobs(LILITH); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAdvEvent(String event, Npc npc, Player player) | ||||
| 	{ | ||||
| 		switch (event) | ||||
| 		{ | ||||
| 			case "MANAGE_SKILLS": | ||||
| 			{ | ||||
| 				if (npc != null) | ||||
| 				{ | ||||
| 					manageSkills(npc); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		return super.onAdvEvent(event, npc, player); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAttack(Npc npc, Player attacker, int damage, boolean isSummon, Skill skill) | ||||
| 	{ | ||||
| 		if (npc.getId() == LILITH) | ||||
| 		{ | ||||
| 			if (skill == null) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 1000)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, ((damage / 3) * 100)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 20)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 10)); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, ((damage / 3) * 20)); | ||||
| 			} | ||||
| 			manageSkills(npc); | ||||
| 		} | ||||
| 		 | ||||
| 		return super.onAttack(npc, attacker, damage, isSummon); | ||||
| 	} | ||||
| 	 | ||||
| 	private final void refreshAiParams(Creature attacker, Npc npc, int damage) | ||||
| 	{ | ||||
| 		refreshAiParams(attacker, npc, damage, damage); | ||||
| 	} | ||||
| 	 | ||||
| 	private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) | ||||
| 	{ | ||||
| 		final int newAggroVal = damage + getRandom(3000); | ||||
| 		final int aggroVal = aggro + 1000; | ||||
| 		final NpcVariables vars = npc.getVariables(); | ||||
| 		for (int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			if (attacker == vars.getObject("c_quest" + i, Creature.class)) | ||||
| 			{ | ||||
| 				if (vars.getInt("i_quest" + i) < aggroVal) | ||||
| 				{ | ||||
| 					vars.set("i_quest" + i, newAggroVal); | ||||
| 				} | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 		final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); | ||||
| 		vars.set("i_quest" + index, newAggroVal); | ||||
| 		vars.set("c_quest" + index, attacker); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onSpellFinished(Npc npc, Player player, Skill skill) | ||||
| 	{ | ||||
| 		startQuestTimer("MANAGE_SKILLS", 1000, npc, null); | ||||
| 		 | ||||
| 		return super.onSpellFinished(npc, player, skill); | ||||
| 	} | ||||
| 	 | ||||
| 	private void manageSkills(Npc npc) | ||||
| 	{ | ||||
| 		if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		final NpcVariables vars = npc.getVariables(); | ||||
| 		for (int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			final Creature attacker = vars.getObject("c_quest" + i, Creature.class); | ||||
| 			if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) | ||||
| 			{ | ||||
| 				vars.set("i_quest" + i, 0); | ||||
| 			} | ||||
| 		} | ||||
| 		final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); | ||||
| 		final Creature player = vars.getObject("c_quest" + index, Creature.class); | ||||
| 		final int i2 = vars.getInt("i_quest" + index); | ||||
| 		if ((i2 > 0) && (getRandom(100) < 70)) | ||||
| 		{ | ||||
| 			vars.set("i_quest" + index, 500); | ||||
| 		} | ||||
| 		 | ||||
| 		SkillHolder skillToCast = null; | ||||
| 		int chance = getRandom(100); | ||||
| 		if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.75)) && !_hp75) | ||||
| 		{ | ||||
| 			_hp75 = true; | ||||
| 			npc.abortCast(); | ||||
| 			npc.abortAttack(); | ||||
| 			npc.setTarget(npc); | ||||
| 			npc.doCast(UNHOLY_SHIELD.getSkill()); | ||||
| 			return; | ||||
| 		} | ||||
| 		else if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.50)) && !_hp50) | ||||
| 		{ | ||||
| 			_hp50 = true; | ||||
| 			npc.abortCast(); | ||||
| 			npc.abortAttack(); | ||||
| 			npc.setTarget(npc); | ||||
| 			npc.doCast(UNHOLY_SHIELD.getSkill()); | ||||
| 			return; | ||||
| 		} | ||||
| 		else if ((npc.getCurrentHp() <= (npc.getMaxHp() * 0.25)) && !_hp25) | ||||
| 		{ | ||||
| 			_hp25 = true; | ||||
| 			npc.abortCast(); | ||||
| 			npc.abortAttack(); | ||||
| 			npc.setTarget(npc); | ||||
| 			npc.doCast(UNHOLY_SHIELD.getSkill()); | ||||
| 			return; | ||||
| 		} | ||||
| 		if ((player != null) && !player.isDead()) | ||||
| 		{ | ||||
| 			if (chance < 15) | ||||
| 			{ | ||||
| 				skillToCast = UNHOLY_DIMENSION; | ||||
| 			} | ||||
| 			else if (chance < 30) | ||||
| 			{ | ||||
| 				skillToCast = UNHOLY_VENGEANCE; | ||||
| 			} | ||||
| 			else if (chance < 50) | ||||
| 			{ | ||||
| 				skillToCast = MAGIC_BLAST; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				skillToCast = MAGIC_BOLT; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) | ||||
| 		 | ||||
| 		{ | ||||
| 			npc.setTarget(player); | ||||
| 			npc.doCast(skillToCast.getSkill()); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public static void main(String[] args) | ||||
| 	{ | ||||
| 		new LilithBoss(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										193
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/LilithEliteShaman.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								L2J_Mobius_08.2_Homunculus/dist/game/data/scripts/ai/bosses/Lilith/LilithEliteShaman.java
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| /* | ||||
|  * This file is part of the L2J Mobius project. | ||||
|  *  | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  *  | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
|  * General Public License for more details. | ||||
|  *  | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| package ai.bosses.Lilith; | ||||
|  | ||||
| import org.l2jmobius.commons.util.CommonUtil; | ||||
| import org.l2jmobius.gameserver.model.actor.Creature; | ||||
| import org.l2jmobius.gameserver.model.actor.Npc; | ||||
| import org.l2jmobius.gameserver.model.actor.Player; | ||||
| import org.l2jmobius.gameserver.model.holders.SkillHolder; | ||||
| import org.l2jmobius.gameserver.model.skill.Skill; | ||||
| import org.l2jmobius.gameserver.model.skill.SkillCaster; | ||||
| import org.l2jmobius.gameserver.model.variables.NpcVariables; | ||||
|  | ||||
| import ai.AbstractNpcAI; | ||||
|  | ||||
| /** | ||||
|  * @author NviX | ||||
|  */ | ||||
| public class LilithEliteShaman extends AbstractNpcAI | ||||
| { | ||||
| 	// Npc | ||||
| 	private static final int LILITH_ELITE_SHAMAN = 29339; | ||||
| 	// Skills | ||||
| 	private static final SkillHolder MAGIC_BOLT = new SkillHolder(32544, 1); | ||||
| 	private static final SkillHolder MAGIC_BLAST = new SkillHolder(32546, 1); | ||||
| 	private static final SkillHolder MAGIC_BURST = new SkillHolder(32547, 1); | ||||
| 	private static final SkillHolder TERA_FEAR = new SkillHolder(32545, 1); | ||||
| 	private static final SkillHolder MAGIC_HOLD = new SkillHolder(32548, 1); | ||||
| 	 | ||||
| 	private LilithEliteShaman() | ||||
| 	{ | ||||
| 		registerMobs(LILITH_ELITE_SHAMAN); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAdvEvent(String event, Npc npc, Player player) | ||||
| 	{ | ||||
| 		switch (event) | ||||
| 		{ | ||||
| 			case "MANAGE_SKILLS": | ||||
| 			{ | ||||
| 				if (npc != null) | ||||
| 				{ | ||||
| 					manageSkills(npc); | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		return super.onAdvEvent(event, npc, player); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onAttack(Npc npc, Player attacker, int damage, boolean isSummon, Skill skill) | ||||
| 	{ | ||||
| 		if (npc.getId() == LILITH_ELITE_SHAMAN) | ||||
| 		{ | ||||
| 			if (skill == null) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 1000)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, ((damage / 3) * 100)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 20)); | ||||
| 			} | ||||
| 			else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)) | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, (damage * 10)); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				refreshAiParams(attacker, npc, ((damage / 3) * 20)); | ||||
| 			} | ||||
| 			manageSkills(npc); | ||||
| 		} | ||||
| 		 | ||||
| 		return super.onAttack(npc, attacker, damage, isSummon); | ||||
| 	} | ||||
| 	 | ||||
| 	private final void refreshAiParams(Creature attacker, Npc npc, int damage) | ||||
| 	{ | ||||
| 		refreshAiParams(attacker, npc, damage, damage); | ||||
| 	} | ||||
| 	 | ||||
| 	private final void refreshAiParams(Creature attacker, Npc npc, int damage, int aggro) | ||||
| 	{ | ||||
| 		final int newAggroVal = damage + getRandom(3000); | ||||
| 		final int aggroVal = aggro + 1000; | ||||
| 		final NpcVariables vars = npc.getVariables(); | ||||
| 		for (int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			if (attacker == vars.getObject("c_quest" + i, Creature.class)) | ||||
| 			{ | ||||
| 				if (vars.getInt("i_quest" + i) < aggroVal) | ||||
| 				{ | ||||
| 					vars.set("i_quest" + i, newAggroVal); | ||||
| 				} | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 		final int index = CommonUtil.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); | ||||
| 		vars.set("i_quest" + index, newAggroVal); | ||||
| 		vars.set("c_quest" + index, attacker); | ||||
| 	} | ||||
| 	 | ||||
| 	@Override | ||||
| 	public String onSpellFinished(Npc npc, Player player, Skill skill) | ||||
| 	{ | ||||
| 		startQuestTimer("MANAGE_SKILLS", 1000, npc, null); | ||||
| 		 | ||||
| 		return super.onSpellFinished(npc, player, skill); | ||||
| 	} | ||||
| 	 | ||||
| 	private void manageSkills(Npc npc) | ||||
| 	{ | ||||
| 		if (npc.isCastingNow(SkillCaster::isAnyNormalType) || npc.isCoreAIDisabled() || !npc.isInCombat()) | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		final NpcVariables vars = npc.getVariables(); | ||||
| 		for (int i = 0; i < 3; i++) | ||||
| 		{ | ||||
| 			final Creature attacker = vars.getObject("c_quest" + i, Creature.class); | ||||
| 			if ((attacker == null) || ((npc.calculateDistance3D(attacker) > 9000) || attacker.isDead())) | ||||
| 			{ | ||||
| 				vars.set("i_quest" + i, 0); | ||||
| 			} | ||||
| 		} | ||||
| 		final int index = CommonUtil.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2")); | ||||
| 		final Creature player = vars.getObject("c_quest" + index, Creature.class); | ||||
| 		final int i2 = vars.getInt("i_quest" + index); | ||||
| 		if ((i2 > 0) && (getRandom(100) < 70)) | ||||
| 		{ | ||||
| 			vars.set("i_quest" + index, 500); | ||||
| 		} | ||||
| 		 | ||||
| 		SkillHolder skillToCast = null; | ||||
| 		int chance = getRandom(100); | ||||
| 		if ((player != null) && !player.isDead()) | ||||
| 		{ | ||||
| 			if (chance < 15) | ||||
| 			{ | ||||
| 				skillToCast = MAGIC_HOLD; | ||||
| 			} | ||||
| 			else if (chance < 25) | ||||
| 			{ | ||||
| 				skillToCast = TERA_FEAR; | ||||
| 			} | ||||
| 			else if (chance < 35) | ||||
| 			{ | ||||
| 				skillToCast = MAGIC_BURST; | ||||
| 			} | ||||
| 			else if (chance < 55) | ||||
| 			{ | ||||
| 				skillToCast = MAGIC_BLAST; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				skillToCast = MAGIC_BOLT; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		if ((skillToCast != null) && SkillCaster.checkUseConditions(npc, skillToCast.getSkill())) | ||||
| 		 | ||||
| 		{ | ||||
| 			npc.setTarget(player); | ||||
| 			npc.doCast(skillToCast.getSkill()); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public static void main(String[] args) | ||||
| 	{ | ||||
| 		new LilithEliteShaman(); | ||||
| 	} | ||||
| } | ||||
| @@ -1727,7 +1727,7 @@ | ||||
| 			<npc id="24488" x="176968" y="-23016" z="-3546" heading="3875" respawnTime="60sec" /> <!-- Doom Archer --> | ||||
| 			<npc id="24491" x="176968" y="-23016" z="-3546" heading="3875" respawnTime="60sec" /> <!-- Doom Knight --> | ||||
| 			<npc id="33867" x="183529" y="-16020" z="-2712" heading="11151" respawnTime="60sec" /> <!-- Shuvann --> | ||||
| 			<npc id="31109" x="171960" y="-17592" z="-4904" heading="33922" respawnTime="60sec" /> <!-- Gatekeeper Ziggurat --> | ||||
| 			<npc id="31101" x="171960" y="-17592" z="-4904" heading="33922" respawnTime="30sec" /> <!-- Gatekeeper Ziggurat - Anakim Entry--> | ||||
| 		</group> | ||||
| 	</spawn> | ||||
| </list> | ||||
| @@ -1649,7 +1649,7 @@ | ||||
| 			<npc id="24454" x="-19006" y="21025" z="-3771" heading="17754" respawnTime="40sec" /> <!-- Doom Berserker --> | ||||
| 			<npc id="24455" x="-18920" y="21256" z="-3774" heading="64798" respawnTime="40sec" /> <!-- Doom Seer --> | ||||
| 			<npc id="24452" x="-18776" y="21384" z="-3776" heading="7635" respawnTime="40sec" /> <!-- Doom Soldier --> | ||||
| 			<npc id="31124" x="-19736" y="13512" z="-4904" heading="33989" respawnTime="60sec" /> <!-- Gatekeeper Ziggurat --> | ||||
| 			<npc id="31118" x="-19736" y="13512" z="-4904" heading="33989" respawnTime="60sec" /> <!-- Gatekeeper Ziggurat - Lilith Entry--> | ||||
| 		</group> | ||||
| 	</spawn> | ||||
| </list> | ||||
		Reference in New Issue
	
	Block a user
	 MobiusDevelopment
					MobiusDevelopment