Organized boss scripts to separate folder.
This commit is contained in:
@@ -1,333 +0,0 @@
|
||||
/*
|
||||
* 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 instances.BaylorWarzone;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Crystal Prison Entrance Portal:<br>
|
||||
You must be in a party to enter.
|
||||
</body></html>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Crystal Prison Entrance Portal:<br>
|
||||
The leader of the party should try to enter.
|
||||
</body></html>
|
||||
@@ -1,352 +0,0 @@
|
||||
/*
|
||||
* 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 instances.CavernOfThePirateCaptain;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.StatsSet;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExSendUIEvent;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Cavern Of The Pirate Captain (Day Dream) instance Zone.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class CavernOfThePirateCaptain extends AbstractInstance
|
||||
{
|
||||
// NPCs
|
||||
private static final int PATHFINDER = 32713; // Pathfinder Worker
|
||||
private static final int ZAKEN_60 = 29176; // Zaken
|
||||
private static final int ZAKEN_83 = 29181; // Zaken
|
||||
private static final int CANDLE = 32705; // Zaken's Candle
|
||||
// Items
|
||||
private static final int VORPAL_RING = 15763; // Sealed Vorpal Ring
|
||||
private static final int VORPAL_EARRING = 15764; // Sealed Vorpal Earring
|
||||
// Reward - Zaken lvl 83 @formatter:off
|
||||
private static final int[][] VORPAL_JEWELS =
|
||||
{
|
||||
// Time, jewel id, chance
|
||||
{300000, VORPAL_RING, 50}, // 5 minutes
|
||||
{600000, VORPAL_EARRING, 30}, // 10 minutes
|
||||
{900000, VORPAL_RING, 25}, // 15 minutes
|
||||
};
|
||||
// Locations @formatter:on
|
||||
private static final Location[] CANDLE_LOC =
|
||||
{
|
||||
// Floor 1
|
||||
new Location(53313, 220133, -3498),
|
||||
new Location(53313, 218079, -3498),
|
||||
new Location(54240, 221045, -3498),
|
||||
new Location(54325, 219095, -3498),
|
||||
new Location(54240, 217155, -3498),
|
||||
new Location(55257, 220028, -3498),
|
||||
new Location(55257, 218172, -3498),
|
||||
new Location(56280, 221045, -3498),
|
||||
new Location(56195, 219095, -3498),
|
||||
new Location(56280, 217155, -3498),
|
||||
new Location(57215, 220133, -3498),
|
||||
new Location(57215, 218079, -3498),
|
||||
// Floor 2
|
||||
new Location(53313, 220133, -3226),
|
||||
new Location(53313, 218079, -3226),
|
||||
new Location(54240, 221045, -3226),
|
||||
new Location(54325, 219095, -3226),
|
||||
new Location(54240, 217155, -3226),
|
||||
new Location(55257, 220028, -3226),
|
||||
new Location(55257, 218172, -3226),
|
||||
new Location(56280, 221045, -3226),
|
||||
new Location(56195, 219095, -3226),
|
||||
new Location(56280, 217155, -3226),
|
||||
new Location(57215, 220133, -3226),
|
||||
new Location(57215, 218079, -3226),
|
||||
// Floor 3
|
||||
new Location(53313, 220133, -2954),
|
||||
new Location(53313, 218079, -2954),
|
||||
new Location(54240, 221045, -2954),
|
||||
new Location(54325, 219095, -2954),
|
||||
new Location(54240, 217155, -2954),
|
||||
new Location(55257, 220028, -2954),
|
||||
new Location(55257, 218172, -2954),
|
||||
new Location(56280, 221045, -2954),
|
||||
new Location(56195, 219095, -2954),
|
||||
new Location(56280, 217155, -2954),
|
||||
new Location(57215, 220133, -2954),
|
||||
new Location(57215, 218079, -2954),
|
||||
};
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID_60 = 133;
|
||||
private static final int TEMPLATE_ID_83 = 135;
|
||||
//@formatter:off
|
||||
private static final int[][] ROOM_DATA =
|
||||
{
|
||||
// Floor 1
|
||||
{54240, 220133, -3498, 1, 3, 4, 6},
|
||||
{54240, 218073, -3498, 2, 5, 4, 7},
|
||||
{55265, 219095, -3498, 4, 9, 6, 7},
|
||||
{56289, 220133, -3498, 8, 11, 6, 9},
|
||||
{56289, 218073, -3498, 10, 12, 7, 9},
|
||||
// Floor 2
|
||||
{54240, 220133, -3226, 13, 15, 16, 18},
|
||||
{54240, 218073, -3226, 14, 17, 16, 19},
|
||||
{55265, 219095, -3226, 21, 16, 19, 18},
|
||||
{56289, 220133, -3226, 20, 23, 21, 18},
|
||||
{56289, 218073, -3226, 22, 24, 19, 21},
|
||||
// Floor 3
|
||||
{54240, 220133, -2954, 25, 27, 28, 30},
|
||||
{54240, 218073, -2954, 26, 29, 28, 31},
|
||||
{55265, 219095, -2954, 33, 28, 31, 30},
|
||||
{56289, 220133, -2954, 32, 35, 30, 33},
|
||||
{56289, 218073, -2954, 34, 36, 31, 33}
|
||||
};
|
||||
//@formatter:on
|
||||
|
||||
public CavernOfThePirateCaptain()
|
||||
{
|
||||
super(TEMPLATE_ID_60, TEMPLATE_ID_83);
|
||||
addStartNpc(PATHFINDER);
|
||||
addTalkId(PATHFINDER);
|
||||
addKillId(ZAKEN_60, ZAKEN_83);
|
||||
addFirstTalkId(CANDLE);
|
||||
addInstanceCreatedId(TEMPLATE_ID_60, TEMPLATE_ID_83);
|
||||
addInstanceEnterId(TEMPLATE_ID_60, TEMPLATE_ID_83);
|
||||
addInstanceLeaveId(TEMPLATE_ID_60, TEMPLATE_ID_83);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceCreated(Instance instance, L2PcInstance player)
|
||||
{
|
||||
final List<L2Npc> candles = new ArrayList<>();
|
||||
final int zakenRoom = getRandom(1, 15);
|
||||
|
||||
for (int i = 0; i < 36; i++)
|
||||
{
|
||||
final L2Npc candle = addSpawn(CANDLE, CANDLE_LOC[i], false, 0, false, instance.getId());
|
||||
candle.getVariables().set("candleId", i + 1);
|
||||
candles.add(candle);
|
||||
}
|
||||
|
||||
for (int i = 3; i < 7; i++)
|
||||
{
|
||||
candles.get(ROOM_DATA[zakenRoom - 1][i] - 1).getVariables().set("isBlue", 1);
|
||||
}
|
||||
final L2Npc zaken = spawnNpc(instance.getTemplateParameters().getInt("Zaken"), zakenRoom, null, instance);
|
||||
zaken.setInvisible(true);
|
||||
zaken.setBlockActions(true);
|
||||
instance.setParameter("zakenRoom", zakenRoom);
|
||||
instance.setParameter("zaken", zaken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceEnter(L2PcInstance player, Instance instance)
|
||||
{
|
||||
final int startTime = (int) (instance.getElapsedTime() / 1000);
|
||||
final int endTime = (int) (instance.getRemainingTime() / 1000);
|
||||
player.sendPacket(new ExSendUIEvent(player, false, true, startTime, endTime, NpcStringId.ELAPSED_TIME));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceLeave(L2PcInstance player, Instance instance)
|
||||
{
|
||||
player.sendPacket(new ExSendUIEvent(player, true, true, 0, 0, NpcStringId.ELAPSED_TIME));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("enter60"))
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID_60);
|
||||
}
|
||||
else if (event.equals("enter83"))
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID_83);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
final StatsSet templParams = world.getTemplateParameters();
|
||||
final StatsSet params = world.getParameters();
|
||||
switch (event)
|
||||
{
|
||||
case "BURN_BLUE":
|
||||
{
|
||||
if (npc.hasDisplayEffect(0))
|
||||
{
|
||||
npc.setDisplayEffect(1); // Burning
|
||||
startQuestTimer("BURN_BLUE2", 3000, npc, player);
|
||||
if (params.getInt("blueFounded") == 4)
|
||||
{
|
||||
startQuestTimer("SHOW_ZAKEN", 5000, npc, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "BURN_BLUE2":
|
||||
{
|
||||
if (npc.hasDisplayEffect(1)) // Burning
|
||||
{
|
||||
npc.setDisplayEffect(3); // Blue glow
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "BURN_RED":
|
||||
{
|
||||
if (npc.hasDisplayEffect(0))
|
||||
{
|
||||
npc.setDisplayEffect(1); // Burning
|
||||
startQuestTimer("BURN_RED2", 3000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "BURN_RED2":
|
||||
{
|
||||
if (npc.hasDisplayEffect(1)) // Burning
|
||||
{
|
||||
final int room = getRoomByCandle(npc);
|
||||
npc.setDisplayEffect(2); // Red glow
|
||||
showOnScreenMsg(world, NpcStringId.THE_CANDLES_CAN_LEAD_YOU_TO_ZAKEN_DESTROY_HIM, ExShowScreenMessage.MIDDLE_CENTER, 6000);
|
||||
spawnNpc(templParams.getInt("DollBlader"), room, player, world);
|
||||
spawnNpc(templParams.getInt("ValeMaster"), room, player, world);
|
||||
spawnNpc(templParams.getInt("PiratesZombie"), room, player, world);
|
||||
spawnNpc(templParams.getInt("PiratesZombieCaptain"), room, player, world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SHOW_ZAKEN":
|
||||
{
|
||||
if (world.getTemplateId() == ZAKEN_83)
|
||||
{
|
||||
showOnScreenMsg(world, NpcStringId.WHO_DARES_AWAKEN_THE_MIGHTY_ZAKEN, ExShowScreenMessage.MIDDLE_CENTER, 6000);
|
||||
}
|
||||
|
||||
final int zakenRoom = params.getInt("zakenRoom");
|
||||
final L2Npc zaken = params.getObject("zaken", L2Npc.class);
|
||||
zaken.setInvisible(false);
|
||||
zaken.setBlockActions(false);
|
||||
spawnNpc(templParams.getInt("DollBlader"), zakenRoom, player, world);
|
||||
spawnNpc(templParams.getInt("PiratesZombie"), zakenRoom, player, world);
|
||||
spawnNpc(templParams.getInt("PiratesZombieCaptain"), zakenRoom, player, world);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
if (npc.getId() == ZAKEN_83)
|
||||
{
|
||||
final long time = world.getElapsedTime();
|
||||
for (L2PcInstance playersInside : world.getPlayersInsideRadius(npc, 1500))
|
||||
{
|
||||
for (int[] reward : VORPAL_JEWELS)
|
||||
{
|
||||
if (time <= reward[0])
|
||||
{
|
||||
if (getRandom(100) < reward[2])
|
||||
{
|
||||
giveItems(playersInside, reward[1], 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
world.finishInstance();
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if ((world != null) && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
if (npc.getVariables().getInt("isBlue", 0) == 1)
|
||||
{
|
||||
final int blueCandles = world.getParameters().getInt("blueFounded", 0);
|
||||
world.setParameter("blueFounded", blueCandles + 1);
|
||||
startQuestTimer("BURN_BLUE", 500, npc, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("BURN_RED", 500, npc, player);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getRoomByCandle(L2Npc npc)
|
||||
{
|
||||
final int candleId = npc.getVariables().getInt("candleId", 0);
|
||||
for (int i = 0; i < 15; i++)
|
||||
{
|
||||
if ((ROOM_DATA[i][3] == candleId) || (ROOM_DATA[i][4] == candleId))
|
||||
{
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((candleId == 6) || (candleId == 7))
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
else if ((candleId == 18) || (candleId == 19))
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
else if ((candleId == 30) || (candleId == 31))
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private L2Npc spawnNpc(int npcId, int roomId, L2PcInstance player, Instance world)
|
||||
{
|
||||
if ((player != null) && (npcId != ZAKEN_60) && (npcId != ZAKEN_83))
|
||||
{
|
||||
final L2Npc mob = addSpawn(npcId, ROOM_DATA[roomId - 1][0] + getRandom(350), ROOM_DATA[roomId - 1][1] + getRandom(350), ROOM_DATA[roomId - 1][2], 0, false, 0, false, world.getId());
|
||||
addAttackPlayerDesire(mob, player);
|
||||
return mob;
|
||||
}
|
||||
return addSpawn(npcId, ROOM_DATA[roomId - 1][0], ROOM_DATA[roomId - 1][1], ROOM_DATA[roomId - 1][2], 0, false, 0, false, world.getId());
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new CavernOfThePirateCaptain();
|
||||
}
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* 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 instances.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();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Kegor:<br>
|
||||
I'd entrust your associate with this mission, but..
|
||||
</body></html>
|
||||
@@ -1,6 +0,0 @@
|
||||
<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
@@ -1,8 +0,0 @@
|
||||
<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>
|
||||
@@ -1,7 +0,0 @@
|
||||
<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>
|
||||
@@ -1,3 +0,0 @@
|
||||
<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>
|
||||
@@ -1,5 +0,0 @@
|
||||
<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>
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
@@ -1,687 +0,0 @@
|
||||
/*
|
||||
* 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 instances.IstinaCavern;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<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>
|
||||
@@ -1,3 +0,0 @@
|
||||
<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>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Noeti Mimilead:<br>
|
||||
Podvodn<EFBFBD>k chlupat<61> hnusn<73>! (noeti_mymirid_indun1002.htm)
|
||||
</body></html>
|
||||
@@ -1,5 +0,0 @@
|
||||
<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>
|
||||
@@ -1,462 +0,0 @@
|
||||
/*
|
||||
* 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 instances.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();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Elite Bodyguard Naomi Kasheron:<br>
|
||||
I will not take a party, friend. Just one. Just you.
|
||||
</body></html>
|
||||
@@ -1,909 +0,0 @@
|
||||
/*
|
||||
* 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 instances.LastImperialTomb;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
/*
|
||||
* 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 instances.LastImperialTomb;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,548 +0,0 @@
|
||||
/*
|
||||
* 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 instances.OctavisWarzone;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
<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>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
I will pray that you save the soul of Octavis...
|
||||
</body></html>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
Please prove your decision is the right one and help your members.
|
||||
</body></html>
|
||||
@@ -1,4 +0,0 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
That many people can't be moved.<br>
|
||||
(A maximum of 35 people can participate.)
|
||||
</body></html>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Divine Messenger Lydia:<br>
|
||||
As I explained earlier, you can enter only by forming an association.
|
||||
</body></html>
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,67 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="list">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="spawnZones" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="zone" minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="point" maxOccurs="unbounded" minOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="x" type="xs:integer" use="required" />
|
||||
<xs:attribute name="y" type="xs:integer" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="id" type="xs:nonNegativeInteger" use="required" />
|
||||
<xs:attribute name="maxZ" type="xs:integer" use="required" />
|
||||
<xs:attribute name="minZ" type="xs:integer" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="npc" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="spawn" minOccurs="1" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:choice minOccurs="1" maxOccurs="1">
|
||||
<xs:element name="loc" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="heading" type="xs:nonNegativeInteger" use="required" />
|
||||
<xs:attribute name="mustKill" type="xs:boolean" />
|
||||
<xs:attribute name="x" type="xs:integer" use="required" />
|
||||
<xs:attribute name="y" type="xs:integer" use="required" />
|
||||
<xs:attribute name="z" type="xs:integer" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="zone" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:attribute name="count" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="id" type="xs:positiveInteger" use="required" />
|
||||
<xs:attribute name="mustKill" type="xs:boolean" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:choice>
|
||||
<xs:attribute name="flag" type="xs:nonNegativeInteger" use="required" />
|
||||
<xs:attribute name="npcId">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:positiveInteger">
|
||||
<xs:minInclusive value="1" />
|
||||
<xs:maxInclusive value="65535" />
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -1,685 +0,0 @@
|
||||
/*
|
||||
* 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 instances.SeedOfDestruction;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jmobius.commons.util.CommonUtil;
|
||||
import com.l2jmobius.commons.util.IGameXmlReader;
|
||||
import com.l2jmobius.gameserver.GeoData;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.Movie;
|
||||
import com.l2jmobius.gameserver.enums.TrapAction;
|
||||
import com.l2jmobius.gameserver.instancemanager.GraciaSeedsManager;
|
||||
import com.l2jmobius.gameserver.model.L2Territory;
|
||||
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.L2DoorInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2TrapInstance;
|
||||
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.zone.L2ZoneType;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
|
||||
import instances.AbstractInstance;
|
||||
|
||||
/**
|
||||
* Seed of Destruction instance zone.<br>
|
||||
* TODO:
|
||||
* <ul>
|
||||
* <li>No random mob spawns after mob kill.</li>
|
||||
* <li>Implement Seed of Destruction Defense state and one party instances.</li>
|
||||
* <li>Use proper zone spawn system.</li>
|
||||
* </ul>
|
||||
* Please maintain consistency between the Seed scripts.
|
||||
* @author Gigiikun
|
||||
*/
|
||||
public final class Stage1 extends AbstractInstance implements IGameXmlReader
|
||||
{
|
||||
protected static class SODSpawn
|
||||
{
|
||||
public boolean isZone = false;
|
||||
public boolean isNeededNextFlag = false;
|
||||
public int npcId;
|
||||
public int x = 0;
|
||||
public int y = 0;
|
||||
public int z = 0;
|
||||
public int h = 0;
|
||||
public int zone = 0;
|
||||
public int count = 0;
|
||||
}
|
||||
|
||||
// Spawn data
|
||||
private final Map<Integer, L2Territory> _spawnZoneList = new HashMap<>();
|
||||
private final Map<Integer, List<SODSpawn>> _spawnList = new HashMap<>();
|
||||
// Locations
|
||||
private static final Location ENTER_TELEPORT_2 = new Location(-245800, 220488, -12112);
|
||||
private static final Location CENTER_TELEPORT = new Location(-245802, 220528, -12104);
|
||||
// Traps/Skills
|
||||
private static final SkillHolder TRAP_HOLD = new SkillHolder(4186, 9); // 18720-18728
|
||||
private static final SkillHolder TRAP_STUN = new SkillHolder(4072, 10); // 18729-18736
|
||||
private static final SkillHolder TRAP_DAMAGE = new SkillHolder(5340, 4); // 18737-18770
|
||||
private static final SkillHolder TRAP_SPAWN = new SkillHolder(10002, 1); // 18771-18774 : handled in this script
|
||||
private static final int[] TRAP_18771_NPCS =
|
||||
{
|
||||
22541,
|
||||
22544,
|
||||
22541,
|
||||
22544
|
||||
};
|
||||
private static final int[] TRAP_OTHER_NPCS =
|
||||
{
|
||||
22546,
|
||||
22546,
|
||||
22538,
|
||||
22537
|
||||
};
|
||||
// NPCs
|
||||
private static final int ALENOS = 32526;
|
||||
private static final int TELEPORT = 32601;
|
||||
// Monsters
|
||||
private static final int OBELISK = 18776;
|
||||
private static final int POWERFUL_DEVICE = 18777;
|
||||
private static final int THRONE_POWERFUL_DEVICE = 18778;
|
||||
private static final int SPAWN_DEVICE = 18696;
|
||||
private static final int TIAT = 29163;
|
||||
private static final int TIAT_GUARD = 29162;
|
||||
private static final int TIAT_GUARD_NUMBER = 5;
|
||||
private static final int TIAT_VIDEO_NPC = 29169;
|
||||
private static final Location MOVE_TO_TIAT = new Location(-250403, 207273, -11952, 16384);
|
||||
private static final Location MOVE_TO_DOOR = new Location(-251432, 214905, -12088, 16384);
|
||||
// TODO: handle this better
|
||||
private static final int[] SPAWN_MOB_IDS =
|
||||
{
|
||||
22536,
|
||||
22537,
|
||||
22538,
|
||||
22539,
|
||||
22540,
|
||||
22541,
|
||||
22542,
|
||||
22543,
|
||||
22544,
|
||||
22547,
|
||||
22550,
|
||||
22551,
|
||||
22552,
|
||||
22596
|
||||
};
|
||||
// Doors/Walls/Zones
|
||||
private static final int[] ATTACKABLE_DOORS =
|
||||
{
|
||||
12240005,
|
||||
12240006,
|
||||
12240007,
|
||||
12240008,
|
||||
12240009,
|
||||
12240010,
|
||||
12240013,
|
||||
12240014,
|
||||
12240015,
|
||||
12240016,
|
||||
12240017,
|
||||
12240018,
|
||||
12240021,
|
||||
12240022,
|
||||
12240023,
|
||||
12240024,
|
||||
12240025,
|
||||
12240026,
|
||||
12240028,
|
||||
12240029,
|
||||
12240030
|
||||
};
|
||||
private static final int[] ENTRANCE_ROOM_DOORS =
|
||||
{
|
||||
12240001,
|
||||
12240002
|
||||
};
|
||||
private static final int[] SQUARE_DOORS =
|
||||
{
|
||||
12240003,
|
||||
12240004,
|
||||
12240011,
|
||||
12240012,
|
||||
12240019,
|
||||
12240020
|
||||
};
|
||||
private static final int SCOUTPASS_DOOR = 12240027;
|
||||
private static final int FORTRESS_DOOR = 12240030;
|
||||
private static final int THRONE_DOOR = 12240031;
|
||||
// Zone
|
||||
private static final int VIDEO_ZONE = 60010;
|
||||
// Misc
|
||||
private static final int TEMPLATE_ID = 110; // this is the client number
|
||||
private static final int MAX_DEVICESPAWNEDMOBCOUNT = 100; // prevent too much mob spawn
|
||||
|
||||
public Stage1()
|
||||
{
|
||||
super(TEMPLATE_ID);
|
||||
load();
|
||||
addStartNpc(ALENOS, TELEPORT);
|
||||
addTalkId(ALENOS, TELEPORT);
|
||||
addAttackId(OBELISK, TIAT);
|
||||
addSpawnId(OBELISK, POWERFUL_DEVICE, THRONE_POWERFUL_DEVICE);
|
||||
addKillId(OBELISK, TIAT, TIAT_GUARD);
|
||||
for (int i = 18771; i <= 18774; i++)
|
||||
{
|
||||
addTrapActionId(i);
|
||||
}
|
||||
addEnterZoneId(VIDEO_ZONE);
|
||||
addInstanceCreatedId(TEMPLATE_ID);
|
||||
addDespawnId(SPAWN_DEVICE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
parseDatapackFile("data/scripts/instances/SeedOfDestruction/SeedOfDestruction.xml");
|
||||
_log.info("[Seed of Destruction] Loaded " + _spawnZoneList.size() + " spawn zones data.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc, File file)
|
||||
{
|
||||
final Set<Integer> killIds = new HashSet<>();
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if (n.getNodeName().equals("list"))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if (d.getNodeName().equals("npc"))
|
||||
{
|
||||
for (Node e = d.getFirstChild(); e != null; e = e.getNextSibling())
|
||||
{
|
||||
if (e.getNodeName().equals("spawn"))
|
||||
{
|
||||
NamedNodeMap attrs = e.getAttributes();
|
||||
final int npcId = parseInteger(attrs, "npcId");
|
||||
final int flag = parseInteger(attrs, "flag");
|
||||
|
||||
if (!_spawnList.containsKey(flag))
|
||||
{
|
||||
_spawnList.put(flag, new ArrayList<SODSpawn>());
|
||||
}
|
||||
|
||||
for (Node f = e.getFirstChild(); f != null; f = f.getNextSibling())
|
||||
{
|
||||
if (f.getNodeName().equals("loc"))
|
||||
{
|
||||
attrs = f.getAttributes();
|
||||
|
||||
final SODSpawn spw = new SODSpawn();
|
||||
spw.npcId = npcId;
|
||||
spw.x = parseInteger(attrs, "x");
|
||||
spw.y = parseInteger(attrs, "y");
|
||||
spw.z = parseInteger(attrs, "z");
|
||||
spw.h = parseInteger(attrs, "heading");
|
||||
spw.isNeededNextFlag = parseBoolean(attrs, "mustKill", false);
|
||||
|
||||
if (spw.isNeededNextFlag)
|
||||
{
|
||||
killIds.add(npcId);
|
||||
}
|
||||
_spawnList.get(flag).add(spw);
|
||||
}
|
||||
else if (f.getNodeName().equals("zone"))
|
||||
{
|
||||
attrs = f.getAttributes();
|
||||
|
||||
final SODSpawn spw = new SODSpawn();
|
||||
spw.npcId = npcId;
|
||||
spw.isZone = true;
|
||||
spw.zone = parseInteger(attrs, "id");
|
||||
spw.count = parseInteger(attrs, "count");
|
||||
spw.isNeededNextFlag = parseBoolean(attrs, "mustKill", false);
|
||||
|
||||
if (spw.isNeededNextFlag)
|
||||
{
|
||||
killIds.add(npcId);
|
||||
}
|
||||
_spawnList.get(flag).add(spw);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (d.getNodeName().equals("spawnZones"))
|
||||
{
|
||||
for (Node e = d.getFirstChild(); e != null; e = e.getNextSibling())
|
||||
{
|
||||
if (e.getNodeName().equals("zone"))
|
||||
{
|
||||
NamedNodeMap attrs = e.getAttributes();
|
||||
final int id = parseInteger(attrs, "id");
|
||||
final int minz = parseInteger(attrs, "minZ");
|
||||
final int maxz = parseInteger(attrs, "maxZ");
|
||||
final L2Territory ter = new L2Territory(id);
|
||||
for (Node f = e.getFirstChild(); f != null; f = f.getNextSibling())
|
||||
{
|
||||
if (f.getNodeName().equals("point"))
|
||||
{
|
||||
attrs = f.getAttributes();
|
||||
final int x = parseInteger(attrs, "x");
|
||||
final int y = parseInteger(attrs, "y");
|
||||
ter.add(x, y, minz, maxz, 0);
|
||||
}
|
||||
}
|
||||
_spawnZoneList.put(id, ter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
addKillId(killIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstanceCreated(Instance instance, L2PcInstance player)
|
||||
{
|
||||
spawnState(instance);
|
||||
for (L2DoorInstance door : instance.getDoors())
|
||||
{
|
||||
if (CommonUtil.contains(ATTACKABLE_DOORS, door.getId()))
|
||||
{
|
||||
door.setIsAttackableDoor(true);
|
||||
}
|
||||
door.closeMe();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean checkKillProgress(Instance world)
|
||||
{
|
||||
return world.getNpcs().stream().filter(n -> !n.isDead() && n.isScriptValue(1)).count() == 0;
|
||||
}
|
||||
|
||||
private void spawnFlaggedNPCs(Instance world, int flag)
|
||||
{
|
||||
for (SODSpawn spw : _spawnList.get(flag))
|
||||
{
|
||||
if (spw.isZone)
|
||||
{
|
||||
if (_spawnZoneList.containsKey(spw.zone))
|
||||
{
|
||||
final L2Territory terr = _spawnZoneList.get(spw.zone);
|
||||
for (int i = 0; i < spw.count; i++)
|
||||
{
|
||||
final Location location = terr.getRandomPoint();
|
||||
if (location != null)
|
||||
{
|
||||
spawn(world, spw.npcId, location.getX(), location.getY(), GeoData.getInstance().getSpawnHeight(location), getRandom(65535), spw.isNeededNextFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.info("[Seed of Destruction] Missing zone: " + spw.zone);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
spawn(world, spw.npcId, spw.x, spw.y, spw.z, spw.h, spw.isNeededNextFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void spawnState(Instance world)
|
||||
{
|
||||
world.incStatus();
|
||||
world.getAliveNpcs().forEach(n -> n.setScriptValue(0));
|
||||
switch (world.getStatus() - 1)
|
||||
{
|
||||
case 0:
|
||||
spawnFlaggedNPCs(world, 0);
|
||||
break;
|
||||
case 1:
|
||||
world.broadcastPacket(new ExShowScreenMessage(NpcStringId.THE_ENEMIES_HAVE_ATTACKED_EVERYONE_COME_OUT_AND_FIGHT_URGH, 5, 1000));
|
||||
for (int i : ENTRANCE_ROOM_DOORS)
|
||||
{
|
||||
world.openCloseDoor(i, true);
|
||||
}
|
||||
spawnFlaggedNPCs(world, 1);
|
||||
break;
|
||||
case 4:
|
||||
world.broadcastPacket(new ExShowScreenMessage(NpcStringId.OBELISK_HAS_COLLAPSED_DON_T_LET_THE_ENEMIES_JUMP_AROUND_WILDLY_ANYMORE, 5, 1000));
|
||||
for (int i : SQUARE_DOORS)
|
||||
{
|
||||
world.openCloseDoor(i, true);
|
||||
}
|
||||
spawnFlaggedNPCs(world, 4);
|
||||
break;
|
||||
case 5:
|
||||
world.openCloseDoor(SCOUTPASS_DOOR, true);
|
||||
spawnFlaggedNPCs(world, 3);
|
||||
spawnFlaggedNPCs(world, 5);
|
||||
break;
|
||||
case 6:
|
||||
world.openCloseDoor(THRONE_DOOR, true);
|
||||
break;
|
||||
case 7:
|
||||
spawnFlaggedNPCs(world, 7);
|
||||
break;
|
||||
case 8:
|
||||
world.broadcastPacket(new ExShowScreenMessage(NpcStringId.COME_OUT_WARRIORS_PROTECT_SEED_OF_DESTRUCTION, 5, 1000));
|
||||
world.setParameter("deviceCount", 0);
|
||||
spawnFlaggedNPCs(world, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void spawn(Instance world, int npcId, int x, int y, int z, int h, boolean addToKillTable)
|
||||
{
|
||||
// traps
|
||||
if ((npcId >= 18720) && (npcId <= 18774))
|
||||
{
|
||||
Skill skill = null;
|
||||
if (npcId <= 18728)
|
||||
{
|
||||
skill = TRAP_HOLD.getSkill();
|
||||
}
|
||||
else if (npcId <= 18736)
|
||||
{
|
||||
skill = TRAP_STUN.getSkill();
|
||||
}
|
||||
else if (npcId <= 18770)
|
||||
{
|
||||
skill = TRAP_DAMAGE.getSkill();
|
||||
}
|
||||
else
|
||||
{
|
||||
skill = TRAP_SPAWN.getSkill();
|
||||
}
|
||||
addTrap(npcId, x, y, z, h, skill, world.getId());
|
||||
return;
|
||||
}
|
||||
final L2Npc npc = addSpawn(npcId, x, y, z, h, false, 0, false, world.getId());
|
||||
if (addToKillTable)
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
|
||||
if (npc.isAttackable())
|
||||
{
|
||||
((L2Attackable) npc).setSeeThroughSilentMove(true);
|
||||
}
|
||||
|
||||
if (npcId == TIAT_VIDEO_NPC)
|
||||
{
|
||||
startQuestTimer("DoorCheck", 10000, npc, null);
|
||||
}
|
||||
else if (npcId == SPAWN_DEVICE)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
startQuestTimer("Spawn", 10000, npc, null, true);
|
||||
}
|
||||
else if (npcId == TIAT)
|
||||
{
|
||||
for (int i = 0; i < TIAT_GUARD_NUMBER; i++)
|
||||
{
|
||||
addMinion((L2MonsterInstance) npc, TIAT_GUARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEnterZone(L2Character character, L2ZoneType zone)
|
||||
{
|
||||
if (character.isPlayer())
|
||||
{
|
||||
final Instance world = character.getInstanceWorld();
|
||||
if ((world != null) && world.isStatus(7))
|
||||
{
|
||||
spawnState(world);
|
||||
final L2Npc videoNpc = world.getNpc(TIAT_VIDEO_NPC);
|
||||
if (videoNpc != null)
|
||||
{
|
||||
playMovie(L2World.getInstance().getVisibleObjects(videoNpc, L2PcInstance.class, 8000), Movie.SC_BOSS_TIAT_OPENING);
|
||||
videoNpc.deleteMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
if (npc.getId() == OBELISK)
|
||||
{
|
||||
if (world.isStatus(2))
|
||||
{
|
||||
world.setStatus(4);
|
||||
spawnFlaggedNPCs(world, 3);
|
||||
}
|
||||
else if (world.isStatus(3))
|
||||
{
|
||||
world.setStatus(4);
|
||||
spawnFlaggedNPCs(world, 2);
|
||||
}
|
||||
}
|
||||
else if ((world.getStatus() <= 8) && (npc.getCurrentHp() < (npc.getMaxHp() / 2)))
|
||||
{
|
||||
spawnState(world);
|
||||
startQuestTimer("TiatFullHp", 3000, npc, null);
|
||||
world.setReenterTime();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "Spawn":
|
||||
{
|
||||
final List<L2PcInstance> players = new ArrayList<>(world.getPlayers());
|
||||
final L2PcInstance target = players.get(getRandom(players.size()));
|
||||
final int deviceCount = world.getParameters().getInt("deviceCount", 0);
|
||||
if ((deviceCount < MAX_DEVICESPAWNEDMOBCOUNT) && !target.isDead())
|
||||
{
|
||||
world.setParameter("deviceCount", deviceCount + 1);
|
||||
|
||||
final L2Attackable mob = (L2Attackable) addSpawn(SPAWN_MOB_IDS[getRandom(SPAWN_MOB_IDS.length)], npc.getSpawn().getLocation(), false, 0, false, world.getId());
|
||||
mob.setSeeThroughSilentMove(true);
|
||||
mob.setRunning();
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, (world.getStatus() >= 7) ? MOVE_TO_TIAT : MOVE_TO_DOOR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "DoorCheck":
|
||||
{
|
||||
final L2DoorInstance tmp = world.getDoor(FORTRESS_DOOR);
|
||||
if (tmp.getCurrentHp() < tmp.getMaxHp())
|
||||
{
|
||||
world.setParameter("deviceCount", 0);
|
||||
spawnFlaggedNPCs(world, 6);
|
||||
world.broadcastPacket(new ExShowScreenMessage(NpcStringId.ENEMIES_ARE_TRYING_TO_DESTROY_THE_FORTRESS_EVERYONE_DEFEND_THE_FORTRESS, ExShowScreenMessage.MIDDLE_CENTER, 1000));
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("DoorCheck", 10000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TiatFullHp":
|
||||
{
|
||||
if (!npc.hasBlockActions() && !npc.isHpBlocked())
|
||||
{
|
||||
npc.setCurrentHp(npc.getMaxHp());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
final Instance world = npc.getInstanceWorld();
|
||||
if (world != null)
|
||||
{
|
||||
switch (world.getStatus())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if (checkKillProgress(world))
|
||||
{
|
||||
spawnState(world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
if (checkKillProgress(world))
|
||||
{
|
||||
world.incStatus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
if (npc.getId() == OBELISK)
|
||||
{
|
||||
spawnState(world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
if ((npc.getId() == POWERFUL_DEVICE) && checkKillProgress(world))
|
||||
{
|
||||
spawnState(world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
if ((npc.getId() == THRONE_POWERFUL_DEVICE) && checkKillProgress(world))
|
||||
{
|
||||
spawnState(world);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (world.getStatus() >= 7)
|
||||
{
|
||||
if (npc.getId() == TIAT)
|
||||
{
|
||||
world.incStatus();
|
||||
playMovie(L2World.getInstance().getVisibleObjects(npc, L2PcInstance.class, 8000), Movie.SC_BOSS_TIAT_ENDING_SUCCES);
|
||||
world.removeNpcs();
|
||||
world.finishInstance();
|
||||
GraciaSeedsManager.getInstance().increaseSoDTiatKilled();
|
||||
}
|
||||
else if (npc.getId() == TIAT_GUARD)
|
||||
{
|
||||
addMinion(((L2MonsterInstance) npc).getLeader(), TIAT_GUARD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNpcDespawn(L2Npc npc)
|
||||
{
|
||||
cancelQuestTimer("Spawn", npc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final int npcId = npc.getId();
|
||||
if (npcId == ALENOS)
|
||||
{
|
||||
final int state = GraciaSeedsManager.getInstance().getSoDState();
|
||||
if (state == 1)
|
||||
{
|
||||
enterInstance(player, npc, TEMPLATE_ID);
|
||||
}
|
||||
else if (state == 2)
|
||||
{
|
||||
player.teleToLocation(ENTER_TELEPORT_2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.teleToLocation(CENTER_TELEPORT);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTrapAction(L2TrapInstance trap, L2Character trigger, TrapAction action)
|
||||
{
|
||||
final Instance world = trap.getInstanceWorld();
|
||||
if ((world != null) && (action == TrapAction.TRAP_TRIGGERED))
|
||||
{
|
||||
final int[] npcs = (trap.getId() == 18771) ? TRAP_18771_NPCS : TRAP_OTHER_NPCS;
|
||||
for (int npcId : npcs)
|
||||
{
|
||||
addSpawn(npcId, trap.getX(), trap.getY(), trap.getZ(), trap.getHeading(), true, 0, true, world.getId());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Stage1();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Teleport Device:<br>
|
||||
You do not have the key.<br>
|
||||
</body></html>
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Sizrak:<br>
|
||||
I will pray that you defeat Tauti... I hope your decision is the right one... I will pray.
|
||||
</body></html>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Sizrak:<br>
|
||||
We will win! We must!
|
||||
</body></html>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Sizrak:<br>
|
||||
Please prove your decision is the right one and help your members.
|
||||
</body></html>
|
||||
@@ -1,241 +0,0 @@
|
||||
/*
|
||||
* 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 instances.TautiWarzone;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
<html><body>Sizrak:<br>
|
||||
That many people can't be moved.<br>
|
||||
(A maximum of 35 people can participate.)
|
||||
</body></html>
|
||||
@@ -1,3 +0,0 @@
|
||||
<html><body>Sizrak:<br>
|
||||
As I explained earlier, you can enter only by forming an association.
|
||||
</body></html>
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
@@ -1,624 +0,0 @@
|
||||
/*
|
||||
* 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 instances.TeredorWarzone;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user