From 532202c8edeeceebdf283732a293006fe8fc781f Mon Sep 17 00:00:00 2001
From: MobiusDevelopment <8391001+MobiusDevelopment@users.noreply.github.com>
Date: Fri, 27 Sep 2019 21:03:54 +0000
Subject: [PATCH] Valakas AI improvements. Contributed by Sahar.
---
.../scripts/ai/bosses/Valakas/Valakas.java | 238 +++++-------------
.../scripts/ai/bosses/Valakas/Valakas.java | 238 +++++-------------
.../scripts/ai/bosses/Valakas/Valakas.java | 238 +++++-------------
.../scripts/ai/bosses/Valakas/Valakas.java | 238 +++++-------------
.../scripts/ai/bosses/Valakas/Valakas.java | 238 +++++-------------
.../scripts/ai/bosses/Valakas/Valakas.java | 238 +++++-------------
.../scripts/ai/bosses/Valakas/Valakas.java | 238 +++++-------------
.../scripts/ai/bosses/Valakas/Valakas.java | 238 +++++-------------
.../scripts/ai/bosses/Valakas/Valakas.java | 45 ++--
9 files changed, 546 insertions(+), 1403 deletions(-)
diff --git a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
index 2d75edac09..456322bc1d 100644
--- a/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
+++ b/L2J_Mobius_1.0_Ertheia/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
@@ -24,11 +24,11 @@ import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatsSet;
+import org.l2jmobius.gameserver.model.actor.Attackable;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.BuffInfo;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.SocialAction;
@@ -45,37 +45,13 @@ public class Valakas extends AbstractNpcAI
// NPC
private static final int VALAKAS = 29028;
// Skills
- // private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
private static final int VALAKAS_REGENERATION = 4691;
-
- // private static final SkillHolder[] VALAKAS_REGULAR_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // };
- //
- // private static final SkillHolder[] VALAKAS_LOWHP_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
- //
- // private static final SkillHolder[] VALAKAS_AOE_SKILLS =
- // {
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4684, 1), // Valakas Dragon Breath
- // new SkillHolder(4685, 1), // Valakas Tail Stomp
- // new SkillHolder(4686, 1), // Valakas Tail Stomp
- // new SkillHolder(4688, 1), // Valakas Stun
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
-
+ /*
+ * private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1); private static final SkillHolder[] VALAKAS_REGULAR_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. }; private static final SkillHolder[] VALAKAS_LOWHP_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm }; private static final SkillHolder[] VALAKAS_AOE_SKILLS = { new SkillHolder(4683, 1), // Valakas Dragon Breath new SkillHolder(4684, 1), // Valakas Dragon
+ * Breath new SkillHolder(4685, 1), // Valakas Tail Stomp new SkillHolder(4686, 1), // Valakas Tail Stomp new SkillHolder(4688, 1), // Valakas Stun new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm };
+ */
// Locations
private static final Location TELEPORT_CUBE_LOCATIONS[] =
{
@@ -95,6 +71,7 @@ public class Valakas extends AbstractNpcAI
new Location(215456, -117328, -1392),
new Location(213200, -118160, -1424)
};
+ private static final Location VALAKAS_HIDDEN_LOC = new Location(220963, -104895, -1620);
private static final Location ATTACKER_REMOVE = new Location(150037, -57255, -2976);
private static final Location VALAKAS_LAIR = new Location(212852, -114842, -1632);
private static final Location VALAKAS_REGENERATION_LOC = new Location(-105200, -253104, -15264);
@@ -119,7 +96,7 @@ public class Valakas extends AbstractNpcAI
if (status == DEAD)
{
// load the unlock date and time for valakas from DB
- final long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
+ final long temp = info.getLong("respawn_time") - System.currentTimeMillis();
if (temp > 0)
{
// The time has not yet expired. Mark Valakas as currently locked (dead).
@@ -128,7 +105,8 @@ public class Valakas extends AbstractNpcAI
else
{
// The time has expired while the server was offline. Spawn valakas in his cave as DORMANT.
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 0, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
@@ -164,13 +142,14 @@ public class Valakas extends AbstractNpcAI
}
else
{
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
valakas.setIsInvul(true);
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Start timer to lock entry after 30 minutes
if (status == WAITING)
{
- startQuestTimer("beginning", (Config.VALAKAS_WAIT_TIME * 60000), valakas, null);
+ startQuestTimer("beginning", Config.VALAKAS_WAIT_TIME * 60000, valakas, null);
}
}
}
@@ -190,11 +169,7 @@ public class Valakas extends AbstractNpcAI
npc.teleToLocation(VALAKAS_LAIR);
// Sound + socialAction.
- for (PlayerInstance plyr : ZONE.getPlayersInside())
- {
- plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
- plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
- }
+ startQuestTimer("broadcast_spawn", 100, npc, null);
// Launch the cinematic, and tasks (regen + skill).
startQuestTimer("spawn_1", 1700, npc, null); // 1700
@@ -212,24 +187,21 @@ public class Valakas extends AbstractNpcAI
else if (event.equalsIgnoreCase("regen_task"))
{
// Inactivity task - 15min
- if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
+ if ((GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING) && ((_timeTracker + 900000) < System.currentTimeMillis()))
{
- if ((_timeTracker + 900000) < System.currentTimeMillis())
- {
- npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- npc.teleToLocation(VALAKAS_REGENERATION_LOC);
-
- GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
- npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
-
- // Drop all players from the zone.
- ZONE.oustAllPlayers();
-
- // Cancel skill_task and regen_task.
- cancelQuestTimer("regen_task", npc, null);
- cancelQuestTimer("skill_task", npc, null);
- return null;
- }
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
+ npc.teleToLocation(VALAKAS_REGENERATION_LOC);
+
+ GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
+ npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
+
+ // Drop all players from the zone.
+ ZONE.oustAllPlayers();
+
+ // Cancel skill_task and regen_task.
+ cancelQuestTimer("regen_task", npc, null);
+ cancelQuestTimer("skill_task", npc, null);
+ return null;
}
// Verify if "Valakas Regeneration" skill is active.
@@ -261,6 +233,14 @@ public class Valakas extends AbstractNpcAI
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
}
}
+ else if (event.equalsIgnoreCase("broadcast_spawn"))
+ {
+ for (PlayerInstance plyr : ZONE.getPlayersInside())
+ {
+ plyr.sendPacket(new PlaySound(1, "BS03_A", 0, 0, 0, 0, 0));
+ plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
+ }
+ }
// Spawn cinematic, regen_task and choose of skill.
else if (event.equalsIgnoreCase("spawn_1"))
{
@@ -353,7 +333,11 @@ public class Valakas extends AbstractNpcAI
}
else if (event.equalsIgnoreCase("valakas_unlock"))
{
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 32768, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
+ valakas.setIsInvul(true);
+ valakas.setRunning();
+ valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
}
@@ -364,12 +348,14 @@ public class Valakas extends AbstractNpcAI
return super.onAdvEvent(event, npc, player);
}
- // @Override
- // public String onSpawn(Npc npc)
- // {
- // npc.disableCoreAI(true);
- // return super.onSpawn(npc);
- // }
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ ((Attackable) npc).setCanReturnToSpawnPoint(false);
+ npc.setRandomWalking(false);
+ npc.disableCoreAI(true);
+ return super.onSpawn(npc);
+ }
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@@ -392,14 +378,10 @@ public class Valakas extends AbstractNpcAI
}
// Debuff strider-mounted players.
- if (attacker.getMountType() == MountType.STRIDER)
+ if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(4258))
{
- final Skill skill = SkillData.getInstance().getSkill(4258, 1);
- if (!attacker.isAffectedBySkill(4258))
- {
- npc.setTarget(attacker);
- npc.doCast(skill);
- }
+ npc.setTarget(attacker);
+ npc.doCast(SkillData.getInstance().getSkill(4258, 1));
}
_timeTracker = System.currentTimeMillis();
@@ -428,117 +410,27 @@ public class Valakas extends AbstractNpcAI
GrandBossManager.getInstance().setBossStatus(VALAKAS, DEAD);
// Calculate Min and Max respawn times randomly.
- long respawnTime = Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM);
- respawnTime *= 3600000;
-
+ final long respawnTime = (Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM)) * 3600000;
startQuestTimer("valakas_unlock", respawnTime, null, null);
// also save the respawn time so that the info is maintained past reboots
final StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
- info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
+ info.set("respawn_time", System.currentTimeMillis() + respawnTime);
GrandBossManager.getInstance().setStatsSet(VALAKAS, info);
return super.onKill(npc, killer, isSummon);
}
- // @Override
- // public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon)
- // {
- // return null;
- // }
- //
- // private void callSkillAI(Npc npc)
- // {
- // if (npc.isInvul() || npc.isCastingNow(SkillCaster::isAnyNormalType))
- // {
- // return;
- // }
- //
- // // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target.
- // if ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0))
- // {
- // _actualVictim = getRandomTarget(npc);
- // }
- //
- // // If result is still null, Valakas will roam. Don't go deeper in skill AI.
- // if (_actualVictim == null)
- // {
- // if (getRandom(10) == 0)
- // {
- // final int posX = npc.getX() + getRandom(-1400, 1400);
- // final int posY = npc.getY() + getRandom(-1400, 1400);
- // if (GeoEngine.getInstance().canMoveToTarget(npc.getX(), npc.getY(), npc.getZ(), posX, posY, npc.getZ(), npc.getInstanceWorld()))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, npc.getZ(), 0));
- // }
- // }
- // return;
- // }
- //
- // final Skill skill = getRandomSkill(npc).getSkill();
- //
- // // Cast the skill or follow the target.
- // if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc, _actualVictim, true))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- // npc.setTarget(_actualVictim);
- // npc.doCast(skill);
- // }
- // else
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null);
- // }
- // }
- //
- // /**
- // * Pick a random skill.
- // * Valakas will mostly use utility skills. If Valakas feels surrounded, he will use AoE skills.
- // * Lower than 50% HPs, he will begin to use Meteor skill.
- // * @param npc valakas
- // * @return a skill holder
- // */
- // private SkillHolder getRandomSkill(Npc npc)
- // {
- // final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100);
- //
- // // Valakas Lava Skin has priority.
- // if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId()))
- // {
- // return VALAKAS_LAVA_SKIN;
- // }
- //
- // // Valakas will use mass spells if he feels surrounded.
- // if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20)
- // {
- // return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)];
- // }
- //
- // if (hpRatio > 50)
- // {
- // return VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)];
- // }
- //
- // return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)];
- // }
- //
- // /**
- // * Pickup a random Playable from the zone, deads targets aren't included.
- // * @param npc
- // * @return a random Playable.
- // */
- // private Playable getRandomTarget(Npc npc)
- // {
- // final List result = new ArrayList<>();
- //
- // World.getInstance().forEachVisibleObject(npc, Playable.class, obj ->
- // {
- // if (!obj.isPet() && !obj.isDead())
- // {
- // result.add(obj);
- // }
- // });
- //
- // return (result.isEmpty()) ? null : result.get(getRandom(result.size()));
- // }
+ /*
+ * @Override public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon) { return null; } private void callSkillAI(Npc npc) { if (npc.isInvul() || npc.isCastingNow()) { return; } // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target. if
+ * ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0)) { _actualVictim = getRandomTarget(npc); } // If result is still null, Valakas will roam. Don't go deeper in skill AI. if (_actualVictim == null) { if (getRandom(10) == 0)
+ * { final int x = npc.getX(); final int y = npc.getY(); final int z = npc.getZ(); final int posX = x + getRandom(-1400, 1400); final int posY = y + getRandom(-1400, 1400); if (GeoEngine.getInstance().canMoveToTarget(x, y, z, posX, posY, z, npc.getInstanceId())) {
+ * npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, z, 0)); } } return; } final Skill skill = getRandomSkill(npc).getSkill(); // Cast the skill or follow the target. if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc,
+ * _actualVictim, true)) { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); npc.setIsCastingNow(true); npc.setTarget(_actualVictim); npc.doCast(skill); } else { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null); npc.setIsCastingNow(false); } } private
+ * SkillHolder getRandomSkill(Npc npc) { final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100); // Valakas Lava Skin has priority. if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId())) { return VALAKAS_LAVA_SKIN; } // Valakas
+ * will use mass spells if he feels surrounded. if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20) { return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)]; } if (hpRatio > 50) { return
+ * VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)]; } return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)]; } private Playable getRandomTarget(Npc npc) { final List result = new ArrayList<>(); World.getInstance().forEachVisibleObject(npc, Playable.class,
+ * obj -> { if ((obj == null) || obj.isPet()) { return; } else if (!obj.isDead() && obj.isPlayable()) { result.add(obj); } }); return result.isEmpty() ? null : result.get(getRandom(result.size())); }
+ */
public static void main(String[] args)
{
diff --git a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
index 2d75edac09..456322bc1d 100644
--- a/L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
+++ b/L2J_Mobius_2.5_Underground/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
@@ -24,11 +24,11 @@ import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatsSet;
+import org.l2jmobius.gameserver.model.actor.Attackable;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.BuffInfo;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.SocialAction;
@@ -45,37 +45,13 @@ public class Valakas extends AbstractNpcAI
// NPC
private static final int VALAKAS = 29028;
// Skills
- // private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
private static final int VALAKAS_REGENERATION = 4691;
-
- // private static final SkillHolder[] VALAKAS_REGULAR_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // };
- //
- // private static final SkillHolder[] VALAKAS_LOWHP_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
- //
- // private static final SkillHolder[] VALAKAS_AOE_SKILLS =
- // {
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4684, 1), // Valakas Dragon Breath
- // new SkillHolder(4685, 1), // Valakas Tail Stomp
- // new SkillHolder(4686, 1), // Valakas Tail Stomp
- // new SkillHolder(4688, 1), // Valakas Stun
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
-
+ /*
+ * private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1); private static final SkillHolder[] VALAKAS_REGULAR_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. }; private static final SkillHolder[] VALAKAS_LOWHP_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm }; private static final SkillHolder[] VALAKAS_AOE_SKILLS = { new SkillHolder(4683, 1), // Valakas Dragon Breath new SkillHolder(4684, 1), // Valakas Dragon
+ * Breath new SkillHolder(4685, 1), // Valakas Tail Stomp new SkillHolder(4686, 1), // Valakas Tail Stomp new SkillHolder(4688, 1), // Valakas Stun new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm };
+ */
// Locations
private static final Location TELEPORT_CUBE_LOCATIONS[] =
{
@@ -95,6 +71,7 @@ public class Valakas extends AbstractNpcAI
new Location(215456, -117328, -1392),
new Location(213200, -118160, -1424)
};
+ private static final Location VALAKAS_HIDDEN_LOC = new Location(220963, -104895, -1620);
private static final Location ATTACKER_REMOVE = new Location(150037, -57255, -2976);
private static final Location VALAKAS_LAIR = new Location(212852, -114842, -1632);
private static final Location VALAKAS_REGENERATION_LOC = new Location(-105200, -253104, -15264);
@@ -119,7 +96,7 @@ public class Valakas extends AbstractNpcAI
if (status == DEAD)
{
// load the unlock date and time for valakas from DB
- final long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
+ final long temp = info.getLong("respawn_time") - System.currentTimeMillis();
if (temp > 0)
{
// The time has not yet expired. Mark Valakas as currently locked (dead).
@@ -128,7 +105,8 @@ public class Valakas extends AbstractNpcAI
else
{
// The time has expired while the server was offline. Spawn valakas in his cave as DORMANT.
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 0, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
@@ -164,13 +142,14 @@ public class Valakas extends AbstractNpcAI
}
else
{
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
valakas.setIsInvul(true);
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Start timer to lock entry after 30 minutes
if (status == WAITING)
{
- startQuestTimer("beginning", (Config.VALAKAS_WAIT_TIME * 60000), valakas, null);
+ startQuestTimer("beginning", Config.VALAKAS_WAIT_TIME * 60000, valakas, null);
}
}
}
@@ -190,11 +169,7 @@ public class Valakas extends AbstractNpcAI
npc.teleToLocation(VALAKAS_LAIR);
// Sound + socialAction.
- for (PlayerInstance plyr : ZONE.getPlayersInside())
- {
- plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
- plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
- }
+ startQuestTimer("broadcast_spawn", 100, npc, null);
// Launch the cinematic, and tasks (regen + skill).
startQuestTimer("spawn_1", 1700, npc, null); // 1700
@@ -212,24 +187,21 @@ public class Valakas extends AbstractNpcAI
else if (event.equalsIgnoreCase("regen_task"))
{
// Inactivity task - 15min
- if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
+ if ((GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING) && ((_timeTracker + 900000) < System.currentTimeMillis()))
{
- if ((_timeTracker + 900000) < System.currentTimeMillis())
- {
- npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- npc.teleToLocation(VALAKAS_REGENERATION_LOC);
-
- GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
- npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
-
- // Drop all players from the zone.
- ZONE.oustAllPlayers();
-
- // Cancel skill_task and regen_task.
- cancelQuestTimer("regen_task", npc, null);
- cancelQuestTimer("skill_task", npc, null);
- return null;
- }
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
+ npc.teleToLocation(VALAKAS_REGENERATION_LOC);
+
+ GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
+ npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
+
+ // Drop all players from the zone.
+ ZONE.oustAllPlayers();
+
+ // Cancel skill_task and regen_task.
+ cancelQuestTimer("regen_task", npc, null);
+ cancelQuestTimer("skill_task", npc, null);
+ return null;
}
// Verify if "Valakas Regeneration" skill is active.
@@ -261,6 +233,14 @@ public class Valakas extends AbstractNpcAI
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
}
}
+ else if (event.equalsIgnoreCase("broadcast_spawn"))
+ {
+ for (PlayerInstance plyr : ZONE.getPlayersInside())
+ {
+ plyr.sendPacket(new PlaySound(1, "BS03_A", 0, 0, 0, 0, 0));
+ plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
+ }
+ }
// Spawn cinematic, regen_task and choose of skill.
else if (event.equalsIgnoreCase("spawn_1"))
{
@@ -353,7 +333,11 @@ public class Valakas extends AbstractNpcAI
}
else if (event.equalsIgnoreCase("valakas_unlock"))
{
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 32768, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
+ valakas.setIsInvul(true);
+ valakas.setRunning();
+ valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
}
@@ -364,12 +348,14 @@ public class Valakas extends AbstractNpcAI
return super.onAdvEvent(event, npc, player);
}
- // @Override
- // public String onSpawn(Npc npc)
- // {
- // npc.disableCoreAI(true);
- // return super.onSpawn(npc);
- // }
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ ((Attackable) npc).setCanReturnToSpawnPoint(false);
+ npc.setRandomWalking(false);
+ npc.disableCoreAI(true);
+ return super.onSpawn(npc);
+ }
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@@ -392,14 +378,10 @@ public class Valakas extends AbstractNpcAI
}
// Debuff strider-mounted players.
- if (attacker.getMountType() == MountType.STRIDER)
+ if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(4258))
{
- final Skill skill = SkillData.getInstance().getSkill(4258, 1);
- if (!attacker.isAffectedBySkill(4258))
- {
- npc.setTarget(attacker);
- npc.doCast(skill);
- }
+ npc.setTarget(attacker);
+ npc.doCast(SkillData.getInstance().getSkill(4258, 1));
}
_timeTracker = System.currentTimeMillis();
@@ -428,117 +410,27 @@ public class Valakas extends AbstractNpcAI
GrandBossManager.getInstance().setBossStatus(VALAKAS, DEAD);
// Calculate Min and Max respawn times randomly.
- long respawnTime = Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM);
- respawnTime *= 3600000;
-
+ final long respawnTime = (Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM)) * 3600000;
startQuestTimer("valakas_unlock", respawnTime, null, null);
// also save the respawn time so that the info is maintained past reboots
final StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
- info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
+ info.set("respawn_time", System.currentTimeMillis() + respawnTime);
GrandBossManager.getInstance().setStatsSet(VALAKAS, info);
return super.onKill(npc, killer, isSummon);
}
- // @Override
- // public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon)
- // {
- // return null;
- // }
- //
- // private void callSkillAI(Npc npc)
- // {
- // if (npc.isInvul() || npc.isCastingNow(SkillCaster::isAnyNormalType))
- // {
- // return;
- // }
- //
- // // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target.
- // if ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0))
- // {
- // _actualVictim = getRandomTarget(npc);
- // }
- //
- // // If result is still null, Valakas will roam. Don't go deeper in skill AI.
- // if (_actualVictim == null)
- // {
- // if (getRandom(10) == 0)
- // {
- // final int posX = npc.getX() + getRandom(-1400, 1400);
- // final int posY = npc.getY() + getRandom(-1400, 1400);
- // if (GeoEngine.getInstance().canMoveToTarget(npc.getX(), npc.getY(), npc.getZ(), posX, posY, npc.getZ(), npc.getInstanceWorld()))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, npc.getZ(), 0));
- // }
- // }
- // return;
- // }
- //
- // final Skill skill = getRandomSkill(npc).getSkill();
- //
- // // Cast the skill or follow the target.
- // if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc, _actualVictim, true))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- // npc.setTarget(_actualVictim);
- // npc.doCast(skill);
- // }
- // else
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null);
- // }
- // }
- //
- // /**
- // * Pick a random skill.
- // * Valakas will mostly use utility skills. If Valakas feels surrounded, he will use AoE skills.
- // * Lower than 50% HPs, he will begin to use Meteor skill.
- // * @param npc valakas
- // * @return a skill holder
- // */
- // private SkillHolder getRandomSkill(Npc npc)
- // {
- // final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100);
- //
- // // Valakas Lava Skin has priority.
- // if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId()))
- // {
- // return VALAKAS_LAVA_SKIN;
- // }
- //
- // // Valakas will use mass spells if he feels surrounded.
- // if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20)
- // {
- // return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)];
- // }
- //
- // if (hpRatio > 50)
- // {
- // return VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)];
- // }
- //
- // return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)];
- // }
- //
- // /**
- // * Pickup a random Playable from the zone, deads targets aren't included.
- // * @param npc
- // * @return a random Playable.
- // */
- // private Playable getRandomTarget(Npc npc)
- // {
- // final List result = new ArrayList<>();
- //
- // World.getInstance().forEachVisibleObject(npc, Playable.class, obj ->
- // {
- // if (!obj.isPet() && !obj.isDead())
- // {
- // result.add(obj);
- // }
- // });
- //
- // return (result.isEmpty()) ? null : result.get(getRandom(result.size()));
- // }
+ /*
+ * @Override public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon) { return null; } private void callSkillAI(Npc npc) { if (npc.isInvul() || npc.isCastingNow()) { return; } // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target. if
+ * ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0)) { _actualVictim = getRandomTarget(npc); } // If result is still null, Valakas will roam. Don't go deeper in skill AI. if (_actualVictim == null) { if (getRandom(10) == 0)
+ * { final int x = npc.getX(); final int y = npc.getY(); final int z = npc.getZ(); final int posX = x + getRandom(-1400, 1400); final int posY = y + getRandom(-1400, 1400); if (GeoEngine.getInstance().canMoveToTarget(x, y, z, posX, posY, z, npc.getInstanceId())) {
+ * npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, z, 0)); } } return; } final Skill skill = getRandomSkill(npc).getSkill(); // Cast the skill or follow the target. if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc,
+ * _actualVictim, true)) { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); npc.setIsCastingNow(true); npc.setTarget(_actualVictim); npc.doCast(skill); } else { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null); npc.setIsCastingNow(false); } } private
+ * SkillHolder getRandomSkill(Npc npc) { final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100); // Valakas Lava Skin has priority. if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId())) { return VALAKAS_LAVA_SKIN; } // Valakas
+ * will use mass spells if he feels surrounded. if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20) { return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)]; } if (hpRatio > 50) { return
+ * VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)]; } return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)]; } private Playable getRandomTarget(Npc npc) { final List result = new ArrayList<>(); World.getInstance().forEachVisibleObject(npc, Playable.class,
+ * obj -> { if ((obj == null) || obj.isPet()) { return; } else if (!obj.isDead() && obj.isPlayable()) { result.add(obj); } }); return result.isEmpty() ? null : result.get(getRandom(result.size())); }
+ */
public static void main(String[] args)
{
diff --git a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
index 2d75edac09..456322bc1d 100644
--- a/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
+++ b/L2J_Mobius_3.0_Helios/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
@@ -24,11 +24,11 @@ import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatsSet;
+import org.l2jmobius.gameserver.model.actor.Attackable;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.BuffInfo;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.SocialAction;
@@ -45,37 +45,13 @@ public class Valakas extends AbstractNpcAI
// NPC
private static final int VALAKAS = 29028;
// Skills
- // private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
private static final int VALAKAS_REGENERATION = 4691;
-
- // private static final SkillHolder[] VALAKAS_REGULAR_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // };
- //
- // private static final SkillHolder[] VALAKAS_LOWHP_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
- //
- // private static final SkillHolder[] VALAKAS_AOE_SKILLS =
- // {
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4684, 1), // Valakas Dragon Breath
- // new SkillHolder(4685, 1), // Valakas Tail Stomp
- // new SkillHolder(4686, 1), // Valakas Tail Stomp
- // new SkillHolder(4688, 1), // Valakas Stun
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
-
+ /*
+ * private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1); private static final SkillHolder[] VALAKAS_REGULAR_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. }; private static final SkillHolder[] VALAKAS_LOWHP_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm }; private static final SkillHolder[] VALAKAS_AOE_SKILLS = { new SkillHolder(4683, 1), // Valakas Dragon Breath new SkillHolder(4684, 1), // Valakas Dragon
+ * Breath new SkillHolder(4685, 1), // Valakas Tail Stomp new SkillHolder(4686, 1), // Valakas Tail Stomp new SkillHolder(4688, 1), // Valakas Stun new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm };
+ */
// Locations
private static final Location TELEPORT_CUBE_LOCATIONS[] =
{
@@ -95,6 +71,7 @@ public class Valakas extends AbstractNpcAI
new Location(215456, -117328, -1392),
new Location(213200, -118160, -1424)
};
+ private static final Location VALAKAS_HIDDEN_LOC = new Location(220963, -104895, -1620);
private static final Location ATTACKER_REMOVE = new Location(150037, -57255, -2976);
private static final Location VALAKAS_LAIR = new Location(212852, -114842, -1632);
private static final Location VALAKAS_REGENERATION_LOC = new Location(-105200, -253104, -15264);
@@ -119,7 +96,7 @@ public class Valakas extends AbstractNpcAI
if (status == DEAD)
{
// load the unlock date and time for valakas from DB
- final long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
+ final long temp = info.getLong("respawn_time") - System.currentTimeMillis();
if (temp > 0)
{
// The time has not yet expired. Mark Valakas as currently locked (dead).
@@ -128,7 +105,8 @@ public class Valakas extends AbstractNpcAI
else
{
// The time has expired while the server was offline. Spawn valakas in his cave as DORMANT.
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 0, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
@@ -164,13 +142,14 @@ public class Valakas extends AbstractNpcAI
}
else
{
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
valakas.setIsInvul(true);
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Start timer to lock entry after 30 minutes
if (status == WAITING)
{
- startQuestTimer("beginning", (Config.VALAKAS_WAIT_TIME * 60000), valakas, null);
+ startQuestTimer("beginning", Config.VALAKAS_WAIT_TIME * 60000, valakas, null);
}
}
}
@@ -190,11 +169,7 @@ public class Valakas extends AbstractNpcAI
npc.teleToLocation(VALAKAS_LAIR);
// Sound + socialAction.
- for (PlayerInstance plyr : ZONE.getPlayersInside())
- {
- plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
- plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
- }
+ startQuestTimer("broadcast_spawn", 100, npc, null);
// Launch the cinematic, and tasks (regen + skill).
startQuestTimer("spawn_1", 1700, npc, null); // 1700
@@ -212,24 +187,21 @@ public class Valakas extends AbstractNpcAI
else if (event.equalsIgnoreCase("regen_task"))
{
// Inactivity task - 15min
- if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
+ if ((GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING) && ((_timeTracker + 900000) < System.currentTimeMillis()))
{
- if ((_timeTracker + 900000) < System.currentTimeMillis())
- {
- npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- npc.teleToLocation(VALAKAS_REGENERATION_LOC);
-
- GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
- npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
-
- // Drop all players from the zone.
- ZONE.oustAllPlayers();
-
- // Cancel skill_task and regen_task.
- cancelQuestTimer("regen_task", npc, null);
- cancelQuestTimer("skill_task", npc, null);
- return null;
- }
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
+ npc.teleToLocation(VALAKAS_REGENERATION_LOC);
+
+ GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
+ npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
+
+ // Drop all players from the zone.
+ ZONE.oustAllPlayers();
+
+ // Cancel skill_task and regen_task.
+ cancelQuestTimer("regen_task", npc, null);
+ cancelQuestTimer("skill_task", npc, null);
+ return null;
}
// Verify if "Valakas Regeneration" skill is active.
@@ -261,6 +233,14 @@ public class Valakas extends AbstractNpcAI
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
}
}
+ else if (event.equalsIgnoreCase("broadcast_spawn"))
+ {
+ for (PlayerInstance plyr : ZONE.getPlayersInside())
+ {
+ plyr.sendPacket(new PlaySound(1, "BS03_A", 0, 0, 0, 0, 0));
+ plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
+ }
+ }
// Spawn cinematic, regen_task and choose of skill.
else if (event.equalsIgnoreCase("spawn_1"))
{
@@ -353,7 +333,11 @@ public class Valakas extends AbstractNpcAI
}
else if (event.equalsIgnoreCase("valakas_unlock"))
{
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 32768, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
+ valakas.setIsInvul(true);
+ valakas.setRunning();
+ valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
}
@@ -364,12 +348,14 @@ public class Valakas extends AbstractNpcAI
return super.onAdvEvent(event, npc, player);
}
- // @Override
- // public String onSpawn(Npc npc)
- // {
- // npc.disableCoreAI(true);
- // return super.onSpawn(npc);
- // }
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ ((Attackable) npc).setCanReturnToSpawnPoint(false);
+ npc.setRandomWalking(false);
+ npc.disableCoreAI(true);
+ return super.onSpawn(npc);
+ }
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@@ -392,14 +378,10 @@ public class Valakas extends AbstractNpcAI
}
// Debuff strider-mounted players.
- if (attacker.getMountType() == MountType.STRIDER)
+ if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(4258))
{
- final Skill skill = SkillData.getInstance().getSkill(4258, 1);
- if (!attacker.isAffectedBySkill(4258))
- {
- npc.setTarget(attacker);
- npc.doCast(skill);
- }
+ npc.setTarget(attacker);
+ npc.doCast(SkillData.getInstance().getSkill(4258, 1));
}
_timeTracker = System.currentTimeMillis();
@@ -428,117 +410,27 @@ public class Valakas extends AbstractNpcAI
GrandBossManager.getInstance().setBossStatus(VALAKAS, DEAD);
// Calculate Min and Max respawn times randomly.
- long respawnTime = Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM);
- respawnTime *= 3600000;
-
+ final long respawnTime = (Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM)) * 3600000;
startQuestTimer("valakas_unlock", respawnTime, null, null);
// also save the respawn time so that the info is maintained past reboots
final StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
- info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
+ info.set("respawn_time", System.currentTimeMillis() + respawnTime);
GrandBossManager.getInstance().setStatsSet(VALAKAS, info);
return super.onKill(npc, killer, isSummon);
}
- // @Override
- // public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon)
- // {
- // return null;
- // }
- //
- // private void callSkillAI(Npc npc)
- // {
- // if (npc.isInvul() || npc.isCastingNow(SkillCaster::isAnyNormalType))
- // {
- // return;
- // }
- //
- // // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target.
- // if ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0))
- // {
- // _actualVictim = getRandomTarget(npc);
- // }
- //
- // // If result is still null, Valakas will roam. Don't go deeper in skill AI.
- // if (_actualVictim == null)
- // {
- // if (getRandom(10) == 0)
- // {
- // final int posX = npc.getX() + getRandom(-1400, 1400);
- // final int posY = npc.getY() + getRandom(-1400, 1400);
- // if (GeoEngine.getInstance().canMoveToTarget(npc.getX(), npc.getY(), npc.getZ(), posX, posY, npc.getZ(), npc.getInstanceWorld()))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, npc.getZ(), 0));
- // }
- // }
- // return;
- // }
- //
- // final Skill skill = getRandomSkill(npc).getSkill();
- //
- // // Cast the skill or follow the target.
- // if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc, _actualVictim, true))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- // npc.setTarget(_actualVictim);
- // npc.doCast(skill);
- // }
- // else
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null);
- // }
- // }
- //
- // /**
- // * Pick a random skill.
- // * Valakas will mostly use utility skills. If Valakas feels surrounded, he will use AoE skills.
- // * Lower than 50% HPs, he will begin to use Meteor skill.
- // * @param npc valakas
- // * @return a skill holder
- // */
- // private SkillHolder getRandomSkill(Npc npc)
- // {
- // final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100);
- //
- // // Valakas Lava Skin has priority.
- // if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId()))
- // {
- // return VALAKAS_LAVA_SKIN;
- // }
- //
- // // Valakas will use mass spells if he feels surrounded.
- // if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20)
- // {
- // return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)];
- // }
- //
- // if (hpRatio > 50)
- // {
- // return VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)];
- // }
- //
- // return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)];
- // }
- //
- // /**
- // * Pickup a random Playable from the zone, deads targets aren't included.
- // * @param npc
- // * @return a random Playable.
- // */
- // private Playable getRandomTarget(Npc npc)
- // {
- // final List result = new ArrayList<>();
- //
- // World.getInstance().forEachVisibleObject(npc, Playable.class, obj ->
- // {
- // if (!obj.isPet() && !obj.isDead())
- // {
- // result.add(obj);
- // }
- // });
- //
- // return (result.isEmpty()) ? null : result.get(getRandom(result.size()));
- // }
+ /*
+ * @Override public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon) { return null; } private void callSkillAI(Npc npc) { if (npc.isInvul() || npc.isCastingNow()) { return; } // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target. if
+ * ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0)) { _actualVictim = getRandomTarget(npc); } // If result is still null, Valakas will roam. Don't go deeper in skill AI. if (_actualVictim == null) { if (getRandom(10) == 0)
+ * { final int x = npc.getX(); final int y = npc.getY(); final int z = npc.getZ(); final int posX = x + getRandom(-1400, 1400); final int posY = y + getRandom(-1400, 1400); if (GeoEngine.getInstance().canMoveToTarget(x, y, z, posX, posY, z, npc.getInstanceId())) {
+ * npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, z, 0)); } } return; } final Skill skill = getRandomSkill(npc).getSkill(); // Cast the skill or follow the target. if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc,
+ * _actualVictim, true)) { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); npc.setIsCastingNow(true); npc.setTarget(_actualVictim); npc.doCast(skill); } else { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null); npc.setIsCastingNow(false); } } private
+ * SkillHolder getRandomSkill(Npc npc) { final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100); // Valakas Lava Skin has priority. if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId())) { return VALAKAS_LAVA_SKIN; } // Valakas
+ * will use mass spells if he feels surrounded. if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20) { return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)]; } if (hpRatio > 50) { return
+ * VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)]; } return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)]; } private Playable getRandomTarget(Npc npc) { final List result = new ArrayList<>(); World.getInstance().forEachVisibleObject(npc, Playable.class,
+ * obj -> { if ((obj == null) || obj.isPet()) { return; } else if (!obj.isDead() && obj.isPlayable()) { result.add(obj); } }); return result.isEmpty() ? null : result.get(getRandom(result.size())); }
+ */
public static void main(String[] args)
{
diff --git a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
index 2d75edac09..456322bc1d 100644
--- a/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
+++ b/L2J_Mobius_4.0_GrandCrusade/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
@@ -24,11 +24,11 @@ import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatsSet;
+import org.l2jmobius.gameserver.model.actor.Attackable;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.BuffInfo;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.SocialAction;
@@ -45,37 +45,13 @@ public class Valakas extends AbstractNpcAI
// NPC
private static final int VALAKAS = 29028;
// Skills
- // private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
private static final int VALAKAS_REGENERATION = 4691;
-
- // private static final SkillHolder[] VALAKAS_REGULAR_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // };
- //
- // private static final SkillHolder[] VALAKAS_LOWHP_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
- //
- // private static final SkillHolder[] VALAKAS_AOE_SKILLS =
- // {
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4684, 1), // Valakas Dragon Breath
- // new SkillHolder(4685, 1), // Valakas Tail Stomp
- // new SkillHolder(4686, 1), // Valakas Tail Stomp
- // new SkillHolder(4688, 1), // Valakas Stun
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
-
+ /*
+ * private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1); private static final SkillHolder[] VALAKAS_REGULAR_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. }; private static final SkillHolder[] VALAKAS_LOWHP_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm }; private static final SkillHolder[] VALAKAS_AOE_SKILLS = { new SkillHolder(4683, 1), // Valakas Dragon Breath new SkillHolder(4684, 1), // Valakas Dragon
+ * Breath new SkillHolder(4685, 1), // Valakas Tail Stomp new SkillHolder(4686, 1), // Valakas Tail Stomp new SkillHolder(4688, 1), // Valakas Stun new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm };
+ */
// Locations
private static final Location TELEPORT_CUBE_LOCATIONS[] =
{
@@ -95,6 +71,7 @@ public class Valakas extends AbstractNpcAI
new Location(215456, -117328, -1392),
new Location(213200, -118160, -1424)
};
+ private static final Location VALAKAS_HIDDEN_LOC = new Location(220963, -104895, -1620);
private static final Location ATTACKER_REMOVE = new Location(150037, -57255, -2976);
private static final Location VALAKAS_LAIR = new Location(212852, -114842, -1632);
private static final Location VALAKAS_REGENERATION_LOC = new Location(-105200, -253104, -15264);
@@ -119,7 +96,7 @@ public class Valakas extends AbstractNpcAI
if (status == DEAD)
{
// load the unlock date and time for valakas from DB
- final long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
+ final long temp = info.getLong("respawn_time") - System.currentTimeMillis();
if (temp > 0)
{
// The time has not yet expired. Mark Valakas as currently locked (dead).
@@ -128,7 +105,8 @@ public class Valakas extends AbstractNpcAI
else
{
// The time has expired while the server was offline. Spawn valakas in his cave as DORMANT.
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 0, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
@@ -164,13 +142,14 @@ public class Valakas extends AbstractNpcAI
}
else
{
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
valakas.setIsInvul(true);
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Start timer to lock entry after 30 minutes
if (status == WAITING)
{
- startQuestTimer("beginning", (Config.VALAKAS_WAIT_TIME * 60000), valakas, null);
+ startQuestTimer("beginning", Config.VALAKAS_WAIT_TIME * 60000, valakas, null);
}
}
}
@@ -190,11 +169,7 @@ public class Valakas extends AbstractNpcAI
npc.teleToLocation(VALAKAS_LAIR);
// Sound + socialAction.
- for (PlayerInstance plyr : ZONE.getPlayersInside())
- {
- plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
- plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
- }
+ startQuestTimer("broadcast_spawn", 100, npc, null);
// Launch the cinematic, and tasks (regen + skill).
startQuestTimer("spawn_1", 1700, npc, null); // 1700
@@ -212,24 +187,21 @@ public class Valakas extends AbstractNpcAI
else if (event.equalsIgnoreCase("regen_task"))
{
// Inactivity task - 15min
- if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
+ if ((GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING) && ((_timeTracker + 900000) < System.currentTimeMillis()))
{
- if ((_timeTracker + 900000) < System.currentTimeMillis())
- {
- npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- npc.teleToLocation(VALAKAS_REGENERATION_LOC);
-
- GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
- npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
-
- // Drop all players from the zone.
- ZONE.oustAllPlayers();
-
- // Cancel skill_task and regen_task.
- cancelQuestTimer("regen_task", npc, null);
- cancelQuestTimer("skill_task", npc, null);
- return null;
- }
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
+ npc.teleToLocation(VALAKAS_REGENERATION_LOC);
+
+ GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
+ npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
+
+ // Drop all players from the zone.
+ ZONE.oustAllPlayers();
+
+ // Cancel skill_task and regen_task.
+ cancelQuestTimer("regen_task", npc, null);
+ cancelQuestTimer("skill_task", npc, null);
+ return null;
}
// Verify if "Valakas Regeneration" skill is active.
@@ -261,6 +233,14 @@ public class Valakas extends AbstractNpcAI
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
}
}
+ else if (event.equalsIgnoreCase("broadcast_spawn"))
+ {
+ for (PlayerInstance plyr : ZONE.getPlayersInside())
+ {
+ plyr.sendPacket(new PlaySound(1, "BS03_A", 0, 0, 0, 0, 0));
+ plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
+ }
+ }
// Spawn cinematic, regen_task and choose of skill.
else if (event.equalsIgnoreCase("spawn_1"))
{
@@ -353,7 +333,11 @@ public class Valakas extends AbstractNpcAI
}
else if (event.equalsIgnoreCase("valakas_unlock"))
{
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 32768, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
+ valakas.setIsInvul(true);
+ valakas.setRunning();
+ valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
}
@@ -364,12 +348,14 @@ public class Valakas extends AbstractNpcAI
return super.onAdvEvent(event, npc, player);
}
- // @Override
- // public String onSpawn(Npc npc)
- // {
- // npc.disableCoreAI(true);
- // return super.onSpawn(npc);
- // }
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ ((Attackable) npc).setCanReturnToSpawnPoint(false);
+ npc.setRandomWalking(false);
+ npc.disableCoreAI(true);
+ return super.onSpawn(npc);
+ }
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@@ -392,14 +378,10 @@ public class Valakas extends AbstractNpcAI
}
// Debuff strider-mounted players.
- if (attacker.getMountType() == MountType.STRIDER)
+ if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(4258))
{
- final Skill skill = SkillData.getInstance().getSkill(4258, 1);
- if (!attacker.isAffectedBySkill(4258))
- {
- npc.setTarget(attacker);
- npc.doCast(skill);
- }
+ npc.setTarget(attacker);
+ npc.doCast(SkillData.getInstance().getSkill(4258, 1));
}
_timeTracker = System.currentTimeMillis();
@@ -428,117 +410,27 @@ public class Valakas extends AbstractNpcAI
GrandBossManager.getInstance().setBossStatus(VALAKAS, DEAD);
// Calculate Min and Max respawn times randomly.
- long respawnTime = Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM);
- respawnTime *= 3600000;
-
+ final long respawnTime = (Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM)) * 3600000;
startQuestTimer("valakas_unlock", respawnTime, null, null);
// also save the respawn time so that the info is maintained past reboots
final StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
- info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
+ info.set("respawn_time", System.currentTimeMillis() + respawnTime);
GrandBossManager.getInstance().setStatsSet(VALAKAS, info);
return super.onKill(npc, killer, isSummon);
}
- // @Override
- // public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon)
- // {
- // return null;
- // }
- //
- // private void callSkillAI(Npc npc)
- // {
- // if (npc.isInvul() || npc.isCastingNow(SkillCaster::isAnyNormalType))
- // {
- // return;
- // }
- //
- // // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target.
- // if ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0))
- // {
- // _actualVictim = getRandomTarget(npc);
- // }
- //
- // // If result is still null, Valakas will roam. Don't go deeper in skill AI.
- // if (_actualVictim == null)
- // {
- // if (getRandom(10) == 0)
- // {
- // final int posX = npc.getX() + getRandom(-1400, 1400);
- // final int posY = npc.getY() + getRandom(-1400, 1400);
- // if (GeoEngine.getInstance().canMoveToTarget(npc.getX(), npc.getY(), npc.getZ(), posX, posY, npc.getZ(), npc.getInstanceWorld()))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, npc.getZ(), 0));
- // }
- // }
- // return;
- // }
- //
- // final Skill skill = getRandomSkill(npc).getSkill();
- //
- // // Cast the skill or follow the target.
- // if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc, _actualVictim, true))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- // npc.setTarget(_actualVictim);
- // npc.doCast(skill);
- // }
- // else
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null);
- // }
- // }
- //
- // /**
- // * Pick a random skill.
- // * Valakas will mostly use utility skills. If Valakas feels surrounded, he will use AoE skills.
- // * Lower than 50% HPs, he will begin to use Meteor skill.
- // * @param npc valakas
- // * @return a skill holder
- // */
- // private SkillHolder getRandomSkill(Npc npc)
- // {
- // final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100);
- //
- // // Valakas Lava Skin has priority.
- // if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId()))
- // {
- // return VALAKAS_LAVA_SKIN;
- // }
- //
- // // Valakas will use mass spells if he feels surrounded.
- // if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20)
- // {
- // return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)];
- // }
- //
- // if (hpRatio > 50)
- // {
- // return VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)];
- // }
- //
- // return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)];
- // }
- //
- // /**
- // * Pickup a random Playable from the zone, deads targets aren't included.
- // * @param npc
- // * @return a random Playable.
- // */
- // private Playable getRandomTarget(Npc npc)
- // {
- // final List result = new ArrayList<>();
- //
- // World.getInstance().forEachVisibleObject(npc, Playable.class, obj ->
- // {
- // if (!obj.isPet() && !obj.isDead())
- // {
- // result.add(obj);
- // }
- // });
- //
- // return (result.isEmpty()) ? null : result.get(getRandom(result.size()));
- // }
+ /*
+ * @Override public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon) { return null; } private void callSkillAI(Npc npc) { if (npc.isInvul() || npc.isCastingNow()) { return; } // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target. if
+ * ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0)) { _actualVictim = getRandomTarget(npc); } // If result is still null, Valakas will roam. Don't go deeper in skill AI. if (_actualVictim == null) { if (getRandom(10) == 0)
+ * { final int x = npc.getX(); final int y = npc.getY(); final int z = npc.getZ(); final int posX = x + getRandom(-1400, 1400); final int posY = y + getRandom(-1400, 1400); if (GeoEngine.getInstance().canMoveToTarget(x, y, z, posX, posY, z, npc.getInstanceId())) {
+ * npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, z, 0)); } } return; } final Skill skill = getRandomSkill(npc).getSkill(); // Cast the skill or follow the target. if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc,
+ * _actualVictim, true)) { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); npc.setIsCastingNow(true); npc.setTarget(_actualVictim); npc.doCast(skill); } else { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null); npc.setIsCastingNow(false); } } private
+ * SkillHolder getRandomSkill(Npc npc) { final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100); // Valakas Lava Skin has priority. if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId())) { return VALAKAS_LAVA_SKIN; } // Valakas
+ * will use mass spells if he feels surrounded. if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20) { return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)]; } if (hpRatio > 50) { return
+ * VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)]; } return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)]; } private Playable getRandomTarget(Npc npc) { final List result = new ArrayList<>(); World.getInstance().forEachVisibleObject(npc, Playable.class,
+ * obj -> { if ((obj == null) || obj.isPet()) { return; } else if (!obj.isDead() && obj.isPlayable()) { result.add(obj); } }); return result.isEmpty() ? null : result.get(getRandom(result.size())); }
+ */
public static void main(String[] args)
{
diff --git a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
index 2d75edac09..456322bc1d 100644
--- a/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
+++ b/L2J_Mobius_5.0_Salvation/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
@@ -24,11 +24,11 @@ import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatsSet;
+import org.l2jmobius.gameserver.model.actor.Attackable;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.BuffInfo;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.SocialAction;
@@ -45,37 +45,13 @@ public class Valakas extends AbstractNpcAI
// NPC
private static final int VALAKAS = 29028;
// Skills
- // private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
private static final int VALAKAS_REGENERATION = 4691;
-
- // private static final SkillHolder[] VALAKAS_REGULAR_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // };
- //
- // private static final SkillHolder[] VALAKAS_LOWHP_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
- //
- // private static final SkillHolder[] VALAKAS_AOE_SKILLS =
- // {
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4684, 1), // Valakas Dragon Breath
- // new SkillHolder(4685, 1), // Valakas Tail Stomp
- // new SkillHolder(4686, 1), // Valakas Tail Stomp
- // new SkillHolder(4688, 1), // Valakas Stun
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
-
+ /*
+ * private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1); private static final SkillHolder[] VALAKAS_REGULAR_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. }; private static final SkillHolder[] VALAKAS_LOWHP_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm }; private static final SkillHolder[] VALAKAS_AOE_SKILLS = { new SkillHolder(4683, 1), // Valakas Dragon Breath new SkillHolder(4684, 1), // Valakas Dragon
+ * Breath new SkillHolder(4685, 1), // Valakas Tail Stomp new SkillHolder(4686, 1), // Valakas Tail Stomp new SkillHolder(4688, 1), // Valakas Stun new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm };
+ */
// Locations
private static final Location TELEPORT_CUBE_LOCATIONS[] =
{
@@ -95,6 +71,7 @@ public class Valakas extends AbstractNpcAI
new Location(215456, -117328, -1392),
new Location(213200, -118160, -1424)
};
+ private static final Location VALAKAS_HIDDEN_LOC = new Location(220963, -104895, -1620);
private static final Location ATTACKER_REMOVE = new Location(150037, -57255, -2976);
private static final Location VALAKAS_LAIR = new Location(212852, -114842, -1632);
private static final Location VALAKAS_REGENERATION_LOC = new Location(-105200, -253104, -15264);
@@ -119,7 +96,7 @@ public class Valakas extends AbstractNpcAI
if (status == DEAD)
{
// load the unlock date and time for valakas from DB
- final long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
+ final long temp = info.getLong("respawn_time") - System.currentTimeMillis();
if (temp > 0)
{
// The time has not yet expired. Mark Valakas as currently locked (dead).
@@ -128,7 +105,8 @@ public class Valakas extends AbstractNpcAI
else
{
// The time has expired while the server was offline. Spawn valakas in his cave as DORMANT.
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 0, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
@@ -164,13 +142,14 @@ public class Valakas extends AbstractNpcAI
}
else
{
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
valakas.setIsInvul(true);
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Start timer to lock entry after 30 minutes
if (status == WAITING)
{
- startQuestTimer("beginning", (Config.VALAKAS_WAIT_TIME * 60000), valakas, null);
+ startQuestTimer("beginning", Config.VALAKAS_WAIT_TIME * 60000, valakas, null);
}
}
}
@@ -190,11 +169,7 @@ public class Valakas extends AbstractNpcAI
npc.teleToLocation(VALAKAS_LAIR);
// Sound + socialAction.
- for (PlayerInstance plyr : ZONE.getPlayersInside())
- {
- plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
- plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
- }
+ startQuestTimer("broadcast_spawn", 100, npc, null);
// Launch the cinematic, and tasks (regen + skill).
startQuestTimer("spawn_1", 1700, npc, null); // 1700
@@ -212,24 +187,21 @@ public class Valakas extends AbstractNpcAI
else if (event.equalsIgnoreCase("regen_task"))
{
// Inactivity task - 15min
- if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
+ if ((GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING) && ((_timeTracker + 900000) < System.currentTimeMillis()))
{
- if ((_timeTracker + 900000) < System.currentTimeMillis())
- {
- npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- npc.teleToLocation(VALAKAS_REGENERATION_LOC);
-
- GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
- npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
-
- // Drop all players from the zone.
- ZONE.oustAllPlayers();
-
- // Cancel skill_task and regen_task.
- cancelQuestTimer("regen_task", npc, null);
- cancelQuestTimer("skill_task", npc, null);
- return null;
- }
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
+ npc.teleToLocation(VALAKAS_REGENERATION_LOC);
+
+ GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
+ npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
+
+ // Drop all players from the zone.
+ ZONE.oustAllPlayers();
+
+ // Cancel skill_task and regen_task.
+ cancelQuestTimer("regen_task", npc, null);
+ cancelQuestTimer("skill_task", npc, null);
+ return null;
}
// Verify if "Valakas Regeneration" skill is active.
@@ -261,6 +233,14 @@ public class Valakas extends AbstractNpcAI
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
}
}
+ else if (event.equalsIgnoreCase("broadcast_spawn"))
+ {
+ for (PlayerInstance plyr : ZONE.getPlayersInside())
+ {
+ plyr.sendPacket(new PlaySound(1, "BS03_A", 0, 0, 0, 0, 0));
+ plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
+ }
+ }
// Spawn cinematic, regen_task and choose of skill.
else if (event.equalsIgnoreCase("spawn_1"))
{
@@ -353,7 +333,11 @@ public class Valakas extends AbstractNpcAI
}
else if (event.equalsIgnoreCase("valakas_unlock"))
{
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 32768, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
+ valakas.setIsInvul(true);
+ valakas.setRunning();
+ valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
}
@@ -364,12 +348,14 @@ public class Valakas extends AbstractNpcAI
return super.onAdvEvent(event, npc, player);
}
- // @Override
- // public String onSpawn(Npc npc)
- // {
- // npc.disableCoreAI(true);
- // return super.onSpawn(npc);
- // }
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ ((Attackable) npc).setCanReturnToSpawnPoint(false);
+ npc.setRandomWalking(false);
+ npc.disableCoreAI(true);
+ return super.onSpawn(npc);
+ }
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@@ -392,14 +378,10 @@ public class Valakas extends AbstractNpcAI
}
// Debuff strider-mounted players.
- if (attacker.getMountType() == MountType.STRIDER)
+ if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(4258))
{
- final Skill skill = SkillData.getInstance().getSkill(4258, 1);
- if (!attacker.isAffectedBySkill(4258))
- {
- npc.setTarget(attacker);
- npc.doCast(skill);
- }
+ npc.setTarget(attacker);
+ npc.doCast(SkillData.getInstance().getSkill(4258, 1));
}
_timeTracker = System.currentTimeMillis();
@@ -428,117 +410,27 @@ public class Valakas extends AbstractNpcAI
GrandBossManager.getInstance().setBossStatus(VALAKAS, DEAD);
// Calculate Min and Max respawn times randomly.
- long respawnTime = Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM);
- respawnTime *= 3600000;
-
+ final long respawnTime = (Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM)) * 3600000;
startQuestTimer("valakas_unlock", respawnTime, null, null);
// also save the respawn time so that the info is maintained past reboots
final StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
- info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
+ info.set("respawn_time", System.currentTimeMillis() + respawnTime);
GrandBossManager.getInstance().setStatsSet(VALAKAS, info);
return super.onKill(npc, killer, isSummon);
}
- // @Override
- // public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon)
- // {
- // return null;
- // }
- //
- // private void callSkillAI(Npc npc)
- // {
- // if (npc.isInvul() || npc.isCastingNow(SkillCaster::isAnyNormalType))
- // {
- // return;
- // }
- //
- // // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target.
- // if ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0))
- // {
- // _actualVictim = getRandomTarget(npc);
- // }
- //
- // // If result is still null, Valakas will roam. Don't go deeper in skill AI.
- // if (_actualVictim == null)
- // {
- // if (getRandom(10) == 0)
- // {
- // final int posX = npc.getX() + getRandom(-1400, 1400);
- // final int posY = npc.getY() + getRandom(-1400, 1400);
- // if (GeoEngine.getInstance().canMoveToTarget(npc.getX(), npc.getY(), npc.getZ(), posX, posY, npc.getZ(), npc.getInstanceWorld()))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, npc.getZ(), 0));
- // }
- // }
- // return;
- // }
- //
- // final Skill skill = getRandomSkill(npc).getSkill();
- //
- // // Cast the skill or follow the target.
- // if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc, _actualVictim, true))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- // npc.setTarget(_actualVictim);
- // npc.doCast(skill);
- // }
- // else
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null);
- // }
- // }
- //
- // /**
- // * Pick a random skill.
- // * Valakas will mostly use utility skills. If Valakas feels surrounded, he will use AoE skills.
- // * Lower than 50% HPs, he will begin to use Meteor skill.
- // * @param npc valakas
- // * @return a skill holder
- // */
- // private SkillHolder getRandomSkill(Npc npc)
- // {
- // final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100);
- //
- // // Valakas Lava Skin has priority.
- // if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId()))
- // {
- // return VALAKAS_LAVA_SKIN;
- // }
- //
- // // Valakas will use mass spells if he feels surrounded.
- // if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20)
- // {
- // return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)];
- // }
- //
- // if (hpRatio > 50)
- // {
- // return VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)];
- // }
- //
- // return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)];
- // }
- //
- // /**
- // * Pickup a random Playable from the zone, deads targets aren't included.
- // * @param npc
- // * @return a random Playable.
- // */
- // private Playable getRandomTarget(Npc npc)
- // {
- // final List result = new ArrayList<>();
- //
- // World.getInstance().forEachVisibleObject(npc, Playable.class, obj ->
- // {
- // if (!obj.isPet() && !obj.isDead())
- // {
- // result.add(obj);
- // }
- // });
- //
- // return (result.isEmpty()) ? null : result.get(getRandom(result.size()));
- // }
+ /*
+ * @Override public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon) { return null; } private void callSkillAI(Npc npc) { if (npc.isInvul() || npc.isCastingNow()) { return; } // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target. if
+ * ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0)) { _actualVictim = getRandomTarget(npc); } // If result is still null, Valakas will roam. Don't go deeper in skill AI. if (_actualVictim == null) { if (getRandom(10) == 0)
+ * { final int x = npc.getX(); final int y = npc.getY(); final int z = npc.getZ(); final int posX = x + getRandom(-1400, 1400); final int posY = y + getRandom(-1400, 1400); if (GeoEngine.getInstance().canMoveToTarget(x, y, z, posX, posY, z, npc.getInstanceId())) {
+ * npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, z, 0)); } } return; } final Skill skill = getRandomSkill(npc).getSkill(); // Cast the skill or follow the target. if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc,
+ * _actualVictim, true)) { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); npc.setIsCastingNow(true); npc.setTarget(_actualVictim); npc.doCast(skill); } else { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null); npc.setIsCastingNow(false); } } private
+ * SkillHolder getRandomSkill(Npc npc) { final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100); // Valakas Lava Skin has priority. if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId())) { return VALAKAS_LAVA_SKIN; } // Valakas
+ * will use mass spells if he feels surrounded. if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20) { return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)]; } if (hpRatio > 50) { return
+ * VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)]; } return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)]; } private Playable getRandomTarget(Npc npc) { final List result = new ArrayList<>(); World.getInstance().forEachVisibleObject(npc, Playable.class,
+ * obj -> { if ((obj == null) || obj.isPet()) { return; } else if (!obj.isDead() && obj.isPlayable()) { result.add(obj); } }); return result.isEmpty() ? null : result.get(getRandom(result.size())); }
+ */
public static void main(String[] args)
{
diff --git a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
index 2d75edac09..456322bc1d 100644
--- a/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
+++ b/L2J_Mobius_5.5_EtinasFate/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
@@ -24,11 +24,11 @@ import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatsSet;
+import org.l2jmobius.gameserver.model.actor.Attackable;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.BuffInfo;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.SocialAction;
@@ -45,37 +45,13 @@ public class Valakas extends AbstractNpcAI
// NPC
private static final int VALAKAS = 29028;
// Skills
- // private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
private static final int VALAKAS_REGENERATION = 4691;
-
- // private static final SkillHolder[] VALAKAS_REGULAR_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // };
- //
- // private static final SkillHolder[] VALAKAS_LOWHP_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
- //
- // private static final SkillHolder[] VALAKAS_AOE_SKILLS =
- // {
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4684, 1), // Valakas Dragon Breath
- // new SkillHolder(4685, 1), // Valakas Tail Stomp
- // new SkillHolder(4686, 1), // Valakas Tail Stomp
- // new SkillHolder(4688, 1), // Valakas Stun
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
-
+ /*
+ * private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1); private static final SkillHolder[] VALAKAS_REGULAR_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. }; private static final SkillHolder[] VALAKAS_LOWHP_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm }; private static final SkillHolder[] VALAKAS_AOE_SKILLS = { new SkillHolder(4683, 1), // Valakas Dragon Breath new SkillHolder(4684, 1), // Valakas Dragon
+ * Breath new SkillHolder(4685, 1), // Valakas Tail Stomp new SkillHolder(4686, 1), // Valakas Tail Stomp new SkillHolder(4688, 1), // Valakas Stun new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm };
+ */
// Locations
private static final Location TELEPORT_CUBE_LOCATIONS[] =
{
@@ -95,6 +71,7 @@ public class Valakas extends AbstractNpcAI
new Location(215456, -117328, -1392),
new Location(213200, -118160, -1424)
};
+ private static final Location VALAKAS_HIDDEN_LOC = new Location(220963, -104895, -1620);
private static final Location ATTACKER_REMOVE = new Location(150037, -57255, -2976);
private static final Location VALAKAS_LAIR = new Location(212852, -114842, -1632);
private static final Location VALAKAS_REGENERATION_LOC = new Location(-105200, -253104, -15264);
@@ -119,7 +96,7 @@ public class Valakas extends AbstractNpcAI
if (status == DEAD)
{
// load the unlock date and time for valakas from DB
- final long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
+ final long temp = info.getLong("respawn_time") - System.currentTimeMillis();
if (temp > 0)
{
// The time has not yet expired. Mark Valakas as currently locked (dead).
@@ -128,7 +105,8 @@ public class Valakas extends AbstractNpcAI
else
{
// The time has expired while the server was offline. Spawn valakas in his cave as DORMANT.
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 0, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
@@ -164,13 +142,14 @@ public class Valakas extends AbstractNpcAI
}
else
{
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
valakas.setIsInvul(true);
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Start timer to lock entry after 30 minutes
if (status == WAITING)
{
- startQuestTimer("beginning", (Config.VALAKAS_WAIT_TIME * 60000), valakas, null);
+ startQuestTimer("beginning", Config.VALAKAS_WAIT_TIME * 60000, valakas, null);
}
}
}
@@ -190,11 +169,7 @@ public class Valakas extends AbstractNpcAI
npc.teleToLocation(VALAKAS_LAIR);
// Sound + socialAction.
- for (PlayerInstance plyr : ZONE.getPlayersInside())
- {
- plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
- plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
- }
+ startQuestTimer("broadcast_spawn", 100, npc, null);
// Launch the cinematic, and tasks (regen + skill).
startQuestTimer("spawn_1", 1700, npc, null); // 1700
@@ -212,24 +187,21 @@ public class Valakas extends AbstractNpcAI
else if (event.equalsIgnoreCase("regen_task"))
{
// Inactivity task - 15min
- if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
+ if ((GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING) && ((_timeTracker + 900000) < System.currentTimeMillis()))
{
- if ((_timeTracker + 900000) < System.currentTimeMillis())
- {
- npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- npc.teleToLocation(VALAKAS_REGENERATION_LOC);
-
- GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
- npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
-
- // Drop all players from the zone.
- ZONE.oustAllPlayers();
-
- // Cancel skill_task and regen_task.
- cancelQuestTimer("regen_task", npc, null);
- cancelQuestTimer("skill_task", npc, null);
- return null;
- }
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
+ npc.teleToLocation(VALAKAS_REGENERATION_LOC);
+
+ GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
+ npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
+
+ // Drop all players from the zone.
+ ZONE.oustAllPlayers();
+
+ // Cancel skill_task and regen_task.
+ cancelQuestTimer("regen_task", npc, null);
+ cancelQuestTimer("skill_task", npc, null);
+ return null;
}
// Verify if "Valakas Regeneration" skill is active.
@@ -261,6 +233,14 @@ public class Valakas extends AbstractNpcAI
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
}
}
+ else if (event.equalsIgnoreCase("broadcast_spawn"))
+ {
+ for (PlayerInstance plyr : ZONE.getPlayersInside())
+ {
+ plyr.sendPacket(new PlaySound(1, "BS03_A", 0, 0, 0, 0, 0));
+ plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
+ }
+ }
// Spawn cinematic, regen_task and choose of skill.
else if (event.equalsIgnoreCase("spawn_1"))
{
@@ -353,7 +333,11 @@ public class Valakas extends AbstractNpcAI
}
else if (event.equalsIgnoreCase("valakas_unlock"))
{
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 32768, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
+ valakas.setIsInvul(true);
+ valakas.setRunning();
+ valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
}
@@ -364,12 +348,14 @@ public class Valakas extends AbstractNpcAI
return super.onAdvEvent(event, npc, player);
}
- // @Override
- // public String onSpawn(Npc npc)
- // {
- // npc.disableCoreAI(true);
- // return super.onSpawn(npc);
- // }
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ ((Attackable) npc).setCanReturnToSpawnPoint(false);
+ npc.setRandomWalking(false);
+ npc.disableCoreAI(true);
+ return super.onSpawn(npc);
+ }
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@@ -392,14 +378,10 @@ public class Valakas extends AbstractNpcAI
}
// Debuff strider-mounted players.
- if (attacker.getMountType() == MountType.STRIDER)
+ if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(4258))
{
- final Skill skill = SkillData.getInstance().getSkill(4258, 1);
- if (!attacker.isAffectedBySkill(4258))
- {
- npc.setTarget(attacker);
- npc.doCast(skill);
- }
+ npc.setTarget(attacker);
+ npc.doCast(SkillData.getInstance().getSkill(4258, 1));
}
_timeTracker = System.currentTimeMillis();
@@ -428,117 +410,27 @@ public class Valakas extends AbstractNpcAI
GrandBossManager.getInstance().setBossStatus(VALAKAS, DEAD);
// Calculate Min and Max respawn times randomly.
- long respawnTime = Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM);
- respawnTime *= 3600000;
-
+ final long respawnTime = (Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM)) * 3600000;
startQuestTimer("valakas_unlock", respawnTime, null, null);
// also save the respawn time so that the info is maintained past reboots
final StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
- info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
+ info.set("respawn_time", System.currentTimeMillis() + respawnTime);
GrandBossManager.getInstance().setStatsSet(VALAKAS, info);
return super.onKill(npc, killer, isSummon);
}
- // @Override
- // public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon)
- // {
- // return null;
- // }
- //
- // private void callSkillAI(Npc npc)
- // {
- // if (npc.isInvul() || npc.isCastingNow(SkillCaster::isAnyNormalType))
- // {
- // return;
- // }
- //
- // // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target.
- // if ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0))
- // {
- // _actualVictim = getRandomTarget(npc);
- // }
- //
- // // If result is still null, Valakas will roam. Don't go deeper in skill AI.
- // if (_actualVictim == null)
- // {
- // if (getRandom(10) == 0)
- // {
- // final int posX = npc.getX() + getRandom(-1400, 1400);
- // final int posY = npc.getY() + getRandom(-1400, 1400);
- // if (GeoEngine.getInstance().canMoveToTarget(npc.getX(), npc.getY(), npc.getZ(), posX, posY, npc.getZ(), npc.getInstanceWorld()))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, npc.getZ(), 0));
- // }
- // }
- // return;
- // }
- //
- // final Skill skill = getRandomSkill(npc).getSkill();
- //
- // // Cast the skill or follow the target.
- // if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc, _actualVictim, true))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- // npc.setTarget(_actualVictim);
- // npc.doCast(skill);
- // }
- // else
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null);
- // }
- // }
- //
- // /**
- // * Pick a random skill.
- // * Valakas will mostly use utility skills. If Valakas feels surrounded, he will use AoE skills.
- // * Lower than 50% HPs, he will begin to use Meteor skill.
- // * @param npc valakas
- // * @return a skill holder
- // */
- // private SkillHolder getRandomSkill(Npc npc)
- // {
- // final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100);
- //
- // // Valakas Lava Skin has priority.
- // if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId()))
- // {
- // return VALAKAS_LAVA_SKIN;
- // }
- //
- // // Valakas will use mass spells if he feels surrounded.
- // if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20)
- // {
- // return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)];
- // }
- //
- // if (hpRatio > 50)
- // {
- // return VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)];
- // }
- //
- // return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)];
- // }
- //
- // /**
- // * Pickup a random Playable from the zone, deads targets aren't included.
- // * @param npc
- // * @return a random Playable.
- // */
- // private Playable getRandomTarget(Npc npc)
- // {
- // final List result = new ArrayList<>();
- //
- // World.getInstance().forEachVisibleObject(npc, Playable.class, obj ->
- // {
- // if (!obj.isPet() && !obj.isDead())
- // {
- // result.add(obj);
- // }
- // });
- //
- // return (result.isEmpty()) ? null : result.get(getRandom(result.size()));
- // }
+ /*
+ * @Override public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon) { return null; } private void callSkillAI(Npc npc) { if (npc.isInvul() || npc.isCastingNow()) { return; } // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target. if
+ * ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0)) { _actualVictim = getRandomTarget(npc); } // If result is still null, Valakas will roam. Don't go deeper in skill AI. if (_actualVictim == null) { if (getRandom(10) == 0)
+ * { final int x = npc.getX(); final int y = npc.getY(); final int z = npc.getZ(); final int posX = x + getRandom(-1400, 1400); final int posY = y + getRandom(-1400, 1400); if (GeoEngine.getInstance().canMoveToTarget(x, y, z, posX, posY, z, npc.getInstanceId())) {
+ * npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, z, 0)); } } return; } final Skill skill = getRandomSkill(npc).getSkill(); // Cast the skill or follow the target. if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc,
+ * _actualVictim, true)) { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); npc.setIsCastingNow(true); npc.setTarget(_actualVictim); npc.doCast(skill); } else { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null); npc.setIsCastingNow(false); } } private
+ * SkillHolder getRandomSkill(Npc npc) { final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100); // Valakas Lava Skin has priority. if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId())) { return VALAKAS_LAVA_SKIN; } // Valakas
+ * will use mass spells if he feels surrounded. if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20) { return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)]; } if (hpRatio > 50) { return
+ * VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)]; } return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)]; } private Playable getRandomTarget(Npc npc) { final List result = new ArrayList<>(); World.getInstance().forEachVisibleObject(npc, Playable.class,
+ * obj -> { if ((obj == null) || obj.isPet()) { return; } else if (!obj.isDead() && obj.isPlayable()) { result.add(obj); } }); return result.isEmpty() ? null : result.get(getRandom(result.size())); }
+ */
public static void main(String[] args)
{
diff --git a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
index 2d75edac09..456322bc1d 100644
--- a/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
+++ b/L2J_Mobius_6.0_Fafurion/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
@@ -24,11 +24,11 @@ import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatsSet;
+import org.l2jmobius.gameserver.model.actor.Attackable;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.BuffInfo;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.SocialAction;
@@ -45,37 +45,13 @@ public class Valakas extends AbstractNpcAI
// NPC
private static final int VALAKAS = 29028;
// Skills
- // private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
private static final int VALAKAS_REGENERATION = 4691;
-
- // private static final SkillHolder[] VALAKAS_REGULAR_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // };
- //
- // private static final SkillHolder[] VALAKAS_LOWHP_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
- //
- // private static final SkillHolder[] VALAKAS_AOE_SKILLS =
- // {
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4684, 1), // Valakas Dragon Breath
- // new SkillHolder(4685, 1), // Valakas Tail Stomp
- // new SkillHolder(4686, 1), // Valakas Tail Stomp
- // new SkillHolder(4688, 1), // Valakas Stun
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
-
+ /*
+ * private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1); private static final SkillHolder[] VALAKAS_REGULAR_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. }; private static final SkillHolder[] VALAKAS_LOWHP_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm }; private static final SkillHolder[] VALAKAS_AOE_SKILLS = { new SkillHolder(4683, 1), // Valakas Dragon Breath new SkillHolder(4684, 1), // Valakas Dragon
+ * Breath new SkillHolder(4685, 1), // Valakas Tail Stomp new SkillHolder(4686, 1), // Valakas Tail Stomp new SkillHolder(4688, 1), // Valakas Stun new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm };
+ */
// Locations
private static final Location TELEPORT_CUBE_LOCATIONS[] =
{
@@ -95,6 +71,7 @@ public class Valakas extends AbstractNpcAI
new Location(215456, -117328, -1392),
new Location(213200, -118160, -1424)
};
+ private static final Location VALAKAS_HIDDEN_LOC = new Location(220963, -104895, -1620);
private static final Location ATTACKER_REMOVE = new Location(150037, -57255, -2976);
private static final Location VALAKAS_LAIR = new Location(212852, -114842, -1632);
private static final Location VALAKAS_REGENERATION_LOC = new Location(-105200, -253104, -15264);
@@ -119,7 +96,7 @@ public class Valakas extends AbstractNpcAI
if (status == DEAD)
{
// load the unlock date and time for valakas from DB
- final long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
+ final long temp = info.getLong("respawn_time") - System.currentTimeMillis();
if (temp > 0)
{
// The time has not yet expired. Mark Valakas as currently locked (dead).
@@ -128,7 +105,8 @@ public class Valakas extends AbstractNpcAI
else
{
// The time has expired while the server was offline. Spawn valakas in his cave as DORMANT.
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 0, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
@@ -164,13 +142,14 @@ public class Valakas extends AbstractNpcAI
}
else
{
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
valakas.setIsInvul(true);
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Start timer to lock entry after 30 minutes
if (status == WAITING)
{
- startQuestTimer("beginning", (Config.VALAKAS_WAIT_TIME * 60000), valakas, null);
+ startQuestTimer("beginning", Config.VALAKAS_WAIT_TIME * 60000, valakas, null);
}
}
}
@@ -190,11 +169,7 @@ public class Valakas extends AbstractNpcAI
npc.teleToLocation(VALAKAS_LAIR);
// Sound + socialAction.
- for (PlayerInstance plyr : ZONE.getPlayersInside())
- {
- plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
- plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
- }
+ startQuestTimer("broadcast_spawn", 100, npc, null);
// Launch the cinematic, and tasks (regen + skill).
startQuestTimer("spawn_1", 1700, npc, null); // 1700
@@ -212,24 +187,21 @@ public class Valakas extends AbstractNpcAI
else if (event.equalsIgnoreCase("regen_task"))
{
// Inactivity task - 15min
- if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
+ if ((GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING) && ((_timeTracker + 900000) < System.currentTimeMillis()))
{
- if ((_timeTracker + 900000) < System.currentTimeMillis())
- {
- npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- npc.teleToLocation(VALAKAS_REGENERATION_LOC);
-
- GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
- npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
-
- // Drop all players from the zone.
- ZONE.oustAllPlayers();
-
- // Cancel skill_task and regen_task.
- cancelQuestTimer("regen_task", npc, null);
- cancelQuestTimer("skill_task", npc, null);
- return null;
- }
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
+ npc.teleToLocation(VALAKAS_REGENERATION_LOC);
+
+ GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
+ npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
+
+ // Drop all players from the zone.
+ ZONE.oustAllPlayers();
+
+ // Cancel skill_task and regen_task.
+ cancelQuestTimer("regen_task", npc, null);
+ cancelQuestTimer("skill_task", npc, null);
+ return null;
}
// Verify if "Valakas Regeneration" skill is active.
@@ -261,6 +233,14 @@ public class Valakas extends AbstractNpcAI
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
}
}
+ else if (event.equalsIgnoreCase("broadcast_spawn"))
+ {
+ for (PlayerInstance plyr : ZONE.getPlayersInside())
+ {
+ plyr.sendPacket(new PlaySound(1, "BS03_A", 0, 0, 0, 0, 0));
+ plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
+ }
+ }
// Spawn cinematic, regen_task and choose of skill.
else if (event.equalsIgnoreCase("spawn_1"))
{
@@ -353,7 +333,11 @@ public class Valakas extends AbstractNpcAI
}
else if (event.equalsIgnoreCase("valakas_unlock"))
{
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 32768, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
+ valakas.setIsInvul(true);
+ valakas.setRunning();
+ valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
}
@@ -364,12 +348,14 @@ public class Valakas extends AbstractNpcAI
return super.onAdvEvent(event, npc, player);
}
- // @Override
- // public String onSpawn(Npc npc)
- // {
- // npc.disableCoreAI(true);
- // return super.onSpawn(npc);
- // }
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ ((Attackable) npc).setCanReturnToSpawnPoint(false);
+ npc.setRandomWalking(false);
+ npc.disableCoreAI(true);
+ return super.onSpawn(npc);
+ }
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@@ -392,14 +378,10 @@ public class Valakas extends AbstractNpcAI
}
// Debuff strider-mounted players.
- if (attacker.getMountType() == MountType.STRIDER)
+ if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(4258))
{
- final Skill skill = SkillData.getInstance().getSkill(4258, 1);
- if (!attacker.isAffectedBySkill(4258))
- {
- npc.setTarget(attacker);
- npc.doCast(skill);
- }
+ npc.setTarget(attacker);
+ npc.doCast(SkillData.getInstance().getSkill(4258, 1));
}
_timeTracker = System.currentTimeMillis();
@@ -428,117 +410,27 @@ public class Valakas extends AbstractNpcAI
GrandBossManager.getInstance().setBossStatus(VALAKAS, DEAD);
// Calculate Min and Max respawn times randomly.
- long respawnTime = Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM);
- respawnTime *= 3600000;
-
+ final long respawnTime = (Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM)) * 3600000;
startQuestTimer("valakas_unlock", respawnTime, null, null);
// also save the respawn time so that the info is maintained past reboots
final StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
- info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
+ info.set("respawn_time", System.currentTimeMillis() + respawnTime);
GrandBossManager.getInstance().setStatsSet(VALAKAS, info);
return super.onKill(npc, killer, isSummon);
}
- // @Override
- // public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon)
- // {
- // return null;
- // }
- //
- // private void callSkillAI(Npc npc)
- // {
- // if (npc.isInvul() || npc.isCastingNow(SkillCaster::isAnyNormalType))
- // {
- // return;
- // }
- //
- // // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target.
- // if ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0))
- // {
- // _actualVictim = getRandomTarget(npc);
- // }
- //
- // // If result is still null, Valakas will roam. Don't go deeper in skill AI.
- // if (_actualVictim == null)
- // {
- // if (getRandom(10) == 0)
- // {
- // final int posX = npc.getX() + getRandom(-1400, 1400);
- // final int posY = npc.getY() + getRandom(-1400, 1400);
- // if (GeoEngine.getInstance().canMoveToTarget(npc.getX(), npc.getY(), npc.getZ(), posX, posY, npc.getZ(), npc.getInstanceWorld()))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, npc.getZ(), 0));
- // }
- // }
- // return;
- // }
- //
- // final Skill skill = getRandomSkill(npc).getSkill();
- //
- // // Cast the skill or follow the target.
- // if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc, _actualVictim, true))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- // npc.setTarget(_actualVictim);
- // npc.doCast(skill);
- // }
- // else
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null);
- // }
- // }
- //
- // /**
- // * Pick a random skill.
- // * Valakas will mostly use utility skills. If Valakas feels surrounded, he will use AoE skills.
- // * Lower than 50% HPs, he will begin to use Meteor skill.
- // * @param npc valakas
- // * @return a skill holder
- // */
- // private SkillHolder getRandomSkill(Npc npc)
- // {
- // final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100);
- //
- // // Valakas Lava Skin has priority.
- // if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId()))
- // {
- // return VALAKAS_LAVA_SKIN;
- // }
- //
- // // Valakas will use mass spells if he feels surrounded.
- // if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20)
- // {
- // return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)];
- // }
- //
- // if (hpRatio > 50)
- // {
- // return VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)];
- // }
- //
- // return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)];
- // }
- //
- // /**
- // * Pickup a random Playable from the zone, deads targets aren't included.
- // * @param npc
- // * @return a random Playable.
- // */
- // private Playable getRandomTarget(Npc npc)
- // {
- // final List result = new ArrayList<>();
- //
- // World.getInstance().forEachVisibleObject(npc, Playable.class, obj ->
- // {
- // if (!obj.isPet() && !obj.isDead())
- // {
- // result.add(obj);
- // }
- // });
- //
- // return (result.isEmpty()) ? null : result.get(getRandom(result.size()));
- // }
+ /*
+ * @Override public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon) { return null; } private void callSkillAI(Npc npc) { if (npc.isInvul() || npc.isCastingNow()) { return; } // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target. if
+ * ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0)) { _actualVictim = getRandomTarget(npc); } // If result is still null, Valakas will roam. Don't go deeper in skill AI. if (_actualVictim == null) { if (getRandom(10) == 0)
+ * { final int x = npc.getX(); final int y = npc.getY(); final int z = npc.getZ(); final int posX = x + getRandom(-1400, 1400); final int posY = y + getRandom(-1400, 1400); if (GeoEngine.getInstance().canMoveToTarget(x, y, z, posX, posY, z, npc.getInstanceId())) {
+ * npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, z, 0)); } } return; } final Skill skill = getRandomSkill(npc).getSkill(); // Cast the skill or follow the target. if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc,
+ * _actualVictim, true)) { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); npc.setIsCastingNow(true); npc.setTarget(_actualVictim); npc.doCast(skill); } else { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null); npc.setIsCastingNow(false); } } private
+ * SkillHolder getRandomSkill(Npc npc) { final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100); // Valakas Lava Skin has priority. if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId())) { return VALAKAS_LAVA_SKIN; } // Valakas
+ * will use mass spells if he feels surrounded. if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20) { return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)]; } if (hpRatio > 50) { return
+ * VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)]; } return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)]; } private Playable getRandomTarget(Npc npc) { final List result = new ArrayList<>(); World.getInstance().forEachVisibleObject(npc, Playable.class,
+ * obj -> { if ((obj == null) || obj.isPet()) { return; } else if (!obj.isDead() && obj.isPlayable()) { result.add(obj); } }); return result.isEmpty() ? null : result.get(getRandom(result.size())); }
+ */
public static void main(String[] args)
{
diff --git a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
index 2d75edac09..456322bc1d 100644
--- a/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
+++ b/L2J_Mobius_7.0_PreludeOfWar/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
@@ -24,11 +24,11 @@ import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
import org.l2jmobius.gameserver.instancemanager.ZoneManager;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatsSet;
+import org.l2jmobius.gameserver.model.actor.Attackable;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
import org.l2jmobius.gameserver.model.skills.BuffInfo;
-import org.l2jmobius.gameserver.model.skills.Skill;
import org.l2jmobius.gameserver.model.zone.ZoneType;
import org.l2jmobius.gameserver.network.serverpackets.PlaySound;
import org.l2jmobius.gameserver.network.serverpackets.SocialAction;
@@ -45,37 +45,13 @@ public class Valakas extends AbstractNpcAI
// NPC
private static final int VALAKAS = 29028;
// Skills
- // private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
private static final int VALAKAS_REGENERATION = 4691;
-
- // private static final SkillHolder[] VALAKAS_REGULAR_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // };
- //
- // private static final SkillHolder[] VALAKAS_LOWHP_SKILLS =
- // {
- // new SkillHolder(4681, 1), // Valakas Trample
- // new SkillHolder(4682, 1), // Valakas Trample
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
- //
- // private static final SkillHolder[] VALAKAS_AOE_SKILLS =
- // {
- // new SkillHolder(4683, 1), // Valakas Dragon Breath
- // new SkillHolder(4684, 1), // Valakas Dragon Breath
- // new SkillHolder(4685, 1), // Valakas Tail Stomp
- // new SkillHolder(4686, 1), // Valakas Tail Stomp
- // new SkillHolder(4688, 1), // Valakas Stun
- // new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
- // new SkillHolder(4690, 1), // Valakas Meteor Storm
- // };
-
+ /*
+ * private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1); private static final SkillHolder[] VALAKAS_REGULAR_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. }; private static final SkillHolder[] VALAKAS_LOWHP_SKILLS = { new SkillHolder(4681, 1), // Valakas Trample new SkillHolder(4682, 1), // Valakas Trample new SkillHolder(4683, 1), // Valakas Dragon Breath new
+ * SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm }; private static final SkillHolder[] VALAKAS_AOE_SKILLS = { new SkillHolder(4683, 1), // Valakas Dragon Breath new SkillHolder(4684, 1), // Valakas Dragon
+ * Breath new SkillHolder(4685, 1), // Valakas Tail Stomp new SkillHolder(4686, 1), // Valakas Tail Stomp new SkillHolder(4688, 1), // Valakas Stun new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used. new SkillHolder(4690, 1), // Valakas Meteor Storm };
+ */
// Locations
private static final Location TELEPORT_CUBE_LOCATIONS[] =
{
@@ -95,6 +71,7 @@ public class Valakas extends AbstractNpcAI
new Location(215456, -117328, -1392),
new Location(213200, -118160, -1424)
};
+ private static final Location VALAKAS_HIDDEN_LOC = new Location(220963, -104895, -1620);
private static final Location ATTACKER_REMOVE = new Location(150037, -57255, -2976);
private static final Location VALAKAS_LAIR = new Location(212852, -114842, -1632);
private static final Location VALAKAS_REGENERATION_LOC = new Location(-105200, -253104, -15264);
@@ -119,7 +96,7 @@ public class Valakas extends AbstractNpcAI
if (status == DEAD)
{
// load the unlock date and time for valakas from DB
- final long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
+ final long temp = info.getLong("respawn_time") - System.currentTimeMillis();
if (temp > 0)
{
// The time has not yet expired. Mark Valakas as currently locked (dead).
@@ -128,7 +105,8 @@ public class Valakas extends AbstractNpcAI
else
{
// The time has expired while the server was offline. Spawn valakas in his cave as DORMANT.
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 0, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
@@ -164,13 +142,14 @@ public class Valakas extends AbstractNpcAI
}
else
{
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
valakas.setIsInvul(true);
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Start timer to lock entry after 30 minutes
if (status == WAITING)
{
- startQuestTimer("beginning", (Config.VALAKAS_WAIT_TIME * 60000), valakas, null);
+ startQuestTimer("beginning", Config.VALAKAS_WAIT_TIME * 60000, valakas, null);
}
}
}
@@ -190,11 +169,7 @@ public class Valakas extends AbstractNpcAI
npc.teleToLocation(VALAKAS_LAIR);
// Sound + socialAction.
- for (PlayerInstance plyr : ZONE.getPlayersInside())
- {
- plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
- plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
- }
+ startQuestTimer("broadcast_spawn", 100, npc, null);
// Launch the cinematic, and tasks (regen + skill).
startQuestTimer("spawn_1", 1700, npc, null); // 1700
@@ -212,24 +187,21 @@ public class Valakas extends AbstractNpcAI
else if (event.equalsIgnoreCase("regen_task"))
{
// Inactivity task - 15min
- if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
+ if ((GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING) && ((_timeTracker + 900000) < System.currentTimeMillis()))
{
- if ((_timeTracker + 900000) < System.currentTimeMillis())
- {
- npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- npc.teleToLocation(VALAKAS_REGENERATION_LOC);
-
- GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
- npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
-
- // Drop all players from the zone.
- ZONE.oustAllPlayers();
-
- // Cancel skill_task and regen_task.
- cancelQuestTimer("regen_task", npc, null);
- cancelQuestTimer("skill_task", npc, null);
- return null;
- }
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
+ npc.teleToLocation(VALAKAS_REGENERATION_LOC);
+
+ GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
+ npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
+
+ // Drop all players from the zone.
+ ZONE.oustAllPlayers();
+
+ // Cancel skill_task and regen_task.
+ cancelQuestTimer("regen_task", npc, null);
+ cancelQuestTimer("skill_task", npc, null);
+ return null;
}
// Verify if "Valakas Regeneration" skill is active.
@@ -261,6 +233,14 @@ public class Valakas extends AbstractNpcAI
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
}
}
+ else if (event.equalsIgnoreCase("broadcast_spawn"))
+ {
+ for (PlayerInstance plyr : ZONE.getPlayersInside())
+ {
+ plyr.sendPacket(new PlaySound(1, "BS03_A", 0, 0, 0, 0, 0));
+ plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
+ }
+ }
// Spawn cinematic, regen_task and choose of skill.
else if (event.equalsIgnoreCase("spawn_1"))
{
@@ -353,7 +333,11 @@ public class Valakas extends AbstractNpcAI
}
else if (event.equalsIgnoreCase("valakas_unlock"))
{
- final Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 32768, false, 0);
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
+ valakas.setIsInvul(true);
+ valakas.setRunning();
+ valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
}
@@ -364,12 +348,14 @@ public class Valakas extends AbstractNpcAI
return super.onAdvEvent(event, npc, player);
}
- // @Override
- // public String onSpawn(Npc npc)
- // {
- // npc.disableCoreAI(true);
- // return super.onSpawn(npc);
- // }
+ @Override
+ public String onSpawn(Npc npc)
+ {
+ ((Attackable) npc).setCanReturnToSpawnPoint(false);
+ npc.setRandomWalking(false);
+ npc.disableCoreAI(true);
+ return super.onSpawn(npc);
+ }
@Override
public String onAttack(Npc npc, PlayerInstance attacker, int damage, boolean isSummon)
@@ -392,14 +378,10 @@ public class Valakas extends AbstractNpcAI
}
// Debuff strider-mounted players.
- if (attacker.getMountType() == MountType.STRIDER)
+ if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(4258))
{
- final Skill skill = SkillData.getInstance().getSkill(4258, 1);
- if (!attacker.isAffectedBySkill(4258))
- {
- npc.setTarget(attacker);
- npc.doCast(skill);
- }
+ npc.setTarget(attacker);
+ npc.doCast(SkillData.getInstance().getSkill(4258, 1));
}
_timeTracker = System.currentTimeMillis();
@@ -428,117 +410,27 @@ public class Valakas extends AbstractNpcAI
GrandBossManager.getInstance().setBossStatus(VALAKAS, DEAD);
// Calculate Min and Max respawn times randomly.
- long respawnTime = Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM);
- respawnTime *= 3600000;
-
+ final long respawnTime = (Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM)) * 3600000;
startQuestTimer("valakas_unlock", respawnTime, null, null);
// also save the respawn time so that the info is maintained past reboots
final StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
- info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
+ info.set("respawn_time", System.currentTimeMillis() + respawnTime);
GrandBossManager.getInstance().setStatsSet(VALAKAS, info);
return super.onKill(npc, killer, isSummon);
}
- // @Override
- // public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon)
- // {
- // return null;
- // }
- //
- // private void callSkillAI(Npc npc)
- // {
- // if (npc.isInvul() || npc.isCastingNow(SkillCaster::isAnyNormalType))
- // {
- // return;
- // }
- //
- // // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target.
- // if ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0))
- // {
- // _actualVictim = getRandomTarget(npc);
- // }
- //
- // // If result is still null, Valakas will roam. Don't go deeper in skill AI.
- // if (_actualVictim == null)
- // {
- // if (getRandom(10) == 0)
- // {
- // final int posX = npc.getX() + getRandom(-1400, 1400);
- // final int posY = npc.getY() + getRandom(-1400, 1400);
- // if (GeoEngine.getInstance().canMoveToTarget(npc.getX(), npc.getY(), npc.getZ(), posX, posY, npc.getZ(), npc.getInstanceWorld()))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, npc.getZ(), 0));
- // }
- // }
- // return;
- // }
- //
- // final Skill skill = getRandomSkill(npc).getSkill();
- //
- // // Cast the skill or follow the target.
- // if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc, _actualVictim, true))
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
- // npc.setTarget(_actualVictim);
- // npc.doCast(skill);
- // }
- // else
- // {
- // npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null);
- // }
- // }
- //
- // /**
- // * Pick a random skill.
- // * Valakas will mostly use utility skills. If Valakas feels surrounded, he will use AoE skills.
- // * Lower than 50% HPs, he will begin to use Meteor skill.
- // * @param npc valakas
- // * @return a skill holder
- // */
- // private SkillHolder getRandomSkill(Npc npc)
- // {
- // final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100);
- //
- // // Valakas Lava Skin has priority.
- // if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId()))
- // {
- // return VALAKAS_LAVA_SKIN;
- // }
- //
- // // Valakas will use mass spells if he feels surrounded.
- // if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20)
- // {
- // return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)];
- // }
- //
- // if (hpRatio > 50)
- // {
- // return VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)];
- // }
- //
- // return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)];
- // }
- //
- // /**
- // * Pickup a random Playable from the zone, deads targets aren't included.
- // * @param npc
- // * @return a random Playable.
- // */
- // private Playable getRandomTarget(Npc npc)
- // {
- // final List result = new ArrayList<>();
- //
- // World.getInstance().forEachVisibleObject(npc, Playable.class, obj ->
- // {
- // if (!obj.isPet() && !obj.isDead())
- // {
- // result.add(obj);
- // }
- // });
- //
- // return (result.isEmpty()) ? null : result.get(getRandom(result.size()));
- // }
+ /*
+ * @Override public String onAggroRangeEnter(Npc npc, PlayerInstance player, boolean isSummon) { return null; } private void callSkillAI(Npc npc) { if (npc.isInvul() || npc.isCastingNow()) { return; } // Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target. if
+ * ((_actualVictim == null) || _actualVictim.isDead() || !(npc.isInSurroundingRegion(_actualVictim)) || (getRandom(10) == 0)) { _actualVictim = getRandomTarget(npc); } // If result is still null, Valakas will roam. Don't go deeper in skill AI. if (_actualVictim == null) { if (getRandom(10) == 0)
+ * { final int x = npc.getX(); final int y = npc.getY(); final int z = npc.getZ(); final int posX = x + getRandom(-1400, 1400); final int posY = y + getRandom(-1400, 1400); if (GeoEngine.getInstance().canMoveToTarget(x, y, z, posX, posY, z, npc.getInstanceId())) {
+ * npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, z, 0)); } } return; } final Skill skill = getRandomSkill(npc).getSkill(); // Cast the skill or follow the target. if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc,
+ * _actualVictim, true)) { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE); npc.setIsCastingNow(true); npc.setTarget(_actualVictim); npc.doCast(skill); } else { npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null); npc.setIsCastingNow(false); } } private
+ * SkillHolder getRandomSkill(Npc npc) { final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100); // Valakas Lava Skin has priority. if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId())) { return VALAKAS_LAVA_SKIN; } // Valakas
+ * will use mass spells if he feels surrounded. if (World.getInstance().getVisibleObjectsInRange(npc, PlayerInstance.class, 1200).size() >= 20) { return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)]; } if (hpRatio > 50) { return
+ * VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)]; } return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)]; } private Playable getRandomTarget(Npc npc) { final List result = new ArrayList<>(); World.getInstance().forEachVisibleObject(npc, Playable.class,
+ * obj -> { if ((obj == null) || obj.isPet()) { return; } else if (!obj.isDead() && obj.isPlayable()) { result.add(obj); } }); return result.isEmpty() ? null : result.get(getRandom(result.size())); }
+ */
public static void main(String[] args)
{
diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
index e4dce89f22..76e77aaaad 100644
--- a/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
+++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/data/scripts/ai/bosses/Valakas/Valakas.java
@@ -28,6 +28,7 @@ import org.l2jmobius.gameserver.instancemanager.GrandBossManager;
import org.l2jmobius.gameserver.model.Location;
import org.l2jmobius.gameserver.model.StatsSet;
import org.l2jmobius.gameserver.model.World;
+import org.l2jmobius.gameserver.model.actor.Attackable;
import org.l2jmobius.gameserver.model.actor.Npc;
import org.l2jmobius.gameserver.model.actor.Playable;
import org.l2jmobius.gameserver.model.actor.instance.GrandBossInstance;
@@ -52,8 +53,8 @@ public class Valakas extends AbstractNpcAI
// NPC
private static final int VALAKAS = 29028;
// Skills
- private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
private static final int VALAKAS_REGENERATION = 4691;
+ private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
private static final SkillHolder[] VALAKAS_REGULAR_SKILLS =
{
@@ -157,7 +158,6 @@ public class Valakas extends AbstractNpcAI
final double mp = info.getDouble("currentMP");
final Npc valakas = addSpawn(VALAKAS, loc_x, loc_y, loc_z, heading, false, 0);
- valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
valakas.setCurrentHpMp(hp, mp);
@@ -174,6 +174,7 @@ public class Valakas extends AbstractNpcAI
}
else
{
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
valakas.setIsInvul(true);
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
@@ -200,11 +201,7 @@ public class Valakas extends AbstractNpcAI
npc.teleToLocation(VALAKAS_LAIR);
// Sound + socialAction.
- for (PlayerInstance plyr : ZONE.getPlayersInside())
- {
- plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
- plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
- }
+ startQuestTimer("broadcast_spawn", 100, npc, null);
// Launch the cinematic, and tasks (regen + skill).
startQuestTimer("spawn_1", 1700, npc, null); // 1700
@@ -268,6 +265,14 @@ public class Valakas extends AbstractNpcAI
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
}
}
+ else if (event.equalsIgnoreCase("broadcast_spawn"))
+ {
+ for (PlayerInstance plyr : ZONE.getPlayersInside())
+ {
+ plyr.sendPacket(new PlaySound(1, "BS03_A", 0, 0, 0, 0, 0));
+ plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
+ }
+ }
// Spawn cinematic, regen_task and choose of skill.
else if (event.equalsIgnoreCase("spawn_1"))
{
@@ -358,19 +363,19 @@ public class Valakas extends AbstractNpcAI
callSkillAI(npc);
}
}
- else
+ else if (event.equalsIgnoreCase("valakas_unlock"))
{
- if (event.equalsIgnoreCase("valakas_unlock"))
- {
- final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
- valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
- GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
- GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
- }
- else if (event.equalsIgnoreCase("remove_players"))
- {
- ZONE.oustAllPlayers();
- }
+ final Npc valakas = addSpawn(VALAKAS, VALAKAS_REGENERATION_LOC, false, 0);
+ valakas.teleToLocation(VALAKAS_HIDDEN_LOC);
+ valakas.setIsInvul(true);
+ valakas.setRunning();
+ valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
+ GrandBossManager.getInstance().addBoss((GrandBossInstance) valakas);
+ GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
+ }
+ else if (event.equalsIgnoreCase("remove_players"))
+ {
+ ZONE.oustAllPlayers();
}
return super.onAdvEvent(event, npc, player);
}
@@ -378,6 +383,8 @@ public class Valakas extends AbstractNpcAI
@Override
public String onSpawn(Npc npc)
{
+ ((Attackable) npc).setCanReturnToSpawnPoint(false);
+ npc.setRandomWalking(false);
npc.disableCoreAI(true);
return super.onSpawn(npc);
}