This commit is contained in:
200
trunk/dist/game/data/scripts/ai/individual/Anais.java
vendored
Normal file
200
trunk/dist/game/data/scripts/ai/individual/Anais.java
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.quest.QuestTimer;
|
||||
|
||||
/**
|
||||
* Anais AI.
|
||||
* @author nonom
|
||||
*/
|
||||
public final class Anais extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int ANAIS = 25701;
|
||||
private static final int DIVINE_BURNER = 18915;
|
||||
private static final int GRAIL_WARD = 18929;
|
||||
// Skill
|
||||
private static SkillHolder DIVINE_NOVA = new SkillHolder(6326, 1);
|
||||
// Instances
|
||||
ArrayList<L2Npc> _divineBurners = new ArrayList<>(4);
|
||||
private L2PcInstance _nextTarget = null;
|
||||
private L2Npc _current = null;
|
||||
private int _pot = 0;
|
||||
|
||||
private Anais()
|
||||
{
|
||||
super(Anais.class.getSimpleName(), "ai/individual");
|
||||
addAttackId(ANAIS);
|
||||
addSpawnId(DIVINE_BURNER);
|
||||
addKillId(GRAIL_WARD);
|
||||
}
|
||||
|
||||
private void burnerOnAttack(int pot, L2Npc anais)
|
||||
{
|
||||
L2Npc npc = _divineBurners.get(pot);
|
||||
npc.setDisplayEffect(1);
|
||||
npc.setIsRunning(false);
|
||||
if (pot < 4)
|
||||
{
|
||||
_current = npc;
|
||||
QuestTimer checkAround = getQuestTimer("CHECK", anais, null);
|
||||
if (checkAround == null) // || !checkAround.getIsActive()
|
||||
{
|
||||
startQuestTimer("CHECK", 3000, anais, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cancelQuestTimer("CHECK", anais, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "CHECK":
|
||||
{
|
||||
if (!npc.isAttackingNow())
|
||||
{
|
||||
cancelQuestTimer("CHECK", npc, null);
|
||||
}
|
||||
if ((_current != null) || (_pot < 4))
|
||||
{
|
||||
final Map<Integer, L2PcInstance> players = npc.getKnownList().getKnownPlayers();
|
||||
final L2PcInstance target = players.get(getRandom(players.size() - 1));
|
||||
_nextTarget = target;
|
||||
if (_nextTarget == null)
|
||||
{
|
||||
_nextTarget = (L2PcInstance) npc.getTarget();
|
||||
}
|
||||
final L2Npc b = _divineBurners.get(_pot);
|
||||
_pot = _pot + 1;
|
||||
b.setDisplayEffect(1);
|
||||
b.setIsRunning(false);
|
||||
L2Npc ward = addSpawn(GRAIL_WARD, new Location(b.getX(), b.getY(), b.getZ()), true, 0);
|
||||
((L2Attackable) ward).addDamageHate(_nextTarget, 0, 999);
|
||||
ward.setIsRunning(true);
|
||||
ward.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, _nextTarget, null);
|
||||
startQuestTimer("GUARD_ATTACK", 1000, ward, _nextTarget, true);
|
||||
startQuestTimer("SUICIDE", 20000, ward, null);
|
||||
ward.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, _nextTarget);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "GUARD_ATTACK":
|
||||
{
|
||||
if (_nextTarget != null)
|
||||
{
|
||||
final double distance = npc.calculateDistance(_nextTarget, false, false);
|
||||
if (distance < 100)
|
||||
{
|
||||
npc.doCast(DIVINE_NOVA.getSkill());
|
||||
}
|
||||
else if (distance > 2000)
|
||||
{
|
||||
npc.doDie(null);
|
||||
cancelQuestTimer("GUARD_ATTACK", npc, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SUICIDE":
|
||||
{
|
||||
npc.doCast(DIVINE_NOVA.getSkill());
|
||||
cancelQuestTimer("GUARD_ATTACK", npc, _nextTarget);
|
||||
if (_current != null)
|
||||
{
|
||||
_current.setDisplayEffect(2);
|
||||
_current.setIsRunning(false);
|
||||
_current = null;
|
||||
}
|
||||
npc.doDie(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (_pot == 0)
|
||||
{
|
||||
burnerOnAttack(0, npc);
|
||||
}
|
||||
else if ((npc.getCurrentHp() <= (npc.getMaxRecoverableHp() * 0.75)) && (_pot == 1))
|
||||
{
|
||||
burnerOnAttack(1, npc);
|
||||
}
|
||||
else if ((npc.getCurrentHp() <= (npc.getMaxRecoverableHp() * 0.5)) && (_pot == 2))
|
||||
{
|
||||
burnerOnAttack(2, npc);
|
||||
}
|
||||
else if ((npc.getCurrentHp() <= (npc.getMaxRecoverableHp() * 0.25)) && (_pot == 3))
|
||||
{
|
||||
burnerOnAttack(3, npc);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.l2jserver.gameserver.model.quest.Quest#onSpawn(com.l2jserver.gameserver.model.actor.L2Npc)
|
||||
*/
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
_divineBurners.add(npc);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
npc.doCast(DIVINE_NOVA.getSkill());
|
||||
cancelQuestTimer("GUARD_ATTACK", npc, _nextTarget);
|
||||
cancelQuestTimer("CHECK", npc, null);
|
||||
if (_current != null)
|
||||
{
|
||||
_current.setDisplayEffect(2);
|
||||
_current.setIsRunning(false);
|
||||
_current = null;
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Anais();
|
||||
}
|
||||
}
|
8
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-01.html
vendored
Normal file
8
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-01.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks.<br>
|
||||
<font color="LEVEL">Do not expect Shilen's authority will diminish<br>
|
||||
while false gods freely roam.<br>
|
||||
Leave, and<br>
|
||||
prepare to face the return of Antharas.</font><br>
|
||||
(Challenging Antharas is not currently available.)
|
||||
</body></html>
|
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-02.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-02.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br>
|
||||
<font color="LEVEL">Do not expect that you might challenge Antharas at your own convenience.<br>
|
||||
When the time is right, Shilen's authority will judge you.</font><br>
|
||||
(Currently, other members are challenging Antharas.)
|
||||
</body></html>
|
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-03.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-03.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
A voice that can shatter your entire body is resonating in your head:<br>
|
||||
<font color="LEVEL">Do not dare to face Shilen's authority<br>
|
||||
without the most determined preparation.</font><br>
|
||||
(Only those who have the Portal Stone can challenge Antharas.)
|
||||
</body></html>
|
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-04.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-04.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br>
|
||||
<font color="LEVEL">No matter how many gather to follow false gods,<br>
|
||||
Shilen's authority is too great.</font><br>
|
||||
(The number of participants are above the allowed number in challenging Antharas.)
|
||||
</body></html>
|
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-05.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-05.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br>
|
||||
<font color="LEVEL">You seek death and defeat by coming here without your leader! You appear before Shilen's authority<br>
|
||||
and you tempt Shilen's wrath!</font><br>
|
||||
(The players who belong to an association can only enter through the Association Leader.)
|
||||
</body></html>
|
12
trunk/dist/game/data/scripts/ai/individual/Antharas/13001.html
vendored
Normal file
12
trunk/dist/game/data/scripts/ai/individual/Antharas/13001.html
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br>
|
||||
<font color="LEVEL">A terrible creature <br>
|
||||
fell to the earth from above <br>
|
||||
in order to vent a mother's spite,<br>
|
||||
cursed and forsaken by her own children.<br>
|
||||
Dark Pilgrim of the Holy Land,<br>
|
||||
Do you dare face the Land Dragon Antharas?</font><br>
|
||||
(A maximum of 200 people can challenge Antharas.)<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Antharas enter">Move to Antharas' Nest</a><br>
|
||||
<a action="bypass -h npc_%objectId%_Quest">Quest</a>
|
||||
</body></html>
|
1052
trunk/dist/game/data/scripts/ai/individual/Antharas/Antharas.java
vendored
Normal file
1052
trunk/dist/game/data/scripts/ai/individual/Antharas/Antharas.java
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
trunk/dist/game/data/scripts/ai/individual/Baium/31862-01.html
vendored
Normal file
3
trunk/dist/game/data/scripts/ai/individual/Baium/31862-01.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><head><body>Angelic Vortex:<br>
|
||||
The Angelic Vortex emits a faint light which twinkles out. The vortex becomes inactive. It seems like, in order to go to the place where the Angelic Vortex is leading, you will need some special object.
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/individual/Baium/31862-02.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Baium/31862-02.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Angelic Vortex:<br>
|
||||
The Angelic Vortex emits a faint light, in the midst of which an image appears. A giant that normally appears as a stone statue has come alive and is fighting with many people. Even angels have joined the fray. It seems that the angels are angry at the humans who have broken the seal of the stone statue.<br>
|
||||
It appears impossible to cross over to that place right now. You have no choice but to wait until the fight is over.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Baium 31862-04.html">Ask about the stone statue that has come alive.</a>
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/individual/Baium/31862-03.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Baium/31862-03.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Angelic Vortex:<br>
|
||||
The Angelic Vortex emits a faint light, in the midst of which an image appears. A large, open space... but the gigantic, human-like stone statue is no longer there.<br>
|
||||
It seems that while the statue is not visible, one could cross over to that place.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Baium 31862-04.html">Ask about the stone statue.</a>
|
||||
</body></html>
|
7
trunk/dist/game/data/scripts/ai/individual/Baium/31862-04.html
vendored
Normal file
7
trunk/dist/game/data/scripts/ai/individual/Baium/31862-04.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<html><body>Angelic Vortex:<br>
|
||||
In ancient times a mighty emperor named Baium became so enamored of his own power that he began to fancy himself a god. He conscripted all of his people to build an awesome tower that reached almost to heaven.<br>
|
||||
The gods were not amused. They struck him down, cursed him with immortality and imprisoned him in his own tower for eternity! A statue of the foolish emperor stands there to this day.<br>
|
||||
Occasionally, the old emperor himself is woken up by those who seek his power. Unfortunately, when Baium is disturbed, so are the angels who guard him.<br>
|
||||
Although the angels are certainly no friend of Baium, they regard Humans with equal disdain.<font color="LEVEL"> Ultimate success against Baium depends upon the defeat of the guardian angels.</font><br>
|
||||
This is all I can tell you. Good luck!
|
||||
</body></html>
|
4
trunk/dist/game/data/scripts/ai/individual/Baium/31862.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/individual/Baium/31862.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Angelic Vortex:<br>
|
||||
The Angelic Vortex emits a faint light, and in the midst of the light an image appears. In the deepest part of a spacious area, a gigantic stone statue is visible. The statue has a human-like appearance and is in a seated position, as though it was being held by some invisible force against its will.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Baium enter">Go where the Angelic Vortex leads.</a>
|
||||
</body></html>
|
792
trunk/dist/game/data/scripts/ai/individual/Baium/Baium.java
vendored
Normal file
792
trunk/dist/game/data/scripts/ai/individual/Baium/Baium.java
vendored
Normal file
@@ -0,0 +1,792 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual.Baium;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.enums.CategoryType;
|
||||
import com.l2jserver.gameserver.enums.MountType;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.variables.NpcVariables;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2NoRestartZone;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.Earthquake;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Baium AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Baium extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int BAIUM = 29020; // Baium
|
||||
private static final int BAIUM_STONE = 29025; // Baium
|
||||
private static final int ANG_VORTEX = 31862; // Angelic Vortex
|
||||
private static final int ARCHANGEL = 29021; // Archangel
|
||||
private static final int TELE_CUBE = 31842; // Teleportation Cubic
|
||||
// Skills
|
||||
private static final SkillHolder BAIUM_ATTACK = new SkillHolder(4127, 1); // Baium: General Attack
|
||||
private static final SkillHolder ENERGY_WAVE = new SkillHolder(4128, 1); // Wind Of Force
|
||||
private static final SkillHolder EARTH_QUAKE = new SkillHolder(4129, 1); // Earthquake
|
||||
private static final SkillHolder THUNDERBOLT = new SkillHolder(4130, 1); // Striking of Thunderbolt
|
||||
private static final SkillHolder GROUP_HOLD = new SkillHolder(4131, 1); // Stun
|
||||
private static final SkillHolder SPEAR_ATTACK = new SkillHolder(4132, 1); // Spear: Pound the Ground
|
||||
private static final SkillHolder ANGEL_HEAL = new SkillHolder(4133, 1); // Angel Heal
|
||||
private static final SkillHolder HEAL_OF_BAIUM = new SkillHolder(4135, 1); // Baium Heal
|
||||
private static final SkillHolder BAIUM_PRESENT = new SkillHolder(4136, 1); // Baium's Gift
|
||||
private static final SkillHolder ANTI_STRIDER = new SkillHolder(4258, 1); // Hinder Strider
|
||||
// Items
|
||||
private static final int FABRIC = 4295; // Blooded Fabric
|
||||
// Zone
|
||||
private static final L2NoRestartZone zone = ZoneManager.getInstance().getZoneById(70051, L2NoRestartZone.class); // Baium zone
|
||||
// Status
|
||||
private static final int ALIVE = 0;
|
||||
private static final int WAITING = 1;
|
||||
private static final int IN_FIGHT = 2;
|
||||
private static final int DEAD = 3;
|
||||
// Locations
|
||||
private static final Location BAIUM_GIFT_LOC = new Location(115910, 17337, 10105);
|
||||
private static final Location BAIUM_LOC = new Location(116033, 17447, 10107, -25348);
|
||||
private static final Location TELEPORT_CUBIC_LOC = new Location(115017, 15549, 10090);
|
||||
private static final Location TELEPORT_IN_LOC = new Location(114077, 15882, 10078);
|
||||
private static final Location[] TELEPORT_OUT_LOC =
|
||||
{
|
||||
new Location(108784, 16000, -4928),
|
||||
new Location(113824, 10448, -5164),
|
||||
new Location(115488, 22096, -5168),
|
||||
};
|
||||
private static final Location[] ARCHANGEL_LOC =
|
||||
{
|
||||
new Location(115792, 16608, 10136, 0),
|
||||
new Location(115168, 17200, 10136, 0),
|
||||
new Location(115780, 15564, 10136, 13620),
|
||||
new Location(114880, 16236, 10136, 5400),
|
||||
new Location(114239, 17168, 10136, -1992)
|
||||
};
|
||||
// Misc
|
||||
private L2GrandBossInstance _baium = null;
|
||||
private static long _lastAttack = 0;
|
||||
private static L2PcInstance _standbyPlayer = null;
|
||||
|
||||
private Baium()
|
||||
{
|
||||
super(Baium.class.getSimpleName(), "ai/individual");
|
||||
addFirstTalkId(ANG_VORTEX);
|
||||
addTalkId(ANG_VORTEX, TELE_CUBE, BAIUM_STONE);
|
||||
addStartNpc(ANG_VORTEX, TELE_CUBE, BAIUM_STONE);
|
||||
addAttackId(BAIUM, ARCHANGEL);
|
||||
addKillId(BAIUM);
|
||||
addSeeCreatureId(BAIUM);
|
||||
addSpellFinishedId(BAIUM);
|
||||
|
||||
final StatsSet info = GrandBossManager.getInstance().getStatsSet(BAIUM);
|
||||
final int curr_hp = info.getInt("currentHP");
|
||||
final int curr_mp = info.getInt("currentMP");
|
||||
final int loc_x = info.getInt("loc_x");
|
||||
final int loc_y = info.getInt("loc_y");
|
||||
final int loc_z = info.getInt("loc_z");
|
||||
final int heading = info.getInt("heading");
|
||||
final long respawnTime = info.getLong("respawn_time");
|
||||
|
||||
switch (getStatus())
|
||||
{
|
||||
case WAITING:
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
}
|
||||
case ALIVE:
|
||||
{
|
||||
addSpawn(BAIUM_STONE, BAIUM_LOC, false, 0);
|
||||
break;
|
||||
}
|
||||
case IN_FIGHT:
|
||||
{
|
||||
_baium = (L2GrandBossInstance) addSpawn(BAIUM, loc_x, loc_y, loc_z, heading, false, 0);
|
||||
_baium.setCurrentHpMp(curr_hp, curr_mp);
|
||||
_lastAttack = System.currentTimeMillis();
|
||||
addBoss(_baium);
|
||||
|
||||
for (Location loc : ARCHANGEL_LOC)
|
||||
{
|
||||
final L2Npc archangel = addSpawn(ARCHANGEL, loc, false, 0, true);
|
||||
startQuestTimer("SELECT_TARGET", 5000, archangel, null);
|
||||
}
|
||||
startQuestTimer("CHECK_ATTACK", 60000, _baium, null);
|
||||
break;
|
||||
}
|
||||
case DEAD:
|
||||
{
|
||||
final long remain = respawnTime - System.currentTimeMillis();
|
||||
if (remain > 0)
|
||||
{
|
||||
startQuestTimer("CLEAR_STATUS", remain, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
notifyEvent("CLEAR_STATUS", null, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "31862-04.html":
|
||||
{
|
||||
return event;
|
||||
}
|
||||
case "enter":
|
||||
{
|
||||
String htmltext = null;
|
||||
if (getStatus() == DEAD)
|
||||
{
|
||||
htmltext = "31862-03.html";
|
||||
}
|
||||
else if (getStatus() == IN_FIGHT)
|
||||
{
|
||||
htmltext = "31862-02.html";
|
||||
}
|
||||
else if (!hasQuestItems(player, FABRIC))
|
||||
{
|
||||
htmltext = "31862-01.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
takeItems(player, FABRIC, 1);
|
||||
player.teleToLocation(TELEPORT_IN_LOC);
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
case "teleportOut":
|
||||
{
|
||||
final Location destination = TELEPORT_OUT_LOC[getRandom(TELEPORT_OUT_LOC.length)];
|
||||
player.teleToLocation(destination.getX() + getRandom(100), destination.getY() + getRandom(100), destination.getZ());
|
||||
break;
|
||||
}
|
||||
case "wakeUp":
|
||||
{
|
||||
if (getStatus() == ALIVE)
|
||||
{
|
||||
npc.deleteMe();
|
||||
setStatus(IN_FIGHT);
|
||||
_baium = (L2GrandBossInstance) addSpawn(BAIUM, BAIUM_LOC, false, 0);
|
||||
_baium.disableCoreAI(true);
|
||||
addBoss(_baium);
|
||||
_lastAttack = System.currentTimeMillis();
|
||||
startQuestTimer("WAKEUP_ACTION", 50, _baium, null);
|
||||
startQuestTimer("MANAGE_EARTHQUAKE", 2000, _baium, null);
|
||||
startQuestTimer("CHECK_ATTACK", 60000, _baium, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "WAKEUP_ACTION":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
zone.broadcastPacket(new SocialAction(_baium.getObjectId(), 2));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "MANAGE_EARTHQUAKE":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
zone.broadcastPacket(new Earthquake(npc.getX(), npc.getY(), npc.getZ(), 40, 10));
|
||||
zone.broadcastPacket(new PlaySound("BS02_A"));
|
||||
startQuestTimer("SOCIAL_ACTION", 8000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SOCIAL_ACTION":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
zone.broadcastPacket(new SocialAction(npc.getObjectId(), 3));
|
||||
startQuestTimer("PLAYER_PORT", 6000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "PLAYER_PORT":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
if ((player != null) && player.isInsideRadius(npc, 16000, true, false))
|
||||
{
|
||||
player.teleToLocation(BAIUM_GIFT_LOC);
|
||||
startQuestTimer("PLAYER_KILL", 3000, npc, player);
|
||||
}
|
||||
else if ((_standbyPlayer != null) && _standbyPlayer.isInsideRadius(npc, 16000, true, false))
|
||||
{
|
||||
_standbyPlayer.teleToLocation(BAIUM_GIFT_LOC);
|
||||
startQuestTimer("PLAYER_KILL", 3000, npc, _standbyPlayer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "PLAYER_KILL":
|
||||
{
|
||||
if ((player != null) && player.isInsideRadius(npc, 16000, true, false))
|
||||
{
|
||||
zone.broadcastPacket(new SocialAction(npc.getObjectId(), 1));
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, player.getName() + ", How dare you wake me! Now you shall die!"); // TODO: replace with NpcStringId when are done core support
|
||||
npc.setTarget(player);
|
||||
npc.doCast(BAIUM_PRESENT.getSkill());
|
||||
}
|
||||
|
||||
for (L2PcInstance players : zone.getPlayersInside())
|
||||
{
|
||||
if (players.isHero())
|
||||
{
|
||||
zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.NOT_EVEN_THE_GODS_THEMSELVES_COULD_TOUCH_ME_BUT_YOU_S1_YOU_DARE_CHALLENGE_ME_IGNORANT_MORTAL, 2, 4000, players.getName()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
startQuestTimer("SPAWN_ARCHANGEL", 8000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "SPAWN_ARCHANGEL":
|
||||
{
|
||||
_baium.disableCoreAI(false);
|
||||
|
||||
for (Location loc : ARCHANGEL_LOC)
|
||||
{
|
||||
final L2Npc archangel = addSpawn(ARCHANGEL, loc, false, 0, true);
|
||||
startQuestTimer("SELECT_TARGET", 5000, archangel, null);
|
||||
}
|
||||
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
else if ((_standbyPlayer != null) && !_standbyPlayer.isDead())
|
||||
{
|
||||
addAttackPlayerDesire(npc, _standbyPlayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (L2Character creature : npc.getKnownList().getKnownCharactersInRadius(2000))
|
||||
{
|
||||
if ((creature != null) && creature.isPlayer() && zone.isInsideZone(creature) && !creature.isDead())
|
||||
{
|
||||
addAttackPlayerDesire(npc, (L2Playable) creature);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SELECT_TARGET":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final L2Character mostHated = mob.getMostHated();
|
||||
|
||||
if ((_baium == null) || _baium.isDead())
|
||||
{
|
||||
mob.deleteMe();
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mostHated != null) && mostHated.isPlayer() && zone.isInsideZone(mostHated))
|
||||
{
|
||||
if (mob.getTarget() != mostHated)
|
||||
{
|
||||
mob.clearAggroList();
|
||||
}
|
||||
addAttackPlayerDesire(mob, (L2Playable) mostHated);
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean found = false;
|
||||
for (L2Character creature : mob.getKnownList().getKnownCharactersInRadius(1000))
|
||||
{
|
||||
if ((creature != null) && creature.isPlayable() && zone.isInsideZone(creature) && !creature.isDead())
|
||||
{
|
||||
if (mob.getTarget() != creature)
|
||||
{
|
||||
mob.clearAggroList();
|
||||
}
|
||||
addAttackPlayerDesire(mob, (L2Playable) creature);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (mob.isInsideRadius(_baium, 40, true, false))
|
||||
{
|
||||
if (mob.getTarget() != _baium)
|
||||
{
|
||||
mob.clearAggroList();
|
||||
}
|
||||
mob.setIsRunning(true);
|
||||
mob.addDamageHate(_baium, 0, 999);
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, _baium);
|
||||
}
|
||||
else
|
||||
{
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _baium);
|
||||
}
|
||||
}
|
||||
}
|
||||
startQuestTimer("SELECT_TARGET", 5000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CHECK_ATTACK":
|
||||
{
|
||||
if ((npc != null) && ((_lastAttack + 1800000) < System.currentTimeMillis()))
|
||||
{
|
||||
notifyEvent("CLEAR_ZONE", null, null);
|
||||
addSpawn(BAIUM_STONE, BAIUM_LOC, false, 0);
|
||||
setStatus(ALIVE);
|
||||
}
|
||||
else if (npc != null)
|
||||
{
|
||||
if (((_lastAttack + 300000) < System.currentTimeMillis()) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(HEAL_OF_BAIUM.getSkill());
|
||||
}
|
||||
startQuestTimer("CHECK_ATTACK", 60000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CLEAR_STATUS":
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
addSpawn(BAIUM_STONE, BAIUM_LOC, false, 0);
|
||||
break;
|
||||
}
|
||||
case "CLEAR_ZONE":
|
||||
{
|
||||
for (L2Character charInside : zone.getCharactersInside())
|
||||
{
|
||||
if (charInside != null)
|
||||
{
|
||||
if (charInside.isNpc())
|
||||
{
|
||||
charInside.deleteMe();
|
||||
}
|
||||
else if (charInside.isPlayer())
|
||||
{
|
||||
notifyEvent("teleportOut", null, (L2PcInstance) charInside);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "RESPAWN_BAIUM":
|
||||
{
|
||||
if (getStatus() == DEAD)
|
||||
{
|
||||
setRespawn(0);
|
||||
cancelQuestTimer("CLEAR_STATUS", null, null);
|
||||
notifyEvent("CLEAR_STATUS", null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You cant respawn Baium while Baium is alive!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ABORT_FIGHT":
|
||||
{
|
||||
if (getStatus() == IN_FIGHT)
|
||||
{
|
||||
_baium = null;
|
||||
notifyEvent("CLEAR_ZONE", null, null);
|
||||
notifyEvent("CLEAR_STATUS", null, null);
|
||||
player.sendMessage(getClass().getSimpleName() + ": Aborting fight!");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You cant abort attack right now!");
|
||||
}
|
||||
cancelQuestTimers("CHECK_ATTACK");
|
||||
cancelQuestTimers("SELECT_TARGET");
|
||||
break;
|
||||
}
|
||||
case "DESPAWN_MINIONS":
|
||||
{
|
||||
if (getStatus() == IN_FIGHT)
|
||||
{
|
||||
for (L2Character charInside : zone.getCharactersInside())
|
||||
{
|
||||
if ((charInside != null) && charInside.isNpc() && (charInside.getId() == ARCHANGEL))
|
||||
{
|
||||
charInside.deleteMe();
|
||||
}
|
||||
}
|
||||
if (player != null)
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": All archangels has been deleted!");
|
||||
}
|
||||
}
|
||||
else if (player != null)
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You cant despawn archangels right now!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "MANAGE_SKILLS":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
manageSkills(npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
_lastAttack = System.currentTimeMillis();
|
||||
|
||||
if (npc.getId() == BAIUM)
|
||||
{
|
||||
if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(ANTI_STRIDER.getSkillId()))
|
||||
{
|
||||
if (!npc.isSkillDisabled(ANTI_STRIDER.getSkill()))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(ANTI_STRIDER.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
if (skill == null)
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 1000));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25))
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 100));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 20));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 20));
|
||||
}
|
||||
manageSkills(npc);
|
||||
}
|
||||
else
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final L2Character mostHated = mob.getMostHated();
|
||||
|
||||
if ((getRandom(100) < 10) && mob.checkDoCastConditions(SPEAR_ATTACK.getSkill()))
|
||||
{
|
||||
if ((mostHated != null) && (npc.calculateDistance(mostHated, true, false) < 1000) && zone.isCharacterInZone(mostHated))
|
||||
{
|
||||
mob.setTarget(mostHated);
|
||||
mob.doCast(SPEAR_ATTACK.getSkill());
|
||||
}
|
||||
else if (zone.isCharacterInZone(attacker))
|
||||
{
|
||||
mob.setTarget(attacker);
|
||||
mob.doCast(SPEAR_ATTACK.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
if ((getRandom(100) < 5) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) && mob.checkDoCastConditions(ANGEL_HEAL.getSkill()))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(ANGEL_HEAL.getSkill());
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (zone.isCharacterInZone(killer))
|
||||
{
|
||||
setStatus(DEAD);
|
||||
addSpawn(TELE_CUBE, TELEPORT_CUBIC_LOC, false, 900000);
|
||||
zone.broadcastPacket(new PlaySound("BS01_D"));
|
||||
long respawnTime = (Config.BAIUM_SPAWN_INTERVAL + getRandom(-Config.BAIUM_SPAWN_RANDOM, Config.BAIUM_SPAWN_RANDOM)) * 3600000;
|
||||
setRespawn(respawnTime);
|
||||
startQuestTimer("CLEAR_STATUS", respawnTime, null, null);
|
||||
startQuestTimer("CLEAR_ZONE", 900000, null, null);
|
||||
cancelQuestTimer("CHECK_ATTACK", npc, null);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (!zone.isInsideZone(creature) || (creature.isNpc() && (creature.getId() == BAIUM_STONE)))
|
||||
{
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
if (creature.isPlayer() && !creature.isDead() && (_standbyPlayer == null))
|
||||
{
|
||||
_standbyPlayer = (L2PcInstance) creature;
|
||||
}
|
||||
|
||||
if (creature.isInCategory(CategoryType.CLERIC_GROUP))
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25))
|
||||
{
|
||||
refreshAiParams(creature, npc, 10000);
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5))
|
||||
{
|
||||
refreshAiParams(creature, npc, 10000, 6000);
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75))
|
||||
{
|
||||
refreshAiParams(creature, npc, 10000, 3000);
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshAiParams(creature, npc, 10000, 2000);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshAiParams(creature, npc, 10000, 1000);
|
||||
}
|
||||
manageSkills(npc);
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
startQuestTimer("MANAGE_SKILLS", 1000, npc, null);
|
||||
|
||||
if (!zone.isCharacterInZone(npc) && (_baium != null))
|
||||
{
|
||||
_baium.teleToLocation(BAIUM_LOC);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unload(boolean removeFromList)
|
||||
{
|
||||
if (_baium != null)
|
||||
{
|
||||
_baium.deleteMe();
|
||||
}
|
||||
return super.unload(removeFromList);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(L2Character attacker, L2Npc npc, int damage)
|
||||
{
|
||||
refreshAiParams(attacker, npc, damage, damage);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(L2Character attacker, L2Npc npc, int damage, int aggro)
|
||||
{
|
||||
final int newAggroVal = damage + getRandom(3000);
|
||||
final int aggroVal = aggro + 1000;
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (attacker == vars.getObject("c_quest" + i, L2Character.class))
|
||||
{
|
||||
if (vars.getInt("i_quest" + i) < aggroVal)
|
||||
{
|
||||
vars.set("i_quest" + i, newAggroVal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
final int index = Util.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
vars.set("i_quest" + index, newAggroVal);
|
||||
vars.set("c_quest" + index, attacker);
|
||||
}
|
||||
|
||||
private int getStatus()
|
||||
{
|
||||
return GrandBossManager.getInstance().getBossStatus(BAIUM);
|
||||
}
|
||||
|
||||
private void addBoss(L2GrandBossInstance grandboss)
|
||||
{
|
||||
GrandBossManager.getInstance().addBoss(grandboss);
|
||||
}
|
||||
|
||||
private void setStatus(int status)
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(BAIUM, status);
|
||||
}
|
||||
|
||||
private void setRespawn(long respawnTime)
|
||||
{
|
||||
GrandBossManager.getInstance().getStatsSet(BAIUM).set("respawn_time", (System.currentTimeMillis() + respawnTime));
|
||||
}
|
||||
|
||||
private void manageSkills(L2Npc npc)
|
||||
{
|
||||
if (npc.isCastingNow() || npc.isCoreAIDisabled() || !npc.isInCombat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
final L2Character attacker = vars.getObject("c_quest" + i, L2Character.class);
|
||||
if ((attacker == null) || ((npc.calculateDistance(attacker, true, false) > 9000) || attacker.isDead()))
|
||||
{
|
||||
vars.set("i_quest" + i, 0);
|
||||
}
|
||||
}
|
||||
final int index = Util.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
final L2Character player = vars.getObject("c_quest" + index, L2Character.class);
|
||||
final int i2 = vars.getInt("i_quest" + index);
|
||||
if ((i2 > 0) && (getRandom(100) < 70))
|
||||
{
|
||||
vars.set("i_quest" + index, 500);
|
||||
}
|
||||
|
||||
SkillHolder skillToCast = null;
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
if (npc.getCurrentHp() > (npc.getMaxHp() * 0.75))
|
||||
{
|
||||
if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = ENERGY_WAVE;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = EARTH_QUAKE;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = BAIUM_ATTACK;
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() > (npc.getMaxHp() * 0.5))
|
||||
{
|
||||
if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = GROUP_HOLD;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = ENERGY_WAVE;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = EARTH_QUAKE;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = BAIUM_ATTACK;
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() > (npc.getMaxHp() * 0.25))
|
||||
{
|
||||
if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = THUNDERBOLT;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = GROUP_HOLD;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = ENERGY_WAVE;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = EARTH_QUAKE;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = BAIUM_ATTACK;
|
||||
}
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = THUNDERBOLT;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = GROUP_HOLD;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = ENERGY_WAVE;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = EARTH_QUAKE;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = BAIUM_ATTACK;
|
||||
}
|
||||
}
|
||||
|
||||
if ((skillToCast != null) && npc.checkDoCastConditions(skillToCast.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skillToCast.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Baium();
|
||||
}
|
||||
}
|
104
trunk/dist/game/data/scripts/ai/individual/Ballista.java
vendored
Normal file
104
trunk/dist/game/data/scripts/ai/individual/Ballista.java
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
|
||||
/**
|
||||
* Ballista AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Ballista extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] BALLISTA =
|
||||
{
|
||||
35685, // Shanty Fortress
|
||||
35723, // Southern Fortress
|
||||
35754, // Hive Fortress
|
||||
35792, // Valley Fortress
|
||||
35823, // Ivory Fortress
|
||||
35854, // Narsell Fortress
|
||||
35892, // Bayou Fortress
|
||||
35923, // White Sands Fortress
|
||||
35961, // Borderland Fortress
|
||||
35999, // Swamp Fortress
|
||||
36030, // Archaic Fortress
|
||||
36068, // Floran Fortress
|
||||
36106, // Cloud Mountain)
|
||||
36137, // Tanor Fortress
|
||||
36168, // Dragonspine Fortress
|
||||
36206, // Antharas's Fortress
|
||||
36244, // Western Fortress
|
||||
36282, // Hunter's Fortress
|
||||
36313, // Aaru Fortress
|
||||
36351, // Demon Fortress
|
||||
36389, // Monastic Fortress
|
||||
};
|
||||
// Skill
|
||||
private static final SkillHolder BOMB = new SkillHolder(2342, 1); // Ballista Bomb
|
||||
// Misc
|
||||
private static final int MIN_CLAN_LV = 5;
|
||||
|
||||
private Ballista()
|
||||
{
|
||||
super(Ballista.class.getSimpleName(), "ai/individual");
|
||||
addSkillSeeId(BALLISTA);
|
||||
addSpawnId(BALLISTA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if ((skill != null) && (caster.getTarget() == npc) && (getRandom(100) < 40) && (skill == BOMB.getSkill()))
|
||||
{
|
||||
if (npc.getFort().getSiege().isInProgress())
|
||||
{
|
||||
if ((caster.getClan() != null) && (caster.getClan().getLevel() >= MIN_CLAN_LV))
|
||||
{
|
||||
caster.getClan().addReputationScore(Config.BALLISTA_POINTS, true);
|
||||
caster.sendPacket(SystemMessageId.THE_BALLISTA_HAS_BEEN_SUCCESSFULLY_DESTROYED_THE_CLAN_REPUTATION_WILL_BE_INCREASED);
|
||||
}
|
||||
}
|
||||
npc.doDie(caster);
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
npc.setIsMortal(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Ballista();
|
||||
}
|
||||
}
|
782
trunk/dist/game/data/scripts/ai/individual/Beleth.java
vendored
Normal file
782
trunk/dist/game/data/scripts/ai/individual/Beleth.java
vendored
Normal file
@@ -0,0 +1,782 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.cache.HtmCache;
|
||||
import com.l2jserver.gameserver.datatables.DoorTable;
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
|
||||
import com.l2jserver.gameserver.network.serverpackets.DoorStatusUpdate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
|
||||
import com.l2jserver.gameserver.network.serverpackets.StaticObject;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Beleth's AI.
|
||||
* @author Treat
|
||||
*/
|
||||
public final class Beleth extends AbstractNpcAI
|
||||
{
|
||||
protected static L2Npc CAMERA;
|
||||
protected static L2Npc CAMERA2;
|
||||
protected static L2Npc CAMERA3;
|
||||
protected static L2Npc CAMERA4;
|
||||
protected static L2Npc BELETH;
|
||||
protected static L2Npc PRIEST;
|
||||
protected static L2ZoneType ZONE = null;
|
||||
private static L2PcInstance BELETH_KILLER;
|
||||
private static boolean DEBUG = false;
|
||||
protected static boolean MOVIE = false;
|
||||
private static boolean ATTACKED = false;
|
||||
private static int ALLOW_OBJECT_ID = 0;
|
||||
private static int KILLED = 0;
|
||||
protected static ScheduledFuture<?> SPAWN_TIMER = null;
|
||||
protected static ArrayList<L2Npc> MINIONS = new ArrayList<>();
|
||||
private static SkillHolder BLEED = new SkillHolder(5495, 1);
|
||||
private static SkillHolder FIREBALL = new SkillHolder(5496, 1);
|
||||
private static SkillHolder HORN_OF_RISING = new SkillHolder(5497, 1);
|
||||
private static SkillHolder LIGHTENING = new SkillHolder(5499, 1);
|
||||
|
||||
protected static final Location BELETH_SPAWN = new Location(16323, 213059, -9357, 49152);
|
||||
|
||||
private Beleth()
|
||||
{
|
||||
super(Beleth.class.getSimpleName(), "ai/individual");
|
||||
ZONE = ZoneManager.getInstance().getZoneById(12018);
|
||||
addEnterZoneId(12018);
|
||||
registerMobs(29118, 29119);
|
||||
addStartNpc(32470);
|
||||
addTalkId(32470);
|
||||
addFirstTalkId(29128);
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(29118);
|
||||
int status = GrandBossManager.getInstance().getBossStatus(29118);
|
||||
if (status == 3)
|
||||
{
|
||||
long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
|
||||
if (temp > 0)
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new unlock(), temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(29118, 0);
|
||||
}
|
||||
}
|
||||
else if (status != 0)
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(29118, 0);
|
||||
}
|
||||
DoorTable.getInstance().getDoor(20240001).openMe();
|
||||
}
|
||||
|
||||
protected static L2Npc spawn(int npcId, Location loc)
|
||||
{
|
||||
try
|
||||
{
|
||||
L2NpcTemplate template = NpcData.getInstance().getTemplate(npcId);
|
||||
if (template != null)
|
||||
{
|
||||
L2Spawn spawn = new L2Spawn(template);
|
||||
spawn.setInstanceId(loc.getInstanceId());
|
||||
spawn.setLocation(loc);
|
||||
spawn.setAmount(spawn.getAmount() + 1);
|
||||
return spawn.doSpawn();
|
||||
}
|
||||
}
|
||||
catch (Exception ignored)
|
||||
{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void startSpawnTask()
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(1), DEBUG ? 10000 : 300000);
|
||||
}
|
||||
|
||||
protected static class unlock implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(29118, 0);
|
||||
DoorTable.getInstance().getDoor(20240001).openMe();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Cast implements Runnable
|
||||
{
|
||||
SkillHolder _skill;
|
||||
L2Npc _npc;
|
||||
|
||||
public Cast(SkillHolder skill, L2Npc npc)
|
||||
{
|
||||
_skill = skill;
|
||||
_npc = npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if ((_npc != null) && !_npc.isDead() && !_npc.isCastingNow())
|
||||
{
|
||||
_npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
_npc.doCast(_skill.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Spawn implements Runnable
|
||||
{
|
||||
private int _taskId = 0;
|
||||
|
||||
public Spawn(int taskId)
|
||||
{
|
||||
_taskId = taskId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
int instanceId = 0;
|
||||
switch (_taskId)
|
||||
{
|
||||
case 1:
|
||||
MOVIE = true;
|
||||
for (L2Character npc : ZONE.getCharactersInside())
|
||||
{
|
||||
if (npc.isNpc())
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
}
|
||||
CAMERA = spawn(29120, new Location(16323, 213142, -9357, 0, instanceId));
|
||||
CAMERA2 = spawn(29121, new Location(16323, 210741, -9357, 0, instanceId));
|
||||
CAMERA3 = spawn(29122, new Location(16323, 213170, -9357, 0, instanceId));
|
||||
CAMERA4 = spawn(29123, new Location(16323, 214917, -9356, 0, instanceId));
|
||||
ZONE.broadcastPacket(new PlaySound(1, "BS07_A", 1, CAMERA.getObjectId(), CAMERA.getX(), CAMERA.getY(), CAMERA.getZ()));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 75, -25, 0, 2500, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 75, -25, 0, 2500, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(2), 300);
|
||||
break;
|
||||
case 2:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 1800, -45, -45, 5000, 5000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(3), 4900);
|
||||
break;
|
||||
case 3:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 2500, -120, -45, 5000, 5000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(4), 4900);
|
||||
break;
|
||||
case 4:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 2200, 130, 0, 0, 1500, -20, 15, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(5), 1400);
|
||||
break;
|
||||
case 5:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 2300, 100, 0, 2000, 4500, 0, 10, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(6), 2500);
|
||||
break;
|
||||
case 6:
|
||||
L2DoorInstance door = DoorTable.getInstance().getDoor(20240001);
|
||||
door.closeMe();
|
||||
ZONE.broadcastPacket(new StaticObject(door, false));
|
||||
ZONE.broadcastPacket(new DoorStatusUpdate(door));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(7), 1700);
|
||||
break;
|
||||
case 7:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 1500, 210, 0, 0, 1500, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 900, 255, 0, 5000, 6500, 0, 10, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(8), 6000);
|
||||
break;
|
||||
case 8:
|
||||
spawn(29125, new Location(16323, 214917, -9356, 0, instanceId));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 900, 255, 0, 0, 1500, 0, 10, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(9), 1000);
|
||||
break;
|
||||
case 9:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 1000, 255, 0, 7000, 17000, 0, 25, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(10), 3000);
|
||||
break;
|
||||
case 10:
|
||||
BELETH = spawn(29118, new Location(16321, 214211, -9352, 49369, instanceId));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(11), 200);
|
||||
break;
|
||||
case 11:
|
||||
ZONE.broadcastPacket(new SocialAction(BELETH.getObjectId(), 1));
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
int x = (int) ((150 * Math.cos(i * 1.046666667)) + 16323);
|
||||
int y = (int) ((150 * Math.sin(i * 1.046666667)) + 213059);
|
||||
L2Npc minion = spawn(29119, new Location(x, y, -9357, 49152, BELETH.getInstanceId()));
|
||||
minion.setShowSummonAnimation(true);
|
||||
minion.decayMe();
|
||||
MINIONS.add(minion);
|
||||
}
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(12), 6800);
|
||||
break;
|
||||
case 12:
|
||||
ZONE.broadcastPacket(new SpecialCamera(BELETH, 0, 270, -5, 0, 4000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(13), 3500);
|
||||
break;
|
||||
case 13:
|
||||
ZONE.broadcastPacket(new SpecialCamera(BELETH, 800, 270, 10, 3000, 6000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(14), 5000);
|
||||
break;
|
||||
case 14:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 100, 270, 15, 0, 5000, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 100, 270, 15, 0, 5000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(15), 100);
|
||||
break;
|
||||
case 15:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 100, 270, 15, 3000, 6000, 0, 5, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(16), 1400);
|
||||
break;
|
||||
case 16:
|
||||
BELETH.teleToLocation(BELETH_SPAWN);
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(17), 200);
|
||||
break;
|
||||
case 17:
|
||||
ZONE.broadcastPacket(new MagicSkillUse(BELETH, BELETH, 5532, 1, 2000, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(18), 2000);
|
||||
break;
|
||||
case 18:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 700, 270, 20, 1500, 8000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(19), 6900);
|
||||
break;
|
||||
case 19:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 40, 260, 0, 0, 4000, 0, 0, 1, 0, 0));
|
||||
for (L2Npc blth : MINIONS)
|
||||
{
|
||||
blth.spawnMe();
|
||||
}
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(20), 3000);
|
||||
break;
|
||||
case 20:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 40, 280, 0, 0, 4000, 5, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(21), 3000);
|
||||
break;
|
||||
case 21:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 5, 250, 5, 0, 13000, 20, 15, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(22), 1000);
|
||||
break;
|
||||
case 22:
|
||||
ZONE.broadcastPacket(new SocialAction(BELETH.getObjectId(), 3));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(23), 4000);
|
||||
break;
|
||||
case 23:
|
||||
ZONE.broadcastPacket(new MagicSkillUse(BELETH, BELETH, 5533, 1, 2000, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(24), 6800);
|
||||
break;
|
||||
case 24:
|
||||
BELETH.deleteMe();
|
||||
for (L2Npc bel : MINIONS)
|
||||
{
|
||||
bel.deleteMe();
|
||||
}
|
||||
MINIONS.clear();
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(25), 1000);
|
||||
break;
|
||||
case 25:
|
||||
CAMERA.deleteMe();
|
||||
CAMERA2.deleteMe();
|
||||
CAMERA3.deleteMe();
|
||||
CAMERA4.deleteMe();
|
||||
MOVIE = false;
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(26), 60000);
|
||||
break;
|
||||
case 26:
|
||||
if (SPAWN_TIMER != null)
|
||||
{
|
||||
SPAWN_TIMER.cancel(false);
|
||||
setSpawnTimer(0);
|
||||
}
|
||||
SpawnBeleths();
|
||||
break;
|
||||
case 27:
|
||||
BELETH.doDie(null);
|
||||
CAMERA = spawn(29122, new Location(16323, 213170, -9357, 0, instanceId));
|
||||
CAMERA.broadcastPacket(new PlaySound(1, "BS07_D", 1, CAMERA.getObjectId(), CAMERA.getX(), CAMERA.getY(), CAMERA.getZ()));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 290, 25, 0, 10000, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 290, 25, 0, 10000, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 110, 25, 4000, 10000, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SocialAction(BELETH.getObjectId(), 5));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(28), 4000);
|
||||
break;
|
||||
case 28:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 295, 25, 4000, 5000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(29), 4500);
|
||||
break;
|
||||
case 29:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 295, 10, 4000, 11000, 0, 25, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(30), 9000);
|
||||
break;
|
||||
case 30:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 250, 90, 25, 0, 1000, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 250, 90, 25, 0, 10000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(31), 2000);
|
||||
break;
|
||||
case 31:
|
||||
PRIEST.spawnMe();
|
||||
BELETH.deleteMe();
|
||||
CAMERA2 = spawn(29121, new Location(14056, 213170, -9357, 0, instanceId));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(32), 3500);
|
||||
break;
|
||||
case 32:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 800, 180, 0, 0, 4000, 0, 10, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 800, 180, 0, 0, 4000, 0, 10, 1, 0, 0));
|
||||
L2DoorInstance door2 = DoorTable.getInstance().getDoor(20240002);
|
||||
door2.openMe();
|
||||
ZONE.broadcastPacket(new StaticObject(door2, false));
|
||||
ZONE.broadcastPacket(new DoorStatusUpdate(door2));
|
||||
DoorTable.getInstance().getDoor(20240003).openMe();
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(33), 4000);
|
||||
break;
|
||||
case 33:
|
||||
CAMERA.deleteMe();
|
||||
CAMERA2.deleteMe();
|
||||
MOVIE = false;
|
||||
break;
|
||||
case 333:
|
||||
BELETH = spawn(29118, new Location(16323, 213170, -9357, 49152));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEnterZone(L2Character character, L2ZoneType zone)
|
||||
{
|
||||
if (((character.isPlayer()) && (GrandBossManager.getInstance().getBossStatus(29118) == 1)) || (DEBUG && (GrandBossManager.getInstance().getBossStatus(29118) != 2) && (character.isPlayer())))
|
||||
{
|
||||
startSpawnTask();
|
||||
GrandBossManager.getInstance().setBossStatus(29118, 2);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc == null)
|
||||
{
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
if ((npc.getId() == 29118) && (killer != null))
|
||||
{
|
||||
setBelethKiller(1, killer);
|
||||
GrandBossManager.getInstance().setBossStatus(29118, 3);
|
||||
// Calculate Min and Max respawn times randomly.
|
||||
long respawnTime = Config.BELETH_SPAWN_INTERVAL + getRandom(-Config.BELETH_SPAWN_RANDOM, Config.BELETH_SPAWN_RANDOM);
|
||||
respawnTime *= 3600000;
|
||||
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(29118);
|
||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
GrandBossManager.getInstance().setStatsSet(29118, info);
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new unlock(), respawnTime);
|
||||
deleteAll();
|
||||
npc.deleteMe();
|
||||
MOVIE = true;
|
||||
BELETH = spawn(29118, new Location(16323, 213170, -9357, 49152));
|
||||
BELETH.setIsInvul(true);
|
||||
BELETH.setIsImmobilized(true);
|
||||
BELETH.disableAllSkills();
|
||||
PRIEST = spawn(29128, new Location(BELETH));
|
||||
PRIEST.setShowSummonAnimation(true);
|
||||
PRIEST.decayMe();
|
||||
spawn(32470, new Location(12470, 215607, -9381, 49152));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(27), 1000);
|
||||
}
|
||||
else if (npc.getId() == 29119)
|
||||
{
|
||||
if (npc.getObjectId() == ALLOW_OBJECT_ID)
|
||||
{
|
||||
MINIONS.remove(npc);
|
||||
KILLED++;
|
||||
if (KILLED >= 5)
|
||||
{
|
||||
deleteAll();
|
||||
setSpawnTimer(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ALLOW_OBJECT_ID = MINIONS.get(getRandom(MINIONS.size())).getObjectId();
|
||||
ATTACKED = false;
|
||||
}
|
||||
}
|
||||
else if (SPAWN_TIMER == null)
|
||||
{
|
||||
deleteAll();
|
||||
setSpawnTimer(2);
|
||||
KILLED = 0;
|
||||
}
|
||||
npc.abortCast();
|
||||
npc.setTarget(null);
|
||||
npc.deleteMe();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance player, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if ((npc != null) && !npc.isDead() && ((npc.getId() == 29118) || (npc.getId() == 29119)) && !npc.isCastingNow() && skill.hasEffectType(L2EffectType.HEAL) && (getRandom(100) < 80))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(HORN_OF_RISING.getSkill());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc == null)
|
||||
{
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
if ((npc.getId() == 29118) || (npc.getId() == 29119))
|
||||
{
|
||||
if ((npc.getObjectId() == ALLOW_OBJECT_ID) && !ATTACKED)
|
||||
{
|
||||
ATTACKED = true;
|
||||
L2Npc fakeBeleth = MINIONS.get(getRandom(MINIONS.size()));
|
||||
while (fakeBeleth.getObjectId() == ALLOW_OBJECT_ID)
|
||||
{
|
||||
fakeBeleth = MINIONS.get(getRandom(MINIONS.size()));
|
||||
}
|
||||
ZONE.broadcastPacket(new CreatureSay(fakeBeleth.getObjectId(), 0, fakeBeleth.getName(), "Miss text."));
|
||||
}
|
||||
if (getRandom(100) < 40)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final double distance = npc.calculateDistance(attacker, false, false);
|
||||
if ((distance > 500) || (getRandom(100) < 80))
|
||||
{
|
||||
for (L2Npc beleth : MINIONS)
|
||||
{
|
||||
if ((beleth != null) && !beleth.isDead() && Util.checkIfInRange(900, beleth, attacker, false) && !beleth.isCastingNow())
|
||||
{
|
||||
beleth.setTarget(attacker);
|
||||
beleth.doCast(FIREBALL.getSkill());
|
||||
}
|
||||
}
|
||||
if ((BELETH != null) && !BELETH.isDead() && Util.checkIfInRange(900, BELETH, attacker, false) && !BELETH.isCastingNow())
|
||||
{
|
||||
BELETH.setTarget(attacker);
|
||||
BELETH.doCast(FIREBALL.getSkill());
|
||||
}
|
||||
}
|
||||
else if (!npc.isDead() && !npc.isCastingNow())
|
||||
{
|
||||
if (!npc.getKnownList().getKnownPlayersInRadius(200).isEmpty())
|
||||
{
|
||||
npc.doCast(LIGHTENING.getSkill());
|
||||
return null;
|
||||
}
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if ((npc != null) && !npc.isDead() && ((npc.getId() == 29118) || (npc.getId() == 29119)) && !npc.isCastingNow())
|
||||
{
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
final double distance2 = npc.calculateDistance(player, false, false);
|
||||
if ((distance2 > 890) && !npc.isMovementDisabled())
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, player);
|
||||
double speed = npc.isRunning() ? npc.getRunSpeed() : npc.getWalkSpeed();
|
||||
int time = (int) (((distance2 - 890) / speed) * 1000);
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Cast(FIREBALL, npc), time);
|
||||
|
||||
}
|
||||
else if (distance2 < 890)
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(FIREBALL.getSkill());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (getRandom(100) < 40)
|
||||
{
|
||||
if (!npc.getKnownList().getKnownPlayersInRadius(200).isEmpty())
|
||||
{
|
||||
npc.doCast(LIGHTENING.getSkill());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
for (L2PcInstance plr : npc.getKnownList().getKnownPlayersInRadius(950))
|
||||
{
|
||||
npc.setTarget(plr);
|
||||
npc.doCast(FIREBALL.getSkill());
|
||||
return null;
|
||||
}
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if ((npc != null) && !npc.isDead() && ((npc.getId() == 29118) || (npc.getId() == 29119)) && !npc.isCastingNow() && !MOVIE)
|
||||
{
|
||||
if (getRandom(100) < 40)
|
||||
{
|
||||
if (!npc.getKnownList().getKnownPlayersInRadius(200).isEmpty())
|
||||
{
|
||||
npc.doCast(BLEED.getSkill());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
npc.setTarget(player);
|
||||
npc.doCast(FIREBALL.getSkill());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if ((npc.getId() == 29118) || (npc.getId() == 29119))
|
||||
{
|
||||
npc.setRunning();
|
||||
if (!MOVIE && !npc.getKnownList().getKnownPlayersInRadius(300).isEmpty() && (getRandom(100) < 60))
|
||||
{
|
||||
npc.doCast(BLEED.getSkill());
|
||||
}
|
||||
if (npc.getId() == 29118)
|
||||
{
|
||||
npc.getSpawn().setRespawnDelay(0);// setOnKillDelay
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final String html;
|
||||
if ((BELETH_KILLER != null) && (player.getObjectId() == BELETH_KILLER.getObjectId()))
|
||||
{
|
||||
player.addItem("Kill Beleth", 10314, 1, null, true);// giveItems(10314, 1, 0)
|
||||
setBelethKiller(0, player);
|
||||
html = "32470a.htm";
|
||||
}
|
||||
else
|
||||
{
|
||||
html = "32470b.htm";
|
||||
}
|
||||
return HtmCache.getInstance().getHtm(player.getHtmlPrefix(), "data/html/default/" + html);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void setBelethKiller(int event, L2PcInstance killer)
|
||||
{
|
||||
if (event == 0)
|
||||
{
|
||||
BELETH_KILLER = null;
|
||||
}
|
||||
else if (event == 1)
|
||||
{
|
||||
if (killer.getParty() != null)
|
||||
{
|
||||
if (killer.getParty().getCommandChannel() != null)
|
||||
{
|
||||
BELETH_KILLER = killer.getParty().getCommandChannel().getLeader();
|
||||
}
|
||||
else
|
||||
{
|
||||
BELETH_KILLER = killer.getParty().getLeader();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BELETH_KILLER = killer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void setSpawnTimer(int event)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case 0:
|
||||
SPAWN_TIMER = null;
|
||||
break;
|
||||
case 1:
|
||||
SPAWN_TIMER = ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(333), 60000);
|
||||
break;
|
||||
case 2:
|
||||
SPAWN_TIMER = ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(26), 60000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void deleteAll()
|
||||
{
|
||||
if ((MINIONS != null) && !MINIONS.isEmpty())
|
||||
{
|
||||
for (L2Npc npc : MINIONS)
|
||||
{
|
||||
if ((npc == null) || npc.isDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
npc.abortCast();
|
||||
npc.setTarget(null);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
npc.deleteMe();
|
||||
}
|
||||
MINIONS.clear();
|
||||
}
|
||||
ALLOW_OBJECT_ID = 0;
|
||||
ATTACKED = false;
|
||||
}
|
||||
|
||||
protected static void SpawnBeleths()
|
||||
{
|
||||
int a = 0;
|
||||
L2Npc npc;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
a++;
|
||||
int x = (int) ((650 * Math.cos(i * 0.39)) + 16323);
|
||||
int y = (int) ((650 * Math.sin(i * 0.39)) + 213170);
|
||||
npc = spawn(29119, new Location(x, y, -9357, 49152));
|
||||
MINIONS.add(npc);
|
||||
if (a >= 2)
|
||||
{
|
||||
npc.setIsOverloaded(true);
|
||||
a = 0;
|
||||
}
|
||||
}
|
||||
int[] xm = new int[16];
|
||||
int[] ym = new int[16];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
xm[i] = (int) ((1700 * Math.cos((i * 1.57) + 0.78)) + 16323);
|
||||
ym[i] = (int) ((1700 * Math.sin((i * 1.57) + 0.78)) + 213170);
|
||||
npc = spawn(29119, new Location(xm[i], ym[i], -9357, 49152));
|
||||
npc.setIsOverloaded(true);
|
||||
MINIONS.add(npc);
|
||||
}
|
||||
xm[4] = (xm[0] + xm[1]) / 2;
|
||||
ym[4] = (ym[0] + ym[1]) / 2;
|
||||
npc = spawn(29119, new Location(xm[4], ym[4], -9357, 49152));
|
||||
npc.setIsOverloaded(true);
|
||||
MINIONS.add(npc);
|
||||
xm[5] = (xm[1] + xm[2]) / 2;
|
||||
ym[5] = (ym[1] + ym[2]) / 2;
|
||||
npc = spawn(29119, new Location(xm[5], ym[5], -9357, 49152));
|
||||
npc.setIsOverloaded(true);
|
||||
MINIONS.add(npc);
|
||||
xm[6] = (xm[2] + xm[3]) / 2;
|
||||
ym[6] = (ym[2] + ym[3]) / 2;
|
||||
npc = spawn(29119, new Location(xm[6], ym[6], -9357, 49152));
|
||||
npc.setIsOverloaded(true);
|
||||
MINIONS.add(npc);
|
||||
xm[7] = (xm[3] + xm[0]) / 2;
|
||||
ym[7] = (ym[3] + ym[0]) / 2;
|
||||
npc = spawn(29119, new Location(xm[7], ym[7], -9357, 49152));
|
||||
npc.setIsOverloaded(true);
|
||||
MINIONS.add(npc);
|
||||
xm[8] = (xm[0] + xm[4]) / 2;
|
||||
ym[8] = (ym[0] + ym[4]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[8], ym[8], -9357, 49152)));
|
||||
xm[9] = (xm[4] + xm[1]) / 2;
|
||||
ym[9] = (ym[4] + ym[1]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[9], ym[9], -9357, 49152)));
|
||||
xm[10] = (xm[1] + xm[5]) / 2;
|
||||
ym[10] = (ym[1] + ym[5]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[10], ym[10], -9357, 49152)));
|
||||
xm[11] = (xm[5] + xm[2]) / 2;
|
||||
ym[11] = (ym[5] + ym[2]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[11], ym[11], -9357, 49152)));
|
||||
xm[12] = (xm[2] + xm[6]) / 2;
|
||||
ym[12] = (ym[2] + ym[6]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[12], ym[12], -9357, 49152)));
|
||||
xm[13] = (xm[6] + xm[3]) / 2;
|
||||
ym[13] = (ym[6] + ym[3]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[13], ym[13], -9357, 49152)));
|
||||
xm[14] = (xm[3] + xm[7]) / 2;
|
||||
ym[14] = (ym[3] + ym[7]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[14], ym[14], -9357, 49152)));
|
||||
xm[15] = (xm[7] + xm[0]) / 2;
|
||||
ym[15] = (ym[7] + ym[0]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[15], ym[15], -9357, 49152)));
|
||||
ALLOW_OBJECT_ID = MINIONS.get(getRandom(MINIONS.size())).getObjectId();
|
||||
ATTACKED = false;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Beleth();
|
||||
}
|
||||
}
|
76
trunk/dist/game/data/scripts/ai/individual/CatsEyeBandit.java
vendored
Normal file
76
trunk/dist/game/data/scripts/ai/individual/CatsEyeBandit.java
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jserver.gameserver.model.quest.QuestState;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Cat's Eye Bandit (Quest Monster) AI.
|
||||
* @author Gladicek
|
||||
*/
|
||||
public final class CatsEyeBandit extends AbstractNpcAI
|
||||
{
|
||||
// NPC ID
|
||||
private static final int MOB_ID = 27038;
|
||||
// Weapons
|
||||
private static final int BOW = 1181;
|
||||
private static final int DAGGER = 1182;
|
||||
|
||||
private CatsEyeBandit()
|
||||
{
|
||||
super(CatsEyeBandit.class.getSimpleName(), "ai/individual");
|
||||
addAttackId(MOB_ID);
|
||||
addKillId(MOB_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final QuestState qs = attacker.getQuestState("403_PathToRogue"); // TODO: Replace with class name.
|
||||
if (npc.isScriptValue(0) && (qs != null) && ((qs.getItemEquipped(Inventory.PAPERDOLL_RHAND) == BOW) || (qs.getItemEquipped(Inventory.PAPERDOLL_RHAND) == DAGGER)))
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_CHILDISH_FOOL_DO_YOU_THINK_YOU_CAN_CATCH_ME);
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final QuestState qs = killer.getQuestState("403_PathToRogue"); // TODO: Replace with class name.
|
||||
if (qs != null)
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.I_MUST_DO_SOMETHING_ABOUT_THIS_SHAMEFUL_INCIDENT);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new CatsEyeBandit();
|
||||
}
|
||||
}
|
230
trunk/dist/game/data/scripts/ai/individual/Core.java
vendored
Normal file
230
trunk/dist/game/data/scripts/ai/individual/Core.java
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
|
||||
/**
|
||||
* Core AI
|
||||
* @author DrLecter Revised By Emperorc
|
||||
*/
|
||||
public final class Core extends AbstractNpcAI
|
||||
{
|
||||
private static final int CORE = 29006;
|
||||
private static final int DEATH_KNIGHT = 29007;
|
||||
private static final int DOOM_WRAITH = 29008;
|
||||
// private static final int DICOR = 29009;
|
||||
// private static final int VALIDUS = 29010;
|
||||
private static final int SUSCEPTOR = 29011;
|
||||
// private static final int PERUM = 29012;
|
||||
// private static final int PREMO = 29013;
|
||||
|
||||
// CORE Status Tracking :
|
||||
private static final byte ALIVE = 0; // Core is spawned.
|
||||
private static final byte DEAD = 1; // Core has been killed.
|
||||
|
||||
private static boolean _FirstAttacked;
|
||||
|
||||
private final List<L2Attackable> Minions = new FastList<>();
|
||||
|
||||
private Core()
|
||||
{
|
||||
super(Core.class.getSimpleName(), "ai/individual");
|
||||
registerMobs(CORE, DEATH_KNIGHT, DOOM_WRAITH, SUSCEPTOR);
|
||||
|
||||
_FirstAttacked = false;
|
||||
final StatsSet info = GrandBossManager.getInstance().getStatsSet(CORE);
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(CORE);
|
||||
if (status == DEAD)
|
||||
{
|
||||
// load the unlock date and time for Core from DB
|
||||
long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
|
||||
// if Core is locked until a certain time, mark it so and start the unlock timer
|
||||
// the unlock time has not yet expired.
|
||||
if (temp > 0)
|
||||
{
|
||||
startQuestTimer("core_unlock", temp, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the time has already expired while the server was offline. Immediately spawn Core.
|
||||
L2GrandBossInstance core = (L2GrandBossInstance) addSpawn(CORE, 17726, 108915, -6480, 0, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(CORE, ALIVE);
|
||||
spawnBoss(core);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final String test = loadGlobalQuestVar("Core_Attacked");
|
||||
if (test.equalsIgnoreCase("true"))
|
||||
{
|
||||
_FirstAttacked = true;
|
||||
}
|
||||
final int loc_x = info.getInt("loc_x");
|
||||
final int loc_y = info.getInt("loc_y");
|
||||
final int loc_z = info.getInt("loc_z");
|
||||
final int heading = info.getInt("heading");
|
||||
final int hp = info.getInt("currentHP");
|
||||
final int mp = info.getInt("currentMP");
|
||||
final L2GrandBossInstance core = (L2GrandBossInstance) addSpawn(CORE, loc_x, loc_y, loc_z, heading, false, 0);
|
||||
core.setCurrentHpMp(hp, mp);
|
||||
spawnBoss(core);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveGlobalData()
|
||||
{
|
||||
saveGlobalQuestVar("Core_Attacked", Boolean.toString(_FirstAttacked));
|
||||
}
|
||||
|
||||
public void spawnBoss(L2GrandBossInstance npc)
|
||||
{
|
||||
GrandBossManager.getInstance().addBoss(npc);
|
||||
npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
|
||||
// Spawn minions
|
||||
L2Attackable mob;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
final int x = 16800 + (i * 360);
|
||||
mob = (L2Attackable) addSpawn(DEATH_KNIGHT, x, 110000, npc.getZ(), 280 + getRandom(40), false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
Minions.add(mob);
|
||||
mob = (L2Attackable) addSpawn(DEATH_KNIGHT, x, 109000, npc.getZ(), 280 + getRandom(40), false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
Minions.add(mob);
|
||||
final int x2 = 16800 + (i * 600);
|
||||
mob = (L2Attackable) addSpawn(DOOM_WRAITH, x2, 109300, npc.getZ(), 280 + getRandom(40), false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
Minions.add(mob);
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int x = 16800 + (i * 450);
|
||||
mob = (L2Attackable) addSpawn(SUSCEPTOR, x, 110300, npc.getZ(), 280 + getRandom(40), false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
Minions.add(mob);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("core_unlock"))
|
||||
{
|
||||
L2GrandBossInstance core = (L2GrandBossInstance) addSpawn(CORE, 17726, 108915, -6480, 0, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(CORE, ALIVE);
|
||||
spawnBoss(core);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_minion"))
|
||||
{
|
||||
L2Attackable mob = (L2Attackable) addSpawn(npc.getId(), npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
Minions.add(mob);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("despawn_minions"))
|
||||
{
|
||||
for (int i = 0; i < Minions.size(); i++)
|
||||
{
|
||||
L2Attackable mob = Minions.get(i);
|
||||
if (mob != null)
|
||||
{
|
||||
mob.decayMe();
|
||||
}
|
||||
}
|
||||
Minions.clear();
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == CORE)
|
||||
{
|
||||
if (_FirstAttacked)
|
||||
{
|
||||
if (getRandom(100) == 0)
|
||||
{
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NpcStringId.REMOVING_INTRUDERS));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_FirstAttacked = true;
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NpcStringId.A_NON_PERMITTED_TARGET_HAS_BEEN_DISCOVERED));
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NpcStringId.INTRUDER_REMOVAL_SYSTEM_INITIATED));
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final int npcId = npc.getId();
|
||||
if (npcId == CORE)
|
||||
{
|
||||
int objId = npc.getObjectId();
|
||||
npc.broadcastPacket(new PlaySound(1, "BS02_D", 1, objId, npc.getX(), npc.getY(), npc.getZ()));
|
||||
npc.broadcastPacket(new NpcSay(objId, Say2.NPC_ALL, npcId, NpcStringId.A_FATAL_ERROR_HAS_OCCURRED));
|
||||
npc.broadcastPacket(new NpcSay(objId, Say2.NPC_ALL, npcId, NpcStringId.SYSTEM_IS_BEING_SHUT_DOWN));
|
||||
npc.broadcastPacket(new NpcSay(objId, Say2.NPC_ALL, npcId, NpcStringId.EMPTY));
|
||||
_FirstAttacked = false;
|
||||
GrandBossManager.getInstance().setBossStatus(CORE, DEAD);
|
||||
// Calculate Min and Max respawn times randomly.
|
||||
long respawnTime = Config.CORE_SPAWN_INTERVAL + getRandom(-Config.CORE_SPAWN_RANDOM, Config.CORE_SPAWN_RANDOM);
|
||||
respawnTime *= 3600000;
|
||||
|
||||
startQuestTimer("core_unlock", respawnTime, null, null);
|
||||
// also save the respawn time so that the info is maintained past reboots
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(CORE);
|
||||
info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
|
||||
GrandBossManager.getInstance().setStatsSet(CORE, info);
|
||||
startQuestTimer("despawn_minions", 20000, null, null);
|
||||
cancelQuestTimers("spawn_minion");
|
||||
}
|
||||
else if ((GrandBossManager.getInstance().getBossStatus(CORE) == ALIVE) && (Minions != null) && Minions.contains(npc))
|
||||
{
|
||||
Minions.remove(npc);
|
||||
startQuestTimer("spawn_minion", 60000, npc, null);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Core();
|
||||
}
|
||||
}
|
107
trunk/dist/game/data/scripts/ai/individual/CrimsonHatuOtis.java
vendored
Normal file
107
trunk/dist/game/data/scripts/ai/individual/CrimsonHatuOtis.java
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* AI for Kamaloka (33) - Crimson Hatu Otis
|
||||
* @author Gladicek
|
||||
*/
|
||||
public final class CrimsonHatuOtis extends AbstractNpcAI
|
||||
{
|
||||
// Npc
|
||||
private static final int CRIMSON_HATU_OTIS = 18558;
|
||||
// Skills
|
||||
private static SkillHolder BOSS_SPINING_SLASH = new SkillHolder(4737, 1);
|
||||
private static SkillHolder BOSS_HASTE = new SkillHolder(4175, 1);
|
||||
|
||||
private CrimsonHatuOtis()
|
||||
{
|
||||
super(CrimsonHatuOtis.class.getSimpleName(), "ai/individual");
|
||||
addAttackId(CRIMSON_HATU_OTIS);
|
||||
addKillId(CRIMSON_HATU_OTIS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "SKILL":
|
||||
{
|
||||
if (npc.isDead())
|
||||
{
|
||||
cancelQuestTimer("SKILL", npc, null);
|
||||
return null;
|
||||
}
|
||||
npc.setTarget(player);
|
||||
npc.doCast(BOSS_SPINING_SLASH.getSkill());
|
||||
startQuestTimer("SKILL", 60000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "BUFF":
|
||||
{
|
||||
if (npc.isScriptValue(2))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(BOSS_HASTE.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("SKILL", 5000, npc, null);
|
||||
}
|
||||
else if (npc.isScriptValue(1) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.3)))
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.I_VE_HAD_IT_UP_TO_HERE_WITH_YOU_I_LL_TAKE_CARE_OF_YOU);
|
||||
npc.setScriptValue(2);
|
||||
startQuestTimer("BUFF", 1000, npc, null);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
cancelQuestTimer("SKILL", npc, null);
|
||||
cancelQuestTimer("BUFF", npc, null);
|
||||
return super.onKill(npc, player, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new CrimsonHatuOtis();
|
||||
}
|
||||
}
|
248
trunk/dist/game/data/scripts/ai/individual/DarkWaterDragon.java
vendored
Normal file
248
trunk/dist/game/data/scripts/ai/individual/DarkWaterDragon.java
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javolution.util.FastSet;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Dark Water Dragon's AI.
|
||||
*/
|
||||
public final class DarkWaterDragon extends AbstractNpcAI
|
||||
{
|
||||
private static final int DRAGON = 22267;
|
||||
private static final int SHADE1 = 22268;
|
||||
private static final int SHADE2 = 22269;
|
||||
private static final int FAFURION = 18482;
|
||||
private static final int DETRACTOR1 = 22270;
|
||||
private static final int DETRACTOR2 = 22271;
|
||||
private static Set<Integer> SECOND_SPAWN = new FastSet<>(); // Used to track if second Shades were already spawned
|
||||
private static Set<Integer> MY_TRACKING_SET = new FastSet<>(); // Used to track instances of npcs
|
||||
private static Map<Integer, L2PcInstance> ID_MAP = new ConcurrentHashMap<>(); // Used to track instances of npcs
|
||||
|
||||
private DarkWaterDragon()
|
||||
{
|
||||
super(DarkWaterDragon.class.getSimpleName(), "ai/individual");
|
||||
int[] mobs =
|
||||
{
|
||||
DRAGON,
|
||||
SHADE1,
|
||||
SHADE2,
|
||||
FAFURION,
|
||||
DETRACTOR1,
|
||||
DETRACTOR2
|
||||
};
|
||||
addKillId(mobs);
|
||||
addAttackId(mobs);
|
||||
addSpawnId(mobs);
|
||||
MY_TRACKING_SET.clear();
|
||||
SECOND_SPAWN.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
if (event.equalsIgnoreCase("first_spawn")) // timer to start timer "1"
|
||||
{
|
||||
startQuestTimer("1", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("second_spawn")) // timer to start timer "2"
|
||||
{
|
||||
startQuestTimer("2", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("third_spawn")) // timer to start timer "3"
|
||||
{
|
||||
startQuestTimer("3", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("fourth_spawn")) // timer to start timer "4"
|
||||
{
|
||||
startQuestTimer("4", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("1")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR1, (npc.getX() + 100), (npc.getY() + 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("2")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR2, (npc.getX() + 100), (npc.getY() - 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("3")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR1, (npc.getX() - 100), (npc.getY() + 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("4")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR2, (npc.getX() - 100), (npc.getY() - 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("fafurion_despawn")) // Fafurion Kindred disappears and drops reward
|
||||
{
|
||||
cancelQuestTimer("fafurion_poison", npc, null);
|
||||
cancelQuestTimer("1", npc, null);
|
||||
cancelQuestTimer("2", npc, null);
|
||||
cancelQuestTimer("3", npc, null);
|
||||
cancelQuestTimer("4", npc, null);
|
||||
|
||||
MY_TRACKING_SET.remove(npc.getObjectId());
|
||||
player = ID_MAP.remove(npc.getObjectId());
|
||||
if (player != null)
|
||||
{
|
||||
((L2Attackable) npc).doItemDrop(NpcData.getInstance().getTemplate(18485), player);
|
||||
}
|
||||
|
||||
npc.deleteMe();
|
||||
}
|
||||
else if (event.equalsIgnoreCase("fafurion_poison")) // Reduces Fafurions hp like it is poisoned
|
||||
{
|
||||
if (npc.getCurrentHp() <= 500)
|
||||
{
|
||||
cancelQuestTimer("fafurion_despawn", npc, null);
|
||||
cancelQuestTimer("first_spawn", npc, null);
|
||||
cancelQuestTimer("second_spawn", npc, null);
|
||||
cancelQuestTimer("third_spawn", npc, null);
|
||||
cancelQuestTimer("fourth_spawn", npc, null);
|
||||
cancelQuestTimer("1", npc, null);
|
||||
cancelQuestTimer("2", npc, null);
|
||||
cancelQuestTimer("3", npc, null);
|
||||
cancelQuestTimer("4", npc, null);
|
||||
MY_TRACKING_SET.remove(npc.getObjectId());
|
||||
ID_MAP.remove(npc.getObjectId());
|
||||
}
|
||||
npc.reduceCurrentHp(500, npc, null); // poison kills Fafurion if he is not healed
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
int npcObjId = npc.getObjectId();
|
||||
if (npcId == DRAGON)
|
||||
{
|
||||
if (!MY_TRACKING_SET.contains(npcObjId)) // this allows to handle multiple instances of npc
|
||||
{
|
||||
MY_TRACKING_SET.add(npcObjId);
|
||||
// Spawn first 5 shades on first attack on Dark Water Dragon
|
||||
L2Character originalAttacker = isSummon ? attacker.getSummon() : attacker;
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() + 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() + 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 150, npc.getY() + 150, npc.getZ());
|
||||
}
|
||||
else if ((npc.getCurrentHp() < (npc.getMaxHp() / 2.0)) && !(SECOND_SPAWN.contains(npcObjId)))
|
||||
{
|
||||
SECOND_SPAWN.add(npcObjId);
|
||||
// Spawn second 5 shades on half hp of on Dark Water Dragon
|
||||
L2Character originalAttacker = isSummon ? attacker.getSummon() : attacker;
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() + 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() + 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 150, npc.getY() + 150, npc.getZ());
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
int npcObjId = npc.getObjectId();
|
||||
if (npcId == DRAGON)
|
||||
{
|
||||
MY_TRACKING_SET.remove(npcObjId);
|
||||
SECOND_SPAWN.remove(npcObjId);
|
||||
L2Attackable faf = (L2Attackable) addSpawn(FAFURION, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0); // spawns Fafurion Kindred when Dard Water Dragon is dead
|
||||
ID_MAP.put(faf.getObjectId(), killer);
|
||||
}
|
||||
else if (npcId == FAFURION)
|
||||
{
|
||||
cancelQuestTimer("fafurion_poison", npc, null);
|
||||
cancelQuestTimer("fafurion_despawn", npc, null);
|
||||
cancelQuestTimer("first_spawn", npc, null);
|
||||
cancelQuestTimer("second_spawn", npc, null);
|
||||
cancelQuestTimer("third_spawn", npc, null);
|
||||
cancelQuestTimer("fourth_spawn", npc, null);
|
||||
cancelQuestTimer("1", npc, null);
|
||||
cancelQuestTimer("2", npc, null);
|
||||
cancelQuestTimer("3", npc, null);
|
||||
cancelQuestTimer("4", npc, null);
|
||||
MY_TRACKING_SET.remove(npcObjId);
|
||||
ID_MAP.remove(npcObjId);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
int npcObjId = npc.getObjectId();
|
||||
if (npcId == FAFURION)
|
||||
{
|
||||
if (!MY_TRACKING_SET.contains(npcObjId))
|
||||
{
|
||||
MY_TRACKING_SET.add(npcObjId);
|
||||
// Spawn 4 Detractors on spawn of Fafurion
|
||||
int x = npc.getX();
|
||||
int y = npc.getY();
|
||||
addSpawn(DETRACTOR2, x + 100, y + 100, npc.getZ(), 0, false, 40000);
|
||||
addSpawn(DETRACTOR1, x + 100, y - 100, npc.getZ(), 0, false, 40000);
|
||||
addSpawn(DETRACTOR2, x - 100, y + 100, npc.getZ(), 0, false, 40000);
|
||||
addSpawn(DETRACTOR1, x - 100, y - 100, npc.getZ(), 0, false, 40000);
|
||||
startQuestTimer("first_spawn", 2000, npc, null); // timer to delay timer "1"
|
||||
startQuestTimer("second_spawn", 4000, npc, null); // timer to delay timer "2"
|
||||
startQuestTimer("third_spawn", 8000, npc, null); // timer to delay timer "3"
|
||||
startQuestTimer("fourth_spawn", 10000, npc, null); // timer to delay timer "4"
|
||||
startQuestTimer("fafurion_poison", 3000, npc, null, true); // Every three seconds reduces Fafurions hp like it is poisoned
|
||||
startQuestTimer("fafurion_despawn", 120000, npc, null); // Fafurion Kindred disappears after two minutes
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public void spawnShade(L2Character attacker, int npcId, int x, int y, int z)
|
||||
{
|
||||
final L2Npc shade = addSpawn(npcId, x, y, z, 0, false, 0);
|
||||
shade.setRunning();
|
||||
((L2Attackable) shade).addDamageHate(attacker, 0, 999);
|
||||
shade.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, attacker);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DarkWaterDragon();
|
||||
}
|
||||
}
|
69
trunk/dist/game/data/scripts/ai/individual/DivineBeast.java
vendored
Normal file
69
trunk/dist/game/data/scripts/ai/individual/DivineBeast.java
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Simple AI that manages special conditions for Divine Beast summon.
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class DivineBeast extends AbstractNpcAI
|
||||
{
|
||||
private static final int DIVINE_BEAST = 14870;
|
||||
private static final int TRANSFORMATION_ID = 258;
|
||||
private static final int CHECK_TIME = 2 * 1000;
|
||||
|
||||
private DivineBeast()
|
||||
{
|
||||
super(DivineBeast.class.getSimpleName(), "ai");
|
||||
addSummonSpawnId(DIVINE_BEAST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSummonSpawn(L2Summon summon)
|
||||
{
|
||||
startQuestTimer("VALIDATE_TRANSFORMATION", CHECK_TIME, null, summon.getActingPlayer(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((player == null) || !player.hasServitor())
|
||||
{
|
||||
cancelQuestTimer(event, npc, player);
|
||||
}
|
||||
else if (player.getTransformationId() != TRANSFORMATION_ID)
|
||||
{
|
||||
cancelQuestTimer(event, npc, player);
|
||||
player.getSummon().unSummon(player);
|
||||
}
|
||||
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DivineBeast();
|
||||
}
|
||||
}
|
134
trunk/dist/game/data/scripts/ai/individual/DrChaos.java
vendored
Normal file
134
trunk/dist/game/data/scripts/ai/individual/DrChaos.java
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SpawnTable;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.quest.Quest;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
|
||||
|
||||
/**
|
||||
* DrChaos' AI.
|
||||
* @author Kerberos
|
||||
*/
|
||||
public final class DrChaos extends Quest
|
||||
{
|
||||
private static final int DR_CHAOS = 32033;
|
||||
private static final int STRANGE_MACHINE = 32032;
|
||||
private static final int CHAOS_GOLEM = 25703;
|
||||
private static boolean _IsGolemSpawned;
|
||||
|
||||
private static final Location PLAYER_TELEPORT = new Location(94832, -112624, -3304);
|
||||
private static final Location NPC_LOCATION = new Location(-113091, -243942, -15536);
|
||||
|
||||
private DrChaos()
|
||||
{
|
||||
// TODO extends AbstractNpcAI
|
||||
super(-1, "Doctor Chaos", "ai/individual");
|
||||
addFirstTalkId(DR_CHAOS);
|
||||
_IsGolemSpawned = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "1":
|
||||
{
|
||||
L2Npc machine = null;
|
||||
for (L2Spawn spawn : SpawnTable.getInstance().getSpawns(STRANGE_MACHINE))
|
||||
{
|
||||
if (spawn != null)
|
||||
{
|
||||
machine = spawn.getLastSpawn();
|
||||
}
|
||||
}
|
||||
if (machine != null)
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, machine);
|
||||
machine.broadcastPacket(new SpecialCamera(machine, 1, -200, 15, 10000, 1000, 20000, 0, 0, 0, 0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("2", 2000, npc, player);
|
||||
}
|
||||
startQuestTimer("3", 10000, npc, player);
|
||||
break;
|
||||
}
|
||||
case "2":
|
||||
{
|
||||
npc.broadcastSocialAction(3);
|
||||
break;
|
||||
}
|
||||
case "3":
|
||||
{
|
||||
npc.broadcastPacket(new SpecialCamera(npc, 1, -150, 10, 3000, 1000, 20000, 0, 0, 0, 0, 0));
|
||||
startQuestTimer("4", 2500, npc, player);
|
||||
break;
|
||||
}
|
||||
case "4":
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(96055, -110759, -3312, 0));
|
||||
startQuestTimer("5", 2000, npc, player);
|
||||
break;
|
||||
}
|
||||
case "5":
|
||||
{
|
||||
player.teleToLocation(PLAYER_TELEPORT);
|
||||
npc.teleToLocation(NPC_LOCATION);
|
||||
if (!_IsGolemSpawned)
|
||||
{
|
||||
L2Npc golem = addSpawn(CHAOS_GOLEM, 94640, -112496, -3336, 0, false, 0);
|
||||
_IsGolemSpawned = true;
|
||||
startQuestTimer("6", 1000, golem, player);
|
||||
player.sendPacket(new PlaySound(1, "Rm03_A", 0, 0, 0, 0, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "6":
|
||||
{
|
||||
npc.broadcastPacket(new SpecialCamera(npc, 30, -200, 20, 6000, 700, 8000, 0, 0, 0, 0, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc.getId() == DR_CHAOS)
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(96323, -110914, -3328, 0));
|
||||
this.startQuestTimer("1", 3000, npc, player);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DrChaos();
|
||||
}
|
||||
}
|
92
trunk/dist/game/data/scripts/ai/individual/DrillSergeant.java
vendored
Normal file
92
trunk/dist/game/data/scripts/ai/individual/DrillSergeant.java
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Drill Sergeant AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class DrillSergeant extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int SERGANT = 33007; // Drill Sergant
|
||||
private static final int GUARD = 33018;
|
||||
// Misc
|
||||
//@formatter:off
|
||||
private final int[] SOCIAL_ACTIONS = {9, 10, 11, 1 };
|
||||
//@formatter:on
|
||||
|
||||
private DrillSergeant()
|
||||
{
|
||||
super(DrillSergeant.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(SERGANT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("SOCIAL_SHOW"))
|
||||
{
|
||||
final int socialActionId = SOCIAL_ACTIONS[getRandom(SOCIAL_ACTIONS.length)];
|
||||
npc.broadcastSocialAction(socialActionId);
|
||||
|
||||
for (L2Character chars : npc.getKnownList().getKnownCharactersInRadius(500))
|
||||
{
|
||||
if (chars.isNpc() && (chars.getId() == GUARD))
|
||||
{
|
||||
final L2Npc guard = (L2Npc) chars;
|
||||
guard.getVariables().set("SOCIAL_ACTION_ID", socialActionId);
|
||||
startQuestTimer("SOCIAL_ACTION", getRandom(500, 1500), guard, null);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equals("SOCIAL_ACTION"))
|
||||
{
|
||||
final int socialActionId = npc.getVariables().getInt("SOCIAL_ACTION_ID", 0);
|
||||
if (socialActionId > 0)
|
||||
{
|
||||
npc.broadcastSocialAction(socialActionId);
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getId() == SERGANT)
|
||||
{
|
||||
startQuestTimer("SOCIAL_SHOW", 10000, npc, null, true);
|
||||
}
|
||||
npc.setRandomAnimationEnabled(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DrillSergeant();
|
||||
}
|
||||
}
|
145
trunk/dist/game/data/scripts/ai/individual/Epidos.java
vendored
Normal file
145
trunk/dist/game/data/scripts/ai/individual/Epidos.java
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.util.MinionList;
|
||||
|
||||
/**
|
||||
* Manages minion's spawn, idle despawn and Teleportation Cube spawn.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class Epidos extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] EPIDOSES =
|
||||
{
|
||||
25609,
|
||||
25610,
|
||||
25611,
|
||||
25612
|
||||
};
|
||||
|
||||
private static final int[] MINIONS =
|
||||
{
|
||||
25605,
|
||||
25606,
|
||||
25607,
|
||||
25608
|
||||
};
|
||||
|
||||
private static final int[] MINIONS_COUNT =
|
||||
{
|
||||
3,
|
||||
6,
|
||||
11
|
||||
};
|
||||
|
||||
private final Map<Integer, Double> _lastHp = new ConcurrentHashMap<>();
|
||||
|
||||
private Epidos()
|
||||
{
|
||||
super(Epidos.class.getSimpleName(), "ai/individual");
|
||||
addKillId(EPIDOSES);
|
||||
addSpawnId(EPIDOSES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("check_minions"))
|
||||
{
|
||||
if ((getRandom(1000) > 250) && _lastHp.containsKey(npc.getObjectId()))
|
||||
{
|
||||
int hpDecreasePercent = (int) (((_lastHp.get(npc.getObjectId()) - npc.getCurrentHp()) * 100) / npc.getMaxHp());
|
||||
int minionsCount = 0;
|
||||
int spawnedMinions = ((L2MonsterInstance) npc).getMinionList().countSpawnedMinions();
|
||||
|
||||
if ((hpDecreasePercent > 5) && (hpDecreasePercent <= 15) && (spawnedMinions <= 9))
|
||||
{
|
||||
minionsCount = MINIONS_COUNT[0];
|
||||
}
|
||||
else if ((((hpDecreasePercent > 1) && (hpDecreasePercent <= 5)) || ((hpDecreasePercent > 15) && (hpDecreasePercent <= 30))) && (spawnedMinions <= 6))
|
||||
{
|
||||
minionsCount = MINIONS_COUNT[1];
|
||||
}
|
||||
else if (spawnedMinions == 0)
|
||||
{
|
||||
minionsCount = MINIONS_COUNT[2];
|
||||
}
|
||||
|
||||
for (int i = 0; i < minionsCount; i++)
|
||||
{
|
||||
MinionList.spawnMinion((L2MonsterInstance) npc, MINIONS[Arrays.binarySearch(EPIDOSES, npc.getId())]);
|
||||
}
|
||||
|
||||
_lastHp.put(npc.getObjectId(), npc.getCurrentHp());
|
||||
}
|
||||
|
||||
startQuestTimer("check_minions", 10000, npc, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("check_idle"))
|
||||
{
|
||||
if (npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("check_idle", 600000, npc, null);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.isInsideRadius(-45474, 247450, -13994, 2000, true, false))
|
||||
{
|
||||
addSpawn(32376, -45482, 246277, -14184, 0, false, 0, false);
|
||||
}
|
||||
|
||||
_lastHp.remove(npc.getObjectId());
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("check_minions", 10000, npc, null);
|
||||
startQuestTimer("check_idle", 600000, npc, null);
|
||||
_lastHp.put(npc.getObjectId(), (double) npc.getMaxHp());
|
||||
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Epidos();
|
||||
}
|
||||
}
|
79
trunk/dist/game/data/scripts/ai/individual/EvasGiftBox.java
vendored
Normal file
79
trunk/dist/game/data/scripts/ai/individual/EvasGiftBox.java
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.ItemHolder;
|
||||
|
||||
/**
|
||||
* Eva's Gift Box AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class EvasGiftBox extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int BOX = 32342; // Eva's Gift Box
|
||||
// Skill
|
||||
private static final int BUFF = 1073; // Kiss of Eva
|
||||
// Items
|
||||
private static final ItemHolder CORAL = new ItemHolder(9692, 1); // Red Coral
|
||||
private static final ItemHolder CRYSTAL = new ItemHolder(9693, 1); // Crystal Fragment
|
||||
|
||||
private EvasGiftBox()
|
||||
{
|
||||
super(EvasGiftBox.class.getSimpleName(), "ai/individual");
|
||||
addKillId(BOX);
|
||||
addSpawnId(BOX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (killer.isAffectedBySkill(BUFF))
|
||||
{
|
||||
if (getRandomBoolean())
|
||||
{
|
||||
npc.dropItem(killer, CRYSTAL);
|
||||
}
|
||||
|
||||
if (getRandom(100) < 33)
|
||||
{
|
||||
npc.dropItem(killer, CORAL);
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setIsNoRndWalk(true);
|
||||
((L2Attackable) npc).setOnKillDelay(0);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new EvasGiftBox();
|
||||
}
|
||||
}
|
149
trunk/dist/game/data/scripts/ai/individual/FrightenedRagnaOrc.java
vendored
Normal file
149
trunk/dist/game/data/scripts/ai/individual/FrightenedRagnaOrc.java
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Frightened Ragna Orc AI.
|
||||
* @author Gladicek, malyelfik
|
||||
*/
|
||||
public final class FrightenedRagnaOrc extends AbstractNpcAI
|
||||
{
|
||||
// NPC ID
|
||||
private static final int MOB_ID = 18807;
|
||||
// Chances
|
||||
private static final int ADENA = 10000;
|
||||
private static final int CHANCE = 1000;
|
||||
private static final int ADENA2 = 1000000;
|
||||
private static final int CHANCE2 = 10;
|
||||
// Skill
|
||||
private static final SkillHolder SKILL = new SkillHolder(6234, 1);
|
||||
|
||||
private FrightenedRagnaOrc()
|
||||
{
|
||||
super(FrightenedRagnaOrc.class.getSimpleName(), "ai/individual");
|
||||
addAttackId(MOB_ID);
|
||||
addKillId(MOB_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("say", (getRandom(5) + 3) * 1000, npc, null, true);
|
||||
}
|
||||
else if ((npc.getCurrentHp() < (npc.getMaxHp() * 0.2)) && npc.isScriptValue(1))
|
||||
{
|
||||
startQuestTimer("reward", 10000, npc, attacker);
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.WAIT_WAIT_STOP_SAVE_ME_AND_I_LL_GIVE_YOU_10_000_000_ADENA);
|
||||
npc.setScriptValue(2);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.UGH_A_CURSE_UPON_YOU : NpcStringId.I_REALLY_DIDN_T_WANT_TO_FIGHT;
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, msg);
|
||||
cancelQuestTimer("say", npc, null);
|
||||
cancelQuestTimer("reward", npc, player);
|
||||
return super.onKill(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "say":
|
||||
{
|
||||
if (npc.isDead() || !npc.isScriptValue(1))
|
||||
{
|
||||
cancelQuestTimer("say", npc, null);
|
||||
return null;
|
||||
}
|
||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.I_DON_T_WANT_TO_FIGHT : NpcStringId.IS_THIS_REALLY_NECESSARY;
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, msg);
|
||||
break;
|
||||
}
|
||||
case "reward":
|
||||
{
|
||||
if (!npc.isDead() && npc.isScriptValue(2))
|
||||
{
|
||||
if (getRandom(100000) < CHANCE2)
|
||||
{
|
||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.TH_THANKS_I_COULD_HAVE_BECOME_GOOD_FRIENDS_WITH_YOU : NpcStringId.I_LL_GIVE_YOU_10_000_000_ADENA_LIKE_I_PROMISED_I_MIGHT_BE_AN_ORC_WHO_KEEPS_MY_PROMISES;
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, msg);
|
||||
npc.setScriptValue(3);
|
||||
npc.doCast(SKILL.getSkill());
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
npc.dropItem(player, Inventory.ADENA_ID, ADENA2);
|
||||
}
|
||||
}
|
||||
else if (getRandom(100000) < CHANCE)
|
||||
{
|
||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.TH_THANKS_I_COULD_HAVE_BECOME_GOOD_FRIENDS_WITH_YOU : NpcStringId.SORRY_BUT_THIS_IS_ALL_I_HAVE_GIVE_ME_A_BREAK;
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, msg);
|
||||
npc.setScriptValue(3);
|
||||
npc.doCast(SKILL.getSkill());
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
((L2Attackable) npc).dropItem(player, Inventory.ADENA_ID, ADENA);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.THANKS_BUT_THAT_THING_ABOUT_10_000_000_ADENA_WAS_A_LIE_SEE_YA : NpcStringId.YOU_RE_PRETTY_DUMB_TO_BELIEVE_ME;
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, msg);
|
||||
}
|
||||
startQuestTimer("despawn", 1000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "despawn":
|
||||
{
|
||||
npc.setRunning();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location((npc.getX() + getRandom(-800, 800)), (npc.getY() + getRandom(-800, 800)), npc.getZ(), npc.getHeading()));
|
||||
npc.deleteMe();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FrightenedRagnaOrc();
|
||||
}
|
||||
}
|
64
trunk/dist/game/data/scripts/ai/individual/Gordon.java
vendored
Normal file
64
trunk/dist/game/data/scripts/ai/individual/Gordon.java
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Gordon AI
|
||||
* @author TOFIZ, malyelfik
|
||||
*/
|
||||
public final class Gordon extends AbstractNpcAI
|
||||
{
|
||||
private static final int GORDON = 29095;
|
||||
|
||||
private Gordon()
|
||||
{
|
||||
super(Gordon.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(GORDON);
|
||||
addSeeCreatureId(GORDON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (creature.isPlayer() && ((L2PcInstance) creature).isCursedWeaponEquipped())
|
||||
{
|
||||
addAttackPlayerDesire(npc, (L2PcInstance) creature);
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
((L2Attackable) npc).setCanReturnToSpawnPoint(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Gordon();
|
||||
}
|
||||
}
|
55
trunk/dist/game/data/scripts/ai/individual/GraveRobbers.java
vendored
Normal file
55
trunk/dist/game/data/scripts/ai/individual/GraveRobbers.java
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* Grove Robber's AI.<br>
|
||||
* <ul>
|
||||
* <li>Grove Robber Summoner</li>
|
||||
* <li>Grove Robber Megician</li>
|
||||
* </ul>
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class GraveRobbers extends AbstractNpcAI
|
||||
{
|
||||
private static final int GRAVE_ROBBER_SUMMONER = 22678;
|
||||
private static final int GRAVE_ROBBER_MEGICIAN = 22679;
|
||||
|
||||
private GraveRobbers()
|
||||
{
|
||||
super(GraveRobbers.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(GRAVE_ROBBER_SUMMONER, GRAVE_ROBBER_MEGICIAN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
spawnMinions(npc, "Privates" + getRandom(1, 2));
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new GraveRobbers();
|
||||
}
|
||||
}
|
64
trunk/dist/game/data/scripts/ai/individual/Mahram.java
vendored
Normal file
64
trunk/dist/game/data/scripts/ai/individual/Mahram.java
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Mahram AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Mahram extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int MAHRAM = 33271;
|
||||
|
||||
private Mahram()
|
||||
{
|
||||
super(Mahram.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(MAHRAM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("SPAM_TEXT") && (npc != null))
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.ALCHEMY_IS_A_SCIENCE_AND_AN_ART);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("SPAM_TEXT", 10000, npc, null, true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Mahram();
|
||||
}
|
||||
}
|
357
trunk/dist/game/data/scripts/ai/individual/Orfen.java
vendored
Normal file
357
trunk/dist/game/data/scripts/ai/individual/Orfen.java
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2BossZone;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
|
||||
/**
|
||||
* Orfen's AI
|
||||
* @author Emperorc
|
||||
*/
|
||||
public final class Orfen extends AbstractNpcAI
|
||||
{
|
||||
private static final Location[] POS =
|
||||
{
|
||||
new Location(43728, 17220, -4342),
|
||||
new Location(55024, 17368, -5412),
|
||||
new Location(53504, 21248, -5486),
|
||||
new Location(53248, 24576, -5262)
|
||||
};
|
||||
|
||||
private static final NpcStringId[] TEXT =
|
||||
{
|
||||
NpcStringId.S1_STOP_KIDDING_YOURSELF_ABOUT_YOUR_OWN_POWERLESSNESS,
|
||||
NpcStringId.S1_I_LL_MAKE_YOU_FEEL_WHAT_TRUE_FEAR_IS,
|
||||
NpcStringId.YOU_RE_REALLY_STUPID_TO_HAVE_CHALLENGED_ME_S1_GET_READY,
|
||||
NpcStringId.S1_DO_YOU_THINK_THAT_S_GOING_TO_WORK
|
||||
};
|
||||
|
||||
private static final int ORFEN = 29014;
|
||||
// private static final int RAIKEL = 29015;
|
||||
private static final int RAIKEL_LEOS = 29016;
|
||||
// private static final int RIBA = 29017;
|
||||
private static final int RIBA_IREN = 29018;
|
||||
|
||||
private static boolean _IsTeleported;
|
||||
private static List<L2Attackable> _Minions = new FastList<>();
|
||||
private static L2BossZone ZONE;
|
||||
|
||||
private static final byte ALIVE = 0;
|
||||
private static final byte DEAD = 1;
|
||||
|
||||
private Orfen()
|
||||
{
|
||||
super(Orfen.class.getSimpleName(), "ai/individual");
|
||||
int[] mobs =
|
||||
{
|
||||
ORFEN,
|
||||
RAIKEL_LEOS,
|
||||
RIBA_IREN
|
||||
};
|
||||
registerMobs(mobs);
|
||||
_IsTeleported = false;
|
||||
ZONE = GrandBossManager.getInstance().getZone(POS[0]);
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(ORFEN);
|
||||
int status = GrandBossManager.getInstance().getBossStatus(ORFEN);
|
||||
if (status == DEAD)
|
||||
{
|
||||
// load the unlock date and time for Orfen from DB
|
||||
long temp = info.getLong("respawn_time") - System.currentTimeMillis();
|
||||
// if Orfen is locked until a certain time, mark it so and start the unlock timer
|
||||
// the unlock time has not yet expired.
|
||||
if (temp > 0)
|
||||
{
|
||||
startQuestTimer("orfen_unlock", temp, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the time has already expired while the server was offline. Immediately spawn Orfen.
|
||||
int i = getRandom(10);
|
||||
Location loc;
|
||||
if (i < 4)
|
||||
{
|
||||
loc = POS[1];
|
||||
}
|
||||
else if (i < 7)
|
||||
{
|
||||
loc = POS[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
loc = POS[3];
|
||||
}
|
||||
L2GrandBossInstance orfen = (L2GrandBossInstance) addSpawn(ORFEN, loc, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE);
|
||||
spawnBoss(orfen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int loc_x = info.getInt("loc_x");
|
||||
int loc_y = info.getInt("loc_y");
|
||||
int loc_z = info.getInt("loc_z");
|
||||
int heading = info.getInt("heading");
|
||||
int hp = info.getInt("currentHP");
|
||||
int mp = info.getInt("currentMP");
|
||||
L2GrandBossInstance orfen = (L2GrandBossInstance) addSpawn(ORFEN, loc_x, loc_y, loc_z, heading, false, 0);
|
||||
orfen.setCurrentHpMp(hp, mp);
|
||||
spawnBoss(orfen);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSpawnPoint(L2Npc npc, int index)
|
||||
{
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null);
|
||||
L2Spawn spawn = npc.getSpawn();
|
||||
spawn.setLocation(POS[index]);
|
||||
npc.teleToLocation(POS[index], false);
|
||||
}
|
||||
|
||||
public void spawnBoss(L2GrandBossInstance npc)
|
||||
{
|
||||
GrandBossManager.getInstance().addBoss(npc);
|
||||
npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
|
||||
startQuestTimer("check_orfen_pos", 10000, npc, null, true);
|
||||
// Spawn minions
|
||||
int x = npc.getX();
|
||||
int y = npc.getY();
|
||||
L2Attackable mob;
|
||||
mob = (L2Attackable) addSpawn(RAIKEL_LEOS, x + 100, y + 100, npc.getZ(), 0, false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
_Minions.add(mob);
|
||||
mob = (L2Attackable) addSpawn(RAIKEL_LEOS, x + 100, y - 100, npc.getZ(), 0, false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
_Minions.add(mob);
|
||||
mob = (L2Attackable) addSpawn(RAIKEL_LEOS, x - 100, y + 100, npc.getZ(), 0, false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
_Minions.add(mob);
|
||||
mob = (L2Attackable) addSpawn(RAIKEL_LEOS, x - 100, y - 100, npc.getZ(), 0, false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
_Minions.add(mob);
|
||||
startQuestTimer("check_minion_loc", 10000, npc, null, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("orfen_unlock"))
|
||||
{
|
||||
int i = getRandom(10);
|
||||
Location loc;
|
||||
if (i < 4)
|
||||
{
|
||||
loc = POS[1];
|
||||
}
|
||||
else if (i < 7)
|
||||
{
|
||||
loc = POS[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
loc = POS[3];
|
||||
}
|
||||
L2GrandBossInstance orfen = (L2GrandBossInstance) addSpawn(ORFEN, loc, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE);
|
||||
spawnBoss(orfen);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("check_orfen_pos"))
|
||||
{
|
||||
if ((_IsTeleported && (npc.getCurrentHp() > (npc.getMaxHp() * 0.95))) || (!ZONE.isInsideZone(npc) && !_IsTeleported))
|
||||
{
|
||||
setSpawnPoint(npc, getRandom(3) + 1);
|
||||
_IsTeleported = false;
|
||||
}
|
||||
else if (_IsTeleported && !ZONE.isInsideZone(npc))
|
||||
{
|
||||
setSpawnPoint(npc, 0);
|
||||
}
|
||||
}
|
||||
else if (event.equalsIgnoreCase("check_minion_loc"))
|
||||
{
|
||||
for (int i = 0; i < _Minions.size(); i++)
|
||||
{
|
||||
L2Attackable mob = _Minions.get(i);
|
||||
if (!npc.isInsideRadius(mob, 3000, false, false))
|
||||
{
|
||||
mob.teleToLocation(npc.getLocation());
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equalsIgnoreCase("despawn_minions"))
|
||||
{
|
||||
for (int i = 0; i < _Minions.size(); i++)
|
||||
{
|
||||
L2Attackable mob = _Minions.get(i);
|
||||
if (mob != null)
|
||||
{
|
||||
mob.decayMe();
|
||||
}
|
||||
}
|
||||
_Minions.clear();
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_minion"))
|
||||
{
|
||||
L2Attackable mob = (L2Attackable) addSpawn(RAIKEL_LEOS, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
_Minions.add(mob);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == ORFEN)
|
||||
{
|
||||
L2Character originalCaster = isSummon ? caster.getSummon() : caster;
|
||||
if ((skill.getEffectPoint() > 0) && (getRandom(5) == 0) && npc.isInsideRadius(originalCaster, 1000, false, false))
|
||||
{
|
||||
NpcSay packet = new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), TEXT[getRandom(4)]);
|
||||
packet.addStringParameter(caster.getName().toString());
|
||||
npc.broadcastPacket(packet);
|
||||
originalCaster.teleToLocation(npc.getLocation());
|
||||
npc.setTarget(originalCaster);
|
||||
npc.doCast(SkillData.getInstance().getSkill(4064, 1));
|
||||
}
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFactionCall(L2Npc npc, L2Npc caller, L2PcInstance attacker, boolean isSummon)
|
||||
{
|
||||
if ((caller == null) || (npc == null) || npc.isCastingNow())
|
||||
{
|
||||
return super.onFactionCall(npc, caller, attacker, isSummon);
|
||||
}
|
||||
int npcId = npc.getId();
|
||||
int callerId = caller.getId();
|
||||
if ((npcId == RAIKEL_LEOS) && (getRandom(20) == 0))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SkillData.getInstance().getSkill(4067, 4));
|
||||
}
|
||||
else if (npcId == RIBA_IREN)
|
||||
{
|
||||
int chance = 1;
|
||||
if (callerId == ORFEN)
|
||||
{
|
||||
chance = 9;
|
||||
}
|
||||
if ((callerId != RIBA_IREN) && (caller.getCurrentHp() < (caller.getMaxHp() / 2.0)) && (getRandom(10) < chance))
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null);
|
||||
npc.setTarget(caller);
|
||||
npc.doCast(SkillData.getInstance().getSkill(4516, 1));
|
||||
}
|
||||
}
|
||||
return super.onFactionCall(npc, caller, attacker, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
if (npcId == ORFEN)
|
||||
{
|
||||
if (!_IsTeleported && ((npc.getCurrentHp() - damage) < (npc.getMaxHp() / 2)))
|
||||
{
|
||||
_IsTeleported = true;
|
||||
setSpawnPoint(npc, 0);
|
||||
}
|
||||
else if (npc.isInsideRadius(attacker, 1000, false, false) && !npc.isInsideRadius(attacker, 300, false, false) && (getRandom(10) == 0))
|
||||
{
|
||||
NpcSay packet = new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npcId, TEXT[getRandom(3)]);
|
||||
packet.addStringParameter(attacker.getName().toString());
|
||||
npc.broadcastPacket(packet);
|
||||
attacker.teleToLocation(npc.getLocation());
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SkillData.getInstance().getSkill(4064, 1));
|
||||
}
|
||||
}
|
||||
else if (npcId == RIBA_IREN)
|
||||
{
|
||||
if (!npc.isCastingNow() && ((npc.getCurrentHp() - damage) < (npc.getMaxHp() / 2.0)))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SkillData.getInstance().getSkill(4516, 1));
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == ORFEN)
|
||||
{
|
||||
npc.broadcastPacket(new PlaySound(1, "BS02_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
|
||||
GrandBossManager.getInstance().setBossStatus(ORFEN, DEAD);
|
||||
// Calculate Min and Max respawn times randomly.
|
||||
long respawnTime = Config.ORFEN_SPAWN_INTERVAL + getRandom(-Config.ORFEN_SPAWN_RANDOM, Config.ORFEN_SPAWN_RANDOM);
|
||||
respawnTime *= 3600000;
|
||||
startQuestTimer("orfen_unlock", respawnTime, null, null);
|
||||
// also save the respawn time so that the info is maintained past reboots
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(ORFEN);
|
||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
GrandBossManager.getInstance().setStatsSet(ORFEN, info);
|
||||
cancelQuestTimer("check_minion_loc", npc, null);
|
||||
cancelQuestTimer("check_orfen_pos", npc, null);
|
||||
startQuestTimer("despawn_minions", 20000, null, null);
|
||||
cancelQuestTimers("spawn_minion");
|
||||
}
|
||||
else if ((GrandBossManager.getInstance().getBossStatus(ORFEN) == ALIVE) && (npc.getId() == RAIKEL_LEOS))
|
||||
{
|
||||
_Minions.remove(npc);
|
||||
startQuestTimer("spawn_minion", 360000, npc, null);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Orfen();
|
||||
}
|
||||
}
|
378
trunk/dist/game/data/scripts/ai/individual/QueenAnt.java
vendored
Normal file
378
trunk/dist/game/data/scripts/ai/individual/QueenAnt.java
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.CommonSkill;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2BossZone;
|
||||
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
|
||||
/**
|
||||
* Queen Ant's AI
|
||||
* @author Emperorc
|
||||
*/
|
||||
public final class QueenAnt extends AbstractNpcAI
|
||||
{
|
||||
private static final int QUEEN = 29001;
|
||||
private static final int LARVA = 29002;
|
||||
private static final int NURSE = 29003;
|
||||
private static final int GUARD = 29004;
|
||||
private static final int ROYAL = 29005;
|
||||
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
QUEEN,
|
||||
LARVA,
|
||||
NURSE,
|
||||
GUARD,
|
||||
ROYAL
|
||||
};
|
||||
|
||||
private static final Location OUST_LOC_1 = new Location(-19480, 187344, -5600);
|
||||
private static final Location OUST_LOC_2 = new Location(-17928, 180912, -5520);
|
||||
private static final Location OUST_LOC_3 = new Location(-23808, 182368, -5600);
|
||||
|
||||
private static final int QUEEN_X = -21610;
|
||||
private static final int QUEEN_Y = 181594;
|
||||
private static final int QUEEN_Z = -5734;
|
||||
|
||||
// QUEEN Status Tracking :
|
||||
private static final byte ALIVE = 0; // Queen Ant is spawned.
|
||||
private static final byte DEAD = 1; // Queen Ant has been killed.
|
||||
|
||||
private static L2BossZone _zone;
|
||||
|
||||
private static SkillHolder HEAL1 = new SkillHolder(4020, 1);
|
||||
private static SkillHolder HEAL2 = new SkillHolder(4024, 1);
|
||||
|
||||
private L2MonsterInstance _queen = null;
|
||||
private L2MonsterInstance _larva = null;
|
||||
private final List<L2MonsterInstance> _nurses = new FastList<>(5);
|
||||
|
||||
private QueenAnt()
|
||||
{
|
||||
super(QueenAnt.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(MOBS);
|
||||
addKillId(MOBS);
|
||||
addAggroRangeEnterId(MOBS);
|
||||
addFactionCallId(NURSE);
|
||||
|
||||
_zone = GrandBossManager.getInstance().getZone(QUEEN_X, QUEEN_Y, QUEEN_Z);
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(QUEEN);
|
||||
int status = GrandBossManager.getInstance().getBossStatus(QUEEN);
|
||||
if (status == DEAD)
|
||||
{
|
||||
// load the unlock date and time for queen ant from DB
|
||||
long temp = info.getLong("respawn_time") - System.currentTimeMillis();
|
||||
// if queen ant is locked until a certain time, mark it so and start the unlock timer
|
||||
// the unlock time has not yet expired.
|
||||
if (temp > 0)
|
||||
{
|
||||
startQuestTimer("queen_unlock", temp, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the time has already expired while the server was offline. Immediately spawn queen ant.
|
||||
L2GrandBossInstance queen = (L2GrandBossInstance) addSpawn(QUEEN, QUEEN_X, QUEEN_Y, QUEEN_Z, 0, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(QUEEN, ALIVE);
|
||||
spawnBoss(queen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int loc_x = info.getInt("loc_x");
|
||||
int loc_y = info.getInt("loc_y");
|
||||
int loc_z = info.getInt("loc_z");
|
||||
int heading = info.getInt("heading");
|
||||
int hp = info.getInt("currentHP");
|
||||
int mp = info.getInt("currentMP");
|
||||
if (!_zone.isInsideZone(loc_x, loc_y, loc_z))
|
||||
{
|
||||
loc_x = QUEEN_X;
|
||||
loc_y = QUEEN_Y;
|
||||
loc_z = QUEEN_Z;
|
||||
}
|
||||
L2GrandBossInstance queen = (L2GrandBossInstance) addSpawn(QUEEN, loc_x, loc_y, loc_z, heading, false, 0);
|
||||
queen.setCurrentHpMp(hp, mp);
|
||||
spawnBoss(queen);
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnBoss(L2GrandBossInstance npc)
|
||||
{
|
||||
GrandBossManager.getInstance().addBoss(npc);
|
||||
if (getRandom(100) < 33)
|
||||
{
|
||||
_zone.movePlayersTo(OUST_LOC_1);
|
||||
}
|
||||
else if (getRandom(100) < 50)
|
||||
{
|
||||
_zone.movePlayersTo(OUST_LOC_2);
|
||||
}
|
||||
else
|
||||
{
|
||||
_zone.movePlayersTo(OUST_LOC_3);
|
||||
}
|
||||
GrandBossManager.getInstance().addBoss(npc);
|
||||
startQuestTimer("action", 10000, npc, null, true);
|
||||
startQuestTimer("heal", 1000, null, null, true);
|
||||
npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
|
||||
_queen = npc;
|
||||
_larva = (L2MonsterInstance) addSpawn(LARVA, -21600, 179482, -5846, getRandom(360), false, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("heal"))
|
||||
{
|
||||
boolean notCasting;
|
||||
final boolean larvaNeedHeal = (_larva != null) && (_larva.getCurrentHp() < _larva.getMaxHp());
|
||||
final boolean queenNeedHeal = (_queen != null) && (_queen.getCurrentHp() < _queen.getMaxHp());
|
||||
for (L2MonsterInstance nurse : _nurses)
|
||||
{
|
||||
if ((nurse == null) || nurse.isDead() || nurse.isCastingNow())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
notCasting = nurse.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST;
|
||||
if (larvaNeedHeal)
|
||||
{
|
||||
if ((nurse.getTarget() != _larva) || notCasting)
|
||||
{
|
||||
nurse.setTarget(_larva);
|
||||
nurse.useMagic(getRandomBoolean() ? HEAL1.getSkill() : HEAL2.getSkill());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (queenNeedHeal)
|
||||
{
|
||||
if (nurse.getLeader() == _larva)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((nurse.getTarget() != _queen) || notCasting)
|
||||
{
|
||||
nurse.setTarget(_queen);
|
||||
nurse.useMagic(HEAL1.getSkill());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// if nurse not casting - remove target
|
||||
if (notCasting && (nurse.getTarget() != null))
|
||||
{
|
||||
nurse.setTarget(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equalsIgnoreCase("action") && (npc != null))
|
||||
{
|
||||
if (getRandom(3) == 0)
|
||||
{
|
||||
if (getRandom(2) == 0)
|
||||
{
|
||||
npc.broadcastSocialAction(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.broadcastSocialAction(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equalsIgnoreCase("queen_unlock"))
|
||||
{
|
||||
L2GrandBossInstance queen = (L2GrandBossInstance) addSpawn(QUEEN, QUEEN_X, QUEEN_Y, QUEEN_Z, 0, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(QUEEN, ALIVE);
|
||||
spawnBoss(queen);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final L2MonsterInstance mob = (L2MonsterInstance) npc;
|
||||
switch (npc.getId())
|
||||
{
|
||||
case LARVA:
|
||||
mob.setIsImmobilized(true);
|
||||
mob.setIsMortal(false);
|
||||
mob.setIsRaidMinion(true);
|
||||
break;
|
||||
case NURSE:
|
||||
mob.disableCoreAI(true);
|
||||
mob.setIsRaidMinion(true);
|
||||
_nurses.add(mob);
|
||||
break;
|
||||
case ROYAL:
|
||||
case GUARD:
|
||||
mob.setIsRaidMinion(true);
|
||||
break;
|
||||
}
|
||||
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFactionCall(L2Npc npc, L2Npc caller, L2PcInstance attacker, boolean isSummon)
|
||||
{
|
||||
if ((caller == null) || (npc == null))
|
||||
{
|
||||
return super.onFactionCall(npc, caller, attacker, isSummon);
|
||||
}
|
||||
|
||||
if (!npc.isCastingNow() && (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST))
|
||||
{
|
||||
if (caller.getCurrentHp() < caller.getMaxHp())
|
||||
{
|
||||
npc.setTarget(caller);
|
||||
((L2Attackable) npc).useMagic(HEAL1.getSkill());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if ((npc == null) || (player.isGM() && player.isInvisible()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final boolean isMage;
|
||||
final L2Playable character;
|
||||
if (isSummon)
|
||||
{
|
||||
isMage = false;
|
||||
character = player.getSummon();
|
||||
}
|
||||
else
|
||||
{
|
||||
isMage = player.isMageClass();
|
||||
character = player;
|
||||
}
|
||||
|
||||
if (character == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!Config.RAID_DISABLE_CURSE && ((character.getLevel() - npc.getLevel()) > 8))
|
||||
{
|
||||
Skill curse = null;
|
||||
if (isMage)
|
||||
{
|
||||
if (!character.isMuted() && (getRandom(4) == 0))
|
||||
{
|
||||
curse = CommonSkill.RAID_CURSE.getSkill();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!character.isParalyzed() && (getRandom(4) == 0))
|
||||
{
|
||||
curse = CommonSkill.RAID_CURSE2.getSkill();
|
||||
}
|
||||
}
|
||||
|
||||
if (curse != null)
|
||||
{
|
||||
npc.broadcastPacket(new MagicSkillUse(npc, character, curse.getId(), curse.getLevel(), 300, 0));
|
||||
curse.applyEffects(npc, character);
|
||||
}
|
||||
|
||||
((L2Attackable) npc).stopHating(character); // for calling again
|
||||
return null;
|
||||
}
|
||||
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
if (npcId == QUEEN)
|
||||
{
|
||||
npc.broadcastPacket(new PlaySound(1, "BS02_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
|
||||
GrandBossManager.getInstance().setBossStatus(QUEEN, DEAD);
|
||||
// Calculate Min and Max respawn times randomly.
|
||||
long respawnTime = Config.QUEEN_ANT_SPAWN_INTERVAL + getRandom(-Config.QUEEN_ANT_SPAWN_RANDOM, Config.QUEEN_ANT_SPAWN_RANDOM);
|
||||
respawnTime *= 3600000;
|
||||
startQuestTimer("queen_unlock", respawnTime, null, null);
|
||||
cancelQuestTimer("action", npc, null);
|
||||
cancelQuestTimer("heal", null, null);
|
||||
// also save the respawn time so that the info is maintained past reboots
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(QUEEN);
|
||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
GrandBossManager.getInstance().setStatsSet(QUEEN, info);
|
||||
_nurses.clear();
|
||||
_larva.deleteMe();
|
||||
_larva = null;
|
||||
_queen = null;
|
||||
}
|
||||
else if ((_queen != null) && !_queen.isAlikeDead())
|
||||
{
|
||||
if (npcId == ROYAL)
|
||||
{
|
||||
L2MonsterInstance mob = (L2MonsterInstance) npc;
|
||||
if (mob.getLeader() != null)
|
||||
{
|
||||
mob.getLeader().getMinionList().onMinionDie(mob, (280 + getRandom(40)) * 1000);
|
||||
}
|
||||
}
|
||||
else if (npcId == NURSE)
|
||||
{
|
||||
L2MonsterInstance mob = (L2MonsterInstance) npc;
|
||||
_nurses.remove(mob);
|
||||
if (mob.getLeader() != null)
|
||||
{
|
||||
mob.getLeader().getMinionList().onMinionDie(mob, 10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new QueenAnt();
|
||||
}
|
||||
}
|
114
trunk/dist/game/data/scripts/ai/individual/QueenShyeed.java
vendored
Normal file
114
trunk/dist/game/data/scripts/ai/individual/QueenShyeed.java
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2EffectZone;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Queen Shyeed AI
|
||||
* @author malyelfik
|
||||
*/
|
||||
public final class QueenShyeed extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int SHYEED = 25671;
|
||||
private static final Location SHYEED_LOC = new Location(79634, -55428, -6104, 0);
|
||||
|
||||
// Respawn
|
||||
private static final int RESPAWN = 86400000; // 24 h
|
||||
private static final int RANDOM_RESPAWN = 43200000; // 12 h
|
||||
|
||||
// Zones
|
||||
private static final L2EffectZone MOB_BUFF_ZONE = ZoneManager.getInstance().getZoneById(200103, L2EffectZone.class);
|
||||
private static final L2EffectZone MOB_BUFF_DISPLAY_ZONE = ZoneManager.getInstance().getZoneById(200104, L2EffectZone.class);
|
||||
private static final L2EffectZone PC_BUFF_ZONE = ZoneManager.getInstance().getZoneById(200105, L2EffectZone.class);
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "respawn":
|
||||
spawnShyeed();
|
||||
break;
|
||||
case "despawn":
|
||||
if (!npc.isDead())
|
||||
{
|
||||
npc.deleteMe();
|
||||
startRespawn();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.SHYEED_S_CRY_IS_STEADILY_DYING_DOWN);
|
||||
startRespawn();
|
||||
PC_BUFF_ZONE.setEnabled(true);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private QueenShyeed()
|
||||
{
|
||||
super(QueenShyeed.class.getSimpleName(), "ai/individual");
|
||||
addKillId(SHYEED);
|
||||
spawnShyeed();
|
||||
}
|
||||
|
||||
private void spawnShyeed()
|
||||
{
|
||||
final String respawn = loadGlobalQuestVar("Respawn");
|
||||
final long remain = (!respawn.isEmpty()) ? Long.parseLong(respawn) - System.currentTimeMillis() : 0;
|
||||
if (remain > 0)
|
||||
{
|
||||
startQuestTimer("respawn", remain, null, null);
|
||||
return;
|
||||
}
|
||||
final L2Npc npc = addSpawn(SHYEED, SHYEED_LOC, false, 0);
|
||||
startQuestTimer("despawn", 10800000, npc, null);
|
||||
PC_BUFF_ZONE.setEnabled(false);
|
||||
MOB_BUFF_ZONE.setEnabled(true);
|
||||
MOB_BUFF_DISPLAY_ZONE.setEnabled(true);
|
||||
}
|
||||
|
||||
private void startRespawn()
|
||||
{
|
||||
final int respawnTime = RESPAWN - getRandom(RANDOM_RESPAWN);
|
||||
saveGlobalQuestVar("Respawn", Long.toString(System.currentTimeMillis() + respawnTime));
|
||||
startQuestTimer("respawn", respawnTime, null, null);
|
||||
MOB_BUFF_ZONE.setEnabled(false);
|
||||
MOB_BUFF_DISPLAY_ZONE.setEnabled(false);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new QueenShyeed();
|
||||
}
|
||||
}
|
51
trunk/dist/game/data/scripts/ai/individual/RagnaOrcCommander.java
vendored
Normal file
51
trunk/dist/game/data/scripts/ai/individual/RagnaOrcCommander.java
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* Ragna Orc Commander AI.
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class RagnaOrcCommander extends AbstractNpcAI
|
||||
{
|
||||
private static final int RAGNA_ORC_COMMANDER = 22694;
|
||||
|
||||
private RagnaOrcCommander()
|
||||
{
|
||||
super(RagnaOrcCommander.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(RAGNA_ORC_COMMANDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
spawnMinions(npc, "Privates1");
|
||||
spawnMinions(npc, getRandomBoolean() ? "Privates2" : "Privates3");
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RagnaOrcCommander();
|
||||
}
|
||||
}
|
50
trunk/dist/game/data/scripts/ai/individual/RagnaOrcHero.java
vendored
Normal file
50
trunk/dist/game/data/scripts/ai/individual/RagnaOrcHero.java
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* Ragna Orc Hero AI.
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class RagnaOrcHero extends AbstractNpcAI
|
||||
{
|
||||
private static final int RAGNA_ORC_HERO = 22693;
|
||||
|
||||
private RagnaOrcHero()
|
||||
{
|
||||
super(RagnaOrcHero.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(RAGNA_ORC_HERO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
spawnMinions(npc, getRandom(100) < 70 ? "Privates1" : "Privates2");
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RagnaOrcHero();
|
||||
}
|
||||
}
|
50
trunk/dist/game/data/scripts/ai/individual/RagnaOrcSeer.java
vendored
Normal file
50
trunk/dist/game/data/scripts/ai/individual/RagnaOrcSeer.java
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* Ragna Orc Seer AI.
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class RagnaOrcSeer extends AbstractNpcAI
|
||||
{
|
||||
private static final int RAGNA_ORC_SEER = 22697;
|
||||
|
||||
private RagnaOrcSeer()
|
||||
{
|
||||
super(RagnaOrcSeer.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(RAGNA_ORC_SEER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
spawnMinions(npc, "Privates" + getRandom(1, 2));
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RagnaOrcSeer();
|
||||
}
|
||||
}
|
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-01.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-01.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
Wait.. It doesn't seem as though you are the one destined for the front lines in this battle. I was supposed to open a passage to Sailren's lair only to the leader of one party. If you wish to teleport, bring your party leader to me or return here as a party leader.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01a.html">Prep for battle.</a>
|
||||
</body></html>
|
8
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-01a.html
vendored
Normal file
8
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-01a.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
You know that in the past, Mother Shilen paid a great sacrifice to lock Sailren here.<br>
|
||||
Afterward, she created a stone likeness of herself and bestowed upon it the power to seal, making it a guardian of this place to ensure that Sailren remained imprisoned.<br>
|
||||
I am that stone statue of Shilen.<br>
|
||||
Mother Shilen also entrusted the power to seal to those who wield the sacred ax Gazkh.<br>
|
||||
I will only open the gate for those who have Gazkh and their friends. When the seal is at its weakest, however, I allow a warrior to enter in order to minimize the sacrifice.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-02a.html">Listen to the conditions to enter in detail.</a>
|
||||
</body></html>
|
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-02.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-02.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
You have the heart to fight Sailren, of that there can be no doubt. But if you do not have Gazkh given to you by Shilen, Sailren will certainly kill you. If you want to teleport within, complete my quest and obtain Gazkh.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01a.html">Prep for battle.</a>
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-02a.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-02a.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
Only a party whose leader weilds Gazkh can enter Sailren's Stronghold and battle the creature.<br>
|
||||
Be aware that any party member who is far away at the time of entry cannot enter the Stronghold. Nor can another party enter until the first party has exited.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-03a.html">Learn more about Sailren's power and how to fight it.</a>
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-03.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-03.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
Shilen's protection is not with you -- go away! You are not qualified to fight against Sailren...<br>
|
||||
If you want to enter Sailren's nest, then you should find a party leader who can fight against Sailren and join his party. Or you can complete my quest to become a party leader, form your own party, and then return here.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01a.html">Listen to the entry requirements and battle method.</a>
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-03a.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-03a.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
There are not many of them, but Sailren is protected by its dinosaur followers. Combined with my enchantment and the power of the other statues, we are restraining Sailren and its followers from escaping. But as they begin to break free of our control, their power and magic also begins to extend beyond the Lost Nest, affecting even the Primeval Plains!<br>
|
||||
If the powers of the Stone Statues are completely broken, Sailren and its followers will escape and this island and everything on it will perish.<br>
|
||||
Alas, Shilen is not here to protect us! In order to re-seal that horrifying dinosaur, you must defeat its followers first, and then work as a team to defeat Sailren.
|
||||
</body></html>
|
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-04.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-04.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
Currently the magic power of Sailren and its followers is very strong. I do not think you can win solely with your own power, especially given how weak the seal stones have become.<br>
|
||||
My counsel is that you first recover the power to seal and wait 'til Sailren's strength lessens a bit. Then you will have your best chance of entering the nest and defeating this ancient evil.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01a.html">Prep for battle.</a>
|
||||
</body></html>
|
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-05.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-05.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
There is another brave party fighting against Sailren right now, so I cannot teleport you into the nest. When they return, I will teleport you.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01a.html">Prep for battle.</a>
|
||||
</body></html>
|
7
trunk/dist/game/data/scripts/ai/individual/Sailren/32109.html
vendored
Normal file
7
trunk/dist/game/data/scripts/ai/individual/Sailren/32109.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<html><body>Stone Statue of Shilen:<br>
|
||||
(The statue is worn in places by wind and rain -- proof that it has stood guard here a long, long time. Despite its weatherbeaten appearance, it feels somehow dignified and majestic. Standing before it, you sense a presence.)<br>
|
||||
You, outsider... Why have you come here to this statue? For I am Mother Shilen's avatar and the last guard of Sailren!<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01.html">Prep for battle.</a><br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren enter">"I wish to participate in clearing out Sailren and its followers."</a><br>
|
||||
<a action="bypass -h npc_%objectId%_Quest">Quest.</a>
|
||||
</body></html>
|
330
trunk/dist/game/data/scripts/ai/individual/Sailren/Sailren.java
vendored
Normal file
330
trunk/dist/game/data/scripts/ai/individual/Sailren/Sailren.java
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual.Sailren;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.instancemanager.GlobalVariablesManager;
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.TeleportWhereType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2RaidBossInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2NoRestartZone;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
|
||||
|
||||
/**
|
||||
* Sailren AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Sailren extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int STATUE = 32109; // Shilen's Stone Statue
|
||||
private static final int MOVIE_NPC = 32110; // Invisible NPC for movie
|
||||
private static final int SAILREN = 29065; // Sailren
|
||||
private static final int VELOCIRAPTOR = 22218; // Velociraptor
|
||||
private static final int PTEROSAUR = 22199; // Pterosaur
|
||||
private static final int TREX = 22217; // Tyrannosaurus
|
||||
private static final int CUBIC = 32107; // Teleportation Cubic
|
||||
// Item
|
||||
private static final int GAZKH = 8784; // Gazkh
|
||||
// Skill
|
||||
private static final SkillHolder ANIMATION = new SkillHolder(5090, 1);
|
||||
// Zone
|
||||
private static final L2NoRestartZone zone = ZoneManager.getInstance().getZoneById(70049, L2NoRestartZone.class);
|
||||
// Misc
|
||||
private static final int RESPAWN = 1; // Respawn time (in hours)
|
||||
private static final int MAX_TIME = 3200; // Max time for Sailren fight (in minutes)
|
||||
private static Status STATUS = Status.ALIVE;
|
||||
private static int _killCount = 0;
|
||||
private static long _lastAttack = 0;
|
||||
|
||||
private static enum Status
|
||||
{
|
||||
ALIVE,
|
||||
IN_FIGHT,
|
||||
DEAD
|
||||
}
|
||||
|
||||
private Sailren()
|
||||
{
|
||||
super(Sailren.class.getSimpleName(), "ai/individual");
|
||||
addStartNpc(STATUE, CUBIC);
|
||||
addTalkId(STATUE, CUBIC);
|
||||
addFirstTalkId(STATUE);
|
||||
addKillId(VELOCIRAPTOR, PTEROSAUR, TREX, SAILREN);
|
||||
addAttackId(VELOCIRAPTOR, PTEROSAUR, TREX, SAILREN);
|
||||
|
||||
final long remain = GlobalVariablesManager.getInstance().getLong("SailrenRespawn", 0) - System.currentTimeMillis();
|
||||
if (remain > 0)
|
||||
{
|
||||
STATUS = Status.DEAD;
|
||||
startQuestTimer("CLEAR_STATUS", remain, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "32109-01.html":
|
||||
case "32109-01a.html":
|
||||
case "32109-02a.html":
|
||||
case "32109-03a.html":
|
||||
{
|
||||
return event;
|
||||
}
|
||||
case "enter":
|
||||
{
|
||||
String htmltext = null;
|
||||
if (!player.isInParty())
|
||||
{
|
||||
htmltext = "32109-01.html";
|
||||
}
|
||||
else if (STATUS == Status.DEAD)
|
||||
{
|
||||
htmltext = "32109-04.html";
|
||||
}
|
||||
else if (STATUS == Status.IN_FIGHT)
|
||||
{
|
||||
htmltext = "32109-05.html";
|
||||
}
|
||||
else if (!player.getParty().isLeader(player))
|
||||
{
|
||||
htmltext = "32109-03.html";
|
||||
}
|
||||
else if (!hasQuestItems(player, GAZKH))
|
||||
{
|
||||
htmltext = "32109-02.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
takeItems(player, GAZKH, 1);
|
||||
STATUS = Status.IN_FIGHT;
|
||||
_lastAttack = System.currentTimeMillis();
|
||||
for (L2PcInstance member : player.getParty().getMembers())
|
||||
{
|
||||
if (member.isInsideRadius(npc, 1000, true, false))
|
||||
{
|
||||
member.teleToLocation(27549, -6638, -2008);
|
||||
}
|
||||
}
|
||||
startQuestTimer("SPAWN_VELOCIRAPTOR", 60000, null, null);
|
||||
startQuestTimer("TIME_OUT", MAX_TIME * 1000, null, null);
|
||||
startQuestTimer("CHECK_ATTACK", 120000, null, null);
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
case "teleportOut":
|
||||
{
|
||||
player.teleToLocation(TeleportWhereType.TOWN);
|
||||
break;
|
||||
}
|
||||
case "SPAWN_VELOCIRAPTOR":
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
addSpawn(VELOCIRAPTOR, 27313 + getRandom(150), -6766 + getRandom(150), -1975, 0, false, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SPAWN_SAILREN":
|
||||
{
|
||||
final L2RaidBossInstance sailren = (L2RaidBossInstance) addSpawn(SAILREN, 27549, -6638, -2008, 0, false, 0);
|
||||
final L2Npc movieNpc = addSpawn(MOVIE_NPC, sailren.getX(), sailren.getY(), sailren.getZ() + 30, 0, false, 26000);
|
||||
sailren.setIsInvul(true);
|
||||
sailren.setIsImmobilized(true);
|
||||
zone.broadcastPacket(new SpecialCamera(movieNpc, 60, 110, 30, 4000, 1500, 20000, 0, 65, 1, 0, 0));
|
||||
|
||||
startQuestTimer("ATTACK", 24600, sailren, null);
|
||||
startQuestTimer("ANIMATION", 2000, movieNpc, null);
|
||||
startQuestTimer("CAMERA_1", 4100, movieNpc, null);
|
||||
break;
|
||||
}
|
||||
case "ANIMATION":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(ANIMATION.getSkill());
|
||||
startQuestTimer("ANIMATION", 2000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CAMERA_1":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 100, 180, 30, 3000, 1500, 20000, 0, 50, 1, 0, 0));
|
||||
startQuestTimer("CAMERA_2", 3000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "CAMERA_2":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 150, 270, 25, 3000, 1500, 20000, 0, 30, 1, 0, 0));
|
||||
startQuestTimer("CAMERA_3", 3000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "CAMERA_3":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 160, 360, 20, 3000, 1500, 20000, 10, 15, 1, 0, 0));
|
||||
startQuestTimer("CAMERA_4", 3000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "CAMERA_4":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 160, 450, 10, 3000, 1500, 20000, 0, 10, 1, 0, 0));
|
||||
startQuestTimer("CAMERA_5", 3000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "CAMERA_5":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 160, 560, 0, 3000, 1500, 20000, 0, 10, 1, 0, 0));
|
||||
startQuestTimer("CAMERA_6", 7000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "CAMERA_6":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 70, 560, 0, 500, 1500, 7000, -15, 20, 1, 0, 0));
|
||||
break;
|
||||
}
|
||||
case "ATTACK":
|
||||
{
|
||||
npc.setIsInvul(false);
|
||||
npc.setIsImmobilized(false);
|
||||
break;
|
||||
}
|
||||
case "CLEAR_STATUS":
|
||||
{
|
||||
STATUS = Status.ALIVE;
|
||||
break;
|
||||
}
|
||||
case "TIME_OUT":
|
||||
{
|
||||
if (STATUS == Status.IN_FIGHT)
|
||||
{
|
||||
STATUS = Status.ALIVE;
|
||||
}
|
||||
for (L2Character charInside : zone.getCharactersInside())
|
||||
{
|
||||
if (charInside != null)
|
||||
{
|
||||
if (charInside.isPlayer())
|
||||
{
|
||||
charInside.teleToLocation(TeleportWhereType.TOWN);
|
||||
}
|
||||
else if (charInside.isNpc())
|
||||
{
|
||||
charInside.deleteMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CHECK_ATTACK":
|
||||
{
|
||||
if (!zone.getPlayersInside().isEmpty() && ((_lastAttack + 600000) < System.currentTimeMillis()))
|
||||
{
|
||||
cancelQuestTimer("TIME_OUT", null, null);
|
||||
notifyEvent("TIME_OUT", null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("CHECK_ATTACK", 120000, null, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (zone.isCharacterInZone(attacker))
|
||||
{
|
||||
_lastAttack = System.currentTimeMillis();
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (zone.isCharacterInZone(killer))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case SAILREN:
|
||||
{
|
||||
STATUS = Status.DEAD;
|
||||
addSpawn(CUBIC, 27644, -6638, -2008, 0, false, 300000);
|
||||
final long respawnTime = RESPAWN * 3600000;
|
||||
GlobalVariablesManager.getInstance().set("SailrenRespawn", System.currentTimeMillis() + respawnTime);
|
||||
cancelQuestTimer("CHECK_ATTACK", null, null);
|
||||
cancelQuestTimer("TIME_OUT", null, null);
|
||||
startQuestTimer("CLEAR_STATUS", respawnTime, null, null);
|
||||
startQuestTimer("TIME_OUT", 300000, null, null);
|
||||
break;
|
||||
}
|
||||
case VELOCIRAPTOR:
|
||||
{
|
||||
_killCount++;
|
||||
if (_killCount == 3)
|
||||
{
|
||||
final L2Npc pterosaur = addSpawn(PTEROSAUR, 27313, -6766, -1975, 0, false, 0);
|
||||
addAttackPlayerDesire(pterosaur, killer);
|
||||
_killCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PTEROSAUR:
|
||||
{
|
||||
final L2Npc trex = addSpawn(TREX, 27313, -6766, -1975, 0, false, 0);
|
||||
addAttackPlayerDesire(trex, killer);
|
||||
break;
|
||||
}
|
||||
case TREX:
|
||||
{
|
||||
startQuestTimer("SPAWN_SAILREN", 180000, null, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unload(boolean removeFromList)
|
||||
{
|
||||
if (STATUS == Status.IN_FIGHT)
|
||||
{
|
||||
_log.info(getClass().getSimpleName() + ": Script is being unloaded while Sailren is active, clearing zone.");
|
||||
notifyEvent("TIME_OUT", null, null);
|
||||
}
|
||||
return super.unload(removeFromList);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Sailren();
|
||||
}
|
||||
}
|
64
trunk/dist/game/data/scripts/ai/individual/Shannon.java
vendored
Normal file
64
trunk/dist/game/data/scripts/ai/individual/Shannon.java
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Shannon AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Shannon extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int SHANNON = 32974;
|
||||
|
||||
private Shannon()
|
||||
{
|
||||
super(Shannon.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(SHANNON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("SPAM_TEXT") && (npc != null))
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.LOOK_AT_ALL_THE_NEWBIES_HA_HA_HA);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("SPAM_TEXT", 12000, npc, null, true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Shannon();
|
||||
}
|
||||
}
|
178
trunk/dist/game/data/scripts/ai/individual/SinEater.java
vendored
Normal file
178
trunk/dist/game/data/scripts/ai/individual/SinEater.java
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.events.EventType;
|
||||
import com.l2jserver.gameserver.model.events.ListenerRegisterType;
|
||||
import com.l2jserver.gameserver.model.events.annotations.Id;
|
||||
import com.l2jserver.gameserver.model.events.annotations.RegisterEvent;
|
||||
import com.l2jserver.gameserver.model.events.annotations.RegisterType;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.OnCreatureAttacked;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.OnCreatureKill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
|
||||
/**
|
||||
* Sin Eater AI.
|
||||
* @author St3eT.
|
||||
*/
|
||||
public final class SinEater extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int SIN_EATER = 12564;
|
||||
|
||||
private SinEater()
|
||||
{
|
||||
super(SinEater.class.getSimpleName(), "ai/individual");
|
||||
addSummonSpawnId(SIN_EATER);
|
||||
addSummonTalkId(SIN_EATER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("TALK") && (player != null) && (player.getSummon() != null))
|
||||
{
|
||||
if (getRandom(100) < 30)
|
||||
{
|
||||
final int random = getRandom(100);
|
||||
final L2Summon summon = player.getSummon();
|
||||
|
||||
if (random < 20)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.YAWWWWN_IT_S_SO_BORING_HERE_WE_SHOULD_GO_AND_FIND_SOME_ACTION);
|
||||
}
|
||||
else if (random < 40)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.HEY_IF_YOU_CONTINUE_TO_WASTE_TIME_YOU_WILL_NEVER_FINISH_YOUR_PENANCE);
|
||||
}
|
||||
else if (random < 60)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.I_KNOW_YOU_DON_T_LIKE_ME_THE_FEELING_IS_MUTUAL);
|
||||
}
|
||||
else if (random < 80)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.I_NEED_A_DRINK);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.OH_THIS_IS_DRAGGING_ON_TOO_LONG_AT_THIS_RATE_I_WON_T_MAKE_IT_HOME_BEFORE_THE_SEVEN_SEALS_ARE_BROKEN);
|
||||
}
|
||||
}
|
||||
startQuestTimer("TALK", 60000, null, player);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@RegisterEvent(EventType.ON_CREATURE_KILL)
|
||||
@RegisterType(ListenerRegisterType.NPC)
|
||||
@Id(SIN_EATER)
|
||||
public void onCreatureKill(OnCreatureKill event)
|
||||
{
|
||||
final int random = getRandom(100);
|
||||
final L2Summon summon = (L2Summon) event.getTarget();
|
||||
|
||||
if (random < 30)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.OH_THIS_IS_JUST_GREAT_WHAT_ARE_YOU_GOING_TO_DO_NOW);
|
||||
}
|
||||
else if (random < 70)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.YOU_INCONSIDERATE_MORON_CAN_T_YOU_EVEN_TAKE_CARE_OF_LITTLE_OLD_ME);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.OH_NO_THE_MAN_WHO_EATS_ONE_S_SINS_HAS_DIED_PENITENCE_IS_FURTHER_AWAY);
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterEvent(EventType.ON_CREATURE_ATTACKED)
|
||||
@RegisterType(ListenerRegisterType.NPC)
|
||||
@Id(SIN_EATER)
|
||||
public void onCreatureAttacked(OnCreatureAttacked event)
|
||||
{
|
||||
if (getRandom(100) < 30)
|
||||
{
|
||||
final int random = getRandom(100);
|
||||
final L2Summon summon = (L2Summon) event.getTarget();
|
||||
|
||||
if (random < 35)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.OH_THAT_SMARTS);
|
||||
}
|
||||
else if (random < 70)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.HEY_MASTER_PAY_ATTENTION_I_M_DYING_OVER_HERE);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.WHAT_HAVE_I_DONE_TO_DESERVE_THIS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSummonSpawn(L2Summon summon)
|
||||
{
|
||||
broadcastSummonSay(summon, getRandomBoolean() ? NpcStringId.HEY_IT_SEEMS_LIKE_YOU_NEED_MY_HELP_DOESN_T_IT : NpcStringId.ALMOST_GOT_IT_OUCH_STOP_DAMN_THESE_BLOODY_MANACLES);
|
||||
startQuestTimer("TALK", 60000, null, summon.getOwner());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSummonTalk(L2Summon summon)
|
||||
{
|
||||
if (getRandom(100) < 10)
|
||||
{
|
||||
final int random = getRandom(100);
|
||||
|
||||
if (random < 25)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.USING_A_SPECIAL_SKILL_HERE_COULD_TRIGGER_A_BLOODBATH);
|
||||
}
|
||||
else if (random < 50)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.HEY_WHAT_DO_YOU_EXPECT_OF_ME);
|
||||
}
|
||||
else if (random < 75)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.UGGGGGH_PUSH_IT_S_NOT_COMING_OUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.AH_I_MISSED_THE_MARK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcastSummonSay(L2Summon summon, NpcStringId npcstringId)
|
||||
{
|
||||
summon.broadcastPacket(new NpcSay(summon.getObjectId(), Say2.NPC_ALL, summon.getId(), npcstringId));
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SinEater();
|
||||
}
|
||||
}
|
95
trunk/dist/game/data/scripts/ai/individual/SinWardens.java
vendored
Normal file
95
trunk/dist/game/data/scripts/ai/individual/SinWardens.java
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
|
||||
/**
|
||||
* Manages Sin Wardens disappearing and chat.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class SinWardens extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] SIN_WARDEN_MINIONS =
|
||||
{
|
||||
22424,
|
||||
22425,
|
||||
22426,
|
||||
22427,
|
||||
22428,
|
||||
22429,
|
||||
22430,
|
||||
22432,
|
||||
22433,
|
||||
22434,
|
||||
22435,
|
||||
22436,
|
||||
22437,
|
||||
22438
|
||||
};
|
||||
|
||||
private final Map<Integer, Integer> killedMinionsCount = new FastMap<>();
|
||||
|
||||
private SinWardens()
|
||||
{
|
||||
super(SinWardens.class.getSimpleName(), "ai/individual");
|
||||
addKillId(SIN_WARDEN_MINIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.isMinion())
|
||||
{
|
||||
final L2MonsterInstance master = ((L2MonsterInstance) npc).getLeader();
|
||||
if ((master != null) && !master.isDead())
|
||||
{
|
||||
int killedCount = killedMinionsCount.containsKey(master.getObjectId()) ? killedMinionsCount.get(master.getObjectId()) : 0;
|
||||
killedCount++;
|
||||
|
||||
if ((killedCount) == 5)
|
||||
{
|
||||
master.broadcastPacket(new NpcSay(master.getObjectId(), Say2.NPC_ALL, master.getId(), NpcStringId.WE_MIGHT_NEED_NEW_SLAVES_I_LL_BE_BACK_SOON_SO_WAIT));
|
||||
master.doDie(killer);
|
||||
killedMinionsCount.remove(master.getObjectId());
|
||||
}
|
||||
else
|
||||
{
|
||||
killedMinionsCount.put(master.getObjectId(), killedCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SinWardens();
|
||||
}
|
||||
}
|
92
trunk/dist/game/data/scripts/ai/individual/TrainningSoldier.java
vendored
Normal file
92
trunk/dist/game/data/scripts/ai/individual/TrainningSoldier.java
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2QuestGuardInstance;
|
||||
|
||||
/**
|
||||
* Trainning Soldier AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class TrainningSoldier extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int SOLDIER = 33201; // Trainning Soldier
|
||||
private static final int DUMMY = 33023; // Trainning Dummy
|
||||
|
||||
private TrainningSoldier()
|
||||
{
|
||||
super(TrainningSoldier.class.getSimpleName(), "ai/individual");
|
||||
addSeeCreatureId(SOLDIER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("START_ATTACK") && (npc instanceof L2QuestGuardInstance))
|
||||
{
|
||||
final L2QuestGuardInstance soldier = (L2QuestGuardInstance) npc;
|
||||
|
||||
//@formatter:off
|
||||
final L2Npc dummy = (L2Npc) soldier.getKnownList().getKnownCharactersInRadius(150)
|
||||
.stream()
|
||||
.filter(L2Object::isNpc)
|
||||
.filter(obj -> (obj.getId() == DUMMY))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
//@formatter:on
|
||||
|
||||
if (dummy != null)
|
||||
{
|
||||
soldier.reduceCurrentHp(1, dummy, null); // TODO: Find better way for attack
|
||||
dummy.reduceCurrentHp(1, soldier, null);
|
||||
soldier.setCanStopAttackByTime(false);
|
||||
soldier.setCanReturnToSpawnPoint(false);
|
||||
soldier.setIsInvul(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("START_ATTACK", 250, npc, null);
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (creature.isPlayer() && (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK))
|
||||
{
|
||||
startQuestTimer("START_ATTACK", 250, npc, null);
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new TrainningSoldier();
|
||||
}
|
||||
}
|
571
trunk/dist/game/data/scripts/ai/individual/Valakas.java
vendored
Normal file
571
trunk/dist/game/data/scripts/ai/individual/Valakas.java
vendored
Normal file
@@ -0,0 +1,571 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.GeoData;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.enums.MountType;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2BossZone;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Valakas' AI.
|
||||
* @author Tryskell
|
||||
*/
|
||||
public final 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
|
||||
};
|
||||
|
||||
// Locations
|
||||
private static final Location TELEPORT_CUBE_LOCATIONS[] =
|
||||
{
|
||||
new Location(214880, -116144, -1644),
|
||||
new Location(213696, -116592, -1644),
|
||||
new Location(212112, -116688, -1644),
|
||||
new Location(211184, -115472, -1664),
|
||||
new Location(210336, -114592, -1644),
|
||||
new Location(211360, -113904, -1644),
|
||||
new Location(213152, -112352, -1644),
|
||||
new Location(214032, -113232, -1644),
|
||||
new Location(214752, -114592, -1644),
|
||||
new Location(209824, -115568, -1421),
|
||||
new Location(210528, -112192, -1403),
|
||||
new Location(213120, -111136, -1408),
|
||||
new Location(215184, -111504, -1392),
|
||||
new Location(215456, -117328, -1392),
|
||||
new Location(213200, -118160, -1424)
|
||||
};
|
||||
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);
|
||||
// Valakas status.
|
||||
private static final byte DORMANT = 0; // Valakas is spawned and no one has entered yet. Entry is unlocked.
|
||||
private static final byte WAITING = 1; // Valakas is spawned and someone has entered, triggering a 30 minute window for additional people to enter. Entry is unlocked.
|
||||
private static final byte FIGHTING = 2; // Valakas is engaged in battle, annihilating his foes. Entry is locked.
|
||||
private static final byte DEAD = 3; // Valakas has been killed. Entry is locked.
|
||||
// Misc
|
||||
private long _timeTracker = 0; // Time tracker for last attack on Valakas.
|
||||
private L2Playable _actualVictim; // Actual target of Valakas.
|
||||
private static L2BossZone ZONE;
|
||||
|
||||
private Valakas()
|
||||
{
|
||||
super(Valakas.class.getSimpleName(), "ai/individual");
|
||||
registerMobs(VALAKAS);
|
||||
|
||||
ZONE = GrandBossManager.getInstance().getZone(212852, -114842, -1632);
|
||||
final StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(VALAKAS);
|
||||
|
||||
if (status == DEAD)
|
||||
{
|
||||
// load the unlock date and time for valakas from DB
|
||||
long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
|
||||
if (temp > 0)
|
||||
{
|
||||
// The time has not yet expired. Mark Valakas as currently locked (dead).
|
||||
startQuestTimer("valakas_unlock", temp, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The time has expired while the server was offline. Spawn valakas in his cave as DORMANT.
|
||||
final L2Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 0, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
|
||||
GrandBossManager.getInstance().addBoss((L2GrandBossInstance) valakas);
|
||||
|
||||
valakas.setIsInvul(true);
|
||||
valakas.setRunning();
|
||||
|
||||
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final int loc_x = info.getInt("loc_x");
|
||||
final int loc_y = info.getInt("loc_y");
|
||||
final int loc_z = info.getInt("loc_z");
|
||||
final int heading = info.getInt("heading");
|
||||
final int hp = info.getInt("currentHP");
|
||||
final int mp = info.getInt("currentMP");
|
||||
|
||||
final L2Npc valakas = addSpawn(VALAKAS, loc_x, loc_y, loc_z, heading, false, 0);
|
||||
GrandBossManager.getInstance().addBoss((L2GrandBossInstance) valakas);
|
||||
|
||||
valakas.setCurrentHpMp(hp, mp);
|
||||
valakas.setRunning();
|
||||
|
||||
// Start timers.
|
||||
if (status == FIGHTING)
|
||||
{
|
||||
// stores current time for inactivity task.
|
||||
_timeTracker = System.currentTimeMillis();
|
||||
|
||||
startQuestTimer("regen_task", 60000, valakas, null, true);
|
||||
startQuestTimer("skill_task", 2000, valakas, null, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
if (event.equalsIgnoreCase("beginning"))
|
||||
{
|
||||
// Stores current time
|
||||
_timeTracker = System.currentTimeMillis();
|
||||
|
||||
// Teleport Valakas to his lair.
|
||||
npc.teleToLocation(VALAKAS_LAIR);
|
||||
|
||||
// Sound + socialAction.
|
||||
for (L2PcInstance plyr : ZONE.getPlayersInside())
|
||||
{
|
||||
plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
|
||||
plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
|
||||
}
|
||||
|
||||
// Launch the cinematic, and tasks (regen + skill).
|
||||
startQuestTimer("spawn_1", 1700, npc, null); // 1700
|
||||
startQuestTimer("spawn_2", 3200, npc, null); // 1500
|
||||
startQuestTimer("spawn_3", 6500, npc, null); // 3300
|
||||
startQuestTimer("spawn_4", 9400, npc, null); // 2900
|
||||
startQuestTimer("spawn_5", 12100, npc, null); // 2700
|
||||
startQuestTimer("spawn_6", 12430, npc, null); // 330
|
||||
startQuestTimer("spawn_7", 15430, npc, null); // 3000
|
||||
startQuestTimer("spawn_8", 16830, npc, null); // 1400
|
||||
startQuestTimer("spawn_9", 23530, npc, null); // 6700 - end of cinematic
|
||||
startQuestTimer("spawn_10", 26000, npc, null); // 2500 - AI + unlock
|
||||
}
|
||||
// Regeneration && inactivity task
|
||||
else if (event.equalsIgnoreCase("regen_task"))
|
||||
{
|
||||
// Inactivity task - 15min
|
||||
if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Verify if "Valakas Regeneration" skill is active.
|
||||
final BuffInfo info = npc.getEffectList().getBuffInfoBySkillId(VALAKAS_REGENERATION);
|
||||
final int lvl = info != null ? info.getSkill().getLevel() : 0;
|
||||
|
||||
// Current HPs are inferior to 25% ; apply lvl 4 of regen skill.
|
||||
if ((npc.getCurrentHp() < (npc.getMaxHp() / 4)) && (lvl != 4))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 4));
|
||||
}
|
||||
// Current HPs are inferior to 50% ; apply lvl 3 of regen skill.
|
||||
else if ((npc.getCurrentHp() < ((npc.getMaxHp() * 2) / 4.0)) && (lvl != 3))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 3));
|
||||
}
|
||||
// Current HPs are inferior to 75% ; apply lvl 2 of regen skill.
|
||||
else if ((npc.getCurrentHp() < ((npc.getMaxHp() * 3) / 4.0)) && (lvl != 2))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 2));
|
||||
}
|
||||
// Apply lvl 1.
|
||||
else if (lvl != 1)
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
|
||||
}
|
||||
}
|
||||
// Spawn cinematic, regen_task and choose of skill.
|
||||
else if (event.equalsIgnoreCase("spawn_1"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1800, 180, -1, 1500, 15000, 10000, 0, 0, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_2"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1300, 180, -5, 3000, 15000, 10000, 0, -5, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_3"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 500, 180, -8, 600, 15000, 10000, 0, 60, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_4"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 800, 180, -8, 2700, 15000, 10000, 0, 30, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_5"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 200, 250, 70, 0, 15000, 10000, 30, 80, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_6"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1100, 250, 70, 2500, 15000, 10000, 30, 80, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_7"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 700, 150, 30, 0, 15000, 10000, -10, 60, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_8"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1200, 150, 20, 2900, 15000, 10000, -10, 30, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_9"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 750, 170, -10, 3400, 15000, 4000, 10, -15, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_10"))
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(VALAKAS, FIGHTING);
|
||||
npc.setIsInvul(false);
|
||||
|
||||
startQuestTimer("regen_task", 60000, npc, null, true);
|
||||
startQuestTimer("skill_task", 2000, npc, null, true);
|
||||
}
|
||||
// Death cinematic, spawn of Teleport Cubes.
|
||||
else if (event.equalsIgnoreCase("die_1"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 2000, 130, -1, 0, 15000, 10000, 0, 0, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_2"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1100, 210, -5, 3000, 15000, 10000, -13, 0, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_3"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1300, 200, -8, 3000, 15000, 10000, 0, 15, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_4"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1000, 190, 0, 500, 15000, 10000, 0, 10, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_5"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1700, 120, 0, 2500, 15000, 10000, 12, 40, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_6"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1700, 20, 0, 700, 15000, 10000, 10, 10, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_7"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1700, 10, 0, 1000, 15000, 10000, 20, 70, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_8"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1700, 10, 0, 300, 15000, 250, 20, -20, 1, 1, 0));
|
||||
|
||||
for (Location loc : TELEPORT_CUBE_LOCATIONS)
|
||||
{
|
||||
addSpawn(31759, loc, false, 900000);
|
||||
}
|
||||
|
||||
startQuestTimer("remove_players", 900000, null, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("skill_task"))
|
||||
{
|
||||
callSkillAI(npc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (event.equalsIgnoreCase("valakas_unlock"))
|
||||
{
|
||||
final L2Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 32768, false, 0);
|
||||
GrandBossManager.getInstance().addBoss((L2GrandBossInstance) valakas);
|
||||
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("remove_players"))
|
||||
{
|
||||
ZONE.oustAllPlayers();
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (!ZONE.isInsideZone(attacker))
|
||||
{
|
||||
attacker.doDie(attacker);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (npc.isInvul())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (GrandBossManager.getInstance().getBossStatus(VALAKAS) != FIGHTING)
|
||||
{
|
||||
attacker.teleToLocation(ATTACKER_REMOVE);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Debuff strider-mounted players.
|
||||
if (attacker.getMountType() == MountType.STRIDER)
|
||||
{
|
||||
final Skill skill = SkillData.getInstance().getSkill(4258, 1);
|
||||
if (!attacker.isAffectedBySkill(4258))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(skill);
|
||||
}
|
||||
}
|
||||
_timeTracker = System.currentTimeMillis();
|
||||
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
// Cancel skill_task and regen_task.
|
||||
cancelQuestTimer("regen_task", npc, null);
|
||||
cancelQuestTimer("skill_task", npc, null);
|
||||
|
||||
// Launch death animation.
|
||||
ZONE.broadcastPacket(new PlaySound(1, "B03_D", 0, 0, 0, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1200, 20, -10, 0, 10000, 13000, 0, 0, 0, 0, 0));
|
||||
|
||||
startQuestTimer("die_1", 300, npc, null); // 300
|
||||
startQuestTimer("die_2", 600, npc, null); // 300
|
||||
startQuestTimer("die_3", 3800, npc, null); // 3200
|
||||
startQuestTimer("die_4", 8200, npc, null); // 4400
|
||||
startQuestTimer("die_5", 8700, npc, null); // 500
|
||||
startQuestTimer("die_6", 13300, npc, null); // 4600
|
||||
startQuestTimer("die_7", 14000, npc, null); // 700
|
||||
startQuestTimer("die_8", 16500, npc, null); // 2500
|
||||
|
||||
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;
|
||||
|
||||
startQuestTimer("valakas_unlock", respawnTime, null, null);
|
||||
// also save the respawn time so that the info is maintained past reboots
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
|
||||
info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
|
||||
GrandBossManager.getInstance().setStatsSet(VALAKAS, info);
|
||||
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private void callSkillAI(L2Npc 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.getKnownList().knowsObject(_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)
|
||||
{
|
||||
int x = npc.getX();
|
||||
int y = npc.getY();
|
||||
int z = npc.getZ();
|
||||
|
||||
int posX = x + getRandom(-1400, 1400);
|
||||
int posY = y + getRandom(-1400, 1400);
|
||||
|
||||
if (GeoData.getInstance().canMove(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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a random skill.<br>
|
||||
* Valakas will mostly use utility skills. If Valakas feels surrounded, he will use AoE skills.<br>
|
||||
* Lower than 50% HPs, he will begin to use Meteor skill.
|
||||
* @param npc valakas
|
||||
* @return a skill holder
|
||||
*/
|
||||
private SkillHolder getRandomSkill(L2Npc 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 (Util.getPlayersCountInRadius(1200, npc, false, false) >= 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 L2Playable from the zone, deads targets aren't included.
|
||||
* @param npc
|
||||
* @return a random L2Playable.
|
||||
*/
|
||||
private L2Playable getRandomTarget(L2Npc npc)
|
||||
{
|
||||
List<L2Playable> result = new ArrayList<>();
|
||||
|
||||
for (L2Character obj : npc.getKnownList().getKnownCharacters())
|
||||
{
|
||||
if ((obj == null) || obj.isPet())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (!obj.isDead() && obj.isPlayable())
|
||||
{
|
||||
result.add((L2Playable) obj);
|
||||
}
|
||||
}
|
||||
|
||||
return (result.isEmpty()) ? null : result.get(getRandom(result.size()));
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Valakas();
|
||||
}
|
||||
}
|
3
trunk/dist/game/data/scripts/ai/individual/Venom/29055.html
vendored
Normal file
3
trunk/dist/game/data/scripts/ai/individual/Venom/29055.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Teleportation Cubic:<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Venom">Leave the prison.</a><br>
|
||||
</body></html>
|
3
trunk/dist/game/data/scripts/ai/individual/Venom/35506-02.html
vendored
Normal file
3
trunk/dist/game/data/scripts/ai/individual/Venom/35506-02.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>
|
||||
When attacking a castle, its defenses can easily be paralyzed.... What if that demon escapes?
|
||||
</body></html>
|
4
trunk/dist/game/data/scripts/ai/individual/Venom/35506.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/individual/Venom/35506.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>
|
||||
The roar of that scary demon in the dungeon always makes me want to run away! I know the dungeon is well-built, but if its defenses are broken, it could collapse!<br><p>
|
||||
<a action="bypass -h npc_%objectId%_Quest Venom">Teleport to the dungeon</a>
|
||||
</body></html>
|
414
trunk/dist/game/data/scripts/ai/individual/Venom/Venom.java
vendored
Normal file
414
trunk/dist/game/data/scripts/ai/individual/Venom/Venom.java
vendored
Normal file
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J DataPack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual.Venom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jserver.gameserver.instancemanager.GlobalVariablesManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.TeleportWhereType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeFinish;
|
||||
import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeStart;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.ZoneId;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Venom AI on Rune Castle.
|
||||
* @author nonom, MELERIX
|
||||
*/
|
||||
public final class Venom extends AbstractNpcAI
|
||||
{
|
||||
private static final int CASTLE = 8; // Rune
|
||||
|
||||
private static final int VENOM = 29054;
|
||||
private static final int TELEPORT_CUBE = 29055;
|
||||
private static final int DUNGEON_KEEPER = 35506;
|
||||
|
||||
private static final byte ALIVE = 0;
|
||||
private static final byte DEAD = 1;
|
||||
|
||||
private static final int HOURS_BEFORE = 24;
|
||||
|
||||
private static final Location[] TARGET_TELEPORTS =
|
||||
{
|
||||
new Location(12860, -49158, 976),
|
||||
new Location(14878, -51339, 1024),
|
||||
new Location(15674, -49970, 864),
|
||||
new Location(15696, -48326, 864),
|
||||
new Location(14873, -46956, 1024),
|
||||
new Location(12157, -49135, -1088),
|
||||
new Location(12875, -46392, -288),
|
||||
new Location(14087, -46706, -288),
|
||||
new Location(14086, -51593, -288),
|
||||
new Location(12864, -51898, -288),
|
||||
new Location(15538, -49153, -1056),
|
||||
new Location(17001, -49149, -1064)
|
||||
};
|
||||
|
||||
private static final Location TRHONE = new Location(11025, -49152, -537);
|
||||
private static final Location DUNGEON = new Location(11882, -49216, -3008);
|
||||
private static final Location TELEPORT = new Location(12589, -49044, -3008);
|
||||
private static final Location CUBE = new Location(12047, -49211, -3009);
|
||||
|
||||
private static final SkillHolder VENOM_STRIKE = new SkillHolder(4993, 1);
|
||||
private static final SkillHolder SONIC_STORM = new SkillHolder(4994, 1);
|
||||
private static final SkillHolder VENOM_TELEPORT = new SkillHolder(4995, 1);
|
||||
private static final SkillHolder RANGE_TELEPORT = new SkillHolder(4996, 1);
|
||||
|
||||
private L2Npc _venom;
|
||||
private L2Npc _massymore;
|
||||
|
||||
private Location _loc;
|
||||
|
||||
private boolean _aggroMode = false;
|
||||
private boolean _prisonIsOpen = false;
|
||||
|
||||
// @formatter:off
|
||||
private static final int[] TARGET_TELEPORTS_OFFSET =
|
||||
{
|
||||
650, 100, 100, 100, 100, 650, 200, 200, 200, 200, 200, 650
|
||||
};
|
||||
// @formatter:on
|
||||
|
||||
private static List<L2PcInstance> _targets = new ArrayList<>();
|
||||
|
||||
private Venom()
|
||||
{
|
||||
super(Venom.class.getSimpleName(), "ai/individual");
|
||||
addStartNpc(DUNGEON_KEEPER, TELEPORT_CUBE);
|
||||
addFirstTalkId(DUNGEON_KEEPER, TELEPORT_CUBE);
|
||||
addTalkId(DUNGEON_KEEPER, TELEPORT_CUBE);
|
||||
addSpawnId(VENOM, DUNGEON_KEEPER);
|
||||
addSpellFinishedId(VENOM);
|
||||
addAttackId(VENOM);
|
||||
addKillId(VENOM);
|
||||
addAggroRangeEnterId(VENOM);
|
||||
setCastleSiegeStartId(this::onSiegeStart, CASTLE);
|
||||
setCastleSiegeFinishId(this::onSiegeFinish, CASTLE);
|
||||
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
final long startSiegeDate = CastleManager.getInstance().getCastleById(CASTLE).getSiegeDate().getTimeInMillis();
|
||||
final long openingDungeonDate = startSiegeDate - (HOURS_BEFORE * 360000);
|
||||
if ((currentTime > openingDungeonDate) && (currentTime < startSiegeDate))
|
||||
{
|
||||
_prisonIsOpen = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance talker)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case TELEPORT_CUBE:
|
||||
{
|
||||
talker.teleToLocation(TeleportWhereType.TOWN);
|
||||
break;
|
||||
}
|
||||
case DUNGEON_KEEPER:
|
||||
{
|
||||
if (_prisonIsOpen)
|
||||
{
|
||||
talker.teleToLocation(TELEPORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "35506-02.html";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onTalk(npc, talker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "tower_check":
|
||||
if (CastleManager.getInstance().getCastleById(CASTLE).getSiege().getControlTowerCount() <= 1)
|
||||
{
|
||||
changeLocation(MoveTo.THRONE);
|
||||
broadcastNpcSay(_massymore, Say2.NPC_SHOUT, NpcStringId.OH_NO_THE_DEFENSES_HAVE_FAILED_IT_IS_TOO_DANGEROUS_TO_REMAIN_INSIDE_THE_CASTLE_FLEE_EVERY_MAN_FOR_HIMSELF);
|
||||
cancelQuestTimer("tower_check", npc, null);
|
||||
startQuestTimer("raid_check", 10000, npc, null, true);
|
||||
}
|
||||
break;
|
||||
case "raid_check":
|
||||
if (!npc.isInsideZone(ZoneId.SIEGE) && !npc.isTeleporting())
|
||||
{
|
||||
npc.teleToLocation(_loc);
|
||||
}
|
||||
break;
|
||||
case "cube_despawn":
|
||||
if (npc != null)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if (isSummon)
|
||||
{
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
if (_aggroMode && (_targets.size() < 10) && (getRandom(3) < 1) && !player.isDead())
|
||||
{
|
||||
_targets.add(player);
|
||||
}
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
public void onSiegeStart(OnCastleSiegeStart event)
|
||||
{
|
||||
_aggroMode = true;
|
||||
_prisonIsOpen = false;
|
||||
if ((_venom != null) && !_venom.isDead())
|
||||
{
|
||||
_venom.setCurrentHp(_venom.getMaxHp());
|
||||
_venom.setCurrentMp(_venom.getMaxMp());
|
||||
_venom.enableSkill(VENOM_TELEPORT.getSkill());
|
||||
_venom.enableSkill(RANGE_TELEPORT.getSkill());
|
||||
startQuestTimer("tower_check", 30000, _venom, null, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void onSiegeFinish(OnCastleSiegeFinish event)
|
||||
{
|
||||
_aggroMode = false;
|
||||
if ((_venom != null) && !_venom.isDead())
|
||||
{
|
||||
changeLocation(MoveTo.PRISON);
|
||||
_venom.disableSkill(VENOM_TELEPORT.getSkill(), -1);
|
||||
_venom.disableSkill(RANGE_TELEPORT.getSkill(), -1);
|
||||
}
|
||||
updateStatus(ALIVE);
|
||||
cancelQuestTimer("tower_check", _venom, null);
|
||||
cancelQuestTimer("raid_check", _venom, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
switch (skill.getId())
|
||||
{
|
||||
case 4222:
|
||||
npc.teleToLocation(_loc);
|
||||
break;
|
||||
case 4995:
|
||||
teleportTarget(player);
|
||||
((L2Attackable) npc).stopHating(player);
|
||||
break;
|
||||
case 4996:
|
||||
teleportTarget(player);
|
||||
((L2Attackable) npc).stopHating(player);
|
||||
if ((_targets != null) && (_targets.size() > 0))
|
||||
{
|
||||
for (L2PcInstance target : _targets)
|
||||
{
|
||||
final long x = player.getX() - target.getX();
|
||||
final long y = player.getY() - target.getY();
|
||||
final long z = player.getZ() - target.getZ();
|
||||
final long range = 250;
|
||||
if (((x * x) + (y * y) + (z * z)) <= (range * range))
|
||||
{
|
||||
teleportTarget(target);
|
||||
((L2Attackable) npc).stopHating(target);
|
||||
}
|
||||
}
|
||||
_targets.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSpawn(L2Npc npc)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case DUNGEON_KEEPER:
|
||||
{
|
||||
_massymore = npc;
|
||||
break;
|
||||
}
|
||||
case VENOM:
|
||||
{
|
||||
_venom = npc;
|
||||
|
||||
_loc = _venom.getLocation();
|
||||
_venom.disableSkill(VENOM_TELEPORT.getSkill(), -1);
|
||||
_venom.disableSkill(RANGE_TELEPORT.getSkill(), -1);
|
||||
_venom.doRevive();
|
||||
broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.WHO_DARES_TO_COVET_THE_THRONE_OF_OUR_CASTLE_LEAVE_IMMEDIATELY_OR_YOU_WILL_PAY_THE_PRICE_OF_YOUR_AUDACITY_WITH_YOUR_VERY_OWN_BLOOD);
|
||||
((L2Attackable) _venom).setCanReturnToSpawnPoint(false);
|
||||
if (checkStatus() == DEAD)
|
||||
{
|
||||
_venom.deleteMe();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checkStatus() == DEAD)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.doRevive();
|
||||
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final double distance = npc.calculateDistance(attacker, false, false);
|
||||
if (_aggroMode && (getRandom(100) < 25))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(VENOM_TELEPORT.getSkill());
|
||||
}
|
||||
else if (_aggroMode && (npc.getCurrentHp() < (npc.getMaxHp() / 3)) && (getRandom(100) < 25) && !npc.isCastingNow())
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(RANGE_TELEPORT.getSkill());
|
||||
}
|
||||
else if ((distance > 300) && (getRandom(100) < 10) && !npc.isCastingNow())
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(VENOM_STRIKE.getSkill());
|
||||
}
|
||||
else if ((getRandom(100) < 10) && !npc.isCastingNow())
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SONIC_STORM.getSkill());
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
updateStatus(DEAD);
|
||||
broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.IT_S_NOT_OVER_YET_IT_WON_T_BE_OVER_LIKE_THIS_NEVER);
|
||||
if (!CastleManager.getInstance().getCastleById(CASTLE).getSiege().isInProgress())
|
||||
{
|
||||
L2Npc cube = addSpawn(TELEPORT_CUBE, CUBE, false, 0);
|
||||
startQuestTimer("cube_despawn", 120000, cube, null);
|
||||
}
|
||||
cancelQuestTimer("raid_check", npc, null);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alters the Venom location
|
||||
* @param loc enum
|
||||
*/
|
||||
private void changeLocation(MoveTo loc)
|
||||
{
|
||||
switch (loc)
|
||||
{
|
||||
case THRONE:
|
||||
_venom.teleToLocation(TRHONE, false);
|
||||
break;
|
||||
case PRISON:
|
||||
if ((_venom == null) || _venom.isDead() || _venom.isDecayed())
|
||||
{
|
||||
_venom = addSpawn(VENOM, DUNGEON, false, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_venom.teleToLocation(DUNGEON, false);
|
||||
}
|
||||
cancelQuestTimer("raid_check", _venom, null);
|
||||
cancelQuestTimer("tower_check", _venom, null);
|
||||
break;
|
||||
}
|
||||
_loc.setLocation(_venom.getLocation());
|
||||
}
|
||||
|
||||
private void teleportTarget(L2PcInstance player)
|
||||
{
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
final int rnd = getRandom(11);
|
||||
player.teleToLocation(TARGET_TELEPORTS[rnd], TARGET_TELEPORTS_OFFSET[rnd]);
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Venom is Alive or Dead
|
||||
* @return status
|
||||
*/
|
||||
private int checkStatus()
|
||||
{
|
||||
int checkStatus = ALIVE;
|
||||
if (GlobalVariablesManager.getInstance().hasVariable("VenomStatus"))
|
||||
{
|
||||
checkStatus = GlobalVariablesManager.getInstance().getInt("VenomStatus");
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalVariablesManager.getInstance().set("VenomStatus", 0);
|
||||
}
|
||||
return checkStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Venom status
|
||||
* @param status the new status. 0 = ALIVE, 1 = DEAD.
|
||||
*/
|
||||
private void updateStatus(int status)
|
||||
{
|
||||
GlobalVariablesManager.getInstance().set("VenomStatus", Integer.toString(status));
|
||||
}
|
||||
|
||||
private enum MoveTo
|
||||
{
|
||||
THRONE,
|
||||
PRISON
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Venom();
|
||||
}
|
||||
}
|
13
trunk/dist/game/data/scripts/ai/individual/documentation.txt
vendored
Normal file
13
trunk/dist/game/data/scripts/ai/individual/documentation.txt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Individual AI:
|
||||
This folder contains AI scripts for single npc templates (one npc ID, but possibly many instances).
|
||||
That is, if a particular NPC/mob has a unique AI or something slightly different from all other generic NPCs,
|
||||
an individual AI script can be created for all occurences of that npc/mob. Such individual scripts ought to be here.
|
||||
|
||||
Individual AI scripts can be subclassed. In other words, an individual may inherit from a group or other individual.
|
||||
For example, one group template might define mobs that cast spells. A particular mob may cast spells but may also
|
||||
talk whenever it gets attacked. In that case, instead of writing all the AI for attacking and casting spells, it may
|
||||
inherit from a group template that defines AI for ALL mobs that cast spells, then add behaviours for talking onAttack.
|
||||
|
||||
"NPC registrations" refers to the addition of NPCs in the various events of the scripts, such as onAttack, onKill, etc
|
||||
Those are done by using keywords such as "addKillId" etc. For more details on registrations, see
|
||||
"scripts/quests/documentation.txt"
|
Reference in New Issue
Block a user