Re-addition of Anakim and Lilith AIs.
Contributed by CostyKiller.
This commit is contained in:
parent
d79d2ad78b
commit
ded255f5af
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>
|
4
L2J_Mobius_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Anakim/31101-01.html
vendored
Normal file
4
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Anakim/31101-02.html
vendored
Normal file
3
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Anakim/31101-03.html
vendored
Normal file
4
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Anakim/31101-04.html
vendored
Normal file
3
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Anakim/31101.html
vendored
Normal file
7
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Anakim/31109.html
vendored
Normal file
5
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Anakim/31111.html
vendored
Normal file
4
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Anakim/Anakim.java
vendored
Normal file
369
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Anakim/AnakimBoss.java
vendored
Normal file
220
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Anakim/AnakimElitePriest.java
vendored
Normal file
188
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Lilith/31110.html
vendored
Normal file
4
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Lilith/31118-01.html
vendored
Normal file
4
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Lilith/31118-02.html
vendored
Normal file
3
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Lilith/31118-03.html
vendored
Normal file
4
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Lilith/31118-04.html
vendored
Normal file
3
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Lilith/31118.html
vendored
Normal file
7
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Lilith/31124.html
vendored
Normal file
5
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Lilith/Lilith.java
vendored
Normal file
368
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Lilith/LilithBoss.java
vendored
Normal file
220
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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_09.2_ReturnOfTheQueenAnt/dist/game/data/scripts/ai/bosses/Lilith/LilithEliteShaman.java
vendored
Normal file
193
L2J_Mobius_09.2_ReturnOfTheQueenAnt/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();
|
||||
}
|
||||
}
|
@ -1520,7 +1520,7 @@
|
||||
<npc id="24490" x="189112" y="-15304" z="-1318" heading="55377" respawnTime="30sec" /> <!-- Doom Soldier -->
|
||||
<npc id="24490" x="189288" y="-14408" z="-1308" heading="63588" respawnTime="30sec" /> <!-- Doom Soldier -->
|
||||
<npc id="24490" x="189688" y="-12920" z="-1424" heading="10332" respawnTime="30sec" /> <!-- Doom Soldier -->
|
||||
<npc id="31109" x="171960" y="-17592" z="-4904" heading="33922" respawnTime="30sec" /> <!-- Gatekeeper Ziggurat -->
|
||||
<npc id="31101" x="171960" y="-17592" z="-4904" heading="33922" respawnTime="30sec" /> <!-- Gatekeeper Ziggurat - Anakim Entry-->
|
||||
<npc id="33867" x="183529" y="-16020" z="-2712" heading="11151" respawnTime="30sec" /> <!-- Shuvann -->
|
||||
</group>
|
||||
</spawn>
|
||||
|
@ -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>
|
4
L2J_Mobius_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31101-01.html
vendored
Normal file
4
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31101-02.html
vendored
Normal file
3
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31101-03.html
vendored
Normal file
4
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31101-04.html
vendored
Normal file
3
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31101.html
vendored
Normal file
7
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31109.html
vendored
Normal file
5
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31111.html
vendored
Normal file
4
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/Anakim.java
vendored
Normal file
369
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/AnakimBoss.java
vendored
Normal file
220
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/AnakimElitePriest.java
vendored
Normal file
188
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31110.html
vendored
Normal file
4
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31118-01.html
vendored
Normal file
4
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31118-02.html
vendored
Normal file
3
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31118-03.html
vendored
Normal file
4
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31118-04.html
vendored
Normal file
3
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31118.html
vendored
Normal file
7
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31124.html
vendored
Normal file
5
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/Lilith.java
vendored
Normal file
368
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/LilithBoss.java
vendored
Normal file
220
L2J_Mobius_10.1_MasterClass/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_10.1_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/LilithEliteShaman.java
vendored
Normal file
193
L2J_Mobius_10.1_MasterClass/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();
|
||||
}
|
||||
}
|
@ -1520,7 +1520,7 @@
|
||||
<npc id="24490" x="189112" y="-15304" z="-1318" heading="55377" respawnTime="30sec" /> <!-- Doom Soldier -->
|
||||
<npc id="24490" x="189288" y="-14408" z="-1308" heading="63588" respawnTime="30sec" /> <!-- Doom Soldier -->
|
||||
<npc id="24490" x="189688" y="-12920" z="-1424" heading="10332" respawnTime="30sec" /> <!-- Doom Soldier -->
|
||||
<npc id="31109" x="171960" y="-17592" z="-4904" heading="33922" respawnTime="30sec" /> <!-- Gatekeeper Ziggurat -->
|
||||
<npc id="31101" x="171960" y="-17592" z="-4904" heading="33922" respawnTime="30sec" /> <!-- Gatekeeper Ziggurat - Anakim Entry-->
|
||||
<npc id="33867" x="183529" y="-16020" z="-2712" heading="11151" respawnTime="30sec" /> <!-- Shuvann -->
|
||||
</group>
|
||||
</spawn>
|
||||
|
@ -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>
|
4
L2J_Mobius_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31101-01.html
vendored
Normal file
4
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31101-02.html
vendored
Normal file
3
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31101-03.html
vendored
Normal file
4
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31101-04.html
vendored
Normal file
3
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31101.html
vendored
Normal file
7
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31109.html
vendored
Normal file
5
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/31111.html
vendored
Normal file
4
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/Anakim.java
vendored
Normal file
369
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/AnakimBoss.java
vendored
Normal file
220
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Anakim/AnakimElitePriest.java
vendored
Normal file
188
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31110.html
vendored
Normal file
4
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31118-01.html
vendored
Normal file
4
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31118-02.html
vendored
Normal file
3
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31118-03.html
vendored
Normal file
4
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31118-04.html
vendored
Normal file
3
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31118.html
vendored
Normal file
7
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/31124.html
vendored
Normal file
5
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/Lilith.java
vendored
Normal file
368
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/LilithBoss.java
vendored
Normal file
220
L2J_Mobius_10.2_MasterClass/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_10.2_MasterClass/dist/game/data/scripts/ai/bosses/Lilith/LilithEliteShaman.java
vendored
Normal file
193
L2J_Mobius_10.2_MasterClass/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();
|
||||
}
|
||||
}
|
@ -1520,7 +1520,7 @@
|
||||
<npc id="24490" x="189112" y="-15304" z="-1318" heading="55377" respawnTime="30sec" /> <!-- Doom Soldier -->
|
||||
<npc id="24490" x="189288" y="-14408" z="-1308" heading="63588" respawnTime="30sec" /> <!-- Doom Soldier -->
|
||||
<npc id="24490" x="189688" y="-12920" z="-1424" heading="10332" respawnTime="30sec" /> <!-- Doom Soldier -->
|
||||
<npc id="31109" x="171960" y="-17592" z="-4904" heading="33922" respawnTime="30sec" /> <!-- Gatekeeper Ziggurat -->
|
||||
<npc id="31101" x="171960" y="-17592" z="-4904" heading="33922" respawnTime="30sec" /> <!-- Gatekeeper Ziggurat - Anakim Entry-->
|
||||
<npc id="33867" x="183529" y="-16020" z="-2712" heading="11151" respawnTime="30sec" /> <!-- Shuvann -->
|
||||
</group>
|
||||
</spawn>
|
||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user