Organized boss scripts to separate folder.
This commit is contained in:
@@ -33,7 +33,7 @@ import ai.AbstractNpcAI;
|
||||
* Lindvior Scene AI.
|
||||
* @author nonom
|
||||
*/
|
||||
public final class Lindvior extends AbstractNpcAI
|
||||
public final class LindviorScene extends AbstractNpcAI
|
||||
{
|
||||
private static final int LINDVIOR_CAMERA = 18669;
|
||||
private static final int TOMARIS = 32552;
|
||||
@@ -51,7 +51,7 @@ public final class Lindvior extends AbstractNpcAI
|
||||
private L2Npc _tomaris = null;
|
||||
private L2Npc _artius = null;
|
||||
|
||||
public Lindvior()
|
||||
public LindviorScene()
|
||||
{
|
||||
scheduleNextLindviorVisit();
|
||||
}
|
||||
@@ -135,6 +135,6 @@ public final class Lindvior extends AbstractNpcAI
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Lindvior();
|
||||
new LindviorScene();
|
||||
}
|
||||
}
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.MonasteryOfSilence;
|
||||
package ai.bosses.Anais;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -159,10 +159,6 @@ public final class Anais extends AbstractNpcAI
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.l2jmobius.gameserver.model.quest.Quest#onSpawn(com.l2jmobius.gameserver.model.actor.L2Npc)
|
||||
*/
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.LairOfAntharas.Antharas;
|
||||
package ai.bosses.Antharas;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.TowerOfInsolence.Baium;
|
||||
package ai.bosses.Baium;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
333
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Baylor/BaylorWarzone.java
vendored
Normal file
333
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Baylor/BaylorWarzone.java
vendored
Normal file
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.bosses.Baylor;
|
||||
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDeath;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureSee;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Baylor Warzone instance zone.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class BaylorWarzone extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int BAYLOR = 29213;
|
||||
private static final int PRISON_GUARD = 29104;
|
||||
private static final int ENTRANCE_PORTAL = 33523;
|
||||
private static final int INVISIBLE_NPC_1 = 29106;
|
||||
private static final int INVISIBLE_NPC_2 = 29108;
|
||||
private static final int INVISIBLE_NPC_3 = 29109;
|
||||
// Skills
|
||||
private static final SkillHolder INVIS_NPC_SOCIAL_SKILL = new SkillHolder(5401, 1);
|
||||
private static final SkillHolder BAYLOR_SOCIAL_SKILL = new SkillHolder(5402, 1);
|
||||
// Locations
|
||||
private static final Location BATTLE_PORT = new Location(153567, 143319, -12736);
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 166;
|
||||
|
||||
public BaylorWarzone()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(ENTRANCE_PORTAL);
|
||||
addTalkId(ENTRANCE_PORTAL);
|
||||
addInstanceCreatedId(TEMPLATE_ID);
|
||||
addSpawnId(INVISIBLE_NPC_1);
|
||||
addSpellFinishedId(INVISIBLE_NPC_1);
|
||||
setCreatureSeeId(this::onCreatureSee, INVISIBLE_NPC_1);
|
||||
setCreatureKillId(this::onBossKill, BAYLOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("enterInstance"))
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (isInInstance(world))
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "START_SCENE_01":
|
||||
{
|
||||
specialCamera(world, npc, 2300, 0, 90, 2000, 3000, 2500, 0, 180, 1, 0, 1);
|
||||
playSound(world, "BS06_A");
|
||||
getTimers().addTimer("START_SCENE_02", 2000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_02":
|
||||
{
|
||||
specialCamera(world, npc, 10, 180, 0, 17000, 3000, 30000, 0, 20, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_03", 17000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_03":
|
||||
{
|
||||
specialCamera(world, npc, 15, 15, 0, 6000, 3000, 9000, 0, 10, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_04", 6000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_04":
|
||||
{
|
||||
specialCamera(world, npc, 5, 200, 0, 6000, 3000, 9000, 0, 10, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_05", 6000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_05":
|
||||
{
|
||||
specialCamera(world, npc, 5, 70, 0, 4000, 3000, 9000, 0, 10, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_06", 4000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_06":
|
||||
{
|
||||
specialCamera(world, npc, 200, 60, 0, 1000, 3000, 4000, 0, 6, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_07", 1000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_07":
|
||||
{
|
||||
specialCamera(world, npc, 500, 260, 0, 8000, 3000, 9000, 0, 10, 1, 0, 0);
|
||||
getTimers().addTimer("SPAWN_GUARD_1", 100, e -> world.spawnGroup("PRISON_GUARD_GROUP_1"));
|
||||
getTimers().addTimer("SPAWN_GUARD_2", 2100, e -> world.spawnGroup("PRISON_GUARD_GROUP_2"));
|
||||
getTimers().addTimer("SPAWN_GUARD_3", 4100, e -> world.spawnGroup("PRISON_GUARD_GROUP_3"));
|
||||
getTimers().addTimer("SPAWN_GUARD_4", 6100, e -> world.spawnGroup("PRISON_GUARD_GROUP_4"));
|
||||
getTimers().addTimer("START_SCENE_08", 8000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_08":
|
||||
{
|
||||
specialCamera(world, npc, 850, 260, 70, 2000, 3000, 5000, 0, 0, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_09", 2000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_09":
|
||||
{
|
||||
specialCamera(world, npc, 0, 260, 70, 1800, 3000, 2000, 0, 0, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_10", 1800, npc, null);
|
||||
getTimers().addTimer("START_SCENE_12", 1000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_10":
|
||||
{
|
||||
specialCamera(world, npc, 200, 20, 0, 100, 3000, 5000, 160, 15, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_11", 2000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_11":
|
||||
{
|
||||
specialCamera(world, npc, 100, 20, 0, 4000, 3000, 7000, 160, 10, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_14", 6500, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_12":
|
||||
{
|
||||
int count = 0;
|
||||
for (L2Npc baylor : world.spawnGroup("BAYLOR"))
|
||||
{
|
||||
baylor.getVariables().set("is_after_you", count);
|
||||
baylor.disableCoreAI(true);
|
||||
baylor.setRandomAnimation(false);
|
||||
baylor.setRandomWalking(false);
|
||||
((L2Attackable) baylor).setCanReturnToSpawnPoint(false);
|
||||
count++;
|
||||
}
|
||||
getTimers().addTimer("START_SCENE_13", 300, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_13":
|
||||
{
|
||||
world.getAliveNpcs(BAYLOR).forEach(baylor ->
|
||||
{
|
||||
getTimers().addTimer("BAYLOR_SOCIAL_SKILL", (baylor.getVariables().getInt("is_after_you") == 0 ? 14 : 16) * 1000, baylor, null);
|
||||
broadcastSocialAction(baylor, 1);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_14":
|
||||
{
|
||||
world.getAliveNpcs(INVISIBLE_NPC_3).forEach(invisNpc ->
|
||||
{
|
||||
specialCamera(world, invisNpc, 45, 237, 0, 0, 3000, 5000, 0, 27, 1, 0, 1);
|
||||
getTimers().addTimer("START_SCENE_15", 1500, invisNpc, null);
|
||||
});
|
||||
|
||||
world.getAliveNpcs(PRISON_GUARD).forEach(guard ->
|
||||
{
|
||||
final int random = getRandom(100);
|
||||
if (random >= 20)
|
||||
{
|
||||
broadcastSocialAction(guard, 2);
|
||||
}
|
||||
else if (random >= 40)
|
||||
{
|
||||
getTimers().addTimer("SOCIAL_ACTION", 250, e -> broadcastSocialAction(guard, 2));
|
||||
}
|
||||
else if (random >= 60)
|
||||
{
|
||||
getTimers().addTimer("SOCIAL_ACTION", 500, e -> broadcastSocialAction(guard, 2));
|
||||
}
|
||||
else if (random >= 80)
|
||||
{
|
||||
getTimers().addTimer("SOCIAL_ACTION", 700, e -> broadcastSocialAction(guard, 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
getTimers().addTimer("SOCIAL_ACTION", 800, e -> broadcastSocialAction(guard, 2));
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_15":
|
||||
{
|
||||
world.getAliveNpcs(INVISIBLE_NPC_3).forEach(invisNpc ->
|
||||
{
|
||||
specialCamera(world, invisNpc, 500, 212, 0, 1500, 3000, 3000, 357, 15, 1, 0, 1);
|
||||
getTimers().addTimer("START_SCENE_16", 1500, invisNpc, null);
|
||||
});
|
||||
|
||||
getTimers().addTimer("NPC_DESPAWN", 3000, e -> npc.deleteMe());
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_16":
|
||||
{
|
||||
specialCamera(world, npc, 500, 212, 0, 1000, 3000, 3000, 357, 40, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_17", 1000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_17":
|
||||
{
|
||||
specialCamera(world, npc, 900, 212, 0, 1000, 3000, 3000, 357, 10, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_18", 2000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_18":
|
||||
{
|
||||
specialCamera(world, npc, 500, 212, 0, 3000, 3000, 15000, 357, 20, 1, 0, 0);
|
||||
getTimers().addTimer("START_SCENE_19", 7000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_SCENE_19":
|
||||
{
|
||||
specialCamera(world, npc, 700, 212, 30, 1000, 7000, 2500, 357, 0, 1, 0, 0);
|
||||
break;
|
||||
}
|
||||
case "BAYLOR_SOCIAL_SKILL":
|
||||
{
|
||||
npc.doCast(BAYLOR_SOCIAL_SKILL.getSkill());
|
||||
npc.disableCoreAI(false);
|
||||
world.getAliveNpcs(INVISIBLE_NPC_1).forEach(invisNpc -> getTimers().addTimer("INVIS_NPC_SOCIAL_SKILL", 1300, invisNpc, null));
|
||||
break;
|
||||
}
|
||||
case "INVIS_NPC_SOCIAL_SKILL":
|
||||
{
|
||||
npc.doCast(INVIS_NPC_SOCIAL_SKILL.getSkill());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (isInInstance(world))
|
||||
{
|
||||
world.getAliveNpcs(INVISIBLE_NPC_1, INVISIBLE_NPC_2, INVISIBLE_NPC_3).forEach(L2Npc::deleteMe);
|
||||
world.getAliveNpcs(PRISON_GUARD).forEach(guard -> guard.doDie(null));
|
||||
npc.deleteMe();
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceCreated(Instance instance, L2PcInstance player)
|
||||
{
|
||||
getTimers().addTimer("BATTLE_PORT", 3000, e ->
|
||||
{
|
||||
instance.getPlayers().forEach(p -> p.teleToLocation(BATTLE_PORT));
|
||||
instance.getDoors().forEach(L2DoorInstance::closeMe);
|
||||
});
|
||||
}
|
||||
|
||||
public void onBossKill(OnCreatureDeath event)
|
||||
{
|
||||
final L2Npc npc = (L2Npc) event.getTarget();
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
|
||||
if (isInInstance(world))
|
||||
{
|
||||
if (world.getAliveNpcs(BAYLOR).isEmpty())
|
||||
{
|
||||
world.finishInstance();
|
||||
}
|
||||
else
|
||||
{
|
||||
world.setReenterTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onCreatureSee(OnCreatureSee event)
|
||||
{
|
||||
final L2Character creature = event.getSeen();
|
||||
final L2Npc npc = (L2Npc) event.getSeer();
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
|
||||
if (isInInstance(world) && creature.isPlayer() && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
getTimers().addTimer("START_SCENE_01", 5000, npc, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getId() == INVISIBLE_NPC_1)
|
||||
{
|
||||
npc.initSeenCreatures();
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new BaylorWarzone();
|
||||
}
|
||||
}
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Baylor/condNoParty.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Baylor/condNoParty.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Crystal Prison Entrance Portal:<br>
|
||||
You must be in a party to enter.
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Baylor/condNoPartyLeader.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Baylor/condNoPartyLeader.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Crystal Prison Entrance Portal:<br>
|
||||
The leader of the party should try to enter.
|
||||
</body></html>
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.CrumaTower;
|
||||
package ai.bosses.Core;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.FrostLake.FreyasSteward;
|
||||
package ai.bosses.Freya.FreyasSteward;
|
||||
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
183
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Freya/IceQueensCastle/IceQueensCastle.java
vendored
Normal file
183
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Freya/IceQueensCastle/IceQueensCastle.java
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.bosses.Freya.IceQueensCastle;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.enums.Movie;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
import quests.Q10285_MeetingSirra.Q10285_MeetingSirra;
|
||||
|
||||
/**
|
||||
* Ice Queen's Castle instance zone.
|
||||
* @author Adry_85
|
||||
*/
|
||||
public final class IceQueensCastle extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int FREYA = 18847;
|
||||
private static final int BATTALION_LEADER = 18848;
|
||||
private static final int LEGIONNAIRE = 18849;
|
||||
private static final int MERCENARY_ARCHER = 18926;
|
||||
private static final int ARCHERY_KNIGHT = 22767;
|
||||
private static final int JINIA = 32781;
|
||||
// Locations
|
||||
private static final Location FREYA_LOC = new Location(114730, -114805, -11200, 50);
|
||||
// Skill
|
||||
private static SkillHolder ETHERNAL_BLIZZARD = new SkillHolder(6276, 1);
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 137;
|
||||
|
||||
public IceQueensCastle()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(JINIA);
|
||||
addTalkId(JINIA);
|
||||
addSeeCreatureId(BATTALION_LEADER, LEGIONNAIRE, MERCENARY_ARCHER);
|
||||
addSpawnId(FREYA);
|
||||
addSpellFinishedId(FREYA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "ATTACK_KNIGHT":
|
||||
{
|
||||
L2World.getInstance().forEachVisibleObject(npc, L2Npc.class, mob ->
|
||||
{
|
||||
if ((mob.getId() == ARCHERY_KNIGHT) && !mob.isDead() && !mob.isDecayed())
|
||||
{
|
||||
npc.setIsRunning(true);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, mob);
|
||||
((L2Attackable) npc).addDamageHate(mob, 0, 999999);
|
||||
}
|
||||
});
|
||||
startQuestTimer("ATTACK_KNIGHT", 3000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "TIMER_MOVING":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, FREYA_LOC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TIMER_BLIZZARD":
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.I_CAN_NO_LONGER_STAND_BY);
|
||||
npc.stopMove(null);
|
||||
npc.setTarget(player);
|
||||
npc.doCast(ETHERNAL_BLIZZARD.getSkill());
|
||||
break;
|
||||
}
|
||||
case "TIMER_SCENE_21":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
playMovie(player, Movie.SC_BOSS_FREYA_FORCED_DEFEAT);
|
||||
npc.deleteMe();
|
||||
startQuestTimer("TIMER_PC_LEAVE", 24000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TIMER_PC_LEAVE":
|
||||
{
|
||||
final QuestState qs = player.getQuestState(Q10285_MeetingSirra.class.getSimpleName());
|
||||
if (qs != null)
|
||||
{
|
||||
qs.setMemoState(3);
|
||||
qs.setCond(10, true);
|
||||
finishInstance(player, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance talker)
|
||||
{
|
||||
enterInstance(talker, npc, TEMPLATE_ID);
|
||||
return super.onTalk(npc, talker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("TIMER_MOVING", 60000, npc, null);
|
||||
startQuestTimer("TIMER_BLIZZARD", 180000, npc, null);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (creature.isPlayer() && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.S1_MAY_THE_PROTECTION_OF_THE_GODS_BE_UPON_YOU, creature.getName());
|
||||
|
||||
L2World.getInstance().forEachVisibleObject(npc, L2Npc.class, mob ->
|
||||
{
|
||||
if ((mob.getId() == ARCHERY_KNIGHT) && !mob.isDead() && !mob.isDecayed())
|
||||
{
|
||||
npc.setIsRunning(true);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, mob);
|
||||
((L2Attackable) npc).addDamageHate(mob, 0, 999999);
|
||||
}
|
||||
});
|
||||
startQuestTimer("ATTACK_KNIGHT", 5000, npc, null);
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if ((world != null) && (skill == ETHERNAL_BLIZZARD.getSkill()))
|
||||
{
|
||||
final L2PcInstance playerInside = world.getFirstPlayer();
|
||||
if (playerInside != null)
|
||||
{
|
||||
startQuestTimer("TIMER_SCENE_21", 1000, npc, playerInside);
|
||||
}
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new IceQueensCastle();
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
<html><body>Kegor:<br>
|
||||
I'd entrust your associate with this mission, but..
|
||||
</body></html>
|
@@ -0,0 +1,6 @@
|
||||
<html><body>Kegor:<br>
|
||||
Without you, we would have failed. I can't thank you enough.<br>
|
||||
Freya's last breath will flutter against your blade, I can feel it!<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IceQueensCastleBattle killFreya">Rest in peace!</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IceQueensCastleBattle 18851-01.html">Can I have a second with you?</Button>
|
||||
</body></html>
|
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
||||
* 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.areas.FreyasGarden.Jinia;
|
||||
package ai.bosses.Freya.Jinia;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.FreyasGarden.Sirra;
|
||||
package ai.bosses.Freya.Sirra;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
909
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Frintezza/LastImperialTomb.java
vendored
Normal file
909
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Frintezza/LastImperialTomb.java
vendored
Normal file
@@ -0,0 +1,909 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.bosses.Frintezza;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.Earthquake;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.IClientOutgoingPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillCanceld;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SpecialCamera;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Last Imperial Tomb AI
|
||||
* @author Mobius (reworked from L2J version)
|
||||
*/
|
||||
public final class LastImperialTomb extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int GUIDE = 32011;
|
||||
private static final int CUBE = 29061;
|
||||
private static final int HALL_ALARM = 18328;
|
||||
private static final int HALL_KEEPER_SUICIDAL_SOLDIER = 18333;
|
||||
private static final int DUMMY = 29052;
|
||||
private static final int DUMMY2 = 29053;
|
||||
private static final int[] PORTRAITS =
|
||||
{
|
||||
29048,
|
||||
29049
|
||||
};
|
||||
private static final int[] DEMONS =
|
||||
{
|
||||
29050,
|
||||
29051
|
||||
};
|
||||
private static final int FRINTEZZA = 29045;
|
||||
private static final int SCARLET1 = 29046;
|
||||
private static final int SCARLET2 = 29047;
|
||||
private static final int[] ON_KILL_MONSTERS =
|
||||
{
|
||||
HALL_ALARM,
|
||||
HALL_KEEPER_SUICIDAL_SOLDIER,
|
||||
18329,
|
||||
18330,
|
||||
18331,
|
||||
18334,
|
||||
18335,
|
||||
18336,
|
||||
18337,
|
||||
18338,
|
||||
18339
|
||||
|
||||
};
|
||||
// Items
|
||||
private static final int DEWDROP_OF_DESTRUCTION_ITEM_ID = 8556;
|
||||
private static final int FIRST_SCARLET_WEAPON = 8204;
|
||||
private static final int SECOND_SCARLET_WEAPON = 7903;
|
||||
// Doors
|
||||
private static final int[] FIRST_ROOM_DOORS =
|
||||
{
|
||||
17130051,
|
||||
17130052,
|
||||
17130053,
|
||||
17130054,
|
||||
17130055,
|
||||
17130056,
|
||||
17130057,
|
||||
17130058
|
||||
};
|
||||
private static final int[] SECOND_ROOM_DOORS =
|
||||
{
|
||||
17130061,
|
||||
17130062,
|
||||
17130063,
|
||||
17130064,
|
||||
17130065,
|
||||
17130066,
|
||||
17130067,
|
||||
17130068,
|
||||
17130069,
|
||||
17130070
|
||||
};
|
||||
private static final int[] FIRST_ROUTE_DOORS =
|
||||
{
|
||||
17130042,
|
||||
17130043
|
||||
};
|
||||
private static final int[] SECOND_ROUTE_DOORS =
|
||||
{
|
||||
17130045,
|
||||
17130046
|
||||
};
|
||||
// Skills
|
||||
private static final int DEWDROP_OF_DESTRUCTION_SKILL_ID = 2276;
|
||||
private static final SkillHolder INTRO_SKILL = new SkillHolder(5004, 1);
|
||||
private static final SkillHolder FIRST_MORPH_SKILL = new SkillHolder(5017, 1);
|
||||
private static final Map<Integer, NpcStringId> SKILL_MSG = new HashMap<>();
|
||||
static
|
||||
{
|
||||
SKILL_MSG.put(1, NpcStringId.REQUIEM_OF_HATRED);
|
||||
SKILL_MSG.put(2, NpcStringId.RONDO_OF_SOLITUDE);
|
||||
SKILL_MSG.put(3, NpcStringId.FRENETIC_TOCCATA);
|
||||
SKILL_MSG.put(4, NpcStringId.FUGUE_OF_JUBILATION);
|
||||
SKILL_MSG.put(5, NpcStringId.HYPNOTIC_MAZURKA);
|
||||
}
|
||||
// Spawns
|
||||
// @formatter:off
|
||||
static final int[][] PORTRAIT_SPAWNS =
|
||||
{
|
||||
{29048, -89381, -153981, -9168, 3368, -89378, -153968, -9168, 3368},
|
||||
{29048, -86234, -152467, -9168, 37656, -86261, -152492, -9168, 37656},
|
||||
{29049, -89342, -152479, -9168, -5152, -89311, -152491, -9168, -5152},
|
||||
{29049, -86189, -153968, -9168, 29456, -86217, -153956, -9168, 29456},
|
||||
};
|
||||
// @formatter:on
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 136;
|
||||
private static final int FRINTEZZA_WAIT_TIME = 10; // minutes
|
||||
private static final int RANDOM_SONG_INTERVAL = 90; // seconds
|
||||
private static final int TIME_BETWEEN_DEMON_SPAWNS = 20; // seconds
|
||||
private static final int MAX_DEMONS = 24;
|
||||
|
||||
public LastImperialTomb()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addTalkId(GUIDE, CUBE);
|
||||
addAttackId(SCARLET1);
|
||||
addKillId(ON_KILL_MONSTERS);
|
||||
addKillId(HALL_ALARM, SCARLET2);
|
||||
addKillId(PORTRAITS);
|
||||
addKillId(DEMONS);
|
||||
addSpawnId(HALL_ALARM, DUMMY, DUMMY2);
|
||||
addSpellFinishedId(HALL_KEEPER_SUICIDAL_SOLDIER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "FRINTEZZA_INTRO_START":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
startQuestTimer("FRINTEZZA_INTRO_1", 17000, null, player, false);
|
||||
startQuestTimer("FRINTEZZA_INTRO_2", 20000, null, player, false);
|
||||
broadCastPacket(world, new Earthquake(-87784, -155083, -9087, 45, 27));
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_1":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
for (int doorId : FIRST_ROOM_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, false);
|
||||
}
|
||||
for (int doorId : FIRST_ROUTE_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, false);
|
||||
}
|
||||
for (int doorId : SECOND_ROOM_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, false);
|
||||
}
|
||||
for (int doorId : SECOND_ROUTE_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, false);
|
||||
}
|
||||
addSpawn(CUBE, -87904, -141296, -9168, 0, false, 0, false, world.getId());
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_2":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
|
||||
final L2Npc frintezzaDummy = addSpawn(DUMMY, -87784, -155083, -9087, 16048, false, 0, false, world.getId());
|
||||
world.setParameter("frintezzaDummy", frintezzaDummy);
|
||||
|
||||
final L2Npc overheadDummy = addSpawn(DUMMY, -87784, -153298, -9175, 16384, false, 0, false, world.getId());
|
||||
overheadDummy.setCollisionHeight(600);
|
||||
broadCastPacket(world, new NpcInfo(overheadDummy));
|
||||
world.setParameter("overheadDummy", overheadDummy);
|
||||
|
||||
final L2Npc portraitDummy1 = addSpawn(DUMMY, -89566, -153168, -9165, 16048, false, 0, false, world.getId());
|
||||
world.setParameter("portraitDummy1", portraitDummy1);
|
||||
|
||||
final L2Npc portraitDummy3 = addSpawn(DUMMY, -86004, -153168, -9165, 16048, false, 0, false, world.getId());
|
||||
world.setParameter("portraitDummy3", portraitDummy3);
|
||||
|
||||
final L2Npc scarletDummy = addSpawn(DUMMY2, -87784, -153298, -9175, 16384, false, 0, false, world.getId());
|
||||
world.setParameter("scarletDummy", scarletDummy);
|
||||
|
||||
disablePlayers(world);
|
||||
|
||||
broadCastPacket(world, new SpecialCamera(overheadDummy, 0, 75, -89, 0, 100, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new SpecialCamera(overheadDummy, 0, 75, -89, 0, 100, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new SpecialCamera(overheadDummy, 300, 90, -10, 6500, 7000, 0, 0, 1, 0, 0));
|
||||
|
||||
final L2Npc frintezza = addSpawn(FRINTEZZA, -87780, -155086, -9080, 16384, false, 0, false, world.getId());
|
||||
frintezza.setIsImmobilized(true);
|
||||
frintezza.setIsInvul(true);
|
||||
frintezza.disableAllSkills();
|
||||
world.setParameter("frintezza", frintezza);
|
||||
|
||||
final List<L2Npc> demons = new ArrayList<>();
|
||||
for (int[] element : PORTRAIT_SPAWNS)
|
||||
{
|
||||
final L2MonsterInstance demon = (L2MonsterInstance) addSpawn(element[0] + 2, element[5], element[6], element[7], element[8], false, 0, false, world.getId());
|
||||
demon.setIsImmobilized(true);
|
||||
demon.disableAllSkills();
|
||||
demons.add(demon);
|
||||
}
|
||||
world.setParameter("demons", demons);
|
||||
|
||||
startQuestTimer("FRINTEZZA_INTRO_3", 6500, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_3":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezzaDummy = world.getParameters().getObject("frintezzaDummy", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezzaDummy, 1800, 90, 8, 6500, 7000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_4", 900, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_4":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezzaDummy = world.getParameters().getObject("frintezzaDummy", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezzaDummy, 140, 90, 10, 2500, 4500, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_5", 4000, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_5":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 40, 75, -10, 0, 1000, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 40, 75, -10, 0, 12000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_6", 1350, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_6":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new SocialAction(frintezza.getObjectId(), 2));
|
||||
final L2Npc frintezzaDummy = world.getParameters().getObject("frintezzaDummy", L2Npc.class);
|
||||
frintezzaDummy.deleteMe();
|
||||
startQuestTimer("FRINTEZZA_INTRO_7", 8000, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_7":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final List<L2Npc> demons = world.getParameters().getList("demons", L2Npc.class);
|
||||
broadCastPacket(world, new SocialAction(demons.get(1).getObjectId(), 1));
|
||||
broadCastPacket(world, new SocialAction(demons.get(2).getObjectId(), 1));
|
||||
startQuestTimer("FRINTEZZA_INTRO_8", 400, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_8":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final List<L2Npc> demons = world.getParameters().getList("demons", L2Npc.class);
|
||||
final L2Npc portraitDummy1 = world.getParameters().getObject("portraitDummy1", L2Npc.class);
|
||||
final L2Npc portraitDummy3 = world.getParameters().getObject("portraitDummy3", L2Npc.class);
|
||||
broadCastPacket(world, new SocialAction(demons.get(0).getObjectId(), 1));
|
||||
broadCastPacket(world, new SocialAction(demons.get(3).getObjectId(), 1));
|
||||
sendPacketX(world, new SpecialCamera(portraitDummy1, 1000, 118, 0, 0, 1000, 0, 0, 1, 0, 0), new SpecialCamera(portraitDummy3, 1000, 62, 0, 0, 1000, 0, 0, 1, 0, 0), -87784);
|
||||
sendPacketX(world, new SpecialCamera(portraitDummy1, 1000, 118, 0, 0, 10000, 0, 0, 1, 0, 0), new SpecialCamera(portraitDummy3, 1000, 62, 0, 0, 10000, 0, 0, 1, 0, 0), -87784);
|
||||
startQuestTimer("FRINTEZZA_INTRO_9", 2000, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_9":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
final L2Npc portraitDummy1 = world.getParameters().getObject("portraitDummy1", L2Npc.class);
|
||||
final L2Npc portraitDummy3 = world.getParameters().getObject("portraitDummy3", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 240, 90, 0, 0, 1000, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 240, 90, 25, 5500, 10000, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new SocialAction(frintezza.getObjectId(), 3));
|
||||
portraitDummy1.deleteMe();
|
||||
portraitDummy3.deleteMe();
|
||||
startQuestTimer("FRINTEZZA_INTRO_10", 4500, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_10":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 100, 195, 35, 0, 10000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_11", 700, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_11":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 100, 195, 35, 0, 10000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_12", 1300, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_12":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new ExShowScreenMessage(NpcStringId.MOURNFUL_CHORALE_PRELUDE, 2, 5000));
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 120, 180, 45, 1500, 10000, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new MagicSkillUse(frintezza, frintezza, 5006, 1, 34000, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_13", 1500, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_13":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 520, 135, 45, 8000, 10000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_14", 7500, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_14":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 1500, 110, 25, 10000, 13000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_15", 9500, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_15":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc overheadDummy = world.getParameters().getObject("overheadDummy", L2Npc.class);
|
||||
final L2Npc scarletDummy = world.getParameters().getObject("scarletDummy", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(overheadDummy, 930, 160, -20, 0, 1000, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new SpecialCamera(overheadDummy, 600, 180, -25, 0, 10000, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new MagicSkillUse(scarletDummy, overheadDummy, 5004, 1, 5800, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_16", 5000, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_16":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc scarletDummy = world.getParameters().getObject("scarletDummy", L2Npc.class);
|
||||
final L2Npc activeScarlet = addSpawn(SCARLET1, -87789, -153295, -9176, 16384, false, 0, false, world.getId());
|
||||
world.setParameter("activeScarlet", activeScarlet);
|
||||
activeScarlet.setRHandId(FIRST_SCARLET_WEAPON);
|
||||
activeScarlet.setIsInvul(true);
|
||||
activeScarlet.setIsImmobilized(true);
|
||||
activeScarlet.disableAllSkills();
|
||||
broadCastPacket(world, new SocialAction(activeScarlet.getObjectId(), 3));
|
||||
broadCastPacket(world, new SpecialCamera(scarletDummy, 800, 180, 10, 1000, 10000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_17", 2100, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_17":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc activeScarlet = world.getParameters().getObject("activeScarlet", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(activeScarlet, 300, 60, 8, 0, 10000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FRINTEZZA_INTRO_18", 2000, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_18":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc activeScarlet = world.getParameters().getObject("activeScarlet", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(activeScarlet, 500, 90, 10, 3000, 5000, 0, 0, 1, 0, 0));
|
||||
world.setParameter("isPlayingSong", false);
|
||||
playRandomSong(world);
|
||||
startQuestTimer("FRINTEZZA_INTRO_19", 3000, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_19":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final Map<L2Npc, Integer> portraits = new HashMap<>();
|
||||
for (int i = 0; i < PORTRAIT_SPAWNS.length; i++)
|
||||
{
|
||||
final L2Npc portrait = addSpawn(PORTRAIT_SPAWNS[i][0], PORTRAIT_SPAWNS[i][1], PORTRAIT_SPAWNS[i][2], PORTRAIT_SPAWNS[i][3], PORTRAIT_SPAWNS[i][4], false, 0, false, world.getId());
|
||||
portraits.put(portrait, i);
|
||||
}
|
||||
world.setParameter("portraits", portraits);
|
||||
final L2Npc overheadDummy = world.getParameters().getObject("overheadDummy", L2Npc.class);
|
||||
final L2Npc scarletDummy = world.getParameters().getObject("scarletDummy", L2Npc.class);
|
||||
overheadDummy.deleteMe();
|
||||
scarletDummy.deleteMe();
|
||||
startQuestTimer("FRINTEZZA_INTRO_20", 2000, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "FRINTEZZA_INTRO_20":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
final L2Npc activeScarlet = world.getParameters().getObject("activeScarlet", L2Npc.class);
|
||||
final List<L2Npc> demons = world.getParameters().getList("demons", L2Npc.class);
|
||||
for (L2Npc demon : demons)
|
||||
{
|
||||
demon.setIsImmobilized(false);
|
||||
demon.enableAllSkills();
|
||||
}
|
||||
activeScarlet.setIsInvul(false);
|
||||
activeScarlet.setIsImmobilized(false);
|
||||
activeScarlet.enableAllSkills();
|
||||
activeScarlet.setRunning();
|
||||
activeScarlet.doCast(INTRO_SKILL.getSkill());
|
||||
frintezza.enableAllSkills();
|
||||
frintezza.disableCoreAI(true);
|
||||
frintezza.setIsInvul(true);
|
||||
enablePlayers(world);
|
||||
startQuestTimer("PLAY_RANDOM_SONG", RANDOM_SONG_INTERVAL * 1000, frintezza, null, false);
|
||||
startQuestTimer("SPAWN_DEMONS", TIME_BETWEEN_DEMON_SPAWNS * 1000, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "SPAWN_DEMONS":
|
||||
{
|
||||
final Instance world = player.getInstanceWorld();
|
||||
final Map<L2Npc, Integer> portraits = world.getParameters().getMap("portraits", L2Npc.class, Integer.class);
|
||||
if (!portraits.isEmpty())
|
||||
{
|
||||
final List<L2Npc> demons = world.getParameters().getList("demons", L2Npc.class);
|
||||
for (int i : portraits.values())
|
||||
{
|
||||
if (demons.size() > MAX_DEMONS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
final L2Npc demon = addSpawn(PORTRAIT_SPAWNS[i][0] + 2, PORTRAIT_SPAWNS[i][5], PORTRAIT_SPAWNS[i][6], PORTRAIT_SPAWNS[i][7], PORTRAIT_SPAWNS[i][8], false, 0, false, world.getId());
|
||||
demons.add(demon);
|
||||
}
|
||||
world.setParameter("demons", demons);
|
||||
startQuestTimer("SPAWN_DEMONS", TIME_BETWEEN_DEMON_SPAWNS * 1000, null, player, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "PLAY_RANDOM_SONG":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
playRandomSong(world);
|
||||
startQuestTimer("PLAY_RANDOM_SONG", RANDOM_SONG_INTERVAL * 1000, null, player, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCARLET_FIRST_MORPH":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
npc.doCast(FIRST_MORPH_SKILL.getSkill());
|
||||
playRandomSong(world);
|
||||
break;
|
||||
}
|
||||
case "SCARLET_SECOND_MORPH":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
disablePlayers(world);
|
||||
final L2Npc activeScarlet = world.getParameters().getObject("activeScarlet", L2Npc.class);
|
||||
activeScarlet.abortAttack();
|
||||
activeScarlet.abortCast();
|
||||
activeScarlet.setIsInvul(true);
|
||||
activeScarlet.setIsImmobilized(true);
|
||||
activeScarlet.disableAllSkills();
|
||||
playRandomSong(world);
|
||||
startQuestTimer("SCARLET_SECOND_MORPH_CAMERA_1", 2000, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "SCARLET_SECOND_MORPH_CAMERA_1":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new SocialAction(frintezza.getObjectId(), 4));
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 250, 120, 15, 0, 1000, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 250, 120, 15, 0, 10000, 0, 0, 1, 0, 0));
|
||||
|
||||
startQuestTimer("SCARLET_SECOND_MORPH_CAMERA_2", 7000, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "SCARLET_SECOND_MORPH_CAMERA_2":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new MagicSkillUse(frintezza, frintezza, 5006, 1, 34000, 0));
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 500, 70, 15, 3000, 10000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("SCARLET_SECOND_MORPH_CAMERA_3", 3000, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "SCARLET_SECOND_MORPH_CAMERA_3":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 2500, 90, 12, 6000, 10000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("SCARLET_SECOND_MORPH_CAMERA_4", 3000, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "SCARLET_SECOND_MORPH_CAMERA_4":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc activeScarlet = world.getParameters().getObject("activeScarlet", L2Npc.class);
|
||||
final Location scarletLocation = activeScarlet.getLocation();
|
||||
int newHeading = 0;
|
||||
if (scarletLocation.getHeading() < 32768)
|
||||
{
|
||||
newHeading = Math.abs(180 - (int) (scarletLocation.getHeading() / 182.044444444));
|
||||
}
|
||||
else
|
||||
{
|
||||
newHeading = Math.abs(540 - (int) (scarletLocation.getHeading() / 182.044444444));
|
||||
}
|
||||
world.setParameter("scarletLocation", scarletLocation);
|
||||
world.setParameter("newHeading", newHeading);
|
||||
broadCastPacket(world, new SpecialCamera(activeScarlet, 250, newHeading, 12, 0, 1000, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new SpecialCamera(activeScarlet, 250, newHeading, 12, 0, 10000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("SCARLET_SECOND_MORPH_CAMERA_5", 500, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "SCARLET_SECOND_MORPH_CAMERA_5":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc activeScarlet = world.getParameters().getObject("activeScarlet", L2Npc.class);
|
||||
final int newHeading = world.getParameters().getInt("newHeading");
|
||||
activeScarlet.doDie(activeScarlet);
|
||||
broadCastPacket(world, new SpecialCamera(activeScarlet, 450, newHeading, 14, 8000, 8000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("SCARLET_SECOND_MORPH_CAMERA_6", 6250, npc, null, false);
|
||||
startQuestTimer("SCARLET_SECOND_MORPH_CAMERA_7", 7200, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "SCARLET_SECOND_MORPH_CAMERA_6":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc activeScarlet = world.getParameters().getObject("activeScarlet", L2Npc.class);
|
||||
activeScarlet.deleteMe();
|
||||
break;
|
||||
}
|
||||
case "SCARLET_SECOND_MORPH_CAMERA_7":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final int newHeading = world.getParameters().getInt("newHeading");
|
||||
final Location scarletLocation = world.getParameters().getLocation("scarletLocation");
|
||||
final L2Npc activeScarlet = addSpawn(SCARLET2, scarletLocation, false, 0, false, world.getId());
|
||||
world.setParameter("activeScarlet", activeScarlet);
|
||||
activeScarlet.setRHandId(SECOND_SCARLET_WEAPON);
|
||||
activeScarlet.setIsInvul(true);
|
||||
activeScarlet.setIsImmobilized(true);
|
||||
activeScarlet.disableAllSkills();
|
||||
broadCastPacket(world, new SpecialCamera(activeScarlet, 450, newHeading, 12, 500, 14000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("SCARLET_SECOND_MORPH_CAMERA_8", 8100, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "SCARLET_SECOND_MORPH_CAMERA_8":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc activeScarlet = world.getParameters().getObject("activeScarlet", L2Npc.class);
|
||||
broadCastPacket(world, new SocialAction(activeScarlet.getObjectId(), 2));
|
||||
startQuestTimer("SCARLET_SECOND_MORPH_CAMERA_9", 9000, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "SCARLET_SECOND_MORPH_CAMERA_9":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc activeScarlet = world.getParameters().getObject("activeScarlet", L2Npc.class);
|
||||
activeScarlet.setIsInvul(false);
|
||||
activeScarlet.setIsImmobilized(false);
|
||||
activeScarlet.enableAllSkills();
|
||||
enablePlayers(world);
|
||||
break;
|
||||
}
|
||||
case "FINISH_CAMERA_1":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc activeScarlet = world.getParameters().getObject("activeScarlet", L2Npc.class);
|
||||
final int newHeading = world.getParameters().getInt("newHeading");
|
||||
broadCastPacket(world, new SpecialCamera(activeScarlet, 300, newHeading - 180, 5, 0, 7000, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new SpecialCamera(activeScarlet, 200, newHeading, 85, 4000, 10000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FINISH_CAMERA_2", 7400, npc, null, false);
|
||||
startQuestTimer("FINISH_CAMERA_3", 7500, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "FINISH_CAMERA_2":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
frintezza.doDie(frintezza);
|
||||
break;
|
||||
}
|
||||
case "FINISH_CAMERA_3":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 100, 120, 5, 0, 7000, 0, 0, 1, 0, 0));
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 100, 90, 5, 5000, 15000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FINISH_CAMERA_4", 7000, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "FINISH_CAMERA_4":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new SpecialCamera(frintezza, 900, 90, 25, 7000, 10000, 0, 0, 1, 0, 0));
|
||||
startQuestTimer("FINISH_CAMERA_5", 9000, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "FINISH_CAMERA_5":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
for (int doorId : FIRST_ROOM_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, true);
|
||||
}
|
||||
for (int doorId : FIRST_ROUTE_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, true);
|
||||
}
|
||||
for (int doorId : SECOND_ROOM_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, true);
|
||||
}
|
||||
for (int doorId : SECOND_ROUTE_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, true);
|
||||
}
|
||||
enablePlayers(world);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc.getId() == GUIDE)
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
}
|
||||
else // Teleport Cube
|
||||
{
|
||||
final Instance world = getPlayerInstance(player);
|
||||
if (world != null)
|
||||
{
|
||||
teleportPlayerOut(player, world);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setRandomWalking(false);
|
||||
npc.setIsImmobilized(true);
|
||||
if (npc.getId() == HALL_ALARM)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
}
|
||||
else // dummy
|
||||
{
|
||||
npc.setIsInvul(true);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
if (npc.getId() == SCARLET1)
|
||||
{
|
||||
if ((npc.getScriptValue() == 0) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.80)))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("SCARLET_FIRST_MORPH", 1000, npc, null, false);
|
||||
}
|
||||
if ((npc.getScriptValue() == 1) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.20)))
|
||||
{
|
||||
npc.setScriptValue(2);
|
||||
startQuestTimer("SCARLET_SECOND_MORPH", 1000, npc, null, false);
|
||||
}
|
||||
}
|
||||
if (skill != null)
|
||||
{
|
||||
// When Dewdrop of Destruction is used on Portraits they suicide.
|
||||
if (CommonUtil.contains(PORTRAITS, npc.getId()) && (skill.getId() == DEWDROP_OF_DESTRUCTION_SKILL_ID))
|
||||
{
|
||||
npc.doDie(attacker);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if (skill.isSuicideAttack())
|
||||
{
|
||||
return onKill(npc, null, false);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final Instance world = killer.getInstanceWorld();
|
||||
if ((npc.getId() == HALL_ALARM) && (world.getStatus() == 0))
|
||||
{
|
||||
world.setStatus(1);
|
||||
world.spawnGroup("room1");
|
||||
final List<L2MonsterInstance> monsters = world.getAliveNpcs(L2MonsterInstance.class);
|
||||
world.setParameter("monstersCount", monsters.size() - 1);
|
||||
for (int doorId : FIRST_ROOM_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, true);
|
||||
}
|
||||
for (L2Npc monster : monsters)
|
||||
{
|
||||
monster.reduceCurrentHp(1, killer, null); // TODO: Find better way for attack
|
||||
}
|
||||
}
|
||||
else if (npc.getId() == SCARLET2)
|
||||
{
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
broadCastPacket(world, new MagicSkillCanceld(frintezza.getObjectId()));
|
||||
startQuestTimer("FINISH_CAMERA_1", 500, npc, null, false);
|
||||
}
|
||||
else if (CommonUtil.contains(DEMONS, npc.getId()))
|
||||
{
|
||||
final List<L2Npc> demons = world.getParameters().getList("demons", L2Npc.class);
|
||||
demons.remove(npc);
|
||||
}
|
||||
else if (CommonUtil.contains(PORTRAITS, npc.getId()))
|
||||
{
|
||||
final Map<L2Npc, Integer> portraits = world.getParameters().getMap("portraits", L2Npc.class, Integer.class);
|
||||
portraits.remove(npc);
|
||||
}
|
||||
else
|
||||
{
|
||||
final int killCount = world.getParameters().getInt("monstersCount");
|
||||
world.setParameter("monstersCount", killCount - 1);
|
||||
if (killCount <= 0)
|
||||
{
|
||||
switch (world.getStatus())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
world.setStatus(2);
|
||||
world.spawnGroup("room2_part1");
|
||||
final List<L2MonsterInstance> monsters = world.getAliveNpcs(L2MonsterInstance.class);
|
||||
world.setParameter("monstersCount", monsters.size() - 1);
|
||||
for (int doorId : FIRST_ROUTE_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
world.setStatus(3);
|
||||
world.spawnGroup("room2_part2");
|
||||
final List<L2MonsterInstance> monsters = world.getAliveNpcs(L2MonsterInstance.class);
|
||||
world.setParameter("monstersCount", monsters.size() - 1);
|
||||
for (int doorId : SECOND_ROOM_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, true);
|
||||
}
|
||||
for (L2Npc monster : monsters)
|
||||
{
|
||||
monster.reduceCurrentHp(1, killer, null); // TODO: Find better way for attack
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
world.setStatus(4);
|
||||
for (int doorId : SECOND_ROUTE_DOORS)
|
||||
{
|
||||
world.openCloseDoor(doorId, true);
|
||||
}
|
||||
startQuestTimer("FRINTEZZA_INTRO_START", FRINTEZZA_WAIT_TIME * 60 * 1000, null, killer, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getRandom(100) < 5)
|
||||
{
|
||||
npc.dropItem(killer, DEWDROP_OF_DESTRUCTION_ITEM_ID, 1);
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private void playRandomSong(Instance world)
|
||||
{
|
||||
final L2Npc frintezza = world.getParameters().getObject("frintezza", L2Npc.class);
|
||||
final boolean isPlayingSong = world.getParameters().getBoolean("isPlayingSong");
|
||||
if (isPlayingSong)
|
||||
{
|
||||
return;
|
||||
}
|
||||
world.setParameter("isPlayingSong", true);
|
||||
final int random = getRandom(1, 5);
|
||||
final SkillHolder skill = new SkillHolder(5007, random);
|
||||
final SkillHolder skillEffect = new SkillHolder(5008, random);
|
||||
broadCastPacket(world, new ExShowScreenMessage(2, -1, 2, 0, 0, 0, 0, true, 4000, false, null, SKILL_MSG.get(random), null));
|
||||
broadCastPacket(world, new MagicSkillUse(frintezza, frintezza, skill.getSkillId(), skill.getSkillLevel(), skill.getSkill().getHitTime(), 0));
|
||||
for (L2PcInstance player : world.getPlayers())
|
||||
{
|
||||
if ((player != null) && player.isOnline())
|
||||
{
|
||||
frintezza.setTarget(player);
|
||||
frintezza.doCast(skillEffect.getSkill());
|
||||
}
|
||||
}
|
||||
world.setParameter("isPlayingSong", false);
|
||||
}
|
||||
|
||||
private void disablePlayers(Instance world)
|
||||
{
|
||||
for (L2PcInstance player : world.getPlayers())
|
||||
{
|
||||
if ((player != null) && player.isOnline())
|
||||
{
|
||||
player.abortAttack();
|
||||
player.abortCast();
|
||||
player.disableAllSkills();
|
||||
player.setTarget(null);
|
||||
player.stopMove(null);
|
||||
player.setIsImmobilized(true);
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void enablePlayers(Instance world)
|
||||
{
|
||||
for (L2PcInstance player : world.getPlayers())
|
||||
{
|
||||
if ((player != null) && player.isOnline())
|
||||
{
|
||||
player.enableAllSkills();
|
||||
player.setIsImmobilized(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void broadCastPacket(Instance world, IClientOutgoingPacket packet)
|
||||
{
|
||||
for (L2PcInstance player : world.getPlayers())
|
||||
{
|
||||
if ((player != null) && player.isOnline())
|
||||
{
|
||||
player.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPacketX(Instance world, IClientOutgoingPacket packet1, IClientOutgoingPacket packet2, int x)
|
||||
{
|
||||
for (L2PcInstance player : world.getPlayers())
|
||||
{
|
||||
if ((player != null) && player.isOnline())
|
||||
{
|
||||
if (player.getX() < x)
|
||||
{
|
||||
player.sendPacket(packet1);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(packet2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new LastImperialTomb();
|
||||
}
|
||||
}
|
282
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Frintezza/ScarletVanHalisha.java
vendored
Normal file
282
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Frintezza/ScarletVanHalisha.java
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.bosses.Frintezza;
|
||||
|
||||
import static com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
|
||||
import static com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
|
||||
import static com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.l2jmobius.gameserver.GeoData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2DecoyInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
import ai.AbstractNpcAI;
|
||||
|
||||
/**
|
||||
* @author Micr0, Zerox, Mobius
|
||||
*/
|
||||
public final class ScarletVanHalisha extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int HALISHA2 = 29046;
|
||||
private static final int HALISHA3 = 29047;
|
||||
// Skills
|
||||
private static final int FRINTEZZA_DAEMON_ATTACK = 5014;
|
||||
private static final int FRINTEZZA_DAEMON_CHARGE = 5015;
|
||||
private static final int YOKE_OF_SCARLET = 5016;
|
||||
private static final int FRINTEZZA_DAEMON_MORPH = 5018;
|
||||
private static final int FRINTEZZA_DAEMON_FIELD = 5019;
|
||||
// Misc
|
||||
private L2Character _target;
|
||||
private Skill _skill;
|
||||
private long _lastRangedSkillTime;
|
||||
private final int _rangedSkillMinCoolTime = 60000; // 1 minute
|
||||
|
||||
public ScarletVanHalisha()
|
||||
{
|
||||
addAttackId(HALISHA2, HALISHA3);
|
||||
addKillId(HALISHA2, HALISHA3);
|
||||
addSpellFinishedId(HALISHA2, HALISHA3);
|
||||
registerMobs(HALISHA2, HALISHA3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "attack":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
getSkillAI(npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "random_target":
|
||||
{
|
||||
_target = getRandomTarget(npc, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
getSkillAI(npc);
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
startQuestTimer("random_Target", 5000, npc, null, true);
|
||||
startQuestTimer("attack", 500, npc, null, true);
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
cancelQuestTimers("attack");
|
||||
cancelQuestTimers("random_Target");
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private Skill getRndSkills(L2Npc npc)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case HALISHA2:
|
||||
{
|
||||
if (getRandom(100) < 10)
|
||||
{
|
||||
return SkillData.getInstance().getSkill(FRINTEZZA_DAEMON_CHARGE, 2);
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
return SkillData.getInstance().getSkill(FRINTEZZA_DAEMON_CHARGE, 5);
|
||||
}
|
||||
else if (getRandom(100) < 2)
|
||||
{
|
||||
return SkillData.getInstance().getSkill(YOKE_OF_SCARLET, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return SkillData.getInstance().getSkill(FRINTEZZA_DAEMON_ATTACK, 2);
|
||||
}
|
||||
}
|
||||
case HALISHA3:
|
||||
{
|
||||
if (getRandom(100) < 10)
|
||||
{
|
||||
return SkillData.getInstance().getSkill(FRINTEZZA_DAEMON_CHARGE, 3);
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
return SkillData.getInstance().getSkill(FRINTEZZA_DAEMON_CHARGE, 6);
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
return SkillData.getInstance().getSkill(FRINTEZZA_DAEMON_CHARGE, 2);
|
||||
}
|
||||
else if (((_lastRangedSkillTime + _rangedSkillMinCoolTime) < System.currentTimeMillis()) && (getRandom(100) < 10))
|
||||
{
|
||||
return SkillData.getInstance().getSkill(FRINTEZZA_DAEMON_FIELD, 1);
|
||||
}
|
||||
else if (((_lastRangedSkillTime + _rangedSkillMinCoolTime) < System.currentTimeMillis()) && (getRandom(100) < 10))
|
||||
{
|
||||
return SkillData.getInstance().getSkill(FRINTEZZA_DAEMON_MORPH, 1);
|
||||
}
|
||||
else if (getRandom(100) < 2)
|
||||
{
|
||||
return SkillData.getInstance().getSkill(YOKE_OF_SCARLET, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return SkillData.getInstance().getSkill(FRINTEZZA_DAEMON_ATTACK, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SkillData.getInstance().getSkill(FRINTEZZA_DAEMON_ATTACK, 1);
|
||||
}
|
||||
|
||||
private synchronized void getSkillAI(L2Npc npc)
|
||||
{
|
||||
if (npc.isInvul() || npc.isCastingNow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((getRandom(100) < 30) || (_target == null) || _target.isDead())
|
||||
{
|
||||
_skill = getRndSkills(npc);
|
||||
_target = getRandomTarget(npc, _skill);
|
||||
}
|
||||
final L2Character target = _target;
|
||||
Skill skill = _skill;
|
||||
if (skill == null)
|
||||
{
|
||||
skill = getRndSkills(npc);
|
||||
}
|
||||
|
||||
if (npc.isPhysicalMuted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((target == null) || target.isDead())
|
||||
{
|
||||
// npc.setIsCastingNow(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Util.checkIfInRange(skill.getCastRange(), npc, target, true))
|
||||
{
|
||||
npc.getAI().setIntention(AI_INTENTION_IDLE);
|
||||
npc.setTarget(target);
|
||||
// npc.setIsCastingNow(true);
|
||||
_target = null;
|
||||
npc.doCast(skill);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getAI().setIntention(AI_INTENTION_FOLLOW, target, null);
|
||||
npc.getAI().setIntention(AI_INTENTION_ATTACK, target, null);
|
||||
// npc.setIsCastingNow(false);
|
||||
}
|
||||
}
|
||||
|
||||
private L2Character getRandomTarget(L2Npc npc, Skill skill)
|
||||
{
|
||||
final ArrayList<L2Character> result = new ArrayList<>();
|
||||
{
|
||||
for (L2Object obj : npc.getInstanceWorld().getPlayers())
|
||||
{
|
||||
if (obj.isPlayable() || (obj instanceof L2DecoyInstance))
|
||||
{
|
||||
if (obj.isPlayer() && obj.getActingPlayer().isInvisible())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((((L2Character) obj).getZ() < (npc.getZ() - 100)) && (((L2Character) obj).getZ() > (npc.getZ() + 100))) || !GeoData.getInstance().canSeeTarget(((L2Character) obj).getX(), ((L2Character) obj).getY(), ((L2Character) obj).getZ(), npc.getX(), npc.getY(), npc.getZ()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (obj.isPlayable() || (obj instanceof L2DecoyInstance))
|
||||
{
|
||||
int skillRange = 150;
|
||||
if (skill != null)
|
||||
{
|
||||
switch (skill.getId())
|
||||
{
|
||||
case FRINTEZZA_DAEMON_ATTACK:
|
||||
{
|
||||
skillRange = 150;
|
||||
break;
|
||||
}
|
||||
case FRINTEZZA_DAEMON_CHARGE:
|
||||
{
|
||||
skillRange = 400;
|
||||
break;
|
||||
}
|
||||
case YOKE_OF_SCARLET:
|
||||
{
|
||||
skillRange = 200;
|
||||
break;
|
||||
}
|
||||
case FRINTEZZA_DAEMON_MORPH:
|
||||
case FRINTEZZA_DAEMON_FIELD:
|
||||
{
|
||||
_lastRangedSkillTime = System.currentTimeMillis();
|
||||
skillRange = 550;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Util.checkIfInRange(skillRange, npc, obj, true) && !((L2Character) obj).isDead())
|
||||
{
|
||||
result.add((L2Character) obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result.isEmpty() && (result.size() != 0))
|
||||
{
|
||||
final Object[] characters = result.toArray();
|
||||
return (L2Character) characters[getRandom(characters.length)];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new ScarletVanHalisha();
|
||||
}
|
||||
}
|
8
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-01.html
vendored
Normal file
8
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-01.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html><body>Rumiese:<br>
|
||||
Here's the plan. You weaken Istina as much as you can, while I prepare the magical Ballista. Have you seen one of those? They're rather impressive. They are powered by soulshots and can do a great deal of damage. Their main drawback is that they require a lot of energy to recharge, so please tell your team to push yourselves to collect as much magical power as you can, as quickly as possible.<br>
|
||||
That is all the advice I can give; the rest of it is up to you.<br>
|
||||
Oh, I once gave you an <font color="LEVEL">Energy Control Device</font>, didn't I? You will most certainly need it for your fight with Istina, so shall I give it to you now?<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern leaveInstance">"No, I have somewhere else to be."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern giveDevice">"Please give me a Control Device."</Button>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
|
||||
</body></html>
|
7
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-02.html
vendored
Normal file
7
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-02.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<html><body>Rumiese:<br>
|
||||
Somebody is already fighting with Istina. If you want, I can let you in.<br>
|
||||
Oh, I once gave you an <font color="LEVEL">Energy Control Device</font>, didn't I? You will most certainly need it for your fight with Istina, so shall I give it to you now?<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern battleTeleport">"Please let me in."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern leaveInstance">"No, I have somewhere else to be."</Button>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern giveDevice">"Please give me a Control Device."</Button>
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-03.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-03.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Rumiese:<br>
|
||||
If you time things right, you can deal a critical blow to Istina with the magical power Ballista. Use all the power you have at your disposal to fully charge magical power within the time limit. If you can manage this--and with a little bit of luck--you'll really hurt Istina. Good luck!
|
||||
</body></html>
|
5
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-04.html
vendored
Normal file
5
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-04.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Rumiese:<br>
|
||||
What an achievement! I am truly in awe of you and your cohorts. Now, let me give you something in recognition of your work. It's not much, compared to your great accomplishments, but I have a chest containing the strength of Istina's soul stone. The soul stone itself sometimes changes materials. Please, accept this with our thanks.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest IstinaCavern giveReward">"Can I get a chest imbued with soul stone power?"</Button>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-05.html
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-05.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Rumiese:<br>
|
||||
Unfortunately, either our skill or our luck was not enough to meet the challenge. Istina has retreated, cowed but undefeated. It is only a matter of time before it returns.<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-06.html
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-06.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Rumiese:<br>
|
||||
Here we go. Please do not forget you use this when you need it!<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-07.html
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-07.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Rumiese:<br>
|
||||
This item can't be sold. But you already have one; you don't need another.<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-08.html
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/33293-08.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Rumiese:<br>
|
||||
You have quite excellent abilities, but you are also greedy. Shouldn't we give someone else a chance?<br>
|
||||
<Button ALIGN=LEFT ICON="QUEST" action="bypass -h npc_%objectId%_Quest">Quest</Button>
|
||||
</body></html>
|
687
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/IstinaCavern.java
vendored
Normal file
687
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Istina/IstinaCavern.java
vendored
Normal file
@@ -0,0 +1,687 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.bosses.Istina;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.enums.CategoryType;
|
||||
import com.l2jmobius.gameserver.enums.Movie;
|
||||
import com.l2jmobius.gameserver.model.AggroInfo;
|
||||
import com.l2jmobius.gameserver.model.DamageDoneInfo;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExSendUIEvent;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Istina Cavern instance zone.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class IstinaCavern extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int RUMIESE = 33151;
|
||||
private static final int RUMIESE_INSTANCE = 33293;
|
||||
private static final int INVISIBLE_NPC = 18919;
|
||||
private static final int BALLISTA = 19021;
|
||||
private static final int EXTREME_MINION = 23125;
|
||||
private static final int[] ISTINA =
|
||||
{
|
||||
29195, // Istina (Common)
|
||||
29196, // Istina (Extreme)
|
||||
};
|
||||
// Skills
|
||||
private static final SkillHolder ERUPTION_1 = new SkillHolder(14222, 1);
|
||||
private static final SkillHolder ERUPTION_2 = new SkillHolder(14223, 1);
|
||||
private static final SkillHolder ISTINA_ERUPTION_SKILL = new SkillHolder(14221, 1);
|
||||
// Items
|
||||
private static final int CONTROL_DEVICE = 17608; // Energy Control Device
|
||||
private static final int REWARD_BOX_COMMON = 30371; // Box Containing Magic Power
|
||||
private static final int REWARD_BOX_EXTREME = 30374; // Magic Filled Box
|
||||
// Locations
|
||||
private static final Location DEFEAT_ISTINA_LOC = new Location(-177120, 148782, -11384, 49140);
|
||||
private static final Location RUMIESE_LOC = new Location(-177001, 147844, -11380, 47684);
|
||||
private static final Location BATTLE_LOC = new Location(-177111, 146802, -11384);
|
||||
// Misc
|
||||
private static final int PERFECT_SCORE_1 = 30000000;
|
||||
private static final int PERFECT_SCORE_2 = 300000000;
|
||||
private static final int TEMPLATE_ID_COMMON = 169;
|
||||
private static final int TEMPLATE_ID_EXTREME = 170;
|
||||
|
||||
public IstinaCavern()
|
||||
{
|
||||
super(TEMPLATE_ID_COMMON, TEMPLATE_ID_EXTREME);
|
||||
addStartNpc(RUMIESE);
|
||||
addTalkId(RUMIESE, RUMIESE_INSTANCE);
|
||||
addFirstTalkId(RUMIESE_INSTANCE);
|
||||
addAttackId(ISTINA);
|
||||
addAttackId(BALLISTA);
|
||||
addSpellFinishedId(ISTINA);
|
||||
addSpellFinishedId(INVISIBLE_NPC);
|
||||
addSpawnId(INVISIBLE_NPC, BALLISTA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = null;
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "leaveInstance":
|
||||
{
|
||||
teleportPlayerOut(player, instance);
|
||||
break;
|
||||
}
|
||||
case "battleTeleport":
|
||||
{
|
||||
player.teleToLocation(BATTLE_LOC);
|
||||
break;
|
||||
}
|
||||
case "giveDevice":
|
||||
{
|
||||
if (!hasQuestItems(player, CONTROL_DEVICE))
|
||||
{
|
||||
giveItems(player, CONTROL_DEVICE, 1);
|
||||
htmltext = "33293-06.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
htmltext = "33293-07.html";
|
||||
}
|
||||
}
|
||||
case "giveReward":
|
||||
{
|
||||
if (instance.isStatus(3))
|
||||
{
|
||||
if (npc.getVariables().getBoolean("PLAYER_" + player.getObjectId(), true))
|
||||
{
|
||||
giveItems(player, (isExtremeMode(instance) ? REWARD_BOX_EXTREME : REWARD_BOX_COMMON), 1);
|
||||
npc.getVariables().set("PLAYER_" + player.getObjectId(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
htmltext = "33293-08.html";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equals("enterInstanceCommon"))
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID_COMMON);
|
||||
}
|
||||
else if (event.equals("enterInstanceExtreme"))
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID_EXTREME);
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
final StatsSet npcParams = npc.getParameters();
|
||||
final StatsSet npcVars = npc.getVariables();
|
||||
switch (event)
|
||||
{
|
||||
case "DEATH_TIMER":
|
||||
{
|
||||
final L2Character mostHated = ((L2Attackable) npc).getMostHated();
|
||||
if ((mostHated != null) && npc.isInsideRadius(mostHated, 15000, false, true))
|
||||
{
|
||||
final SkillHolder death1 = npcParams.getSkillHolder("Istina_Death_Skill01");
|
||||
final SkillHolder death2 = npcParams.getSkillHolder("Istina_Death_Skill02");
|
||||
|
||||
if (mostHated.isInCategory(CategoryType.TANKER_GROUP))
|
||||
{
|
||||
addSkillCastDesire(npc, mostHated, (mostHated.isAffectedBySkill(death1) ? death2 : death1), 23);
|
||||
}
|
||||
else
|
||||
{
|
||||
addSkillCastDesire(npc, mostHated, death2, 23);
|
||||
}
|
||||
}
|
||||
getTimers().addTimer("DEATH_TIMER", 35000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "DEATH_CHECK_TIMER":
|
||||
{
|
||||
final SkillHolder death1 = npcParams.getSkillHolder("Istina_Death_Skill01");
|
||||
final SkillHolder death2 = npcParams.getSkillHolder("Istina_Death_Skill02");
|
||||
final L2Character mostHated = ((L2Attackable) npc).getMostHated();
|
||||
|
||||
if ((mostHated != null) && npc.isInsideRadius(mostHated, 15000, false, true) && mostHated.isInCategory(CategoryType.TANKER_GROUP) && mostHated.isAffectedBySkill(death1))
|
||||
{
|
||||
addSkillCastDesire(npc, mostHated, death2, 23);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "REFLECT_TIMER":
|
||||
{
|
||||
if (!isExtremeMode(instance))
|
||||
{
|
||||
showOnScreenMsg(instance, NpcStringId.ISTINA_SPREADS_THE_REFLECTING_PROTECTIVE_SHEET, ExShowScreenMessage.TOP_CENTER, 4000);
|
||||
}
|
||||
final SkillHolder reflect = npcParams.getSkillHolder("Istina_Refraction_Skill");
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(reflect.getSkill());
|
||||
instance.broadcastPacket(new PlaySound(1, "Npcdialog1.istina_voice_02", 0, 0, 0, 0, 0));
|
||||
getTimers().addTimer("REFLECT_TIMER", 90000 + getRandom(15000), npc, null);
|
||||
break;
|
||||
}
|
||||
case "REFLECT_CHECK_TIMER":
|
||||
{
|
||||
if (npc.isAffectedBySkill(npcParams.getSkillHolder("Istina_Refraction_Skill")))
|
||||
{
|
||||
getTimers().addTimer("REFLECT_CHECK_TIMER", 1000, npc, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.setDisplayEffect(2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "LOW_ERUPTION_TIMER":
|
||||
{
|
||||
final L2Attackable istina = (L2Attackable) npc;
|
||||
if ((istina.getHateList() != null) && (istina.getHateList().size() > 0))
|
||||
{
|
||||
final L2Character target = istina.getHateList().stream().sorted((o1, o2) -> (int) o1.calculateDistance(o2, true, false)).findFirst().orElse(null);
|
||||
if (target != null)
|
||||
{
|
||||
final L2Npc eruption = addSpawn(INVISIBLE_NPC, Util.getRandomPosition(target, 50, 50), false, 0, false, instance.getId());
|
||||
eruption.getVariables().set("ERUPTION_TARGET", target);
|
||||
}
|
||||
}
|
||||
getTimers().addTimer("LOW_ERUPTION_TIMER", 15000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "ERUPTION_TIMER":
|
||||
{
|
||||
addSkillCastDesire(npc, npc, ISTINA_ERUPTION_SKILL, 23);
|
||||
showOnScreenMsg(instance, NpcStringId.POWERFUL_ACIDIC_ENERGY_IS_ERUPTING_FROM_ISTINA_S_BODY, ExShowScreenMessage.TOP_CENTER, 6000);
|
||||
getTimers().addTimer("ERUPTION_TIMER", 50000 + getRandom(15000), npc, null);
|
||||
break;
|
||||
}
|
||||
case "BALLISTA_START_TIMER":
|
||||
{
|
||||
final int helpCountDown = npcVars.getInt("HELP_COUNT_DOWN", 5);
|
||||
if (helpCountDown == 0)
|
||||
{
|
||||
getTimers().addTimer("BALLISTA_CHECK_TIMER", 1000, npc, null);
|
||||
npc.setTargetable(true);
|
||||
npc.setIsInvul(false);
|
||||
npcVars.set("COUNTING_ENABLED", true);
|
||||
showOnScreenMsg(instance, NpcStringId.START_CHARGING_MANA_BALLISTA, ExShowScreenMessage.MIDDLE_CENTER, 4000);
|
||||
}
|
||||
else
|
||||
{
|
||||
showOnScreenMsg(instance, NpcStringId.AFTER_S1_SECONDS_THE_CHARGING_MAGIC_BALLISTAS_STARTS, ExShowScreenMessage.MIDDLE_CENTER, 4000, Integer.toString(helpCountDown));
|
||||
npcVars.set("HELP_COUNT_DOWN", helpCountDown - 1);
|
||||
getTimers().addTimer("BALLISTA_START_TIMER", 1000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "BALLISTA_CHECK_TIMER":
|
||||
{
|
||||
if (npcVars.getBoolean("COUNTING_ENABLED", false))
|
||||
{
|
||||
final int countDown = npcVars.getInt("COUNT_DOWN", 30);
|
||||
final int charged = getChargedPercent(npcVars.getInt("SCORE_VAL", 0), isExtremeMode(instance));
|
||||
|
||||
if (countDown == 0)
|
||||
{
|
||||
npcVars.set("COUNTING_ENABLED", false);
|
||||
npc.setTargetable(false);
|
||||
npc.setIsInvul(true);
|
||||
getTimers().addTimer("BALLISTA_END_TIMER", 1000, npc, null);
|
||||
instance.getPlayers().forEach(temp -> temp.sendPacket(new ExSendUIEvent(temp, 2, countDown, charged, 0, 2042, 0, NpcStringId.REPLENISH_BALLISTA_MAGIC_POWER.getId())));
|
||||
}
|
||||
|
||||
npcVars.set("HELP_COUNT_DOWN", npcVars.getInt("HELP_COUNT_DOWN", 0) + 1);
|
||||
if (npcVars.getInt("HELP_COUNT_DOWN", 0) == 2)
|
||||
{
|
||||
npcVars.set("COUNT_DOWN", countDown - 1);
|
||||
npcVars.set("HELP_COUNT_DOWN", 0);
|
||||
instance.getPlayers().forEach(temp -> temp.sendPacket(new ExSendUIEvent(temp, 2, countDown, charged, 0, 2042, 0, NpcStringId.REPLENISH_BALLISTA_MAGIC_POWER.getId())));
|
||||
}
|
||||
getTimers().addTimer("BALLISTA_CHECK_TIMER", 500, npc, null);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "BALLISTA_END_TIMER":
|
||||
{
|
||||
if (getChargedPercent(npcVars.getInt("SCORE_VAL", 0), isExtremeMode(instance)) >= getRandom(100))
|
||||
{
|
||||
playMovie(instance, Movie.SC_ISTINA_ENDING_A);
|
||||
instance.setStatus(3);
|
||||
getTimers().addTimer("INSTANCE_FINISH_TIMER", 23000, npc, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
playMovie(instance, Movie.SC_ISTINA_ENDING_B);
|
||||
instance.setStatus(4);
|
||||
getTimers().addTimer("INSTANCE_FINISH_TIMER", 22000, npc, null);
|
||||
}
|
||||
instance.getAliveNpcs(ISTINA).forEach(istina ->
|
||||
{
|
||||
istina.teleToLocation(instance.getEnterLocation());
|
||||
istina.setInvisible(true);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "INSTANCE_FINISH_TIMER":
|
||||
{
|
||||
getTimers().addTimer("NPC_DELETE", 3000, evnt -> npc.deleteMe());
|
||||
instance.finishInstance();
|
||||
instance.getAliveNpcs(L2Attackable.class, ISTINA).forEach(istina ->
|
||||
{
|
||||
istina.teleToLocation(DEFEAT_ISTINA_LOC);
|
||||
istina.setInvisible(false);
|
||||
istina.setUndying(false);
|
||||
istina.reduceCurrentHp(istina.getVariables().getInt("REWARD_DAMAGE", 1000000), istina.getVariables().getObject("REWARD_PLAYER", L2PcInstance.class), null);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "AUTHORITY_TIMER":
|
||||
{
|
||||
final int random = getRandom(1, 3);
|
||||
final SkillHolder authoritySkill = npcParams.getSkillHolder("Istina_Authority_Skill0" + random);
|
||||
if (authoritySkill != null)
|
||||
{
|
||||
addSkillCastDesire(npc, npc, authoritySkill, 23);
|
||||
instance.broadcastPacket(new PlaySound(1, "Npcdialog1.istina_voice_01", 0, 0, 0, 0, 0));
|
||||
|
||||
switch (random)
|
||||
{
|
||||
case 1:
|
||||
showOnScreenMsg(instance, NpcStringId.ISTINA_S_SOUL_STONE_STARTS_POWERFULLY_ILLUMINATING_IN_RED, ExShowScreenMessage.TOP_CENTER, 6000);
|
||||
break;
|
||||
case 2:
|
||||
showOnScreenMsg(instance, NpcStringId.ISTINA_S_SOUL_STONE_STARTS_POWERFULLY_ILLUMINATING_IN_BLUE, ExShowScreenMessage.TOP_CENTER, 6000);
|
||||
break;
|
||||
case 3:
|
||||
showOnScreenMsg(instance, NpcStringId.ISTINA_S_SOUL_STONE_STARTS_POWERFULLY_ILLUMINATING_IN_GREEN, ExShowScreenMessage.TOP_CENTER, 6000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
getTimers().addTimer("AUTHORITY_TIMER", 70000 + getRandom(25000), npc, null);
|
||||
break;
|
||||
}
|
||||
case "AUTHORITY_END_TIMER":
|
||||
{
|
||||
// gg->Area_SetOnOffEx(Istina_Authority_AreaData1, @OFF, myself->InstantZone_GetId());
|
||||
// gg->Area_SetOnOffEx(Istina_Authority_AreaData2, @OFF, myself->InstantZone_GetId());
|
||||
// gg->Area_SetOnOffEx(Istina_Authority_AreaData3, @OFF, myself->InstantZone_GetId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if ((skill != null) && isInInstance(instance))
|
||||
{
|
||||
final int skillId = skill.getId();
|
||||
|
||||
if (npc.getId() == INVISIBLE_NPC)
|
||||
{
|
||||
if (skillId == ERUPTION_1.getSkillId())
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(ERUPTION_2.getSkill());
|
||||
}
|
||||
else if (skillId == ERUPTION_2.getSkillId())
|
||||
{
|
||||
getTimers().addTimer("NPC_DELETE", 2000, event -> npc.deleteMe());
|
||||
|
||||
if (isExtremeMode(instance) && (getRandom(100) < 30))
|
||||
{
|
||||
addAttackPlayerDesire(addSpawn(EXTREME_MINION, npc, false, 0, false, instance.getId()), npc.getVariables().getObject("ERUPTION_TARGET", L2PcInstance.class), 23);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final StatsSet npcParams = npc.getParameters();
|
||||
|
||||
if (skillId == npcParams.getSkillHolder("Istina_Death_Skill01").getSkillId())
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.ISTINA_S_MARK_SHINES_ABOVE_THE_HEAD, ExShowScreenMessage.TOP_CENTER, 4000);
|
||||
getTimers().addTimer("DEATH_CHECK_TIMER", 10000, npc, null);
|
||||
}
|
||||
else if (skillId == npcParams.getSkillHolder("Istina_Refraction_Skill").getSkillId())
|
||||
{
|
||||
npc.setDisplayEffect(1);
|
||||
getTimers().addTimer("REFLECT_CHECK_TIMER", 1000, npc, null);
|
||||
}
|
||||
else if (skillId == ISTINA_ERUPTION_SKILL.getSkillId())
|
||||
{
|
||||
((L2Attackable) npc).getAggroList().values().stream().sorted(Comparator.comparingInt(AggroInfo::getHate)).map(AggroInfo::getAttacker).limit(5).forEach(character ->
|
||||
{
|
||||
final L2Npc eruption = addSpawn(INVISIBLE_NPC, Util.getRandomPosition(character, 150, 150), false, 0, false, instance.getId());
|
||||
eruption.getVariables().set("ERUPTION_TARGET", character);
|
||||
});
|
||||
}
|
||||
else if (skillId == npcParams.getSkillHolder("Istina_Authority_Skill01").getSkillId())
|
||||
{
|
||||
// gg->Area_SetOnOffEx(Istina_Authority_AreaData2, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
|
||||
// gg->Area_SetOnOffEx(Istina_Authority_AreaData3, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
|
||||
getTimers().addTimer("AUTHORITY_END_TIMER", 15000, npc, null);
|
||||
}
|
||||
else if (skillId == npcParams.getSkillHolder("Istina_Authority_Skill02").getSkillId())
|
||||
{
|
||||
// gg->Area_SetOnOffEx(Istina_Authority_AreaData1, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
|
||||
// gg->Area_SetOnOffEx(Istina_Authority_AreaData3, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
|
||||
getTimers().addTimer("AUTHORITY_END_TIMER", 15000, npc, null);
|
||||
}
|
||||
else if (skillId == npcParams.getSkillHolder("Istina_Authority_Skill03").getSkillId())
|
||||
{
|
||||
// gg->Area_SetOnOffEx(Istina_Authority_AreaData1, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
|
||||
// gg->Area_SetOnOffEx(Istina_Authority_AreaData2, @ON, myself->InstantZone_GetId()); // TODO: Need be finished after zone rework
|
||||
getTimers().addTimer("AUTHORITY_END_TIMER", 15000, npc, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
final StatsSet npcVars = npc.getVariables();
|
||||
final int stage = npcVars.getInt("ISTINA_STAGE", -1);
|
||||
|
||||
if (npc.getId() == BALLISTA)
|
||||
{
|
||||
if (npcVars.getBoolean("COUNTING_ENABLED", false))
|
||||
{
|
||||
final int score = npcVars.getInt("SCORE_VAL", 0);
|
||||
|
||||
if (getChargedPercent(score, isExtremeMode(instance)) < 100)
|
||||
{
|
||||
int addScore = damage;
|
||||
|
||||
if (skill != null)
|
||||
{
|
||||
if (skill.getEffectPoint() < 0)
|
||||
{
|
||||
addScore *= 1.5;
|
||||
}
|
||||
addScore *= 1.5;
|
||||
}
|
||||
|
||||
if (attacker.isInCategory(CategoryType.FIGHTER_GROUP))
|
||||
{
|
||||
addScore *= 2;
|
||||
}
|
||||
npcVars.set("SCORE_VAL", score + addScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (stage)
|
||||
{
|
||||
case -1:
|
||||
{
|
||||
instance.setStatus(1);
|
||||
npcVars.set("ISTINA_STAGE", 1);
|
||||
instance.getDoors().forEach(L2DoorInstance::closeMe);
|
||||
npc.setUndying(true);
|
||||
((L2Attackable) npc).setCanReturnToSpawnPoint(false);
|
||||
getTimers().addTimer("DEATH_TIMER", 3500, npc, null);
|
||||
getTimers().addTimer("REFLECT_TIMER", 3500, npc, null);
|
||||
getTimers().addTimer("LOW_ERUPTION_TIMER", 15000, npc, null);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (npc.getCurrentHpPercent() < 85)
|
||||
{
|
||||
npcVars.set("ISTINA_STAGE", 2);
|
||||
getTimers().addTimer("AUTHORITY_TIMER", 3000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if (npc.getCurrentHpPercent() < 70)
|
||||
{
|
||||
npcVars.set("ISTINA_STAGE", 3);
|
||||
if (isExtremeMode(instance))
|
||||
{
|
||||
// myself->AddTimerEx(Seal_Timer, (3 * 1000));
|
||||
}
|
||||
// myself->AddTimerEx(Overcrowding_Timer, (10 * 1000));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if (npc.getCurrentHpPercent() < 55)
|
||||
{
|
||||
npcVars.set("ISTINA_STAGE", 4);
|
||||
getTimers().addTimer("ERUPTION_TIMER", 50000, npc, null);
|
||||
// myself->AddTimerEx(Creation_Timer, (Creation_Timer_Interval * 1000));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
if (npc.getCurrentHpPercent() < 40)
|
||||
{
|
||||
npcVars.set("ISTINA_STAGE", 5);
|
||||
if (isExtremeMode(instance))
|
||||
{
|
||||
// myself->AddTimerEx(Order_Timer, (Order_Timer_Interval * 100));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
if (npc.getCurrentHpPercent() < 0.01)
|
||||
{
|
||||
setPlayerRewardInfo(npc);
|
||||
npcVars.set("ISTINA_STAGE", 6);
|
||||
getTimers().cancelTimer("DEATH_TIMER", npc, null);
|
||||
getTimers().cancelTimer("DEATH_CHECK_TIMER", npc, null);
|
||||
getTimers().cancelTimer("REFLECT_TIMER", npc, null);
|
||||
getTimers().cancelTimer("REFLECT_CHECK_TIMER", npc, null);
|
||||
getTimers().cancelTimer("AUTHORITY_TIMER", npc, null);
|
||||
getTimers().cancelTimer("ERUPTION_TIMER", npc, null);
|
||||
getTimers().cancelTimer("LOW_ERUPTION_TIMER", npc, null);
|
||||
// myself->BlockTimer(Overcrowding_Timer);
|
||||
if (isExtremeMode(instance))
|
||||
{
|
||||
// myself->BlockTimer(Seal_Timer);
|
||||
// myself->BlockTimer(Order_Timer);
|
||||
}
|
||||
instance.getAliveNpcs(EXTREME_MINION, INVISIBLE_NPC).forEach(L2Npc::deleteMe);
|
||||
instance.spawnGroup("BALLISTA");
|
||||
instance.setStatus(2);
|
||||
instance.getAliveNpcs(RUMIESE_INSTANCE).forEach(rumiese -> rumiese.teleToLocation(RUMIESE_LOC));
|
||||
instance.getDoors().forEach(L2DoorInstance::openMe);
|
||||
// myself->AddTimerEx(Broadcast_Timer, (2 * 1000));
|
||||
onTimerEvent("AUTHORITY_END_TIMER", null, npc, null);
|
||||
// myself->AddTimerEx(Location_Check_Timer, (4 * 1000));
|
||||
npc.disableCoreAI(true);
|
||||
npc.teleToLocation(DEFEAT_ISTINA_LOC);
|
||||
npc.setDisplayEffect(3);
|
||||
npc.setTargetable(false);
|
||||
playMovie(instance, Movie.SC_ISTINA_BRIDGE);
|
||||
instance.finishInstance(15);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
if (npc.getId() == INVISIBLE_NPC)
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(ERUPTION_1.getSkill());
|
||||
}
|
||||
else if (npc.getId() == BALLISTA)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
npc.setUndying(true);
|
||||
npc.setIsInvul(true);
|
||||
npc.setTargetable(false);
|
||||
getTimers().addTimer("BALLISTA_START_TIMER", 10000, npc, null);
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = null;
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (instance.getStatus())
|
||||
{
|
||||
case 0:
|
||||
htmltext = "33293-01.html";
|
||||
break;
|
||||
case 1:
|
||||
htmltext = "33293-02.html";
|
||||
break;
|
||||
case 2:
|
||||
htmltext = "33293-03.html";
|
||||
break;
|
||||
case 3:
|
||||
htmltext = "33293-04.html";
|
||||
break;
|
||||
case 4:
|
||||
htmltext = "33293-05.html";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
private boolean isExtremeMode(Instance instance)
|
||||
{
|
||||
return instance.getTemplateId() == TEMPLATE_ID_EXTREME;
|
||||
}
|
||||
|
||||
private int getChargedPercent(int score, boolean isExtreme)
|
||||
{
|
||||
final int charged;
|
||||
if (score >= (isExtreme ? PERFECT_SCORE_2 : PERFECT_SCORE_1))
|
||||
{
|
||||
charged = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
charged = (score * 100) / (isExtreme ? PERFECT_SCORE_2 : PERFECT_SCORE_1);
|
||||
}
|
||||
return charged;
|
||||
}
|
||||
|
||||
private L2PcInstance setPlayerRewardInfo(L2Npc npc)
|
||||
{
|
||||
final Map<L2PcInstance, DamageDoneInfo> rewards = new ConcurrentHashMap<>();
|
||||
final StatsSet npcVars = npc.getVariables();
|
||||
L2PcInstance maxDealer = null;
|
||||
int maxDamage = 0;
|
||||
int totalDamage = 0;
|
||||
|
||||
for (AggroInfo info : ((L2Attackable) npc).getAggroList().values())
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final L2PcInstance attacker = info.getAttacker().getActingPlayer();
|
||||
if (attacker != null)
|
||||
{
|
||||
final int damage = info.getDamage();
|
||||
if (damage > 1)
|
||||
{
|
||||
if (!Util.checkIfInRange(Config.ALT_PARTY_RANGE, npc, attacker, true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final DamageDoneInfo reward = rewards.computeIfAbsent(attacker, DamageDoneInfo::new);
|
||||
reward.addDamage(damage);
|
||||
|
||||
if (reward.getDamage() > maxDamage)
|
||||
{
|
||||
maxDealer = attacker;
|
||||
maxDamage = reward.getDamage();
|
||||
}
|
||||
totalDamage += damage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
npcVars.set("REWARD_PLAYER", maxDealer);
|
||||
npcVars.set("REWARD_DAMAGE", totalDamage);
|
||||
return maxDealer;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new IstinaCavern();
|
||||
}
|
||||
}
|
7
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/33098-01.html
vendored
Normal file
7
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/33098-01.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<html><body>Noeti Mimilead:<br>
|
||||
We tracked down Kimerian only to find him deranged and very, very dangerous!<br>
|
||||
Please, you must stop him before the Magmeld Fairies are gone forever! We want to help, too, and will send the bravest of the warrior fairies, Naomi Kasheron, to fight alongside you.<br>
|
||||
This is <font color="LEVEL">Glimmer</font>, which you need to use when the fairies that are helping you become weak and defenseless. The <font color="LEVEL">Glimmer</font> will be very useful.<br>
|
||||
You should also remember to use the <font color="LEVEL">Fairy's Leaf Flute</font>, if you have it! Its melodies will attract other fairies to fight alongside you!<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest KimerianCommon giveFlute">"Let's try that..."</Button>
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/33098-02.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/33098-02.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Noeti Mimilead:<br>
|
||||
I don't think you have the Fairy's Leaf Flute! Remember, if you collect and bring me Certificates of Friendship, I can give you the Fairy's Leaf Flute. You can get Certificates of Friendship from the Fairy being held by Timiniel.
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/33098-03.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/33098-03.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Noeti Mimilead:<br>
|
||||
Podvodn<EFBFBD>k chlupat<61> hnusn<73>! (noeti_mymirid_indun1002.htm)
|
||||
</body></html>
|
5
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/33131-01.html
vendored
Normal file
5
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/33131-01.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Noeti Mimilead:<br>
|
||||
You faced Kimerian, even stood toe to toe with him!<br1>
|
||||
This is amazing! Even though Kimerian ran away in the end, he'll at least know that he can't just rampage around as he pleases anymore. Thank you!<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h KimerianCommon zdrhamCus">"You're welcome. I will now head back to the village."</Button>
|
||||
</body></html>
|
462
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/KimerianCommon.java
vendored
Normal file
462
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/KimerianCommon.java
vendored
Normal file
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.bosses.Kimerian;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.CategoryType;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureDeath;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureSee;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Kimerian Common instance zone.
|
||||
* @author St3eT, Gladicek
|
||||
*/
|
||||
public final class KimerianCommon extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int KIMERIAN = 25745;
|
||||
private static final int KIMERIAN_GHOST = 25746;
|
||||
private static final int KIMERIAN_DEAD = 25747;
|
||||
private static final int NOETI_KASHERON = 32896;
|
||||
private static final int NOETI_KASHERON_ENTRANCE = 33098;
|
||||
private static final int NOETI_KASHERON_LEAVE = 33131;
|
||||
private static final int NEOMI_KASHERON = 32914;
|
||||
private static final int FAIRY_REBEL = 32913;
|
||||
private static final int INVISIBLE_NPC = 33137;
|
||||
private static final int KIMERIAN_HOLLOW = 25745;
|
||||
private static final int KIMERIAN_HOLLOW_2 = 25746;
|
||||
private static final int FAIRY_WARRIOR = 25735;
|
||||
private static final int SATYR_WITCH = 25740;
|
||||
private static final int FAIRY_ROGUE = 25736;
|
||||
// Skills
|
||||
private static final SkillHolder INVUL_SKILL = new SkillHolder(14190, 1);
|
||||
// Items
|
||||
private static final int GLIMMER = 17374;
|
||||
private static final int FLUTE = 17378; // Fairy's Leaf Flute
|
||||
// Misc
|
||||
private static final NpcStringId[] KIMERIAN_MSG =
|
||||
{
|
||||
NpcStringId.THEY_ARE_ROOKIE_REBELLIONS,
|
||||
NpcStringId.RESISTANCE_UNDERLINGS,
|
||||
NpcStringId.TREASON_IS_PUNISHABLE_BY_DEATH,
|
||||
NpcStringId.WHO_DO_YOU_THINK_YOU_ARE_TO_TRY_MY_AUTHORITY,
|
||||
};
|
||||
private static final int TEMPLATE_ID = 161;
|
||||
|
||||
public KimerianCommon()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(NOETI_KASHERON);
|
||||
addTalkId(NOETI_KASHERON, NOETI_KASHERON_ENTRANCE);
|
||||
addFirstTalkId(NOETI_KASHERON_ENTRANCE, NOETI_KASHERON_LEAVE);
|
||||
addSpawnId(FAIRY_REBEL, NEOMI_KASHERON, INVISIBLE_NPC, KIMERIAN);
|
||||
addAttackId(KIMERIAN);
|
||||
addKillId(KIMERIAN_GHOST, KIMERIAN);
|
||||
setCreatureSeeId(this::onCreatureSee, FAIRY_REBEL, NEOMI_KASHERON, INVISIBLE_NPC, KIMERIAN);
|
||||
setCreatureKillId(this::onCreatureKill, FAIRY_REBEL, NEOMI_KASHERON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "HELPER_TIME_ACTION":
|
||||
{
|
||||
player = npc.getVariables().getObject("PC_INSTANCE", L2PcInstance.class);
|
||||
if (player != null)
|
||||
{
|
||||
final double distance = npc.calculateDistance(player, false, false);
|
||||
if (distance > 1000)
|
||||
{
|
||||
npc.teleToLocation(new Location(player.getX() + getRandom(-100, 100), player.getY() + getRandom(-100, 100), player.getZ() + 50));
|
||||
}
|
||||
else if (!npc.isAttackingNow() && (distance > 250))
|
||||
{
|
||||
npc.setIsRunning(true);
|
||||
addMoveToDesire(npc, new Location(player.getX() + getRandom(-100, 100), player.getY() + getRandom(-100, 100), player.getZ() + 50), 23);
|
||||
}
|
||||
else if (!npc.isInCombat() || !npc.isAttackingNow() || (npc.getTarget() == null))
|
||||
{
|
||||
final L2Character monster = (L2Character) player.getTarget();
|
||||
if ((monster != null) && (monster instanceof L2MonsterInstance) && player.isInCombat())
|
||||
{
|
||||
addAttackDesire(npc, monster);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
getTimers().cancelTimersOf(npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "KIMERIAN_INVUL_END":
|
||||
{
|
||||
if (npc.getVariables().getBoolean("INVUL_CAN_BE_CANCELLED", true))
|
||||
{
|
||||
npc.getVariables().set("INVUL_CAN_BE_CANCELLED", false);
|
||||
npc.getEffectList().stopSkillEffects(true, INVUL_SKILL.getSkillId());
|
||||
npc.disableCoreAI(false);
|
||||
npc.setTargetable(true);
|
||||
addAttackPlayerDesire(npc, player, 23);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = null;
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "giveFlute":
|
||||
{
|
||||
if (npc.getVariables().getBoolean("CAN_SPAWN_SUPPORT", true))
|
||||
{
|
||||
if (hasQuestItems(player, FLUTE))
|
||||
{
|
||||
if (player.isInCategory(CategoryType.AEORE_GROUP))
|
||||
{
|
||||
addSpawn(FAIRY_REBEL, player.getX() + 60, player.getY(), player.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_REBEL, player.getX() - 60, player.getY(), player.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_REBEL, player.getX(), player.getY() + 60, player.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_REBEL, player.getX(), player.getY() - 60, player.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_REBEL, player.getX() + 120, player.getY(), player.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_REBEL, player.getX() - 120, player.getY(), player.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_REBEL, player.getX(), player.getY() + 120, player.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_REBEL, player.getX(), player.getY() - 120, player.getZ(), 0, false, 0, false, instance.getId());
|
||||
takeItems(player, FLUTE, 1);
|
||||
npc.getVariables().set("CAN_SPAWN_SUPPORT", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
addSpawn(FAIRY_REBEL, player.getX() + 60, player.getY(), player.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_REBEL, player.getX() - 60, player.getY(), player.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_REBEL, player.getX(), player.getY() + 60, player.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_REBEL, player.getX(), player.getY() - 60, player.getZ(), 0, false, 0, false, instance.getId());
|
||||
takeItems(player, FLUTE, 1);
|
||||
npc.getVariables().set("CAN_SPAWN_SUPPORT", false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
htmltext = "33098-02.html";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
htmltext = "33098-03.html";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "zdrhamCus":
|
||||
{
|
||||
instance.destroy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (instance == null)
|
||||
{
|
||||
if (event.equals("enterInstance"))
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
if (npc.getId() == KIMERIAN)
|
||||
{
|
||||
if ((npc.getCurrentHpPercent() <= 50) && npc.getVariables().getBoolean("CAN_ACTIVATE_INVUL", true))
|
||||
{
|
||||
npc.getVariables().set("CAN_ACTIVATE_INVUL", false);
|
||||
npc.setTargetable(false);
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.PHANTOM_IMAGE);
|
||||
getTimers().addRepeatingTimer("KIMERIAN_INVUL_END", 60000, npc, player);
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
final L2Npc ghost = addSpawn(KIMERIAN_GHOST, npc.getX(), npc.getY(), npc.getZ(), Util.calculateHeadingFrom(npc, player), false, 0, false, instance.getId());
|
||||
addAttackPlayerDesire(ghost, player, 23);
|
||||
}
|
||||
|
||||
npc.disableCoreAI(true);
|
||||
npc.breakAttack();
|
||||
npc.breakCast();
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
|
||||
getTimers().addTimer("KIMERIAN_INVUL_START", 6000, n ->
|
||||
{
|
||||
addSkillCastDesire(npc, npc, INVUL_SKILL, 23);
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.FOOLISH_INSIGNIFICANT_CREATURES_HOW_DARE_YOU_CHALLENGE_ME);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, player, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case KIMERIAN_GHOST:
|
||||
{
|
||||
final int killedCount = instance.getParameters().getInt("GHOST_KILLED_COUNT", 0) + 1;
|
||||
instance.getParameters().set("GHOST_KILLED_COUNT", killedCount);
|
||||
|
||||
if (killedCount >= 5)
|
||||
{
|
||||
onTimerEvent("KIMERIAN_INVUL_END", null, npc, killer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KIMERIAN:
|
||||
{
|
||||
instance.finishInstance(5);
|
||||
final L2Npc kimerian = addSpawn(KIMERIAN_DEAD, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
final Location loc = Util.getRandomPosition(kimerian, 500, 500);
|
||||
kimerian.setInvisible(true);
|
||||
playSound(killer, "RM01_S");
|
||||
getTimers().addTimer("KIMERIAN_VISIBLE", 4000, t -> kimerian.setInvisible(false));
|
||||
getTimers().addTimer("KIMERIAN_CHAT_1", 5000, t -> kimerian.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.I_WILL_COME_BACK_ALIVE_WITH_ROTTING_AURA));
|
||||
getTimers().addTimer("KIMERIAN_RUN", 6000, t ->
|
||||
{
|
||||
kimerian.setIsRunning(true);
|
||||
addMoveToDesire(kimerian, loc, 23);
|
||||
kimerian.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.HA_HA_HA_HA);
|
||||
});
|
||||
getTimers().addTimer("KIMERIAN_SPAWN_DEFKA", 7000, t ->
|
||||
{
|
||||
kimerian.deleteMe();
|
||||
final L2Npc noeti = addSpawn(NOETI_KASHERON_LEAVE, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
getTimers().addTimer("NOETI_SAY2", 3000, n -> noeti.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.UNFORTUNATELY_THEY_RAN_AWAY));
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public void onCreatureKill(OnCreatureDeath event)
|
||||
{
|
||||
final L2Npc npc = (L2Npc) event.getTarget();
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
getTimers().cancelTimersOf(npc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case FAIRY_REBEL:
|
||||
case NEOMI_KASHERON:
|
||||
{
|
||||
npc.initSeenCreatures();
|
||||
npc.setIsRunning(true);
|
||||
break;
|
||||
}
|
||||
case INVISIBLE_NPC:
|
||||
case KIMERIAN:
|
||||
{
|
||||
npc.initSeenCreatures();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = null;
|
||||
switch (npc.getId())
|
||||
{
|
||||
case NOETI_KASHERON_ENTRANCE:
|
||||
{
|
||||
if (npc.getVariables().getBoolean("CAN_GET_GLIMMER", true))
|
||||
{
|
||||
giveItems(player, GLIMMER, 10);
|
||||
npc.getVariables().set("CAN_GET_GLIMMER", false);
|
||||
}
|
||||
htmltext = "33098-01.html";
|
||||
break;
|
||||
}
|
||||
case NOETI_KASHERON_LEAVE:
|
||||
{
|
||||
htmltext = " 33131-01.html";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
public void onCreatureSee(OnCreatureSee event)
|
||||
{
|
||||
final L2Character creature = event.getSeen();
|
||||
final L2Npc npc = (L2Npc) event.getSeer();
|
||||
final StatsSet npcParams = npc.getParameters();
|
||||
final StatsSet npcVars = npc.getVariables();
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case FAIRY_REBEL:
|
||||
case NEOMI_KASHERON:
|
||||
{
|
||||
if (creature.isPlayer() && (npcVars.getObject("PC_INSTANCE", L2PcInstance.class) == null))
|
||||
{
|
||||
npcVars.set("PC_INSTANCE", creature.getActingPlayer());
|
||||
getTimers().addRepeatingTimer("HELPER_TIME_ACTION", 2000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INVISIBLE_NPC:
|
||||
{
|
||||
final int hollow = npcParams.getInt("hollow", -1);
|
||||
final int trap = npcParams.getInt("trap", -1);
|
||||
|
||||
if (creature.isPlayer() && npc.isScriptValue(0))
|
||||
{
|
||||
if (hollow == 1)
|
||||
{
|
||||
spawnHollow(npc, creature.getActingPlayer(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (trap)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
spawnHollow(npc, creature.getActingPlayer(), false);
|
||||
addSpawn(FAIRY_WARRIOR, npc.getX() + 80, npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_WARRIOR, npc.getX(), npc.getY() + 80, npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(SATYR_WITCH, npc.getX() + 50, npc.getY() + 50, npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
spawnHollow(npc, creature.getActingPlayer(), false);
|
||||
addSpawn(SATYR_WITCH, npc.getX() + 80, npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(SATYR_WITCH, npc.getX(), npc.getY() + 80, npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_ROGUE, npc.getX() + 50, npc.getY() + 50, npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
spawnHollow(npc, creature.getActingPlayer(), false);
|
||||
addSpawn(FAIRY_WARRIOR, npc.getX() + 80, npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(SATYR_WITCH, npc.getX(), npc.getY() + 80, npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
addSpawn(FAIRY_ROGUE, npc.getX() + 50, npc.getY() + 50, npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KIMERIAN:
|
||||
{
|
||||
if (creature.isPlayer() && npcVars.getBoolean("FIGHT_CAN_START", true))
|
||||
{
|
||||
npc.broadcastSay(ChatType.NPC_GENERAL, KIMERIAN_MSG[getRandom(KIMERIAN_MSG.length)]);
|
||||
addAttackPlayerDesire(npc, creature.getActingPlayer(), 23);
|
||||
npcVars.set("FIGHT_CAN_START", false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnHollow(L2Npc npc, L2PcInstance player, boolean isHollow)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
if (isHollow)
|
||||
{
|
||||
final L2Npc kimerian = addSpawn(KIMERIAN_HOLLOW, npc.getX(), npc.getY(), npc.getZ(), Util.calculateHeadingFrom(npc, player), false, 0, false, instance.getId());
|
||||
kimerian.setTargetable(false);
|
||||
kimerian.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.HOW_RIDICULOUS_YOU_THINK_YOU_CAN_FIND_ME);
|
||||
getTimers().addTimer("KIMERIAN_HOLLOW_SAY_2", 3000, n -> kimerian.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.THEN_TRY_HA_HA_HA));
|
||||
getTimers().addTimer("KIMERIAN_HOLLOW_DELETE", 6000, n -> kimerian.deleteMe());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
final L2Npc kimerian = addSpawn(KIMERIAN_HOLLOW_2, npc.getX(), npc.getY(), npc.getZ(), Util.calculateHeadingFrom(npc, player), false, 0, false, instance.getId());
|
||||
kimerian.setTargetable(false);
|
||||
kimerian.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.YOU_RE_STILL_TRYING);
|
||||
getTimers().addTimer("KIMERIAN_HOLLOW_SAY_2", 3000, n -> kimerian.broadcastSay(ChatType.NPC_GENERAL, NpcStringId.HA_HA_HA_HA));
|
||||
getTimers().addTimer("KIMERIAN_HOLLOW_DELETE", 6000, n -> kimerian.deleteMe());
|
||||
}
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new KimerianCommon();
|
||||
}
|
||||
}
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/condParty.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Kimerian/condParty.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Elite Bodyguard Naomi Kasheron:<br>
|
||||
I will not take a party, friend. Just one. Just you.
|
||||
</body></html>
|
548
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/OctavisWarzone.java
vendored
Normal file
548
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/OctavisWarzone.java
vendored
Normal file
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.bosses.Octavis;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.gameserver.enums.Movie;
|
||||
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureSee;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.model.zone.type.L2ScriptZone;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowUsm;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Octavis Warzone instance zone.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class OctavisWarzone extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] OCTAVIS_STAGE_1 =
|
||||
{
|
||||
29191, // Common
|
||||
29209, // Extreme
|
||||
};
|
||||
private static final int[] OCTAVIS_STAGE_2 =
|
||||
{
|
||||
29193, // Common
|
||||
29211, // Extreme
|
||||
};
|
||||
private static final int[] OCTAVIS_STAGE_3 =
|
||||
{
|
||||
29194, // Common
|
||||
29212, // Extreme
|
||||
};
|
||||
private static final int[] BEASTS =
|
||||
{
|
||||
29192, // Common
|
||||
29210, // Extreme
|
||||
};
|
||||
private static final int[] BEASTS_MINIONS =
|
||||
{
|
||||
22929, // Common
|
||||
23087, // Extreme
|
||||
};
|
||||
private static final int[] GLADIATORS =
|
||||
{
|
||||
22928, // Common
|
||||
23086, // Extreme
|
||||
};
|
||||
private static final int LYDIA = 32892;
|
||||
private static final int DOOR_MANAGER = 18984;
|
||||
// Skills
|
||||
private static final SkillHolder STAGE_2_SKILL_1 = new SkillHolder(14026, 1);
|
||||
private static final SkillHolder STAGE_2_SKILL_2 = new SkillHolder(14027, 1);
|
||||
private static final SkillHolder STAGE_2_SKILL_3 = new SkillHolder(14575, 1);
|
||||
// Locations
|
||||
private static final Location BATTLE_LOC = new Location(208720, 120576, -10000);
|
||||
private static final Location OCTAVIS_SPAWN_LOC = new Location(207069, 120580, -9987);
|
||||
private static final Location BEASTS_RANDOM_POINT = new Location(207244, 120579, -10008);
|
||||
private static final Location[] BEASTS_MINIONS_LOC =
|
||||
{
|
||||
new Location(206681, 119327, -9987),
|
||||
new Location(207724, 119303, -9987),
|
||||
new Location(208472, 120047, -9987),
|
||||
new Location(208484, 121110, -9987),
|
||||
new Location(207730, 121859, -9987),
|
||||
new Location(206654, 121865, -9987),
|
||||
};
|
||||
// Zones
|
||||
private static final L2ScriptZone TELEPORT_ZONE = ZoneManager.getInstance().getZoneById(12042, L2ScriptZone.class);
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 180;
|
||||
private static final int EXTREME_TEMPLATE_ID = 181;
|
||||
private static final int MAIN_DOOR_1 = 26210002;
|
||||
private static final int MAIN_DOOR_2 = 26210001;
|
||||
|
||||
public OctavisWarzone()
|
||||
{
|
||||
super(TEMPLATE_ID, EXTREME_TEMPLATE_ID);
|
||||
addStartNpc(LYDIA);
|
||||
addTalkId(LYDIA);
|
||||
addSpawnId(DOOR_MANAGER);
|
||||
addSpawnId(GLADIATORS);
|
||||
addAttackId(OCTAVIS_STAGE_1);
|
||||
addAttackId(OCTAVIS_STAGE_2);
|
||||
addAttackId(BEASTS);
|
||||
addKillId(OCTAVIS_STAGE_1);
|
||||
addKillId(OCTAVIS_STAGE_2);
|
||||
addKillId(OCTAVIS_STAGE_3);
|
||||
addMoveFinishedId(GLADIATORS);
|
||||
addSpellFinishedId(OCTAVIS_STAGE_2);
|
||||
addEnterZoneId(TELEPORT_ZONE.getId());
|
||||
setCreatureSeeId(this::onCreatureSee, DOOR_MANAGER);
|
||||
addInstanceCreatedId(TEMPLATE_ID, EXTREME_TEMPLATE_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "enterEasyInstance":
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
break;
|
||||
}
|
||||
case "enterExtremeInstance":
|
||||
{
|
||||
enterInstance(player, npc, EXTREME_TEMPLATE_ID);
|
||||
break;
|
||||
}
|
||||
case "reenterInstance":
|
||||
{
|
||||
final Instance activeInstance = getPlayerInstance(player);
|
||||
if (isInInstance(activeInstance))
|
||||
{
|
||||
enterInstance(player, npc, activeInstance.getTemplateId());
|
||||
return "PartyMemberReenter.html";
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (isInInstance(world))
|
||||
{
|
||||
final StatsSet npcVars = npc.getVariables();
|
||||
final StatsSet npcParams = npc.getParameters();
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case "SECOND_DOOR_OPEN":
|
||||
{
|
||||
world.openCloseDoor(MAIN_DOOR_2, true);
|
||||
break;
|
||||
}
|
||||
case "CLOSE_DOORS":
|
||||
{
|
||||
world.openCloseDoor(MAIN_DOOR_2, false);
|
||||
world.openCloseDoor(MAIN_DOOR_1, false);
|
||||
world.getParameters().set("TELEPORT_ACTIVE", true);
|
||||
npc.teleToLocation(BATTLE_LOC);
|
||||
playMovie(world, Movie.SC_OCTABIS_OPENING);
|
||||
getTimers().addTimer("START_STAGE_1", 26500, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_STAGE_1":
|
||||
{
|
||||
world.spawnGroup("STAGE_1");
|
||||
world.getAliveNpcs(BEASTS).forEach(beasts ->
|
||||
{
|
||||
beasts.disableCoreAI(true);
|
||||
beasts.setUndying(true);
|
||||
((L2Attackable) beasts).setCanReturnToSpawnPoint(false);
|
||||
final L2Npc octavis = addSpawn((!isExtremeMode(world) ? OCTAVIS_STAGE_1[0] : OCTAVIS_STAGE_1[1]), OCTAVIS_SPAWN_LOC, false, 0, false, world.getId());
|
||||
octavis.disableCoreAI(true);
|
||||
octavis.setIsRunning(true);
|
||||
octavis.sendChannelingEffect(beasts, 1);
|
||||
octavis.setTargetable(false);
|
||||
((L2Attackable) octavis).setCanReturnToSpawnPoint(false);
|
||||
getTimers().addRepeatingTimer("FOLLOW_BEASTS", 500, octavis, null);
|
||||
getTimers().addRepeatingTimer("BEASTS_CHECK_HP", 5000, beasts, null);
|
||||
WalkingManager.getInstance().startMoving(beasts, "octabis_superpoint");
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "FOLLOW_BEASTS":
|
||||
{
|
||||
world.getAliveNpcs(BEASTS).forEach(beasts ->
|
||||
{
|
||||
addMoveToDesire(npc, beasts.getLocation(), 23);
|
||||
npc.sendChannelingEffect(beasts, 1);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "BEASTS_CHECK_HP":
|
||||
{
|
||||
final int hpPer = npc.getCurrentHpPercent();
|
||||
|
||||
if ((hpPer < 50) && npc.isScriptValue(0))
|
||||
{
|
||||
npc.getStat().addFixedValue(Stats.REGENERATE_HP_RATE, 95000d);
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
else if ((hpPer > 90) && npc.isScriptValue(1))
|
||||
{
|
||||
npc.getStat().addFixedValue(Stats.REGENERATE_HP_RATE, 0d);
|
||||
npc.setScriptValue(0);
|
||||
}
|
||||
|
||||
final L2Npc octavis = world.getAliveNpcs(OCTAVIS_STAGE_1).stream().findAny().orElse(null);
|
||||
if (octavis != null)
|
||||
{
|
||||
octavis.setTargetable(hpPer < 50);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "END_STAGE_1":
|
||||
{
|
||||
playMovie(world, Movie.SC_OCTABIS_PHASECH_A);
|
||||
getTimers().addTimer("START_STAGE_2", 12000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_STAGE_2":
|
||||
{
|
||||
world.spawnGroup("STAGE_2").forEach(octavis -> ((L2Attackable) octavis).setCanReturnToSpawnPoint(false));
|
||||
break;
|
||||
}
|
||||
case "END_STAGE_2":
|
||||
{
|
||||
playMovie(world, Movie.SC_OCTABIS_PHASECH_B);
|
||||
getTimers().addTimer("START_STAGE_3", 15000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "START_STAGE_3":
|
||||
{
|
||||
world.spawnGroup("STAGE_3").forEach(octavis -> ((L2Attackable) octavis).setCanReturnToSpawnPoint(false));
|
||||
break;
|
||||
}
|
||||
case "END_STAGE_3":
|
||||
{
|
||||
playMovie(world, Movie.SC_OCTABIS_ENDING);
|
||||
getTimers().addTimer("USM_SCENE_TIMER", 40000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "USM_SCENE_TIMER":
|
||||
{
|
||||
world.broadcastPacket(ExShowUsm.OCTAVIS_INSTANCE_END);
|
||||
break;
|
||||
}
|
||||
case "GLADIATOR_START_SPAWN":
|
||||
{
|
||||
final int spawnIndex = npcVars.getInt("SPAWN_INDEX", 1);
|
||||
if (spawnIndex < 7)
|
||||
{
|
||||
if (isExtremeMode(world))
|
||||
{
|
||||
world.spawnGroup("magmeld4_2621_gro" + spawnIndex + "m1");
|
||||
}
|
||||
else
|
||||
{
|
||||
world.spawnGroup("magmeld4_2621_gmo" + spawnIndex + "m1");
|
||||
}
|
||||
npcVars.set("SPAWN_INDEX", spawnIndex + 1);
|
||||
getTimers().addTimer("GLADIATOR_START_SPAWN", 3000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "GLADIATOR_MOVING":
|
||||
{
|
||||
final int moveX = npcParams.getInt("Move_to_X", 0);
|
||||
final int moveY = npcParams.getInt("Move_to_Y", 0);
|
||||
|
||||
if ((moveX != 0) && (moveY != 0))
|
||||
{
|
||||
npc.setIsRunning(true);
|
||||
addMoveToDesire(npc, new Location(moveX, moveY, -10008), 23);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "BEASTS_MINIONS_SPAWN":
|
||||
{
|
||||
final Location loc = BEASTS_MINIONS_LOC[getRandom(BEASTS_MINIONS_LOC.length)];
|
||||
final int count = getRandom(10);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
final L2Npc beast = addSpawn((!isExtremeMode(world) ? BEASTS_MINIONS[0] : BEASTS_MINIONS[1]), loc, false, 0, false, world.getId());
|
||||
beast.setIsRunning(true);
|
||||
((L2Attackable) beast).setCanReturnToSpawnPoint(false);
|
||||
addMoveToDesire(beast, Util.getRandomPosition(BEASTS_RANDOM_POINT, 500, 500), 23);
|
||||
}
|
||||
|
||||
getTimers().addTimer("BEASTS_MINIONS_SPAWN", 30000 + (getRandom(10) * 1000), npc, null);
|
||||
break;
|
||||
}
|
||||
case "MINION_CALL":
|
||||
{
|
||||
final L2PcInstance mostHated = ((L2Attackable) npc).getMostHated().getActingPlayer();
|
||||
if ((mostHated != null) && (mostHated.calculateDistance(npc, true, false) < 5000))
|
||||
{
|
||||
L2World.getInstance().getVisibleObjects(npc, L2Attackable.class, 4000, obj -> CommonUtil.contains(BEASTS_MINIONS, obj.getId()) || CommonUtil.contains(GLADIATORS, obj.getId())).forEach(minion ->
|
||||
{
|
||||
addAttackPlayerDesire(minion, mostHated, 23);
|
||||
});
|
||||
}
|
||||
getTimers().addTimer("MINION_CALL", 5000 + (getRandom(5) * 1000), npc, null);
|
||||
break;
|
||||
}
|
||||
case "ATTACK_TIMER":
|
||||
{
|
||||
final L2Character mostHated = ((L2Attackable) npc).getMostHated();
|
||||
if ((mostHated != null) && mostHated.isPlayable() && (npc.calculateDistance(mostHated, false, false) < 1000))
|
||||
{
|
||||
final int random = getRandom(5);
|
||||
if (random < 3)
|
||||
{
|
||||
addSkillCastDesire(npc, mostHated, STAGE_2_SKILL_1, 23);
|
||||
}
|
||||
else if (random < 5)
|
||||
{
|
||||
addSkillCastDesire(npc, mostHated, STAGE_2_SKILL_2, 23);
|
||||
}
|
||||
}
|
||||
getTimers().addTimer("ATTACK_TIMER", getRandom(7, 9) * 1000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "MEDUSA_SKILL_TIMER":
|
||||
{
|
||||
addSkillCastDesire(npc, npc, STAGE_2_SKILL_3, 23);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (isInInstance(world))
|
||||
{
|
||||
final int hpPer = npc.getCurrentHpPercent();
|
||||
|
||||
if (CommonUtil.contains(OCTAVIS_STAGE_1, npc.getId()))
|
||||
{
|
||||
if (hpPer >= 90)
|
||||
{
|
||||
npc.setDisplayEffect(0);
|
||||
}
|
||||
else if (hpPer >= 80)
|
||||
{
|
||||
npc.setDisplayEffect(1);
|
||||
}
|
||||
else if (hpPer >= 70)
|
||||
{
|
||||
npc.setDisplayEffect(2);
|
||||
}
|
||||
else if (hpPer >= 60)
|
||||
{
|
||||
npc.setDisplayEffect(3);
|
||||
}
|
||||
else if (hpPer >= 50)
|
||||
{
|
||||
npc.setDisplayEffect(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.setDisplayEffect(5);
|
||||
}
|
||||
}
|
||||
else if (CommonUtil.contains(OCTAVIS_STAGE_2, npc.getId()))
|
||||
{
|
||||
final StatsSet npcVars = npc.getVariables();
|
||||
|
||||
if (npcVars.getBoolean("START_TIMERS", true))
|
||||
{
|
||||
npcVars.set("START_TIMERS", false);
|
||||
getTimers().addTimer("GLADIATOR_START_SPAWN", 6000, npc, null);
|
||||
getTimers().addTimer("ATTACK_TIMER", 15000, npc, null);
|
||||
getTimers().addTimer("MINION_CALL", 30000, npc, null);
|
||||
// myself->AddTimerEx(Royal_Timer, 30 * 1000);
|
||||
// myself->AddTimerEx(Scan_Timer, 1000);
|
||||
getTimers().addTimer("BEASTS_MINIONS_SPAWN", 1000, npc, null);
|
||||
// myself->AddTimerEx(Gladiator_Fishnet_Timer, 15 * 1000);
|
||||
}
|
||||
|
||||
final int hpState = npcVars.getInt("HP_STATE", 0);
|
||||
if ((npc.getMaxHp() - npc.getCurrentHp()) > (npc.getMaxHp() * 0.01 * hpState))
|
||||
{
|
||||
final int state = hpState % 5;
|
||||
if (state == 0)
|
||||
{
|
||||
npc.setDisplayEffect(5);
|
||||
getTimers().addTimer("MEDUSA_SKILL_TIMER", 15000, npc, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.setDisplayEffect(state);
|
||||
}
|
||||
npcVars.set("HP_STATE", hpState + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (isInInstance(world))
|
||||
{
|
||||
if (CommonUtil.contains(OCTAVIS_STAGE_1, npc.getId()))
|
||||
{
|
||||
getTimers().cancelTimer("FOLLOW_BEASTS", npc, null);
|
||||
world.getAliveNpcs(BEASTS).forEach(beast ->
|
||||
{
|
||||
getTimers().cancelTimer("BEASTS_CHECK_HP", beast, null);
|
||||
beast.teleToLocation(new Location(-113360, -244676, -15536)); // Don't even ask, it's pure hack. - St3eT 2k16
|
||||
beast.deleteMe();
|
||||
});
|
||||
getTimers().addTimer("END_STAGE_1", 1000, npc, null);
|
||||
}
|
||||
else if (CommonUtil.contains(OCTAVIS_STAGE_2, npc.getId()))
|
||||
{
|
||||
// Cancel timers
|
||||
getTimers().cancelTimer("BEASTS_MINIONS_SPAWN", npc, null);
|
||||
getTimers().cancelTimer("MINION_CALL", npc, null);
|
||||
getTimers().cancelTimer("ATTACK_TIMER", npc, null);
|
||||
getTimers().cancelTimer("MEDUSA_SKILL_TIMER", npc, null);
|
||||
// Despawn beasts
|
||||
world.getAliveNpcs(BEASTS_MINIONS).forEach(beast -> beast.doDie(null));
|
||||
|
||||
// Despawn gladiators
|
||||
for (int i = 1; i < 7; i++)
|
||||
{
|
||||
world.despawnGroup(isExtremeMode(world) ? ("magmeld4_2621_gro" + i + "m1") : ("magmeld4_2621_gmo" + i + "m1"));
|
||||
}
|
||||
getTimers().addTimer("END_STAGE_2", 3000, npc, null);
|
||||
}
|
||||
else if (CommonUtil.contains(OCTAVIS_STAGE_3, npc.getId()))
|
||||
{
|
||||
world.finishInstance();
|
||||
getTimers().addTimer("END_STAGE_3", 2000, npc, null);
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceCreated(Instance instance, L2PcInstance player)
|
||||
{
|
||||
if ((player != null) && isInInstance(instance))
|
||||
{
|
||||
showHtmlFile(player, (instance.getTemplateId() == TEMPLATE_ID) ? "PartyEnterCommon.html" : "PartyEnterExtreme.html");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (isInInstance(world))
|
||||
{
|
||||
if (CommonUtil.contains(GLADIATORS, npc.getId()))
|
||||
{
|
||||
npc.setRandomWalking(false);
|
||||
world.openCloseDoor(npc.getParameters().getInt("My_DoorName", -1), true);
|
||||
getTimers().addTimer("GLADIATOR_MOVING", 3000, npc, null);
|
||||
}
|
||||
npc.initSeenCreatures();
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveFinished(L2Npc npc)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (isInInstance(world))
|
||||
{
|
||||
world.openCloseDoor(npc.getParameters().getInt("My_DoorName", -1), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if (skill.getId() == STAGE_2_SKILL_3.getSkillId())
|
||||
{
|
||||
npc.setDisplayEffect(6);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
public void onCreatureSee(OnCreatureSee event)
|
||||
{
|
||||
final L2Character creature = event.getSeen();
|
||||
final L2Npc npc = (L2Npc) event.getSeer();
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
|
||||
if (isInInstance(world) && creature.isPlayer() && npc.isScriptValue(0))
|
||||
{
|
||||
world.openCloseDoor(MAIN_DOOR_1, true);
|
||||
getTimers().addTimer("SECOND_DOOR_OPEN", 3000, npc, null);
|
||||
getTimers().addTimer("CLOSE_DOORS", 60000, npc, null);
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEnterZone(L2Character character, L2ZoneType zone)
|
||||
{
|
||||
final Instance world = character.getInstanceWorld();
|
||||
if (character.isPlayer() && isInInstance(world))
|
||||
{
|
||||
if (world.getParameters().getBoolean("TELEPORT_ACTIVE", false))
|
||||
{
|
||||
character.teleToLocation(BATTLE_LOC);
|
||||
}
|
||||
}
|
||||
return super.onEnterZone(character, zone);
|
||||
}
|
||||
|
||||
private boolean isExtremeMode(Instance instance)
|
||||
{
|
||||
return instance.getTemplateId() == EXTREME_TEMPLATE_ID;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new OctavisWarzone();
|
||||
}
|
||||
}
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/PartyEnterCommon.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/PartyEnterCommon.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
I will pray that you defeat Octavis... I hope your decision is the right one... I will pray.
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/PartyEnterExtreme.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/PartyEnterExtreme.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
I will pray that you save the soul of Octavis...
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/PartyMemberReenter.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/PartyMemberReenter.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
Please prove your decision is the right one and help your members.
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/condBigGroup.html
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/condBigGroup.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
That many people can't be moved.<br>
|
||||
(A maximum of 35 people can participate.)
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/condNoGroup.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/condNoGroup.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
As I explained earlier, you can enter only by forming an association.
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/condNoLevelCommon.html
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/condNoLevelCommon.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
I don't think you are quite prepared yet.<br>
|
||||
(Party includes character(s) <font color="LEVEL">under level 95</font>.)
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/condNoLevelExtreme.html
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Octavis/condNoLevelExtreme.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
I don't think you are quite prepared yet.<br>
|
||||
(Party includes character(s) <font color="LEVEL">under level 97</font>.)
|
||||
</body></html>
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.SeaOfSpores;
|
||||
package ai.bosses.Orfen;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.Wastelands;
|
||||
package ai.bosses.QueenAnt;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.StakatoNest;
|
||||
package ai.bosses.QueenShyeed;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.PrimevalIsle.Sailren;
|
||||
package ai.bosses.Sailren;
|
||||
|
||||
import com.l2jmobius.gameserver.instancemanager.GlobalVariablesManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.PrisonOfDarkness.Cannon;
|
||||
package ai.bosses.Spezion.Cannon;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -55,7 +55,6 @@ public final class Cannon extends AbstractNpcAI
|
||||
private static final int F_MEMORY_FRAGMENT = 17613; // Frightening Memory Fragment
|
||||
// Misc
|
||||
private static final Map<Integer, Integer> TRANSFORM_DATA = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
TRANSFORM_DATA.put(22965, 22979); // Novice Phantom -> Novice Escort Swordsman
|
@@ -14,7 +14,7 @@
|
||||
* 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.areas.PrisonOfDarkness;
|
||||
package ai.bosses.Spezion;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/33675.htm
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/33675.htm
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Finaria:<br>
|
||||
Welcome back! I've been waiting for you. A fierce battle between the <font color="LEVEL">Revolutionaries</font> and <font color="LEVEL">Kundas</font>.<br>
|
||||
Be careful! If all the <font color="LEVEL">Revolutionaries</font> fall, our plans to the end! Help <font color="LEVEL">Revolutionaries</font> to beat <font color="LEVEL">Kunda</font>. Before everyone power <font color="LEVEL">Revolutionaries</font> run out of, you must immediately kill <font color="LEVEL">Tauti</font>!<br>
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/33678-1.htm
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/33678-1.htm
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Teleport Device:<br>
|
||||
You do not have the key.<br>
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/33678-2.htm
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/33678-2.htm
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Teleport Device:<br>
|
||||
Mechanical device. Requires key.<br>
|
||||
<Button ALIGN=LEFT ICON="NORMAL" action="bypass -h Quest TautiWarzone useKey">"Use key"</Button>
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/33678-3.htm
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/33678-3.htm
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Teleport Device:<br>
|
||||
Teleport Device is now working.<br>
|
||||
<Button ALIGN=LEFT ICON="TELEPORT" action="bypass -h Quest TautiWarzone teleport">"Move"</Button>
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/PartyEnterCommon.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/PartyEnterCommon.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Sizrak:<br>
|
||||
I will pray that you defeat Tauti... I hope your decision is the right one... I will pray.
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/PartyEnterExtreme.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/PartyEnterExtreme.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Sizrak:<br>
|
||||
We will win! We must!
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/PartyMemberReenter.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/PartyMemberReenter.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Sizrak:<br>
|
||||
Please prove your decision is the right one and help your members.
|
||||
</body></html>
|
241
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/TautiWarzone.java
vendored
Normal file
241
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/TautiWarzone.java
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.bosses.Tauti;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Movie;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Tauti Warzone instance zone.
|
||||
* @author Mobius
|
||||
*/
|
||||
public final class TautiWarzone extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int FINARIA = 33675;
|
||||
private static final int ZAHAK = 19266;
|
||||
private static final int TELEPORTER = 33678;
|
||||
private static final int TAUTI_COMMON = 29233;
|
||||
private static final int TAUTI_EXTREME = 29234;
|
||||
private static final int TAUTI_COMMON_AXE = 29236;
|
||||
private static final int TAUTI_EXTREME_AXE = 29237;
|
||||
// Item
|
||||
private static final int KEY_OF_DARKNESS = 34899;
|
||||
// Teleport
|
||||
private static final Location TAUTI_TELEPORT = new Location(-148972, 209879, -10199);
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 218;
|
||||
private static final int EXTREME_TEMPLATE_ID = 219;
|
||||
private static final int DOOR_1 = 15240001;
|
||||
private static final int DOOR_2 = 15240002;
|
||||
|
||||
public TautiWarzone()
|
||||
{
|
||||
super(TEMPLATE_ID, EXTREME_TEMPLATE_ID);
|
||||
addTalkId(FINARIA, TELEPORTER);
|
||||
addFirstTalkId(FINARIA, TELEPORTER);
|
||||
addAttackId(TAUTI_COMMON, TAUTI_EXTREME);
|
||||
addKillId(ZAHAK, TAUTI_COMMON_AXE, TAUTI_EXTREME_AXE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "enterEasyInstance":
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
startQuestTimer("WORLD_STATUS_CHECK", 5000, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "enterExtremeInstance":
|
||||
{
|
||||
enterInstance(player, npc, EXTREME_TEMPLATE_ID);
|
||||
startQuestTimer("WORLD_STATUS_CHECK", 5000, null, player, false);
|
||||
break;
|
||||
}
|
||||
case "useKey":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (hasAtLeastOneQuestItem(player, KEY_OF_DARKNESS))
|
||||
{
|
||||
takeItems(player, KEY_OF_DARKNESS, -1);
|
||||
world.setStatus(3);
|
||||
return "33678-3.htm";
|
||||
}
|
||||
return "33678-1.htm";
|
||||
}
|
||||
case "teleport":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
world.setStatus(4);
|
||||
world.openCloseDoor(DOOR_2, true);
|
||||
for (L2PcInstance member : world.getPlayers())
|
||||
{
|
||||
member.teleToLocation(TAUTI_TELEPORT, world);
|
||||
startQuestTimer("PLAY_OPENING_B_MOVIE", 5000, null, member, false);
|
||||
}
|
||||
startQuestTimer("SPAWN_TAUTI", 60000, npc, null, false);
|
||||
break;
|
||||
}
|
||||
case "PLAY_OPENING_B_MOVIE":
|
||||
{
|
||||
playMovie(player, Movie.SC_TAUTI_OPENING_B);
|
||||
break;
|
||||
}
|
||||
case "SPAWN_TAUTI":
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
world.openCloseDoor(DOOR_1, true);
|
||||
world.spawnGroup("boss");
|
||||
break;
|
||||
}
|
||||
case "SPAWN_AXE":
|
||||
{
|
||||
final L2Npc axe = addSpawn(npc.getId() == TAUTI_EXTREME ? TAUTI_EXTREME_AXE : TAUTI_COMMON_AXE, npc, false, 0, false, npc.getInstanceId());
|
||||
axe.setRandomWalking(false);
|
||||
axe.setIsImmobilized(true);
|
||||
break;
|
||||
}
|
||||
case "WORLD_STATUS_CHECK":
|
||||
{
|
||||
if ((player == null) || (player.getInstanceId() == 0))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final Instance world = player.getInstanceWorld();
|
||||
if (world.isStatus(0))
|
||||
{
|
||||
world.setStatus(1);
|
||||
world.spawnGroup("room1");
|
||||
playMovie(world.getPlayers(), Movie.SC_TAUTI_OPENING);
|
||||
for (L2PcInstance member : world.getPlayers())
|
||||
{
|
||||
takeItems(member, KEY_OF_DARKNESS, -1);
|
||||
}
|
||||
startQuestTimer("WORLD_STATUS_CHECK", 5000, null, player, false);
|
||||
}
|
||||
else if (world.isStatus(1))
|
||||
{
|
||||
if (world.getAliveNpcs(L2MonsterInstance.class).isEmpty())
|
||||
{
|
||||
world.setStatus(2);
|
||||
final List<L2Npc> monsters = world.spawnGroup("room2");
|
||||
for (L2Npc monster : monsters)
|
||||
{
|
||||
monster.setRandomWalking(false);
|
||||
}
|
||||
}
|
||||
startQuestTimer("WORLD_STATUS_CHECK", 5000, null, player, false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
String htmltext = "";
|
||||
switch (npc.getId())
|
||||
{
|
||||
case FINARIA:
|
||||
{
|
||||
htmltext = "33675.htm";
|
||||
break;
|
||||
}
|
||||
case TELEPORTER:
|
||||
{
|
||||
final int worldStatus = npc.getInstanceWorld().getStatus();
|
||||
if (worldStatus > 2)
|
||||
{
|
||||
htmltext = "33678-3.htm";
|
||||
}
|
||||
else if ((worldStatus == 2) && hasAtLeastOneQuestItem(player, KEY_OF_DARKNESS))
|
||||
{
|
||||
htmltext = "33678-2.htm";
|
||||
}
|
||||
else
|
||||
{
|
||||
htmltext = "33678-1.htm";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world.isStatus(5) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.15)))
|
||||
{
|
||||
world.setStatus(6);
|
||||
npc.deleteMe();
|
||||
startQuestTimer("SPAWN_AXE", 15000, npc, null, false);
|
||||
playMovie(world.getPlayers(), Movie.SC_TAUTI_PHASE);
|
||||
}
|
||||
if (world.isStatus(4))
|
||||
{
|
||||
world.setStatus(5);
|
||||
world.openCloseDoor(DOOR_1, false);
|
||||
world.openCloseDoor(DOOR_2, false);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == ZAHAK)
|
||||
{
|
||||
npc.dropItem(killer, KEY_OF_DARKNESS, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
playMovie(world.getPlayers(), Movie.SC_TAUTI_ENDING);
|
||||
npc.deleteMe();
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceCreated(Instance instance, L2PcInstance player)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
showHtmlFile(player, instance.getTemplateId() == EXTREME_TEMPLATE_ID ? "PartyEnterExtreme.html" : "PartyEnterCommon.html");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new TautiWarzone();
|
||||
}
|
||||
}
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/condBigGroup.html
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/condBigGroup.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Sizrak:<br>
|
||||
That many people can't be moved.<br>
|
||||
(A maximum of 35 people can participate.)
|
||||
</body></html>
|
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/condNoGroup.html
vendored
Normal file
3
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/condNoGroup.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Sizrak:<br>
|
||||
As I explained earlier, you can enter only by forming an association.
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/condNoLevelCommon.html
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/condNoLevelCommon.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Sizrak:<br>
|
||||
I don't think you are quite prepared yet.<br>
|
||||
(Party includes character(s) <font color="LEVEL">under level 95</font>.)
|
||||
</body></html>
|
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/condNoLevelExtreme.html
vendored
Normal file
4
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Tauti/condNoLevelExtreme.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Sizrak:<br>
|
||||
I don't think you are quite prepared yet.<br>
|
||||
(Party includes character(s) <font color="LEVEL">under level 97</font>.)
|
||||
</body></html>
|
624
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Teredor/TeredorWarzone.java
vendored
Normal file
624
L2J_Mobius_Underground/dist/game/data/scripts/ai/bosses/Teredor/TeredorWarzone.java
vendored
Normal file
@@ -0,0 +1,624 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.bosses.Teredor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureSee;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Teredor Warzone instance zone.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class TeredorWarzone extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int FILAUR = 30535;
|
||||
private static final int TEREDOR = 25785;
|
||||
private static final int FAKE_TEREDOR = 25801;
|
||||
private static final int TEREDOR_POISON = 18998;
|
||||
private static final int BEETLE = 19024;
|
||||
private static final int POS_CHECKER = 18999;
|
||||
private static final int EGG_2 = 18997;
|
||||
private static final int ELITE_MILLIPADE = 19015;
|
||||
private static final int AWAKENED_MILLIPADE = 18995; // Awakened Millipede
|
||||
private static final int HATCHET_MILLIPADE = 18993; // Hatched Millipede
|
||||
private static final int HATCHET_UNDERBUG = 18994; // Hatched Underbug
|
||||
private static final int TEREDOR_LARVA = 19016; // Teredor's Larva
|
||||
private static final int MUTANTED_MILLIPADE = 19000; // Mutated Millipede
|
||||
// Items
|
||||
private static final int FAKE_TEREDOR_WEAPON = 15280;
|
||||
// Skill
|
||||
private static final SkillHolder FAKE_TEREDOR_JUMP_SKILL = new SkillHolder(6268, 1);
|
||||
private static final SkillHolder POISON_SKILL = new SkillHolder(14113, 1);
|
||||
private static final SkillHolder BEETLE_SKILL = new SkillHolder(14412, 1);
|
||||
private static final SkillHolder TEREDOR_POISON_SKILL = new SkillHolder(14112, 1);
|
||||
private static final SkillHolder TEREDOR_POISON_SKILL_2 = new SkillHolder(14112, 2);
|
||||
private static final SkillHolder TEREDOR_CANCEL = new SkillHolder(5902, 1);
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 160;
|
||||
//@formatter:off
|
||||
private static final Map<Integer, String[]> WALKING_DATA = new HashMap<>();
|
||||
static
|
||||
{
|
||||
WALKING_DATA.put(1, new String[] {"trajan101", "trajan102", "trajan103", "trajan104", "trajan105"});
|
||||
WALKING_DATA.put(2, new String[] {"trajan106", "trajan107", "trajan108", "trajan109", "trajan110"});
|
||||
WALKING_DATA.put(3, new String[] {"trajan111", "trajan112", "trajan113"});
|
||||
WALKING_DATA.put(4, new String[] {"trajan114", "trajan115"});
|
||||
WALKING_DATA.put(5, new String[] {"trajan116", "trajan117"});
|
||||
WALKING_DATA.put(6, new String[] {"trajan118", "trajan119", "trajan120"});
|
||||
WALKING_DATA.put(7, new String[] {"trajan121", "trajan122"});
|
||||
WALKING_DATA.put(8, new String[] {"trajan14", "trajan15", "trajan16"});
|
||||
}
|
||||
//@formatter:on
|
||||
|
||||
public TeredorWarzone()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
addStartNpc(FILAUR);
|
||||
addTalkId(FILAUR);
|
||||
addSpawnId(BEETLE, POS_CHECKER, EGG_2, FAKE_TEREDOR, TEREDOR);
|
||||
addSpellFinishedId(BEETLE);
|
||||
addEventReceivedId(EGG_2);
|
||||
addAttackId(TEREDOR);
|
||||
addKillId(EGG_2, TEREDOR);
|
||||
setCreatureSeeId(this::onCreatureSee, BEETLE, POS_CHECKER, EGG_2, FAKE_TEREDOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimerEvent(String event, StatsSet params, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
final StatsSet npcVars = npc.getVariables();
|
||||
final StatsSet npcParams = npc.getParameters();
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case "EGG_SPAWN_TIMER":
|
||||
{
|
||||
final L2Npc minion = addSpawn(AWAKENED_MILLIPADE, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
WalkingManager.getInstance().startMoving(minion, getRandomEntry(WALKING_DATA.get(npcParams.getInt("Spot", 0))));
|
||||
npc.deleteMe();
|
||||
break;
|
||||
}
|
||||
case "FAKE_TEREDOR_POISON_TIMER":
|
||||
{
|
||||
final L2Npc minion = addSpawn(TEREDOR_POISON, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
|
||||
getTimers().addTimer("POISON_TIMER", 5000, minion, null);
|
||||
getTimers().addTimer("POISON_TIMER", 10000, minion, null);
|
||||
getTimers().addTimer("POISON_TIMER", 15000, minion, null);
|
||||
getTimers().addTimer("POISON_TIMER", 20000, minion, null);
|
||||
getTimers().addTimer("DELETE_ME", 22000, minion, null);
|
||||
break;
|
||||
}
|
||||
case "POISON_TIMER":
|
||||
{
|
||||
addSkillCastDesire(npc, npc, POISON_SKILL, 23);
|
||||
break;
|
||||
}
|
||||
case "DELETE_ME":
|
||||
{
|
||||
npc.deleteMe();
|
||||
break;
|
||||
}
|
||||
case "TEREDOR_LAIR_CHECK":
|
||||
{
|
||||
final Location spawnLoc = npc.getSpawn().getLocation();
|
||||
|
||||
if (((spawnLoc.getX() - npc.getX()) > 1000) || ((spawnLoc.getX() - npc.getX()) < -2000))
|
||||
{
|
||||
showOnScreenMsg(instance, NpcStringId.TEREDOR_SUMMONS_SUBORDINATE_BECAUSE_YOU_MOVED_OUT_OF_TEREDOR_S_AREA, ExShowScreenMessage.TOP_CENTER, 4000);
|
||||
addSpawn(ELITE_MILLIPADE, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TEREDOR_BUHATIMER":
|
||||
{
|
||||
npcVars.increaseInt("i_ai3", 0, 1);
|
||||
break;
|
||||
}
|
||||
case "TEREDOR_POISON_TIMER":
|
||||
{
|
||||
final int i_ai4 = npcVars.increaseInt("i_ai4", 0, 1);
|
||||
if (i_ai4 == 7)
|
||||
{
|
||||
npcVars.increaseInt("i_ai4", 0, -7);
|
||||
}
|
||||
else
|
||||
{
|
||||
// myself->CreateOnePrivateEx(18998, "trajan_poison_dummy", 0, 0, gg->FloatToInt(myself->sm->x), gg->FloatToInt(myself->sm->y), gg->FloatToInt(myself->sm->z), 0, 0, 0, 0); //TODO:
|
||||
getTimers().addTimer("TEREDOR_POISON_TIMER", 2000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TEREDOR_RUNTIMER_1":
|
||||
case "TEREDOR_RUNTIMER_2":
|
||||
case "TEREDOR_RUNTIMER_3":
|
||||
case "TEREDOR_RUNTIMER_4":
|
||||
{
|
||||
npc.disableCoreAI(false);
|
||||
npc.setTargetable(true);
|
||||
npc.broadcastSocialAction(3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("enterInstance"))
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
final StatsSet npcParams = npc.getParameters();
|
||||
|
||||
switch (npc.getId())
|
||||
{
|
||||
case TEREDOR:
|
||||
{
|
||||
WalkingManager.getInstance().startMoving(npc, "trajan5");
|
||||
getTimers().addRepeatingTimer("TEREDOR_LAIR_CHECK", 5000, npc, null);
|
||||
((L2Attackable) npc).setCanReturnToSpawnPoint(false);
|
||||
npc.initSeenCreatures();
|
||||
break;
|
||||
}
|
||||
case BEETLE:
|
||||
{
|
||||
if (npcParams.getInt("Sp", 0) == 1)
|
||||
{
|
||||
WalkingManager.getInstance().startMoving(npc, npcParams.getString("SuperPointName1", ""));
|
||||
}
|
||||
npc.initSeenCreatures();
|
||||
break;
|
||||
}
|
||||
case FAKE_TEREDOR:
|
||||
{
|
||||
WalkingManager.getInstance().startMoving(npc, npcParams.getString("SuperPointName", ""));
|
||||
npc.setRHandId(FAKE_TEREDOR_WEAPON);
|
||||
npc.initSeenCreatures();
|
||||
getTimers().addTimer("FAKE_TEREDOR_POISON_TIMER", 3000, npc, null);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
npc.initSeenCreatures();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public void onCreatureSee(OnCreatureSee event)
|
||||
{
|
||||
final L2Character creature = event.getSeen();
|
||||
final L2Npc npc = (L2Npc) event.getSeer();
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
final StatsSet npcParams = npc.getParameters();
|
||||
|
||||
switch (npc.getId())
|
||||
{
|
||||
case BEETLE:
|
||||
{
|
||||
if (creature.isPlayer() && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
addSkillCastDesire(npc, npc, BEETLE_SKILL, 23);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FAKE_TEREDOR:
|
||||
{
|
||||
if (creature.isPlayer() && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
addSkillCastDesire(npc, npc, FAKE_TEREDOR_JUMP_SKILL, 23);
|
||||
getTimers().addTimer("FAKE_TEREDOR_ELITE_REUSE", 30000, n -> npc.setScriptValue(0));
|
||||
final L2Npc minion = addSpawn(ELITE_MILLIPADE, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
addAttackPlayerDesire(minion, creature.getActingPlayer());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case POS_CHECKER:
|
||||
{
|
||||
if (creature.isPlayer() && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
final int spot = npcParams.getInt("Spot", 0);
|
||||
|
||||
switch (spot)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
instance.spawnGroup("schuttgart29_2512_sp1m1");
|
||||
npc.broadcastEvent("SCE_BREAK_AN_EGG1", 800, null);
|
||||
getTimers().addTimer("EGG_SPAWN_TIMER_2", 30000, n -> npc.broadcastEvent("SCE_BREAK_AN_EGG2", 800, creature));
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
instance.spawnGroup("schuttgart29_2512_sp2m1");
|
||||
npc.broadcastEvent("SCE_BREAK_AN_EGG1", 800, null);
|
||||
getTimers().addTimer("EGG_SPAWN_TIMER_2", 30000, n -> npc.broadcastEvent("SCE_BREAK_AN_EGG2", 800, creature));
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
instance.spawnGroup("schuttgart29_2512_sp4m1");
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
instance.spawnGroup("schuttgart29_2512_306m1");
|
||||
npc.broadcastEvent("SCE_BREAK_AN_EGG1", 800, null);
|
||||
getTimers().addTimer("EGG_SPAWN_TIMER_2", 30000, n -> npc.broadcastEvent("SCE_BREAK_AN_EGG2", 800, creature));
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
instance.spawnGroup("schuttgart29_2512_305m1");
|
||||
npc.broadcastEvent("SCE_BREAK_AN_EGG1", 800, null);
|
||||
getTimers().addTimer("EGG_SPAWN_TIMER_2", 30000, n -> npc.broadcastEvent("SCE_BREAK_AN_EGG2", 800, creature));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EGG_2:
|
||||
{
|
||||
if (creature.isPlayer() && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
getTimers().addTimer("EGG_SPAWN_TIMER", (180 + getRandom(120)) * 1000, npc, null);
|
||||
npc.getVariables().set("SEE_CREATURE_ID", creature.getObjectId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEventReceived(String eventName, L2Npc sender, L2Npc npc, L2Object reference)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case EGG_2:
|
||||
{
|
||||
switch (eventName)
|
||||
{
|
||||
case "SCE_EGG_DIE":
|
||||
{
|
||||
npc.setDisplayEffect(2);
|
||||
final L2PcInstance player = instance.getPlayerById(npc.getVariables().getInt("SEE_CREATURE_ID", 0));
|
||||
if (player != null)
|
||||
{
|
||||
final L2Npc minion = addSpawn(getRandomBoolean() ? HATCHET_MILLIPADE : HATCHET_UNDERBUG, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
addAttackPlayerDesire(minion, player, 23);
|
||||
npc.deleteMe();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCE_BREAK_AN_EGG1":
|
||||
{
|
||||
npc.setDisplayEffect(2);
|
||||
break;
|
||||
}
|
||||
case "SCE_BREAK_AN_EGG2":
|
||||
{
|
||||
final L2PcInstance player = reference == null ? instance.getPlayerById(npc.getVariables().getInt("SEE_CREATURE_ID", 0)) : reference.getActingPlayer();
|
||||
int npcId = 0;
|
||||
|
||||
switch (npc.getParameters().getInt("Spot", 0))
|
||||
{
|
||||
case 1:
|
||||
npcId = getRandomBoolean() ? TEREDOR_LARVA : MUTANTED_MILLIPADE;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
npcId = getRandomBoolean() ? MUTANTED_MILLIPADE : HATCHET_UNDERBUG;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
npcId = getRandomBoolean() ? MUTANTED_MILLIPADE : HATCHET_UNDERBUG;
|
||||
break;
|
||||
case 7:
|
||||
npcId = getRandomEntry(MUTANTED_MILLIPADE, HATCHET_UNDERBUG, HATCHET_MILLIPADE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (npcId > 0)
|
||||
{
|
||||
final L2Npc minion = addSpawn(npcId, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
if ((player != null) && (minion.calculateDistance(player, true, false) < 2000))
|
||||
{
|
||||
addAttackPlayerDesire(minion, player, 23);
|
||||
}
|
||||
npc.deleteMe();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCE_BREAK_AN_EGG3":
|
||||
{
|
||||
npc.setDisplayEffect(4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onEventReceived(eventName, sender, npc, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case TEREDOR:
|
||||
{
|
||||
final StatsSet npcVars = npc.getVariables();
|
||||
final int hpPer = npc.getCurrentHpPercent();
|
||||
int teredorStatus = npcVars.getInt("TEREDOR_STATUS", 1);
|
||||
|
||||
if ((npc.distFromMe(attacker) > 450) && (getRandom(100) < 5))
|
||||
{
|
||||
addSkillCastDesire(npc, attacker, TEREDOR_POISON_SKILL, 23);
|
||||
// myself->CreateOnePrivateEx(18998, "trajan_poison_dummy", 0, 0, gg->FloatToInt(attacker->x), gg->FloatToInt(attacker->y), gg->FloatToInt(attacker->z), 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if ((hpPer <= 80) && (hpPer >= 60))
|
||||
{
|
||||
if (teredorStatus == 1)
|
||||
{
|
||||
addSkillCastDesire(npc, npc, TEREDOR_CANCEL, 23);
|
||||
teredorStatus = npcVars.increaseInt("TEREDOR_STATUS", 1);
|
||||
npc.disableCoreAI(true);
|
||||
npc.setTargetable(false);
|
||||
npc.breakAttack();
|
||||
npc.breakCast();
|
||||
npc.setWalking();
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
npc.broadcastSocialAction(4);
|
||||
WalkingManager.getInstance().resumeMoving(npc);
|
||||
getTimers().addTimer("TEREDOR_BUHATIMER", 10000, npc, null);
|
||||
getTimers().addTimer("TEREDOR_RUNTIMER_1", 30000, npc, null);
|
||||
getTimers().addTimer("TEREDOR_POISON_TIMER", 2000, npc, null);
|
||||
}
|
||||
else if (getRandom(100) < 1)
|
||||
{
|
||||
addSkillCastDesire(npc, attacker, TEREDOR_POISON_SKILL, 23);
|
||||
// myself->CreateOnePrivateEx(18998, "trajan_poison_dummy", 0, 0, gg->FloatToInt(attacker->x), gg->FloatToInt(attacker->y), gg->FloatToInt(attacker->z), 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else if ((hpPer <= 60) && (hpPer >= 40))
|
||||
{
|
||||
if (teredorStatus == 2)
|
||||
{
|
||||
addSkillCastDesire(npc, npc, TEREDOR_CANCEL, 23);
|
||||
teredorStatus = npcVars.increaseInt("TEREDOR_STATUS", 1);
|
||||
npc.disableCoreAI(true);
|
||||
npc.setTargetable(false);
|
||||
npc.breakAttack();
|
||||
npc.breakCast();
|
||||
npc.setWalking();
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
npc.broadcastSocialAction(4);
|
||||
WalkingManager.getInstance().resumeMoving(npc);
|
||||
// myself->BroadcastScriptEvent(@SCE_EGG_SPAWN5, 0, 3000);
|
||||
getTimers().addTimer("TEREDOR_BUHATIMER", 10000, npc, null);
|
||||
getTimers().addTimer("TEREDOR_RUNTIMER_2", 30000, npc, null);
|
||||
getTimers().addTimer("TEREDOR_POISON_TIMER", 2000, npc, null);
|
||||
}
|
||||
else if (getRandom(100) < 3)
|
||||
{
|
||||
addSkillCastDesire(npc, attacker, TEREDOR_POISON_SKILL, 23);
|
||||
// myself->CreateOnePrivateEx(18998, "trajan_poison_dummy", 0, 0, gg->FloatToInt(attacker->x), gg->FloatToInt(attacker->y), gg->FloatToInt(attacker->z), 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else if ((hpPer <= 40) && (hpPer >= 20))
|
||||
{
|
||||
if (teredorStatus == 3)
|
||||
{
|
||||
addSkillCastDesire(npc, npc, TEREDOR_CANCEL, 23);
|
||||
// if (myself->i_ai2 == 1)
|
||||
// {
|
||||
// myself->AddUseSkillDesire(myself->sm, toggle_shield1, @HEAL, @STAND, 500000000);
|
||||
// myself->ChangeNPCState(myself->sm, 4);
|
||||
// myself->i_ai2 = myself->i_ai2 - 1;
|
||||
// }
|
||||
// if (myself->i_ai2 == 2)
|
||||
// {
|
||||
// myself->AddUseSkillDesire(myself->sm, toggle_shield2, @HEAL, @STAND, 500000000);
|
||||
npc.setDisplayEffect(4);
|
||||
// myself->i_ai2 = myself->i_ai2 - 2;
|
||||
// }
|
||||
teredorStatus = npcVars.increaseInt("TEREDOR_STATUS", 1);
|
||||
npc.disableCoreAI(true);
|
||||
npc.setTargetable(false);
|
||||
npc.breakAttack();
|
||||
npc.breakCast();
|
||||
npc.setWalking();
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
npc.broadcastSocialAction(4);
|
||||
WalkingManager.getInstance().resumeMoving(npc);
|
||||
// myself->BroadcastScriptEvent(@SCE_TRAJAN_EGG_DIE, gg->GetIndexFromCreature(c0), 3000);
|
||||
// myself->BroadcastScriptEvent(@SCE_EGG_SPAWN6, 0, 3000);
|
||||
getTimers().addTimer("TEREDOR_BUHATIMER", 10000, npc, null);
|
||||
getTimers().addTimer("TEREDOR_RUNTIMER_3", 30000, npc, null);
|
||||
getTimers().addTimer("TEREDOR_POISON_TIMER", 2000, npc, null);
|
||||
}
|
||||
else if (getRandom(100) < 5)
|
||||
{
|
||||
addSkillCastDesire(npc, attacker, TEREDOR_POISON_SKILL, 23);
|
||||
// myself->CreateOnePrivateEx(18998, "trajan_poison_dummy", 0, 0, gg->FloatToInt(attacker->x), gg->FloatToInt(attacker->y), gg->FloatToInt(attacker->z), 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else if (hpPer < 20)
|
||||
{
|
||||
if (teredorStatus == 4)
|
||||
{
|
||||
addSkillCastDesire(npc, npc, TEREDOR_CANCEL, 23);
|
||||
// if (myself->i_ai2 == 1)
|
||||
// {
|
||||
// myself->AddUseSkillDesire(myself->sm, toggle_shield1, @HEAL, @STAND, 500000000);
|
||||
// myself->ChangeNPCState(myself->sm, 4);
|
||||
// myself->i_ai2 = myself->i_ai2 - 1;
|
||||
// }
|
||||
// if (myself->i_ai2 == 2)
|
||||
// {
|
||||
// myself->AddUseSkillDesire(myself->sm, toggle_shield2, @HEAL, @STAND, 500000000);
|
||||
npc.setDisplayEffect(4);
|
||||
// myself->i_ai2 = myself->i_ai2 - 2;
|
||||
// }
|
||||
teredorStatus = npcVars.increaseInt("TEREDOR_STATUS", 1);
|
||||
npc.disableCoreAI(true);
|
||||
npc.setTargetable(false);
|
||||
npc.breakAttack();
|
||||
npc.breakCast();
|
||||
npc.setWalking();
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
npc.broadcastSocialAction(4);
|
||||
WalkingManager.getInstance().resumeMoving(npc);
|
||||
// myself->BroadcastScriptEvent(@SCE_TRAJAN_EGG_DIE, gg->GetIndexFromCreature(c0), 3000);
|
||||
// myself->BroadcastScriptEvent(@SCE_EGG_SPAWN7, 0, 3000);
|
||||
// myself->AddUseSkillDesire(myself->sm, Lastskill, @HEAL, @STAND, 500000000);
|
||||
npc.setDisplayEffect(1);
|
||||
getTimers().addTimer("TEREDOR_BUHATIMER", 10000, npc, null);
|
||||
getTimers().addTimer("TEREDOR_RUNTIMER_4", 30000, npc, null);
|
||||
getTimers().addTimer("TEREDOR_POISON_TIMER", 2000, npc, null);
|
||||
}
|
||||
else if (getRandom(100) < 5)
|
||||
{
|
||||
addSkillCastDesire(npc, attacker, TEREDOR_POISON_SKILL_2, 23);
|
||||
// myself->CreateOnePrivateEx(18998, "trajan_poison_dummy", 0, 0, gg->FloatToInt(attacker->x), gg->FloatToInt(attacker->y), gg->FloatToInt(attacker->z), 0, 0, 0, 0);
|
||||
}
|
||||
else if (getRandom(100) < 5)
|
||||
{
|
||||
// myself->AddUseSkillDesire(attacker, Specialskill1, @ATTACK, @MOVE_TO_TARGET, 1000000);
|
||||
}
|
||||
}
|
||||
else if ((teredorStatus == 5) && (hpPer < 7))
|
||||
{
|
||||
// myself->BroadcastScriptEvent(@SCE_ALL_BREAK_AN_EGG5, gg->GetIndexFromCreature(c0), 3000);
|
||||
teredorStatus = npcVars.increaseInt("TEREDOR_STATUS", 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case TEREDOR:
|
||||
{
|
||||
instance.finishInstance();
|
||||
break;
|
||||
}
|
||||
case EGG_2:
|
||||
{
|
||||
if (getRandom(4) < 3)
|
||||
{
|
||||
final L2Npc minion = addSpawn(getRandomBoolean() ? MUTANTED_MILLIPADE : TEREDOR_LARVA, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0, false, instance.getId());
|
||||
addAttackPlayerDesire(minion, killer, 23);
|
||||
npc.deleteMe();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
final Instance instance = npc.getInstanceWorld();
|
||||
if (isInInstance(instance))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case BEETLE:
|
||||
{
|
||||
npc.broadcastEvent("SCE_EGG_DIE", 500, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new TeredorWarzone();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user