rendered paste body/* * 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.FinalEmperialTomb;import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_MOVE_TO;import gnu.trove.set.hash.TIntHashSet;import java.util.Calendar;import java.util.GregorianCalendar;import java.util.Map;import java.util.concurrent.ScheduledFuture;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;import javolution.util.FastList;import com.l2jserver.gameserver.ThreadPoolManager;import com.l2jserver.gameserver.datatables.SkillTable;import com.l2jserver.gameserver.instancemanager.InstanceManager;import com.l2jserver.gameserver.instancemanager.InstanceManager.InstanceWorld;import com.l2jserver.gameserver.instancemanager.ZoneManager;import com.l2jserver.gameserver.model.L2CharPosition;import com.l2jserver.gameserver.model.L2CommandChannel;import com.l2jserver.gameserver.model.L2ItemInstance;import com.l2jserver.gameserver.model.L2Object;import com.l2jserver.gameserver.model.L2Object.InstanceType;import com.l2jserver.gameserver.model.L2Party;import com.l2jserver.gameserver.model.L2Skill;import com.l2jserver.gameserver.model.L2Spawn;import com.l2jserver.gameserver.model.L2World;import com.l2jserver.gameserver.model.actor.L2Attackable;import com.l2jserver.gameserver.model.actor.L2Character;import com.l2jserver.gameserver.model.actor.L2Npc;import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;import com.l2jserver.gameserver.model.quest.Quest;import com.l2jserver.gameserver.model.quest.QuestState;import com.l2jserver.gameserver.model.zone.L2ZoneType;import com.l2jserver.gameserver.network.NpcStringId;import com.l2jserver.gameserver.network.SystemMessageId;import com.l2jserver.gameserver.network.clientpackets.Say2;import com.l2jserver.gameserver.network.serverpackets.AbstractNpcInfo.NpcInfo;import com.l2jserver.gameserver.network.serverpackets.Earthquake;import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;import com.l2jserver.gameserver.network.serverpackets.FlyToLocation;import com.l2jserver.gameserver.network.serverpackets.FlyToLocation.FlyType;import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;import com.l2jserver.gameserver.network.serverpackets.MagicSkillCanceld;import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;import com.l2jserver.gameserver.network.serverpackets.NpcSay;import com.l2jserver.gameserver.network.serverpackets.SocialAction;import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;import com.l2jserver.gameserver.network.serverpackets.SystemMessage;import com.l2jserver.gameserver.network.serverpackets.ValidateLocation;import com.l2jserver.gameserver.templates.effects.EffectTemplate;import com.l2jserver.gameserver.templates.skills.L2SkillType;import com.l2jserver.gameserver.util.Util;import com.l2jserver.util.Rnd;/** * Frintezza AI * * @author Darki699 * @author SANDMAN L2J_JP * @author JOJO * @author rocknow * @author L2jOff team *//*TODO:- test when Frintezza song use 5008 effect skill- maybe test more deeply halishas AI- use correct Song names- use proper zone spawn systemContributing authors: Gigiikun*/public class FinalEmperialTomb extends Quest{ private static final boolean DEBUG = false; private static final boolean ASSERT = false; private static final boolean DETECT_ACTION_LOCK = true; private class FETWorld extends InstanceWorld { public Lock lock = new ReentrantLock(); public FastList<L2Npc> npcList = new FastList<L2Npc>(); public int npcMax = 0; public int darkChoirPlayerCount = 0; public ScheduledFuture<?> songTask = null; public boolean isVideo = false; public L2Npc frintezzaDummy = null; public L2Npc overheadDummy = null; public L2Npc portraitDummy1 = null; public L2Npc portraitDummy3 = null; public L2Npc scarletDummy = null; public L2GrandBossInstance frintezza = null; public L2GrandBossInstance activeScarlet = null; public L2MonsterInstance[] ghosts = new L2MonsterInstance[4]; public L2MonsterInstance[] portraits = new L2MonsterInstance[4]; public int scarlet_x = 0; public int scarlet_y = 0; public int scarlet_z = 0; public int scarlet_h = 0; public int scarlet_a = 0; private long lastAction; public FETWorld() {if (DETECT_ACTION_LOCK) {{ class ActionLockListener implements Runnable { public void run() { if (status == 1 || status == 2) { if (System.currentTimeMillis() - lastAction > 300000) { /*#IF DEBUG#*/ // TRACE("時間切れ", ""); // for (L2Npc npc : npcList) // { // TRACE((npc.isVisible() ? "V" : " ") // + (npc.isDead() ? "D" : " ") // + " " + npc.getObjectId() + " " + npc.getNpcId() + " " + npc.getName()); // } /*#END IF#*/ if (status == 1) { if (InstanceManager.getInstance().getInstance(instanceId).getDoor(17130051).getOpen()) addAggroToMobs(FETWorld.this, ROOM1_CENTER_X, ROOM1_CENTER_Y, ROOM1_CENTER_Z); } else if (status == 2) { if (InstanceManager.getInstance().getInstance(instanceId).getDoor(17130061).getOpen()) addAggroToMobs(FETWorld.this, ROOM2_CENTER_X, ROOM2_CENTER_Y, ROOM2_CENTER_Z); } lastAction = System.currentTimeMillis(); } ThreadPoolManager.getInstance().scheduleGeneral(ActionLockListener.this, 30000); } }/*#IF DEBUG#*/ @Override protected void finalize() throws Throwable { super.finalize(); TRACE(getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()), "finalize()"); }/*#END IF#*/ } lastAction = System.currentTimeMillis(); ThreadPoolManager.getInstance().scheduleGeneral(new ActionLockListener(), 60000);}} } } private static class FrintezzaSong { public int songId, songLevel; public int effectId, effectLevel; public NpcStringId songName; public int chance; public FrintezzaSong(int songId, int songLevel, int effectId, int effectLevel, NpcStringId songName, int chance) { this.songId = songId; this.songLevel = songLevel; this.effectId = effectId; this.effectLevel = effectLevel; this.songName = songName; this.chance = chance; } } private static final String qn = "FinalEmperialTomb"; private static final int INSTANCEID = 136; // this is the client number private static final int MIN_PLAYERS = 36; private static final int MAX_PLAYERS = 45; // Initialization at 6:30 am on Wednesday and Saturday private static final int RESET_HOUR_OF_DAY = 6; private static final int RESET_MINUTE = 30; private static final int[] RESET_DAY_OF_WEEK = { Calendar.WEDNESDAY, Calendar.SATURDAY, }; private final TIntHashSet _mustKillMobsId = new TIntHashSet(); //Items private static final int FRINTEZZA_SCROLL = 8073; // Frintezza's Magic Force Field Removal Scroll | フリンテッサの結界解除スクロール private static final int SOUL_BREAKING_ARROW = 8192; // Soul Breaking Arrow | 破魂の矢 private static final int DEWDROP_OF_DESTRUCTION = 8556; // Dewdrop of Destruction | 破魂の露 @SuppressWarnings("unused") private static final int FIRST_SCARLET_WEAPON = 8204; // --> npc.sql private static final int SECOND_SCARLET_WEAPON = 7903; @SuppressWarnings("unused") private static final int THIRD_SCARLET_WEAPON = 8222; // --> npc.sql //NPCs private static final int GUIDE = 32011; // Imperial Tomb Guide | フリンテッサ テレポーター private static final int CUBE = 29061; // Teleportation Cubic | テレポート キューブ //mobs: ROOM 3 private static final int FRINTEZZA = 29045; private static final int SCARLET1 = 29046; // Daemon #1,#2 Scarlet van Halisha | スカーレット ヴァン ハリシャ private static final int SCARLET2 = 29047; // Daemon #3 Scarlet van Halisha | スカーレット ヴァン ハリシャ private static final int PORTRAIT_FIGHTER = 29048; // Evil Spirit | エヴィレイト(ファイター) private static final int PORTRAIT_MAGE = 29049; // Evil Spirit | エヴィレイト(メイジ) private static final int GHOST_FIGHTER = 29050; // Breath of Halisha | ハリシャ ブレス(ファイター) private static final int GHOST_MAGE = 29051; // Breath of Halisha | ハリシャ ブレス(メイジ) @SuppressWarnings("unused") private static final int CAMERA_DUMMY = 29052; @SuppressWarnings("unused") private static final int DIMENSIONAL_SHOCK = 29053; //mobs: ROOM 1 private static final int HALL_ALARM = 18328; // ホール アラーム private static final int HALL_KEEPER_CAPTAIN = 18329; // Hall Keeper Captain | ホールキーパー キャプテン private static final int HALL_KEEPER_WIZARD = 18330; // Hall Keeper Wizard | ホールキーパー ウィザード private static final int HALL_KEEPER_GUARD = 18331; // Hall Keeper Guard | ホールキーパー ガード @SuppressWarnings("unused") private static final int HALL_KEEPER_PATROL = 18332; // Hall Keeper Patrol | ホールキーパー パトロール private static final int HALL_KEEPER_SUICIDAL_SOLDIER_1 = 18333; // Hall Keeper Suicidal Soldier | ホールキーパー カミカゼ(攻撃力16かなり高め/スキル4614-9 NPC Death Bomb) //mobs: ROOM 2 private static final int DARK_CHOIR_CAPTAIN = 18334; // Dark Choir Captain | 黒聖歌団長 private static final int DARK_CHOIR_PRIMA_DONNA = 18335; // Dark Choir Prima Donna | 黒聖歌団 プリマ private static final int DARK_CHOIR_LANCER = 18336; // Dark Choir Lancer | 黒聖歌団 ランサー private static final int DARK_CHOIR_ARCHER = 18337; // Dark Choir Archer | 黒聖歌団 アーチャー private static final int DARK_CHOIR_WITCH_DOCTOR = 18338; // Dark Choir Witch Doctor | 黒聖歌団 ウィザード private static final int DARK_CHOIR_PLAYER = 18339; // Dark Choir Player | 黒聖歌団 プレイヤー @SuppressWarnings("unused") private static final int HALL_KEEPER_SUICIDAL_SOLDIER_2a = 18340; // Hall Keeper Suicidal Soldier | ホールキーパー カミカゼ(攻撃力11普通/スキル5042-9 NPC Dispel Bomb) @SuppressWarnings("unused") private static final int HALL_KEEPER_SUICIDAL_SOLDIER_2b = 18341; // Hall Keeper Suicidal Soldier | ホールキーパー カミカゼ(攻撃力16かなり高め/スキル5042-9 NPC Dispel Bomb) private static final int[] AI_DISABLED_MOBS = { HALL_ALARM }; private static final int[] NO_AGGRO_MOBS = { DARK_CHOIR_CAPTAIN }; // Skills private static final int FRINTEZZA_SONG = 5007, FRINTEZZA_EFFECT = 5008; private static final FrintezzaSong[] FRINTEZZA_SONG_LIST = {/*#IF DEBUG#*/// new FrintezzaSong(FRINTEZZA_SONG,1, FRINTEZZA_EFFECT,1, NpcStringId.REQUIEM_OF_HATRED, 16), // 16% ヒール演奏。// new FrintezzaSong(FRINTEZZA_SONG,2, FRINTEZZA_EFFECT,2, NpcStringId.RONDO_OF_SOLITUDE, 33), // 17% 演出:ダッシュ+肖像画再生演奏。// new FrintezzaSong(FRINTEZZA_SONG,3, FRINTEZZA_EFFECT,3, NpcStringId.FRENETIC_TOCCATA, 50), // 17% 攻撃/速度演奏。// new FrintezzaSong(FRINTEZZA_SONG,4, FRINTEZZA_EFFECT,4, NpcStringId.MOURNFUL_CHORALE_PRELUDE, 75), // 25% 悲嘆のコラール// new FrintezzaSong(FRINTEZZA_SONG,5, FRINTEZZA_EFFECT,5, NpcStringId.HYPNOTIC_MAZURKA, 100), // 25% 魅惑のマズルカ/*#END IF#*/ new FrintezzaSong(FRINTEZZA_SONG,1, FRINTEZZA_EFFECT,1, NpcStringId.REQUIEM_OF_HATRED, 5), // 5% ヒール演奏。 new FrintezzaSong(FRINTEZZA_SONG,2, FRINTEZZA_EFFECT,2, NpcStringId.RONDO_OF_SOLITUDE, 50), // 45% 演出:ダッシュ+肖像画再生演奏。 new FrintezzaSong(FRINTEZZA_SONG,3, FRINTEZZA_EFFECT,3, NpcStringId.FRENETIC_TOCCATA, 70), // 20% 攻撃/速度演奏。 new FrintezzaSong(FRINTEZZA_SONG,4, FRINTEZZA_EFFECT,4, NpcStringId.MOURNFUL_CHORALE_PRELUDE, 90), // 20% 悲嘆のコラール new FrintezzaSong(FRINTEZZA_SONG,5, FRINTEZZA_EFFECT,5, NpcStringId.HYPNOTIC_MAZURKA, 100), // 10% 魅惑のマズルカ }; // Doors/Walls/Zones 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/*=>フリン部屋*/ }; private static final int ROOM1_CENTER_X = -87904, ROOM1_CENTER_Y = -141296, ROOM1_CENTER_Z = -9168; private static final int ROOM2_CENTER_X = -87904, ROOM2_CENTER_Y = -147065, ROOM2_CENTER_Z = -9168; private static final int ROOM3_ZONE = 12911; // Teleports private static final int[] ENTER_TELEPORT = { -88015,-141153,-9168 }; // spawns private static final int GHOST_RESPAWN_DELAY = 10; //sec. private static final int[][] PORTRAIT_SPAWNS = { { PORTRAIT_FIGHTER, -89381, -153981, -9168, 3368 }, { PORTRAIT_FIGHTER, -86234, -152467, -9168, 37656 }, { PORTRAIT_MAGE, -89342, -152479, -9168, -5152 }, { PORTRAIT_MAGE, -86189, -153968, -9168, 29456 } }; private static final int[][] GHOST_SPAWNS = { { GHOST_FIGHTER, -89378, -153968, -9168, 3368 }, { GHOST_FIGHTER, -86261, -152492, -9168, 37656 }, { GHOST_MAGE, -89311, -152491, -9168, -5152 }, { GHOST_MAGE, -86217, -153956, -9168, 29456 } }; private void openDoors(int[]doorIds, int instanceId) { for (int doorId : doorIds) openDoor(doorId, instanceId); } private void closeDoors(int[]doorIds, int instanceId) { for (int doorId : doorIds) closeDoor(doorId, instanceId); } private void openDoor(int doorId, int instanceId) { for (L2DoorInstance door : InstanceManager.getInstance().getInstance(instanceId).getDoors()) if (door.getDoorId() == doorId) door.openMe(); } private void closeDoor(int doorId, int instanceId) { for (L2DoorInstance door : InstanceManager.getInstance().getInstance(instanceId).getDoors()) if (door.getDoorId() == doorId) if (door.getOpen()) door.closeMe(); } private boolean checkConditions(L2PcInstance player) { if (DEBUG || player.isGM()) return true; L2Party party = player.getParty(); if (party == null) { player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.NOT_IN_PARTY_CANT_ENTER)); return false; } L2CommandChannel channel = player.getParty().getCommandChannel(); if (channel == null) { player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.NOT_IN_COMMAND_CHANNEL_CANT_ENTER)); return false; } else if (channel.getChannelLeader() != player) { player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.ONLY_PARTY_LEADER_CAN_ENTER)); return false; } else if (player.getInventory().getItemByItemId(FRINTEZZA_SCROLL) == null) { SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_ITEM_REQUIREMENT_NOT_SUFFICIENT); sm.addPcName(player); player.sendPacket(sm); return false; } else if (channel.getMemberCount() < MIN_PLAYERS || channel.getMemberCount() > MAX_PLAYERS) { player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.PARTY_EXCEEDED_THE_LIMIT_CANT_ENTER)); return false; } boolean condition = true; for (L2PcInstance channelMember : channel.getMembers()) { if (channelMember.getLevel() < 80) { SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_LEVEL_REQUIREMENT_NOT_SUFFICIENT); sm.addPcName(channelMember); party.broadcastToPartyMembers(sm); condition = false; } if (!Util.checkIfInRange(1000, player, channelMember, true)) { SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_IS_IN_LOCATION_THAT_CANNOT_BE_ENTERED); sm.addPcName(channelMember); party.broadcastToPartyMembers(sm); condition = false; } long reentertime = InstanceManager.getInstance().getInstanceTime(channelMember.getObjectId(), INSTANCEID); if (System.currentTimeMillis() < reentertime) { SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_MAY_NOT_REENTER_YET); sm.addPcName(channelMember); party.broadcastToPartyMembers(sm); condition = false; } } return condition; } private void teleportPlayer(L2PcInstance player, int[] coords, int instanceId)/*テスト済*/ { player.setInstanceId(instanceId); player.teleToLocation(coords[0], coords[1], coords[2]); destroyAllItem(player, SOUL_BREAKING_ARROW); destroyAllItem(player, DEWDROP_OF_DESTRUCTION); } private void destroyAllItem(L2PcInstance player, int itemId)/*テスト済*/ { L2ItemInstance item = player.getInventory().getItemByItemId(itemId); if (item != null) player.destroyItemByItemId("Quest", itemId, item.getCount(), player, true); } private int enterInstance(L2PcInstance player, String template, int[] coords) { int instanceId = 0; //check for existing instances for this player InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player); //existing instance if (world != null) { if (!(world instanceof FETWorld)) { player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.ALREADY_ENTERED_ANOTHER_INSTANCE_CANT_ENTER)); return 0; } teleportPlayer(player, coords, world.instanceId); return world.instanceId; } //New instance else { if (!checkConditions(player)) return 0; if (!player.isGM() && !player.destroyItemByItemId("Quest", FRINTEZZA_SCROLL, 1, player, true)) return 0; instanceId = InstanceManager.getInstance().createDynamicInstance(template); //Instance ins = InstanceManager.getInstance().getInstance(instanceId); //ins.setSpawnLoc(new int[]{player.getX(),player.getY(),player.getZ()}); world = new FETWorld(); world.instanceId = instanceId; world.status = 0; InstanceManager.getInstance().addWorld(world); controlStatus((FETWorld) world);/*=>0*/ _log.info("Final Emperial Tomb started " + template + " Instance: " + instanceId + " created by player: " + player.getName()); // teleport players if (player.getParty() == null || player.getParty().getCommandChannel() == null) { world.allowed.add(player.getObjectId()); teleportPlayer(player, coords, instanceId); } else { for (L2PcInstance channelMember : player.getParty().getCommandChannel().getMembers()) { world.allowed.add(channelMember.getObjectId()); teleportPlayer(channelMember, coords, instanceId); } } return instanceId; } } /** * モンスター配置:1部屋め ホールアラーム * @param world */ private void spawnHallAlarm(FETWorld world)/*テスト済*/ { spawn(world, HALL_ALARM, -87904, -141296, -9168, 0, false); } /** * モンスター配置:1部屋め ホールキーパー * @param world */ private void spawnHallKeepers(FETWorld world)/*テスト済*/ { spawn(world, HALL_KEEPER_WIZARD, -89179, -141151, -9084, 29201, true); spawn(world, HALL_KEEPER_WIZARD, -89072, -141422, -9084, 55195, true); spawn(world, HALL_KEEPER_WIZARD, -89241, -140900, -9084, 29568, true); spawn(world, HALL_KEEPER_GUARD, -88982, -141058, -9084, 18641, true); spawn(world, HALL_KEEPER_GUARD, -89168, -141063, -9084, 24129, true); spawn(world, HALL_KEEPER_GUARD, -89013, -141080, -9084, 15361, true); spawn(world, HALL_KEEPER_GUARD, -89060, -141558, -9084, 12654, true); spawn(world, HALL_KEEPER_GUARD, -89277, -141133, -9084, 27853, true); spawn(world, HALL_KEEPER_GUARD, -88982, -141441, -9084, 41976, true); spawn(world, HALL_KEEPER_GUARD, -89154, -141486, -9084, 55794, true); spawn(world, HALL_KEEPER_GUARD, -89002, -141243, -9084, 46318, true); spawn(world, HALL_KEEPER_GUARD, -89175, -141221, -9084, 32141, true); spawn(world, HALL_KEEPER_GUARD, -89286, -141786, -9084, 59388, true); spawn(world, HALL_KEEPER_CAPTAIN, -89265, -141731, -9084, 4186, true); spawn(world, HALL_KEEPER_CAPTAIN, -89154, -141696, -9084, 40154, true); spawn(world, HALL_KEEPER_CAPTAIN, -89004, -141261, -9084, 26412, true); spawn(world, HALL_KEEPER_CAPTAIN, -89098, -141667, -9084, 6500, true); spawn(world, HALL_KEEPER_CAPTAIN, -89238, -140994, -9084, 34003, true); spawn(world, HALL_KEEPER_CAPTAIN, -89221, -140948, -9084, 413, true); spawn(world, HALL_KEEPER_CAPTAIN, -89177, -141249, -9084, 32846, true); spawn(world, HALL_KEEPER_CAPTAIN, -89277, -141646, -9084, 50123, true); spawn(world, HALL_KEEPER_CAPTAIN, -89289, -141179, -9084, 38433, true); spawn(world, HALL_KEEPER_CAPTAIN, -89048, -141471, -9084, 23960, true); spawn(world, HALL_KEEPER_WIZARD, -89293, -141554, -9084, 44386, true); spawn(world, HALL_KEEPER_WIZARD, -89279, -141608, -9084, 17601, true); spawn(world, HALL_KEEPER_WIZARD, -89293, -141733, -9084, 22291, true); spawn(world, HALL_KEEPER_WIZARD, -89261, -140966, -9084, 33093, true); spawn(world, HALL_KEEPER_WIZARD, -89110, -141304, -9084, 49199, true); spawn(world, HALL_KEEPER_WIZARD, -89201, -141057, -9084, 61192, true); spawn(world, HALL_KEEPER_WIZARD, -88970, -141444, -9084, 33115, true); spawn(world, HALL_KEEPER_WIZARD, -89287, -141117, -9084, 31752, true); spawn(world, HALL_KEEPER_WIZARD, -89144, -141588, -9084, 9834, true); spawn(world, HALL_KEEPER_WIZARD, -89141, -141262, -9084, 48686, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89206, -141647, -9084, 2679, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88991, -141322, -9084, 9016, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89094, -141219, -9084, 54854, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89041, -141506, -9084, 46264, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89206, -141299, -9084, 7060, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89137, -141194, -9084, 46678, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89255, -141383, -9084, 1658, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89239, -141546, -9084, 4935, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89253, -141120, -9084, 15924, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89236, -140921, -9084, 37100, true); spawn(world, HALL_KEEPER_WIZARD, -88994, -141895, -9084, 40023, true); spawn(world, HALL_KEEPER_WIZARD, -88671, -142486, -9084, 63707, true); spawn(world, HALL_KEEPER_WIZARD, -89070, -141952, -9084, 55610, true); spawn(world, HALL_KEEPER_GUARD, -88677, -142231, -9084, 5076, true); spawn(world, HALL_KEEPER_GUARD, -88911, -142162, -9084, 46095, true); spawn(world, HALL_KEEPER_GUARD, -89206, -141915, -9084, 29714, true); spawn(world, HALL_KEEPER_GUARD, -88913, -142183, -9084, 9773, true); spawn(world, HALL_KEEPER_GUARD, -88940, -141918, -9084, 59795, true); spawn(world, HALL_KEEPER_GUARD, -88750, -142240, -9084, 40924, true); spawn(world, HALL_KEEPER_GUARD, -88995, -141945, -9084, 4964, true); spawn(world, HALL_KEEPER_GUARD, -88456, -142398, -9084, 28245, true); spawn(world, HALL_KEEPER_GUARD, -89184, -141910, -9084, 31201, true); spawn(world, HALL_KEEPER_GUARD, -88621, -142366, -9084, 14877, true); spawn(world, HALL_KEEPER_CAPTAIN, -88581, -142228, -9084, 59733, true); spawn(world, HALL_KEEPER_CAPTAIN, -88605, -142268, -9084, 16013, true); spawn(world, HALL_KEEPER_CAPTAIN, -88804, -142360, -9084, 2054, true); spawn(world, HALL_KEEPER_CAPTAIN, -89085, -141940, -9084, 24413, true); spawn(world, HALL_KEEPER_CAPTAIN, -88521, -142542, -9084, 42030, true); spawn(world, HALL_KEEPER_CAPTAIN, -88856, -142048, -9084, 56049, true); spawn(world, HALL_KEEPER_CAPTAIN, -89033, -142038, -9084, 7498, true); spawn(world, HALL_KEEPER_CAPTAIN, -88685, -142335, -9084, 12201, true); spawn(world, HALL_KEEPER_CAPTAIN, -88827, -142060, -9084, 23417, true); spawn(world, HALL_KEEPER_CAPTAIN, -88895, -142065, -9084, 56831, true); spawn(world, HALL_KEEPER_WIZARD, -88890, -142145, -9084, 13966, true); spawn(world, HALL_KEEPER_WIZARD, -88814, -142315, -9084, 23378, true); spawn(world, HALL_KEEPER_WIZARD, -88985, -141993, -9084, 20346, true); spawn(world, HALL_KEEPER_WIZARD, -88882, -141894, -9084, 39953, true); spawn(world, HALL_KEEPER_WIZARD, -88772, -142064, -9084, 8081, true); spawn(world, HALL_KEEPER_WIZARD, -89193, -141924, -9084, 1410, true); spawn(world, HALL_KEEPER_WIZARD, -88515, -142586, -9084, 50268, true); spawn(world, HALL_KEEPER_WIZARD, -88951, -141997, -9084, 36420, true); spawn(world, HALL_KEEPER_WIZARD, -89080, -141960, -9084, 64618, true); spawn(world, HALL_KEEPER_WIZARD, -88911, -142051, -9084, 47432, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88630, -142205, -9084, 34636, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88511, -142481, -9084, 61532, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88854, -141942, -9084, 19805, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88888, -142146, -9084, 41516, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88811, -142349, -9084, 34329, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88515, -142514, -9084, 46043, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89187, -141975, -9084, 18674, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88540, -142353, -9084, 51463, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89009, -142081, -9084, 52367, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -89073, -141879, -9084, 36950, true); spawn(world, HALL_KEEPER_WIZARD, -87487, -142622, -9084, 11560, true); spawn(world, HALL_KEEPER_WIZARD, -87699, -142648, -9084, 8491, true); spawn(world, HALL_KEEPER_WIZARD, -87977, -142597, -9084, 20714, true); spawn(world, HALL_KEEPER_GUARD, -87625, -142520, -9084, 23555, true); spawn(world, HALL_KEEPER_GUARD, -88273, -142655, -9084, 55342, true); spawn(world, HALL_KEEPER_GUARD, -87945, -142633, -9084, 35172, true); spawn(world, HALL_KEEPER_GUARD, -87736, -142630, -9084, 24731, true); spawn(world, HALL_KEEPER_GUARD, -87968, -142406, -9084, 60800, true); spawn(world, HALL_KEEPER_GUARD, -87796, -142378, -9084, 58660, true); spawn(world, HALL_KEEPER_GUARD, -87632, -142640, -9084, 56686, true); spawn(world, HALL_KEEPER_GUARD, -87678, -142539, -9084, 7582, true); spawn(world, HALL_KEEPER_GUARD, -87793, -142541, -9084, 29086, true); spawn(world, HALL_KEEPER_GUARD, -87447, -142630, -9084, 60299, true); spawn(world, HALL_KEEPER_CAPTAIN, -87799, -142466, -9084, 5759, true); spawn(world, HALL_KEEPER_CAPTAIN, -87514, -142628, -9084, 58262, true); spawn(world, HALL_KEEPER_CAPTAIN, -87724, -142647, -9084, 24200, true); spawn(world, HALL_KEEPER_CAPTAIN, -88087, -142588, -9084, 10858, true); spawn(world, HALL_KEEPER_CAPTAIN, -87967, -142663, -9084, 57780, true); spawn(world, HALL_KEEPER_CAPTAIN, -87720, -142648, -9084, 37602, true); spawn(world, HALL_KEEPER_CAPTAIN, -87929, -142660, -9084, 46137, true); spawn(world, HALL_KEEPER_CAPTAIN, -88174, -142673, -9084, 24488, true); spawn(world, HALL_KEEPER_CAPTAIN, -88240, -142449, -9084, 13398, true); spawn(world, HALL_KEEPER_CAPTAIN, -87607, -142680, -9084, 17097, true); spawn(world, HALL_KEEPER_WIZARD, -88200, -142534, -9084, 15141, true); spawn(world, HALL_KEEPER_WIZARD, -88108, -142534, -9084, 32296, true); spawn(world, HALL_KEEPER_WIZARD, -87730, -142419, -9084, 42508, true); spawn(world, HALL_KEEPER_WIZARD, -87719, -142525, -9084, 49712, true); spawn(world, HALL_KEEPER_WIZARD, -88154, -142633, -9084, 46219, true); spawn(world, HALL_KEEPER_WIZARD, -87627, -142460, -9084, 41723, true); spawn(world, HALL_KEEPER_WIZARD, -87838, -142485, -9084, 1086, true); spawn(world, HALL_KEEPER_WIZARD, -87938, -142561, -9084, 8226, true); spawn(world, HALL_KEEPER_WIZARD, -87762, -142527, -9084, 17686, true); spawn(world, HALL_KEEPER_WIZARD, -88098, -142438, -9084, 13467, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87900, -142655, -9084, 53098, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87862, -142433, -9084, 23101, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87887, -142604, -9084, 16537, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88230, -142612, -9084, 38105, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88049, -142431, -9084, 26056, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87878, -142463, -9084, 31627, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88044, -142632, -9084, 41814, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87675, -142577, -9084, 35302, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87983, -142414, -9084, 24927, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87884, -142401, -9084, 46450, true); spawn(world, HALL_KEEPER_WIZARD, -86759, -141907, -9084, 17429, true); spawn(world, HALL_KEEPER_WIZARD, -86651, -141971, -9084, 5614, true); spawn(world, HALL_KEEPER_WIZARD, -86955, -142198, -9084, 31911, true); spawn(world, HALL_KEEPER_GUARD, -87092, -142250, -9084, 22242, true); spawn(world, HALL_KEEPER_GUARD, -86888, -142003, -9084, 3622, true); spawn(world, HALL_KEEPER_GUARD, -87177, -142347, -9084, 30199, true); spawn(world, HALL_KEEPER_GUARD, -86769, -141937, -9084, 9524, true); spawn(world, HALL_KEEPER_GUARD, -87163, -142476, -9084, 62322, true); spawn(world, HALL_KEEPER_GUARD, -86909, -142200, -9084, 13244, true); spawn(world, HALL_KEEPER_GUARD, -86788, -141977, -9084, 19113, true); spawn(world, HALL_KEEPER_GUARD, -87025, -142281, -9084, 40342, true); spawn(world, HALL_KEEPER_GUARD, -87125, -142427, -9084, 23676, true); spawn(world, HALL_KEEPER_GUARD, -87043, -142051, -9084, 61011, true); spawn(world, HALL_KEEPER_CAPTAIN, -86660, -141918, -9084, 60818, true); spawn(world, HALL_KEEPER_CAPTAIN, -87041, -142298, -9084, 4384, true); spawn(world, HALL_KEEPER_CAPTAIN, -87024, -142242, -9084, 52296, true); spawn(world, HALL_KEEPER_CAPTAIN, -86942, -142164, -9084, 18800, true); spawn(world, HALL_KEEPER_CAPTAIN, -87334, -142391, -9084, 26082, true); spawn(world, HALL_KEEPER_CAPTAIN, -86811, -141878, -9084, 24000, true); spawn(world, HALL_KEEPER_CAPTAIN, -86886, -141984, -9084, 52192, true); spawn(world, HALL_KEEPER_CAPTAIN, -87362, -142430, -9084, 362, true); spawn(world, HALL_KEEPER_CAPTAIN, -87313, -142321, -9084, 35934, true); spawn(world, HALL_KEEPER_CAPTAIN, -87164, -142092, -9084, 2405, true); spawn(world, HALL_KEEPER_WIZARD, -87174, -142324, -9084, 40368, true); spawn(world, HALL_KEEPER_WIZARD, -87022, -142014, -9084, 49873, true); spawn(world, HALL_KEEPER_WIZARD, -86978, -142210, -9084, 27160, true); spawn(world, HALL_KEEPER_WIZARD, -87316, -142380, -9084, 24693, true); spawn(world, HALL_KEEPER_WIZARD, -87166, -142212, -9084, 55605, true); spawn(world, HALL_KEEPER_WIZARD, -87147, -142416, -9084, 28904, true); spawn(world, HALL_KEEPER_WIZARD, -87393, -142346, -9084, 8960, true); spawn(world, HALL_KEEPER_WIZARD, -86909, -141964, -9084, 28331, true); spawn(world, HALL_KEEPER_WIZARD, -86680, -141996, -9084, 25744, true); spawn(world, HALL_KEEPER_WIZARD, -87047, -142082, -9084, 29196, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86952, -141993, -9084, 40622, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86960, -142294, -9084, 35741, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87257, -142281, -9084, 39057, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86915, -141969, -9084, 52851, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87180, -142479, -9084, 59051, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86946, -142118, -9084, 7156, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87216, -142452, -9084, 30191, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87169, -142482, -9084, 31494, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87087, -142319, -9084, 59175, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87244, -142336, -9084, 2847, true); spawn(world, HALL_KEEPER_WIZARD, -86553, -140940, -9084, 42599, true); spawn(world, HALL_KEEPER_WIZARD, -86573, -140862, -9084, 27920, true); spawn(world, HALL_KEEPER_WIZARD, -86687, -141658, -9084, 50112, true); spawn(world, HALL_KEEPER_GUARD, -86578, -141628, -9084, 16570, true); spawn(world, HALL_KEEPER_GUARD, -86845, -141272, -9084, 49416, true); spawn(world, HALL_KEEPER_GUARD, -86543, -141609, -9084, 9735, true); spawn(world, HALL_KEEPER_GUARD, -86702, -141546, -9084, 18913, true); spawn(world, HALL_KEEPER_GUARD, -86634, -141286, -9084, 25878, true); spawn(world, HALL_KEEPER_GUARD, -86833, -141524, -9084, 36512, true); spawn(world, HALL_KEEPER_GUARD, -86642, -140920, -9084, 12438, true); spawn(world, HALL_KEEPER_GUARD, -86627, -141565, -9084, 10380, true); spawn(world, HALL_KEEPER_GUARD, -86746, -140969, -9084, 4535, true); spawn(world, HALL_KEEPER_GUARD, -86806, -141341, -9084, 25441, true); spawn(world, HALL_KEEPER_CAPTAIN, -86568, -141314, -9084, 54899, true); spawn(world, HALL_KEEPER_CAPTAIN, -86798, -141130, -9084, 11892, true); spawn(world, HALL_KEEPER_CAPTAIN, -86836, -141468, -9084, 29780, true); spawn(world, HALL_KEEPER_CAPTAIN, -86717, -141395, -9084, 37205, true); spawn(world, HALL_KEEPER_CAPTAIN, -86711, -141351, -9084, 16553, true); spawn(world, HALL_KEEPER_CAPTAIN, -86625, -141329, -9084, 12887, true); spawn(world, HALL_KEEPER_CAPTAIN, -86629, -141758, -9084, 13472, true); spawn(world, HALL_KEEPER_CAPTAIN, -86700, -141048, -9084, 58459, true); spawn(world, HALL_KEEPER_CAPTAIN, -86649, -140899, -9084, 37420, true); spawn(world, HALL_KEEPER_CAPTAIN, -86656, -141659, -9084, 53390, true); spawn(world, HALL_KEEPER_WIZARD, -86639, -141628, -9084, 27370, true); spawn(world, HALL_KEEPER_WIZARD, -86678, -140895, -9084, 51579, true); spawn(world, HALL_KEEPER_WIZARD, -86666, -141401, -9084, 2166, true); spawn(world, HALL_KEEPER_WIZARD, -86707, -141364, -9084, 38717, true); spawn(world, HALL_KEEPER_WIZARD, -86626, -141263, -9084, 34845, true); spawn(world, HALL_KEEPER_WIZARD, -86843, -141133, -9084, 43750, true); spawn(world, HALL_KEEPER_WIZARD, -86683, -141644, -9084, 46859, true); spawn(world, HALL_KEEPER_WIZARD, -86540, -140925, -9084, 52340, true); spawn(world, HALL_KEEPER_WIZARD, -86764, -141468, -9084, 29290, true); spawn(world, HALL_KEEPER_WIZARD, -86789, -141479, -9084, 39464, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86821, -141526, -9084, 586, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86836, -141079, -9084, 2316, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86583, -140867, -9084, 55682, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86723, -141179, -9084, 57311, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86551, -140986, -9084, 36818, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86825, -141415, -9084, 57390, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86549, -141026, -9084, 34174, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86671, -141631, -9084, 4159, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86631, -140963, -9084, 49098, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86552, -140935, -9084, 54831, true); spawn(world, HALL_KEEPER_WIZARD, -86913, -140358, -9084, 29722, true); spawn(world, HALL_KEEPER_WIZARD, -87255, -140089, -9084, 21995, true); spawn(world, HALL_KEEPER_WIZARD, -87118, -140500, -9084, 64831, true); spawn(world, HALL_KEEPER_GUARD, -87362, -140225, -9084, 18420, true); spawn(world, HALL_KEEPER_GUARD, -87353, -140230, -9084, 57857, true); spawn(world, HALL_KEEPER_GUARD, -87044, -140238, -9084, 14115, true); spawn(world, HALL_KEEPER_GUARD, -87321, -140279, -9084, 56692, true); spawn(world, HALL_KEEPER_GUARD, -87178, -140473, -9084, 29072, true); spawn(world, HALL_KEEPER_GUARD, -86888, -140620, -9084, 28810, true); spawn(world, HALL_KEEPER_GUARD, -87132, -140419, -9084, 53381, true); spawn(world, HALL_KEEPER_GUARD, -87162, -140553, -9084, 65457, true); spawn(world, HALL_KEEPER_GUARD, -87102, -140306, -9084, 34336, true); spawn(world, HALL_KEEPER_GUARD, -87145, -140561, -9084, 31080, true); spawn(world, HALL_KEEPER_CAPTAIN, -86925, -140704, -9084, 36929, true); spawn(world, HALL_KEEPER_CAPTAIN, -87049, -140669, -9084, 52241, true); spawn(world, HALL_KEEPER_CAPTAIN, -87164, -140348, -9084, 886, true); spawn(world, HALL_KEEPER_CAPTAIN, -87088, -140315, -9084, 45956, true); spawn(world, HALL_KEEPER_CAPTAIN, -87091, -140383, -9084, 59410, true); spawn(world, HALL_KEEPER_CAPTAIN, -86991, -140683, -9084, 16050, true); spawn(world, HALL_KEEPER_CAPTAIN, -86954, -140636, -9084, 62620, true); spawn(world, HALL_KEEPER_CAPTAIN, -86778, -140547, -9084, 38397, true); spawn(world, HALL_KEEPER_CAPTAIN, -86569, -140711, -9084, 19800, true); spawn(world, HALL_KEEPER_CAPTAIN, -87137, -140466, -9084, 47134, true); spawn(world, HALL_KEEPER_WIZARD, -87090, -140437, -9084, 54990, true); spawn(world, HALL_KEEPER_WIZARD, -86914, -140597, -9084, 10165, true); spawn(world, HALL_KEEPER_WIZARD, -87228, -140344, -9084, 38409, true); spawn(world, HALL_KEEPER_WIZARD, -86788, -140669, -9084, 56995, true); spawn(world, HALL_KEEPER_WIZARD, -86970, -140551, -9084, 2111, true); spawn(world, HALL_KEEPER_WIZARD, -87113, -140269, -9084, 45123, true); spawn(world, HALL_KEEPER_WIZARD, -86771, -140659, -9084, 62476, true); spawn(world, HALL_KEEPER_WIZARD, -86998, -140535, -9084, 17946, true); spawn(world, HALL_KEEPER_WIZARD, -87164, -140367, -9084, 31052, true); spawn(world, HALL_KEEPER_WIZARD, -87177, -140427, -9084, 21561, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87074, -140212, -9084, 54927, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87216, -140397, -9084, 50949, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -86945, -140425, -9084, 3892, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87195, -140156, -9084, 5887, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87204, -140445, -9084, 25114, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87006, -140498, -9084, 39595, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87155, -140363, -9084, 10302, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87189, -140528, -9084, 64655, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87052, -140527, -9084, 28893, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87317, -139959, -9084, 54399, true); spawn(world, HALL_KEEPER_WIZARD, -87628, -140026, -9084, 57208, true); spawn(world, HALL_KEEPER_WIZARD, -87744, -139968, -9084, 9834, true); spawn(world, HALL_KEEPER_WIZARD, -88052, -140041, -9084, 49080, true); spawn(world, HALL_KEEPER_GUARD, -88286, -140125, -9084, 34428, true); spawn(world, HALL_KEEPER_GUARD, -87949, -139989, -9084, 44173, true); spawn(world, HALL_KEEPER_GUARD, -87503, -139971, -9084, 63468, true); spawn(world, HALL_KEEPER_GUARD, -88041, -140029, -9084, 63562, true); spawn(world, HALL_KEEPER_GUARD, -88072, -140021, -9084, 60924, true); spawn(world, HALL_KEEPER_GUARD, -88138, -140250, -9084, 54354, true); spawn(world, HALL_KEEPER_GUARD, -87913, -140068, -9084, 5959, true); spawn(world, HALL_KEEPER_GUARD, -87615, -140033, -9084, 54464, true); spawn(world, HALL_KEEPER_GUARD, -88242, -140194, -9084, 57541, true); spawn(world, HALL_KEEPER_GUARD, -88269, -139985, -9084, 65308, true); spawn(world, HALL_KEEPER_CAPTAIN, -88139, -140250, -9084, 62428, true); spawn(world, HALL_KEEPER_CAPTAIN, -87949, -140037, -9084, 21905, true); spawn(world, HALL_KEEPER_CAPTAIN, -87569, -140051, -9084, 58704, true); spawn(world, HALL_KEEPER_CAPTAIN, -88137, -140234, -9084, 58580, true); spawn(world, HALL_KEEPER_CAPTAIN, -87661, -140093, -9084, 38266, true); spawn(world, HALL_KEEPER_CAPTAIN, -87577, -140146, -9084, 27046, true); spawn(world, HALL_KEEPER_CAPTAIN, -87773, -140149, -9084, 37681, true); spawn(world, HALL_KEEPER_CAPTAIN, -88014, -140241, -9084, 7654, true); spawn(world, HALL_KEEPER_CAPTAIN, -88087, -140070, -9084, 7795, true); spawn(world, HALL_KEEPER_CAPTAIN, -87570, -140181, -9084, 36646, true); spawn(world, HALL_KEEPER_WIZARD, -87994, -139974, -9084, 57714, true); spawn(world, HALL_KEEPER_WIZARD, -88248, -139972, -9084, 62214, true); spawn(world, HALL_KEEPER_WIZARD, -87858, -140172, -9084, 46664, true); spawn(world, HALL_KEEPER_WIZARD, -88101, -140173, -9084, 61120, true); spawn(world, HALL_KEEPER_WIZARD, -88131, -140048, -9084, 60111, true); spawn(world, HALL_KEEPER_WIZARD, -88184, -140116, -9084, 58359, true); spawn(world, HALL_KEEPER_WIZARD, -87658, -139936, -9084, 11270, true); spawn(world, HALL_KEEPER_WIZARD, -87877, -140104, -9084, 5007, true); spawn(world, HALL_KEEPER_WIZARD, -87618, -140158, -9084, 57288, true); spawn(world, HALL_KEEPER_WIZARD, -88337, -140037, -9084, 50516, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87572, -140110, -9084, 14254, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88267, -140147, -9084, 12254, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -87423, -139957, -9084, 54758, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88355, -140024, -9084, 35328, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88422, -139969, -9084, 39172, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88084, -140054, -9084, 30771, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88076, -140072, -9084, 12242, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88271, -140150, -9084, 37892, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88025, -140147, -9084, 23699, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88163, -140079, -9084, 40986, true); spawn(world, HALL_KEEPER_WIZARD, -88733, -140567, -9084, 9785, true); spawn(world, HALL_KEEPER_WIZARD, -88547, -140103, -9084, 20344, true); spawn(world, HALL_KEEPER_WIZARD, -88617, -140237, -9084, 48681, true); spawn(world, HALL_KEEPER_GUARD, -88425, -140302, -9084, 33198, true); spawn(world, HALL_KEEPER_GUARD, -88985, -140693, -9084, 61882, true); spawn(world, HALL_KEEPER_GUARD, -88587, -140341, -9084, 6286, true); spawn(world, HALL_KEEPER_GUARD, -88555, -140020, -9084, 25728, true); spawn(world, HALL_KEEPER_GUARD, -88632, -140197, -9084, 49223, true); spawn(world, HALL_KEEPER_GUARD, -88693, -140230, -9084, 49954, true); spawn(world, HALL_KEEPER_GUARD, -89118, -140666, -9084, 61663, true); spawn(world, HALL_KEEPER_GUARD, -88966, -140668, -9084, 39800, true); spawn(world, HALL_KEEPER_GUARD, -88902, -140795, -9084, 10329, true); spawn(world, HALL_KEEPER_GUARD, -89137, -140658, -9084, 26689, true); spawn(world, HALL_KEEPER_CAPTAIN, -89014, -140617, -9084, 18805, true); spawn(world, HALL_KEEPER_CAPTAIN, -88674, -140157, -9084, 19431, true); spawn(world, HALL_KEEPER_CAPTAIN, -88816, -140546, -9084, 11754, true); spawn(world, HALL_KEEPER_CAPTAIN, -89023, -140482, -9084, 50721, true); spawn(world, HALL_KEEPER_CAPTAIN, -88634, -140389, -9084, 53263, true); spawn(world, HALL_KEEPER_CAPTAIN, -89019, -140784, -9084, 31464, true); spawn(world, HALL_KEEPER_CAPTAIN, -88593, -140403, -9084, 55532, true); spawn(world, HALL_KEEPER_CAPTAIN, -88511, -140243, -9084, 57893, true); spawn(world, HALL_KEEPER_CAPTAIN, -88919, -140751, -9084, 31574, true); spawn(world, HALL_KEEPER_CAPTAIN, -88901, -140622, -9084, 2091, true); spawn(world, HALL_KEEPER_WIZARD, -88496, -139996, -9084, 60873, true); spawn(world, HALL_KEEPER_WIZARD, -88854, -140695, -9084, 51659, true); spawn(world, HALL_KEEPER_WIZARD, -88998, -140537, -9084, 46494, true); spawn(world, HALL_KEEPER_WIZARD, -88746, -140309, -9084, 58583, true); spawn(world, HALL_KEEPER_WIZARD, -88617, -140235, -9084, 23701, true); spawn(world, HALL_KEEPER_WIZARD, -88848, -140390, -9084, 38252, true); spawn(world, HALL_KEEPER_WIZARD, -88776, -140566, -9084, 33157, true); spawn(world, HALL_KEEPER_WIZARD, -88859, -140367, -9084, 53480, true); spawn(world, HALL_KEEPER_WIZARD, -89087, -140682, -9084, 13235, true); spawn(world, HALL_KEEPER_WIZARD, -88506, -140087, -9084, 17858, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88770, -140340, -9084, 22287, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88770, -140441, -9084, 2029, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88421, -140322, -9084, 28902, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88942, -140701, -9084, 10314, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88546, -140214, -9084, 65055, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88503, -139978, -9084, 17454, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88629, -140177, -9084, 48872, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88934, -140417, -9084, 32545, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88874, -140323, -9084, 64196, true); spawn(world, HALL_KEEPER_SUICIDAL_SOLDIER_1, -88833, -140384, -9084, 33, true); } /** * モンスター配置:2部屋め 聖歌団プレイヤー * @param world */ private void spawnDarkPlayers(FETWorld world)/*テスト済*/ { spawn(world, DARK_CHOIR_PLAYER, -87875, -147001, -9128, 39939, false); spawn(world, DARK_CHOIR_PLAYER, -88014, -147087, -9128, 35800, false); spawn(world, DARK_CHOIR_PLAYER, -87785, -147219, -9128, 53478, false); spawn(world, DARK_CHOIR_PLAYER, -87825, -147176, -9128, 59347, false); } /** * モンスター配置:2部屋め 黒聖歌団 * @param world */ private void spawnDarkChoirs(FETWorld world)/*テスト済*/ { spawn(world, DARK_CHOIR_CAPTAIN, -88755, -147395, -9138, 0, true); spawn(world, DARK_CHOIR_CAPTAIN, -88755, -147187, -9138, 0, true); spawn(world, DARK_CHOIR_CAPTAIN, -88755, -146963, -9138, 0, true); spawn(world, DARK_CHOIR_CAPTAIN, -88755, -146723, -9138, 0, true); spawn(world, DARK_CHOIR_CAPTAIN, -87155, -147411, -9138, 33000, true); spawn(world, DARK_CHOIR_CAPTAIN, -87155, -147219, -9138, 33000, true); spawn(world, DARK_CHOIR_CAPTAIN, -87155, -146963, -9138, 33000, true); spawn(world, DARK_CHOIR_CAPTAIN, -87171, -146739, -9138, 33000, true); spawn(world, DARK_CHOIR_LANCER, -88467, -148467, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88467, -148403, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88467, -148339, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88467, -148271, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88471, -148199, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88499, -148435, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88503, -148375, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88499, -148307, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88503, -148239, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -87427, -148191, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87427, -148263, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87427, -148331, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87427, -148395, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87427, -148467, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87395, -148435, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87395, -148371, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87395, -148303, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87395, -148227, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87427, -145683, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87427, -145747, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87427, -145883, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87427, -145819, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87427, -145955, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87395, -145715, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87395, -145779, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87395, -145859, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -87395, -145923, -9170, 33000, true); spawn(world, DARK_CHOIR_LANCER, -88463, -145971, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88467, -145899, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88467, -145827, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88467, -145763, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88471, -145699, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88495, -145939, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88499, -145863, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88499, -145795, -9170, 0, true); spawn(world, DARK_CHOIR_LANCER, -88499, -145731, -9170, 0, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88708, -146105, -9152, 46242, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88931, -146103, -9152, 15665, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88846, -146548, -9152, 57906, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88745, -146356, -9152, 47356, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88867, -146608, -9152, 2847, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88734, -146033, -9152, 249, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88813, -146453, -9152, 34935, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88773, -145967, -9152, 63174, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88928, -146028, -9152, 43447, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88918, -146165, -9152, 26885, true); spawn(world, DARK_CHOIR_ARCHER, -89207, -147428, -9156, 45072, true); spawn(world, DARK_CHOIR_ARCHER, -89018, -147611, -9156, 59002, true); spawn(world, DARK_CHOIR_ARCHER, -89053, -147079, -9156, 61936, true); spawn(world, DARK_CHOIR_ARCHER, -89158, -147440, -9156, 10110, true); spawn(world, DARK_CHOIR_ARCHER, -89047, -147321, -9156, 42674, true); spawn(world, DARK_CHOIR_ARCHER, -89102, -146927, -9156, 55423, true); spawn(world, DARK_CHOIR_ARCHER, -89238, -146461, -9156, 46669, true); spawn(world, DARK_CHOIR_ARCHER, -89074, -146800, -9156, 42740, true); spawn(world, DARK_CHOIR_ARCHER, -89080, -146722, -9156, 51097, true); spawn(world, DARK_CHOIR_ARCHER, -89094, -146927, -9156, 57530, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -89292, -146968, -9156, 23921, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -89098, -146973, -9156, 53398, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -89364, -146683, -9156, 55886, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -89137, -147813, -9156, 58589, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -89031, -146677, -9156, 16478, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -89248, -147458, -9156, 28103, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -89192, -146584, -9156, 60165, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -89267, -147106, -9156, 2957, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -89100, -147886, -9156, 29995, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -89233, -147463, -9156, 4825, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88958, -147968, -9152, 27850, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88924, -147685, -9152, 26191, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88877, -147770, -9152, 12542, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88663, -148105, -9152, 62369, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88898, -147524, -9152, 49103, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88826, -147954, -9152, 5382, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88691, -148079, -9152, 10623, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88900, -148144, -9152, 60510, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88674, -148034, -9152, 48606, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -88780, -148206, -9152, 30841, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87198, -148242, -9132, 2239, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87006, -147837, -9132, 23704, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87106, -147738, -9132, 20373, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87024, -147805, -9132, 10273, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87133, -147746, -9132, 63628, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87200, -148138, -9132, 36796, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87178, -147893, -9132, 53531, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87018, -147727, -9132, 39064, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87162, -148270, -9132, 44769, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87232, -148216, -9132, 23745, true); spawn(world, DARK_CHOIR_ARCHER, -86848, -146626, -9140, 21800, true); spawn(world, DARK_CHOIR_ARCHER, -86898, -147680, -9140, 12664, true); spawn(world, DARK_CHOIR_ARCHER, -86803, -146525, -9140, 4869, true); spawn(world, DARK_CHOIR_ARCHER, -86809, -147543, -9140, 32242, true); spawn(world, DARK_CHOIR_ARCHER, -86682, -146528, -9140, 26051, true); spawn(world, DARK_CHOIR_ARCHER, -86843, -147847, -9140, 37485, true); spawn(world, DARK_CHOIR_ARCHER, -86793, -146556, -9140, 17726, true); spawn(world, DARK_CHOIR_ARCHER, -86594, -147369, -9140, 25664, true); spawn(world, DARK_CHOIR_ARCHER, -86729, -147721, -9140, 39674, true); spawn(world, DARK_CHOIR_ARCHER, -86706, -147356, -9140, 64275, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -86892, -146732, -9140, 44902, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -86972, -148050, -9140, 64642, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -86822, -147296, -9140, 39669, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -86748, -146511, -9140, 59277, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -86811, -147359, -9140, 54652, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -86930, -146945, -9140, 16040, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -86741, -147577, -9140, 53106, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -86614, -146629, -9140, 36495, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -86899, -146940, -9140, 62921, true); spawn(world, DARK_CHOIR_WITCH_DOCTOR, -86650, -146646, -9140, 56177, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87162, -146112, -9132, 59727, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87187, -146185, -9132, 21514, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87308, -146022, -9132, 22939, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87152, -146145, -9132, 20344, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87235, -146167, -9132, 12091, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -86976, -146437, -9132, 17215, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -86990, -146411, -9132, 12879, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -86957, -146378, -9132, 28758, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87042, -146025, -9132, 26909, true); spawn(world, DARK_CHOIR_PRIMA_DONNA, -87142, -146307, -9132, 17233, true); } private boolean controlStatus(FETWorld world) { if (world.lock.tryLock()) { try { if (DEBUG) _log.info("[Final Emperial Tomb] Starting " + world.status + ". status."); switch (world.status) { case 0: spawnHallAlarm(world); break; case 1: if (ASSERT) if (!(world.npcList.size() == 0)) throw new RuntimeException("npcList.size()=" + world.npcList.size()); spawnDarkPlayers(world); break; case 2: ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(world, 0), 600000); break; case 3: ThreadPoolManager.getInstance().executeTask(new IntroTask(world, 200)); break; case 4: ThreadPoolManager.getInstance().executeTask(new IntroTask(world, 300)); break; case 5: ThreadPoolManager.getInstance().executeTask(new IntroTask(world, 400)); break; case 6: InstanceManager.getInstance().getInstance(world.instanceId).setDuration(300000); openDoors(FIRST_ROOM_DOORS, world.instanceId); openDoors(FIRST_ROUTE_DOORS, world.instanceId); openDoors(SECOND_ROUTE_DOORS, world.instanceId); openDoors(SECOND_ROOM_DOORS, world.instanceId); break; default: if (ASSERT) throw new RuntimeException("status=" + world.status); } ++world.status; if (DEBUG) broadcastPacket(world, new ExShowScreenMessage("status="+world.status, 1, 5000)); return true; } finally { world.lock.unlock(); } } else TRACE("__BASENAME__:__LINE__", "[LOCK] .status=" + world.status);/*@IF DEBUG@*/ return false; } private void spawn(FETWorld world, int npcId, int x, int y, int z, int h, boolean addToKillTable) { L2Npc npc = addSpawn(npcId, x, y, z, h, false, 0, false, world.instanceId); if (addToKillTable) { world.npcList.add(npc); world.npcMax = world.npcList.size(); final boolean add; synchronized (_mustKillMobsId) { add = _mustKillMobsId.add(npcId); } if (add) { addKillId(npcId); if (npc.getTemplate().getSuicideSkills().size() > 0) addSpellFinishedId(npcId); } npc.setIsNoRndWalk(true); } if (npc.isInstanceType(InstanceType.L2Attackable)) ((L2Attackable) npc).setSeeThroughSilentMove(true); if (Util.contains(AI_DISABLED_MOBS, npcId)) npc.disableCoreAI(true); if (npcId == DARK_CHOIR_PLAYER) ++world.darkChoirPlayerCount; } private boolean isZZZ(L2Character character) { return character.isStunned() || character.isSleeping() || character.isParalyzed(); } private boolean isZZZ(L2Skill skill) { for (EffectTemplate i : skill.getEffectTemplates()) { L2SkillType t = i.effectType; if (t == L2SkillType.STUN || t == L2SkillType.SLEEP || t == L2SkillType.PARALYZE) return true; } return false; } private class SongTask implements Runnable/*テスト済*/ { private final FETWorld _world; SongTask(FETWorld world) { _world = world; } @Override public void run() { if (InstanceManager.getInstance().getWorld(_world.instanceId) != _world) return; if (_world.frintezza == null || _world.frintezza.isDead() || !_world.frintezza.isVisible()) return; if (isZZZ(_world.frintezza)) { _world.songTask = ThreadPoolManager.getInstance().scheduleGeneral(SongTask.this, 1000); //TRACE("SongTask", "isStunned=>" + _world.frintezza.isStunned() + " isSleeping=>" + _world.frintezza.isSleeping() + " isParalyzed=>" + _world.frintezza.isParalyzed());/*@IF DEBUG@*/ return; } if (_world.isVideo) { _world.songTask = ThreadPoolManager.getInstance().scheduleGeneral(SongTask.this, 1000); return; } // new song play int rnd = Rnd.get(100); for (FrintezzaSong song : FRINTEZZA_SONG_LIST) { if (rnd < song.chance) { L2Skill skill = SkillTable.getInstance().getInfo(song.songId, song.songLevel); broadcastSongTitle(_world, song.songName); broadcastPacket(_world, new MagicSkillUse(_world.frintezza, _world.frintezza, skill.getId(), skill.getLevel(), skill.getHitTime(), 0)); doSongEffect(song.effectId, song.effectLevel); _world.songTask = ThreadPoolManager.getInstance().scheduleGeneral(SongTask.this, skill.getHitTime() + Rnd.get(5000)); break; } } } public void doSongEffect(int effectId, int effectLevel) { // Frintezza song effect if (_world.activeScarlet == null || _world.activeScarlet.isDead() || !_world.activeScarlet.isVisible()) return; if (_world.isVideo) return; _world.activeScarlet.doCast(SkillTable.getInstance().getInfo(effectId, effectLevel)); //TRACE(STR(SkillTable.getInstance().getInfo(effectId, effectLevel)));/*@IF DEBUG@*/ }/*#IF DEBUG#*/ @Override protected void finalize() throws Throwable { super.finalize(); TRACE(getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()), "finalize()"); }/*#END IF#*/ } private class IntroTask implements Runnable { private final FETWorld _world; private final int _taskId; IntroTask(FETWorld world, int taskId) { _world = world; _taskId = taskId; }//TODO: void scheduleNextTask(int taskId, long delay)// {// _taskId = taskId;// ThreadPoolManager.getInstance().scheduleGeneral(this, delay);// } @Override public void run() { if (DEBUG) broadcastPacket(_world, new ExShowScreenMessage(String.valueOf(_taskId), 7, 5000)); switch (_taskId) {/*#IF DEBUG#*/ /** * Spawns Frintezza, the weak version of Scarlet Van Halisha, the minions, and all that is shown in a movie to the observing players. *///TODO: private class ScarletWeakSpawn implements Runnable {}/*#END IF#*/ /********************/ /* SPAWN DAEMON 1ST */ /********************/ case 0: ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 1), 28000); broadcastPacket(_world, new Earthquake(-87784, -155083, -9087, 45, 27)); _world.activeScarlet = (L2GrandBossInstance) addSpawn(SCARLET1, -88595, -153695, -7446, 16384, false, 0, false, _world.instanceId); _world.activeScarlet.setOnKillDelay(100); _world.activeScarlet.setIsInvul(true); _world.activeScarlet.setIsImmobilized(true); _world.activeScarlet.disableAllSkills(); _world.activeScarlet.disableCoreAI(true); updateKnownList(_world, _world.activeScarlet); break; case 1: closeDoors(FIRST_ROOM_DOORS, _world.instanceId); closeDoors(FIRST_ROUTE_DOORS, _world.instanceId); closeDoors(SECOND_ROOM_DOORS, _world.instanceId); closeDoors(SECOND_ROUTE_DOORS, _world.instanceId); for (L2Npc n : _world.npcList) // remove Dark Choirs n.deleteMe(); _world.npcList.clear(); addSpawn(CUBE, -87904, -141296, -9168, 0, false, 0, false, _world.instanceId); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 2), 1000); break; case 2: _world.frintezzaDummy = addSpawn(29052, -87784, -155083, -9087, 16048, false, 0, false, _world.instanceId); _world.frintezzaDummy.setIsInvul(true); _world.frintezzaDummy.setIsImmobilized(true); _world.overheadDummy = addSpawn(29052, -87784, -153298, -9175, 16384, false, 0, false, _world.instanceId); _world.overheadDummy.setIsInvul(true); _world.overheadDummy.setIsImmobilized(true); _world.overheadDummy.setCollisionHeight(600); broadcastPacket(_world, new NpcInfo(_world.overheadDummy, null)); _world.portraitDummy1 = addSpawn(29052, -89566, -153168, -9165, 16048, false, 0, false, _world.instanceId); _world.portraitDummy1.setIsImmobilized(true); _world.portraitDummy1.setIsInvul(true); _world.portraitDummy3 = addSpawn(29052, -86004, -153168, -9165, 16048, false, 0, false, _world.instanceId); _world.portraitDummy3.setIsImmobilized(true); _world.portraitDummy3.setIsInvul(true); _world.scarletDummy = addSpawn(29053, -87784, -153298, -9175, 16384, false, 0, false, _world.instanceId); _world.scarletDummy.setIsInvul(true); _world.scarletDummy.setIsImmobilized(true); _world.isVideo = true; stopNpc(); stopPc(); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 3), 1000); break; case 3: broadcastPacket(_world, new SpecialCamera(_world.overheadDummy.getObjectId(), 0, 75, -89, 0, 100, 0, 0, 1, 0)); broadcastPacket(_world, new SpecialCamera(_world.overheadDummy.getObjectId(), 0, 75, -89, 0, 100, 0, 0, 1, 0)); broadcastPacket(_world, new SpecialCamera(_world.overheadDummy.getObjectId(), 300, 90, -10, 6500, 7000, 0, 0, 1, 0)); _world.frintezza = (L2GrandBossInstance) addSpawn(FRINTEZZA, -87784, -155083, -9087, 16048, false, 0, false, _world.instanceId); _world.frintezza.setIsImmobilized(true); _world.frintezza.disableAllSkills(); _world.frintezza.disableCoreAI(true); _world.frintezza.setIsInvul(true); updateKnownList(_world, _world.frintezza); for (int i = 0; i < 4; ++i) { int[] gs = GHOST_SPAWNS[i]; //{npcId,x,y,z,h} L2MonsterInstance ghost = _world.ghosts[i] = (L2MonsterInstance) addSpawn(gs[0], gs[1], gs[2], gs[3], gs[4], false, 0, false, _world.instanceId); ghost.setIsImmobilized(true); ghost.setIsNoRndWalk(true); ghost.disableAllSkills(); updateKnownList(_world, ghost); L2Spawn spawn = ghost.getSpawn(); spawn.setAmount(1); spawn.setRespawnDelay(GHOST_RESPAWN_DELAY);//TODO: spawn.setRespawnDelay(0); spawn.startRespawn(); } ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 4), 6500); break; case 4: broadcastPacket(_world, new SpecialCamera(_world.frintezzaDummy.getObjectId(), 1800, 90, 8, 6500, 7000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 5), 900); break; case 5: broadcastPacket(_world, new SpecialCamera(_world.frintezzaDummy.getObjectId(), 140, 90, 10, 2500, 4500, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 6), 4000); break; case 6: broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 40, 75, -10, 0, 1000, 0, 0, 1, 0)); broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 40, 75, -10, 0, 12000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 7), 1350); break; case 7: broadcastPacket(_world, new SocialAction(_world.frintezza.getObjectId(), 2)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 8), 7000); break; case 8: _world.frintezzaDummy.deleteMe(); _world.frintezzaDummy = null; ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 9), 1000); break; case 9: broadcastPacket(_world, new SocialAction(_world.ghosts[1].getObjectId(), 1)); broadcastPacket(_world, new SocialAction(_world.ghosts[2].getObjectId(), 1)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 10), 400); break; case 10: broadcastPacket(_world, new SocialAction(_world.ghosts[0].getObjectId(), 1)); broadcastPacket(_world, new SocialAction(_world.ghosts[3].getObjectId(), 1)); sendPacketX(new SpecialCamera(_world.portraitDummy1.getObjectId(), 1000, 118, 0, 0, 1000, 0, 0, 1, 0), new SpecialCamera(_world.portraitDummy3.getObjectId(), 1000, 62, 0, 0, 1000, 0, 0, 1, 0), -87784); sendPacketX(new SpecialCamera(_world.portraitDummy1.getObjectId(), 1000, 118, 0, 0, 10000, 0, 0, 1, 0), new SpecialCamera(_world.portraitDummy3.getObjectId(), 1000, 62, 0, 0, 10000, 0, 0, 1, 0), -87784); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 11), 2000); break; case 11: broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 240, 90, 0, 0, 1000, 0, 0, 1, 0)); broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 240, 90, 25, 5500, 10000, 0, 0, 1, 0)); broadcastPacket(_world, new SocialAction(_world.frintezza.getObjectId(), 3)); _world.portraitDummy1.deleteMe(); _world.portraitDummy3.deleteMe(); _world.portraitDummy1 = null; _world.portraitDummy3 = null; ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 12), 4500); break; case 12: broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 100, 195, 35, 0, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 13), 700); break; case 13: broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 100, 195, 35, 0, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 14), 1300); break; case 14: broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 120, 180, 45, 1500, 10000, 0, 0, 1, 0)); broadcastSongTitle(_world, NpcStringId.RONDO_OF_SOLITUDE/*=>孤独のロンド(動画で確認済。でも怪しい)*/); // RONDO_OF_SOLITUDE ? MOURNFUL_CHORALE_PRELUDE ? broadcastPacket(_world, new MagicSkillUse(_world.frintezza, _world.frintezza, 5006, 1, 34000, 0));/*=>孤独のロンド*/ ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 15), 1500); break; case 15: broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 520, 135, 45, 8000, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 16), 7500); break; case 16: broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 1500, 110, 25, 10000, 13000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 17), 9500); break; case 17: broadcastPacket(_world, new SpecialCamera(_world.overheadDummy.getObjectId(), 930, 160, -20, 0, 1000, 0, 0, 1, 0)); broadcastPacket(_world, new SpecialCamera(_world.overheadDummy.getObjectId(), 600, 180, -25, 0, 10000, 0, 0, 1, 0)); broadcastPacket(_world, new MagicSkillUse(_world.scarletDummy, _world.overheadDummy, 5004, 1, 5800, 0));/*=>次元のショック*/ ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 18), 2500); break; case 18: _world.activeScarlet.teleToLocation(-87784, -153298, -9175); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 19), 2000); break; case 19: broadcastPacket(_world, new SocialAction(_world.activeScarlet.getObjectId(), 3)); broadcastPacket(_world, new SpecialCamera(_world.scarletDummy.getObjectId(), 800, 180, 10, 1000, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 20), 1500); break; case 20: updateKnownList(_world, _world.scarletDummy); throwUp(_world.scarletDummy, 500, SystemMessage.getSystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT).addSkillName(5004, 1)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 21), 2600); break; case 21: broadcastPacket(_world, new SpecialCamera(_world.scarletDummy.getObjectId(), 300, 60, 8, 0, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 22), 2000); break; case 22: broadcastPacket(_world, new SpecialCamera(_world.activeScarlet.getObjectId(), 500, 90, 10, 3000, 5000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 23), 3000); break; case 23: _world.overheadDummy.deleteMe(); _world.scarletDummy.deleteMe(); _world.overheadDummy = null; _world.scarletDummy = null; for (int i = 0; i < 4; ++i) { int[] ps = PORTRAIT_SPAWNS[i]; //{npcId,x,y,z,h} L2MonsterInstance portrait = _world.portraits[i] = (L2MonsterInstance) addSpawn(ps[0], ps[1], ps[2], ps[3], ps[4], false, 0, false, _world.instanceId); updateKnownList(_world, portrait); } startPc(); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 24), 10000); break; case 24: _world.activeScarlet.setIsInvul(false); _world.activeScarlet.setIsImmobilized(false); _world.activeScarlet.enableAllSkills(); _world.activeScarlet.disableCoreAI(false); _world.activeScarlet.setRunning(); _world.frintezza.setIsInvul(false); _world.frintezza.setIsMortal(false); _world.songTask = ThreadPoolManager.getInstance().scheduleGeneral(new SongTask(_world), 5000); //+ startNpc(); _world.isVideo = false; break;/*#IF DEBUG#*/ /** * Does the 2nd Morph for Scarlet Van Halisha. Now he's bigger and he teleports to his targets *///TODO: private void doSecondMorph() {}/*#END IF#*/ /********************/ /* MORPH DAEMON 2ND */ /********************/ case 200: _world.activeScarlet.setIsInvul(true); if (_world.activeScarlet.isCastingNow()) _world.activeScarlet.abortCast(); setInstanceTimeRestrictions(_world); _world.activeScarlet.doCast(SkillTable.getInstance().getInfo(5017, 1)/*=>Frintezza's Daemon Morph|デーモン1 変身。*/); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 201), 1500); break; case 201: _world.activeScarlet.setRHandId(SECOND_SCARLET_WEAPON); _world.activeScarlet.setIsInvul(false); break;/*#IF DEBUG#*/ /** * Does the 3rd and last polymorph for Scarlet Van Halisha. Now he looks entirely different... (he is different) *///TODO: private void doThirdMorph() {}/*#END IF#*/ /********************/ /* MORPH DAEMON 3RD */ /********************/ case 300: _world.isVideo = true; stopNpc(); stopPc(); _world.activeScarlet.abortAttack(); _world.activeScarlet.abortCast(); _world.activeScarlet.setIsInvul(true); _world.activeScarlet.setIsImmobilized(true); _world.activeScarlet.disableAllSkills(); broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 250, 120, 15, 0, 1000, 0, 0, 1, 0)); broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 250, 120, 15, 0, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 301), 1000); break; case 301: _world.frintezza.stopAllEffects(); broadcastPacket(_world, new MagicSkillCanceld(_world.frintezza.getObjectId())); broadcastPacket(_world, new SocialAction(_world.frintezza.getObjectId(), 4)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 302), 4000); break; case 302: broadcastPacket(_world, new MagicSkillUse(_world.frintezza, _world.frintezza, 5006, 1, 34000, 0)); broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 500, 70, 15, 3000, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 303), 3000); break; case 303: broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 2500, 90, 12, 6000, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 304), 3000); break; case 304: _world.scarlet_x = _world.activeScarlet.getX(); _world.scarlet_y = _world.activeScarlet.getY(); _world.scarlet_z = _world.activeScarlet.getZ(); _world.scarlet_h = _world.activeScarlet.getHeading(); if (_world.scarlet_h < 32768) _world.scarlet_a = Math.abs(180 - (int) (_world.scarlet_h / 182.044444444)); else _world.scarlet_a = Math.abs(540 - (int) (_world.scarlet_h / 182.044444444)); broadcastPacket(_world, new SpecialCamera(_world.activeScarlet.getObjectId(), 250, _world.scarlet_a, 12, 0, 1000, 0, 0, 1, 0)); broadcastPacket(_world, new SpecialCamera(_world.activeScarlet.getObjectId(), 250, _world.scarlet_a, 12, 0, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 305), 500); break; case 305: _world.activeScarlet.doDie(_world.activeScarlet); broadcastPacket(_world, new SpecialCamera(_world.activeScarlet.getObjectId(), 450, _world.scarlet_a, 14, 8000, 8000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 306), 6250); break; case 306: _world.activeScarlet.deleteMe(); _world.activeScarlet = null; ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 307), 950); break; case 307: _world.activeScarlet = (L2GrandBossInstance) addSpawn(SCARLET2, _world.scarlet_x, _world.scarlet_y, _world.scarlet_z, _world.scarlet_h, false, 0, false, _world.instanceId); _world.activeScarlet.setOnKillDelay(100); _world.activeScarlet.setIsInvul(true); _world.activeScarlet.setIsImmobilized(true); _world.activeScarlet.disableAllSkills(); updateKnownList(_world, _world.activeScarlet); broadcastPacket(_world, new SpecialCamera(_world.activeScarlet.getObjectId(), 450, _world.scarlet_a, 12, 500, 14000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 308), 8100); break; case 308: broadcastPacket(_world, new SocialAction(_world.activeScarlet.getObjectId(), 2)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 309), 9000); break; case 309: startPc(); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 310), 10000); break; case 310: _world.activeScarlet.setIsInvul(false); _world.activeScarlet.setIsImmobilized(false); _world.activeScarlet.enableAllSkills(); startNpc(); _world.isVideo = false; break;/*#IF DEBUG#*/ /** * Dead Scarlet Van Halisha (NPC ID:29046 weak & ID:29047 strong). [JOJO] *///TODO: public void onKillScarlet(L2PcInstance player)/*#END IF#*/ /********************/ /* DIE DAEMON */ /********************/ case 400: _world.isVideo = true; stopNpc(); stopPc(); if (_world.songTask != null) { _world.songTask.cancel(true); _world.songTask = null; } broadcastPacket(_world, new MagicSkillCanceld(_world.frintezza.getObjectId())); broadcastPacket(_world, new SpecialCamera(_world.activeScarlet.getObjectId(), 300, _world.scarlet_a - 180, 5, 0, 7000, 0, 0, 1, 0)); broadcastPacket(_world, new SpecialCamera(_world.activeScarlet.getObjectId(), 200, _world.scarlet_a, 85, 4000, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 401), 7400); break; case 401: _world.frintezza.doDie(_world.frintezza); for (int i = 0; i < 4; ++i) { L2MonsterInstance portrait = _world.portraits[i]; if (portrait != null) { portrait.deleteMe(); _world.portraits[i] = null; } L2MonsterInstance ghost = _world.ghosts[i]; if (ghost != null) { //TRACE("__BASENAME__:__LINE__: ghost #" + i + " isVisible=>" + ghost.isVisible() + " isDead=>" + ghost.isDead());/*@IF DEBUG@*/ ghost.getSpawn().stopRespawn(); } } ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 402), 100); break; case 402: broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 100, 120, 5, 0, 7000, 0, 0, 1, 0)); broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 100, 90, 5, 5000, 15000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 403), 7000); break; case 403: broadcastPacket(_world, new SpecialCamera(_world.frintezza.getObjectId(), 900, 90, 25, 7000, 10000, 0, 0, 1, 0)); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 404), 9000); break; case 404: if (ASSERT) if (!(_world.status == 6)) throw new RuntimeException("status=" + _world.status); controlStatus(_world); startPc(); ThreadPoolManager.getInstance().scheduleGeneral(new IntroTask(_world, 405), 10000); break; case 405: startNpc(); _world.isVideo = false; break; default: if (ASSERT) throw new RuntimeException("_taskId=" + _taskId); } } private void stopNpc(L2MonsterInstance npc) { npc.abortAttack(); npc.abortCast(); npc.disableAllSkills(); npc.setTarget(null); npc.stopMove(null); npc.setIsImmobilized(true); if (npc.hasAI()) npc.getAI().setIntention(AI_INTENTION_IDLE); } private void startNpc(L2MonsterInstance npc)/*テスト済*/ { npc.setIsImmobilized(false); npc.enableAllSkills(); } private void stopNpc()/*テスト済*/ { for (L2MonsterInstance npc : _world.portraits) if (npc != null) stopNpc(npc); for (L2MonsterInstance npc : _world.ghosts) if (npc != null) stopNpc(npc); } private void startNpc()/*テスト済*/ { for (L2MonsterInstance npc : _world.portraits) if (npc != null) startNpc(npc); for (L2MonsterInstance npc : _world.ghosts) if (npc != null) startNpc(npc); } private void stopPc()/*テスト済*/ { for (int objId : _world.allowed) { L2PcInstance player = L2World.getInstance().getPlayer(objId); if (player != null && player.isOnline() && player.getInstanceId() == _world.instanceId) { player.abortAttack(); player.abortCast(); player.disableAllSkills(); player.setTarget(null); player.stopMove(null); player.setIsImmobilized(true); player.getAI().setIntention(AI_INTENTION_IDLE); } } } private void startPc()/*テスト済*/ { for (int objId : _world.allowed) { L2PcInstance player = L2World.getInstance().getPlayer(objId); if (player != null && player.isOnline() && player.getInstanceId() == _world.instanceId) { player.enableAllSkills(); player.setIsImmobilized(false); } } } private void sendPacketX(L2GameServerPacket packet1, L2GameServerPacket packet2, int x)/*テスト済*/ { for (int objId : _world.allowed) { L2PcInstance player = L2World.getInstance().getPlayer(objId); if (player != null && player.isOnline() && player.getInstanceId() == _world.instanceId) { if (player.getX() < x) player.sendPacket(packet1); else player.sendPacket(packet2); } } }/*#IF DEBUG#*/ @Override protected void finalize() throws Throwable { super.finalize(); TRACE(getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()), "finalize() _taskId=>" + _taskId); }/*#END IF#*/ } private class OnKillHallAlarmTask implements Runnable/*テスト済*/ { private final FETWorld _world; private int _taskId; OnKillHallAlarmTask(FETWorld world) { _world = world; _taskId = 0; } void scheduleNextTask(int taskId, long delay) { _taskId = taskId; ThreadPoolManager.getInstance().scheduleGeneral(this, delay); } @Override public void run() { if (InstanceManager.getInstance().getWorld(_world.instanceId) != _world) return; switch (_taskId) { case 0: spawnHallKeepers(_world); scheduleNextTask(1, 1000); break; case 1: openDoors(FIRST_ROOM_DOORS, _world.instanceId); scheduleNextTask(2, 1000); break; case 2: addAggroToMobs(_world, ROOM1_CENTER_X, ROOM1_CENTER_Y, ROOM1_CENTER_Z); break; } } /*#IF DEBUG#*/ @Override protected void finalize() throws Throwable { super.finalize(); TRACE(getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()), "finalize()"); }/*#END IF#*/ } private class OnKillDarkChoirPlayerTask implements Runnable/*テスト済*/ { private final FETWorld _world; private int _taskId; OnKillDarkChoirPlayerTask(FETWorld world) { _world = world; _taskId = 0; } void scheduleNextTask(int taskId, long delay) { _taskId = taskId; ThreadPoolManager.getInstance().scheduleGeneral(this, delay); } @Override public void run() { if (InstanceManager.getInstance().getWorld(_world.instanceId) != _world) return; switch (_taskId) { case 0: closeDoors(SECOND_ROUTE_DOORS, _world.instanceId); spawnDarkChoirs(_world); scheduleNextTask(1, 1000); break; case 1: openDoors(SECOND_ROOM_DOORS, _world.instanceId); scheduleNextTask(2, 1000); break; case 2: for (L2Npc actor : _world.npcList) if (actor.getNpcId() == DARK_CHOIR_CAPTAIN) { // 1010645 黒聖歌団の演奏を妨げる邪魔者を消せ! // 1010646 死の演奏が聞こえないのか!黒聖歌団の恐ろしさを見せてやれ! // 1010644 黒聖歌団のステージをぶち壊すとは...許せぬ! int npcstring = Rnd.get(1010644, 1010646); actor.broadcastPacket(new NpcSay(actor.getObjectId(), Say2.SHOUT, actor.getNpcId(), npcstring)); break; } addAggroToMobs(_world, ROOM2_CENTER_X, ROOM2_CENTER_Y, ROOM2_CENTER_Z); break; } } /*#IF DEBUG#*/ @Override protected void finalize() throws Throwable { super.finalize(); TRACE(getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()), "finalize()"); }/*#END IF#*/ } private void addAggroToMobs(FETWorld _world, int x, int y, int z)/*テスト済*/ { L2PcInstance target = L2World.getInstance().getPlayer(_world.allowed.get(Rnd.get(_world.allowed.size()))); if (target == null || target.getInstanceId() != _world.instanceId || target.isDead() || target.isFakeDeath()) for (int objId : _world.allowed) { target = L2World.getInstance().getPlayer(objId); if (target != null && target.getInstanceId() == _world.instanceId && !target.isDead() && !target.isFakeDeath()) break; target = null; } for (L2Npc mob : _world.npcList) { if (Util.contains(NO_AGGRO_MOBS, mob.getNpcId()))/*テスト済*/ continue; if (mob.getAI().getIntention() != AI_INTENTION_ACTIVE && mob.getAI().getIntention() != AI_INTENTION_IDLE && mob.isInCombat()) continue; mob.setRunning(); if (target != null) { ((L2MonsterInstance) mob).addDamageHate(target, 0, 500); mob.getAI().setIntention(AI_INTENTION_ATTACK, target); } else mob.getAI().setIntention(AI_INTENTION_MOVE_TO, new L2CharPosition(x, y, z, 0));/*TODO:一点に集中しておだんごになってしまう*/ } } private void setInstanceTimeRestrictions(FETWorld world)/*テスト済*/ { long now = System.currentTimeMillis(); GregorianCalendar reenter = new GregorianCalendar(); reenter.setTimeInMillis(now); reenter.set(Calendar.MILLISECOND, 0); reenter.set(Calendar.SECOND, 0); reenter.set(Calendar.MINUTE, RESET_MINUTE); reenter.set(Calendar.HOUR_OF_DAY, RESET_HOUR_OF_DAY); // if time is >= RESET_HOUR - roll to the next day if (reenter.getTimeInMillis() <= now) reenter.add(Calendar.DAY_OF_MONTH, 1); while (!Util.contains(RESET_DAY_OF_WEEK, reenter.get(Calendar.DAY_OF_WEEK))) reenter.add(Calendar.DAY_OF_MONTH, 1); SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.INSTANT_ZONE_S1_RESTRICTED); sm.addInstanceName(INSTANCEID); // set instance reenter time for all allowed players for (int objectId : world.allowed) { L2PcInstance player = L2World.getInstance().getPlayer(objectId); InstanceManager.getInstance().setInstanceTime(objectId, INSTANCEID, reenter.getTimeInMillis()); if (player != null && player.isOnline()) player.sendPacket(sm); } } private void broadcastPacket(FETWorld world, L2GameServerPacket packet) { for (int objId : world.allowed) { L2PcInstance player = L2World.getInstance().getPlayer(objId); if (player != null && player.isOnline() && player.getInstanceId() == world.instanceId) player.sendPacket(packet); } } private void broadcastSongTitle(FETWorld world, NpcStringId song)/*テスト済*/ { broadcastPacket(world, new ExShowScreenMessage(/*type=*/2, /*messageId=*/-1, /*position=*/2, /*unk1=*/0, /*size=*/0, /*unk2=*/0, /*unk3=*/0, /*showEffect=*/true, /*time=*/3000, /*fade=*/false, /*text=*/null, song)); } private void updateKnownList(FETWorld world, L2Npc npc) { Map<Integer, L2PcInstance> npcKnownPlayers = npc.getKnownList().getKnownPlayers(); for (int objId : world.allowed) { L2PcInstance player = L2World.getInstance().getPlayer(objId); if (player != null && player.isOnline() && player.getInstanceId() == world.instanceId) npcKnownPlayers.put(player.getObjectId(), player); } } private void throwUp(L2Character attacker, final double range, SystemMessage msg)/*テスト済*/ { final int mx = attacker.getX(), my = attacker.getY(); for (L2Object obj : attacker.getKnownList().getKnownObjects().values()) { if (!(obj instanceof L2Character)) continue; L2Character target = (L2Character)obj; if (obj == attacker || isFrintezzaFriend(target)) continue; double dx = target.getX() - mx; double dy = target.getY() - my; if (dx == 0 && dy == 0) dx = dy = range / 2; double aa = range / Math.sqrt(dx * dx + dy * dy); if (aa > 1.0) { int x = mx + (int)(dx * aa); int y = my + (int)(dy * aa); int z = target.getZ(); target.getAI().setIntention(AI_INTENTION_IDLE); target.abortAttack(); target.abortCast(); target.broadcastPacket(new FlyToLocation(target, x, y, z, FlyType.THROW_UP)); target.setXYZ(x, y, z); target.setHeading(Util.calculateHeadingFrom(x, y, mx, my)); target.broadcastPacket(new ValidateLocation(target)); if (msg != null) target.sendPacket(msg); if (target instanceof L2PcInstance) ((L2PcInstance)target).standUp(); } } } private boolean isFrintezzaFriend(L2Object target)/*テスト済*/ { if (target instanceof L2Npc) { int npcId = ((L2Npc)target).getNpcId(); return npcId >= 29045 && npcId <= 29053; } return false; } @Override public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isPet, L2Skill skill) { //TRACE("__BASENAME__:__LINE__: onAttack("+STR(npc)+","+STR(attacker)+","+damage+","+isPet+","+STR(skill)+") HP=>" + npc.getStatus().getCurrentHp());/*@IF DEBUG@*/ InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId()); if (tmpworld instanceof FETWorld) { FETWorld world = (FETWorld) tmpworld; if (DETECT_ACTION_LOCK) world.lastAction = System.currentTimeMillis(); switch (npc.getNpcId()) { case FRINTEZZA: //TRACE("__BASENAME__:__LINE__: onAttack("+STR(npc)+","+STR(attacker)+","+damage+","+isPet+","+STR(skill)+") HP=>" + npc.getStatus().getCurrentHp());/*@IF DEBUG@*/ if (!npc.isDead() && npc.isVisible()) npc.getStatus().setCurrentHp(npc.getMaxHp(), false); //TODO: npc.sql側で調整できないか break; case SCARLET1: if (world.status == 3 && npc.getCurrentHp() < npc.getMaxHp() * 0.80)/*テスト済*/ { controlStatus(world); } else if (world.status == 4 && npc.getCurrentHp() < npc.getMaxHp() * 0.20)/*テスト済*/ { controlStatus(world); } break; } } return null; } @Override public String onSkillSee(L2Npc npc, L2PcInstance player, L2Skill skill, L2Object[] targets, boolean isPet) { //TRACE("__BASENAME__:__LINE__: onSkillSee("+STR(npc)+","+STR(player)+","+STR(skill)+","+STR(targets)+","+isPet+")" );/*@IF DEBUG@*/ InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId()); if (tmpworld instanceof FETWorld) { FETWorld world = (FETWorld) tmpworld; if (DETECT_ACTION_LOCK) world.lastAction = System.currentTimeMillis(); if (npc == world.frintezza && !npc.isDead() && npc.isVisible()) npc.getStatus().setCurrentHp(npc.getMaxHp(), false); //TODO: npc.sql側で調整できないか if (targets.length > 0 && targets[0] == npc && npc == world.frintezza) { // skill 2234 Soul Breaking Arrow ... if (isZZZ(npc) && isZZZ(skill)) broadcastPacket(world, new MagicSkillCanceld(npc.getObjectId())); } } return super.onSkillSee(npc, player, skill, targets, isPet); } @Override public String onSpellFinished(L2Npc npc, L2PcInstance player, L2Skill skill)/*テスト済*/ { // TRACE("__BASENAME__:__LINE__: onSpellFinished("+STR(npc)+","+STR(player)+","+STR(skill)+")" );/*@IF DEBUG@*/ if (skill.isSuicideAttack()) return onKill(npc, null, false); return super.onSpellFinished(npc, player, skill); } @Override public String onKill(L2Npc npc, L2PcInstance player, boolean isPet) { //TRACE("onKill("+STR(npc)+","+STR(player)+","+isPet+")", "");/*@IF DEBUG@*/ InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId()); if (tmpworld instanceof FETWorld) { FETWorld world = (FETWorld) tmpworld; if (DETECT_ACTION_LOCK) world.lastAction = System.currentTimeMillis(); switch (npc.getNpcId()) { case HALL_ALARM:/*テスト済*/ if (ASSERT) if (!(world.status == 1)) throw new RuntimeException("status=" + world.status); new OnKillHallAlarmTask(world).run(); // if (Rnd.get(100) < 33) // player.addItem("Quest", DEWDROP_OF_DESTRUCTION, 1, npc, true); // Dewdrop of Destruction if (DEBUG) _log.info("[Final Emperial Tomb] Hall alarm is disabled, doors will open!"); //player.addItem("Quest", SOUL_BREAKING_ARROW, 10, npc, true);/*@IF DEBUG@*/ break; case DARK_CHOIR_PLAYER:/*テスト済*/ //TRACE("onKill("+STR(npc)+","+STR(player)+","+isPet+")", "" + Thread.currentThread().getId());/*@IF DEBUG@*/ if (ASSERT) if (!(world.status >= 2)) throw new RuntimeException("status=" + world.status); // note: world.status は変化しない.ドアの開閉のみ制御する. /*if (world.status == 2)*/ { final int count; synchronized (world) { count = --world.darkChoirPlayerCount; } if (count == 0) { new OnKillDarkChoirPlayerTask(world).run(); if (DEBUG) _log.info("[Final Emperial Tomb] All Dark Choir Players are killed, doors will open!"); } } break; default: if (world.status == 1) { // 1st room - Hall Keepers /*テスト済*/ final boolean done; synchronized (world) { done = world.npcList.remove(npc) && world.npcList.size() == 0; } if (done) { controlStatus(world); openDoors(FIRST_ROUTE_DOORS, world.instanceId); openDoors(SECOND_ROUTE_DOORS, world.instanceId); } if (player != null && Rnd.get(world.npcMax) < 3) player.addItem("Quest", DEWDROP_OF_DESTRUCTION, 1, npc, true); // Dewdrop of Destruction } else /*if (world.status == 2)*/ { // 2nd room - Dark Choirs/*テスト済*/ final boolean done; synchronized (world) { done = world.npcList.remove(npc) && world.npcList.size() == 0; } if (done) { openDoors(SECOND_ROUTE_DOORS, world.instanceId); } if (player != null && Rnd.get(world.npcMax) < 5) player.addItem("Quest", SOUL_BREAKING_ARROW, 1, npc, true); // Soul Breaking Arrow if (npc.getNpcId() == DARK_CHOIR_CAPTAIN) { // 1010645 黒聖歌団の演奏を妨げる邪魔者を消せ! // 1010646 死の演奏が聞こえないのか!黒聖歌団の恐ろしさを見せてやれ! // 1010644 黒聖歌団のステージをぶち壊すとは...許せぬ! int npcstring = Rnd.get(1010644, 1010646); npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.SHOUT, npc.getNpcId(), npcstring)); } } break; case SCARLET1:/*テスト済*/ if (ASSERT) if (!(world.status == 3 || world.status == 4)) throw new RuntimeException("status=" + world.status); world.status = 5; controlStatus(world); break; case SCARLET2:/*テスト済*/ if (ASSERT) if (!(world.status == 5)) throw new RuntimeException("status=" + world.status); controlStatus(world); break; case PORTRAIT_FIGHTER:/*テスト済*/ case PORTRAIT_MAGE:/*テスト済*/ for (int i = 0; i < 4; ++i) { if (npc == world.portraits[i]) { L2MonsterInstance ghost = world.ghosts[i]; ghost.getSpawn().stopRespawn(); world.portraits[i] = world.ghosts[i] = null; return null; } } if (ASSERT) throw new RuntimeException(); else break; } } return ""; } // @Override// public String onDeath(L2Character killer, L2Character victim, QuestState qs)// {// TRACE("onDeath("+STR(killer)+","+STR(victim)+","+(qs == null ? "NULL" : qs.getQuest() == null ? "NUL" : qs.getQuest().getName())+")");// TODO: キャラクターが死亡して○○分以内に復活しないと場外にとばされてしまう// return super.onDeath(killer, victim, qs);// } @Override public String onEnterZone(L2Character character, L2ZoneType zone)/*テスト済*/ { if (character instanceof L2PcInstance) { //TRACE("onEnterZone(" + STR(character) + "," + zone.getId()+" "+zone.getClass().getSimpleName() + ")");/*@IF DEBUG@*/ if (ASSERT) if (!(zone.getId() == ROOM3_ZONE)) throw new RuntimeException(); InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(character.getInstanceId()); if (tmpworld instanceof FETWorld) { FETWorld world = (FETWorld) tmpworld; if (world.status == 2) controlStatus(world); } else throw new RuntimeException();/*@IF DEBUG@*/ } return super.onEnterZone(character, zone); } @Override public String onTalk(L2Npc npc, L2PcInstance player) { QuestState st = player.getQuestState(qn); if (st == null) st = newQuestState(player); switch (npc.getNpcId()) { case GUIDE:/*=>1部屋めに移動*/ enterInstance(player, "FinalEmperialTomb.xml", ENTER_TELEPORT); break; case CUBE:/*=>フリンテッサ部屋へ移動*/ player.teleToLocation(-87784 + Rnd.get(-250, 250), -153298 + Rnd.get(-250, 250), -9175); return null; } return ""; } public FinalEmperialTomb(int questId, String name, String descr) { super(questId, name, descr); addStartNpc(GUIDE); addTalkId(GUIDE); addStartNpc(CUBE); addTalkId(CUBE); addKillId(HALL_ALARM); addKillId(DARK_CHOIR_PLAYER); addSkillSeeId(FRINTEZZA); addAttackId(FRINTEZZA); addAttackId(SCARLET1); addKillId(SCARLET1); addKillId(SCARLET2); addKillId(PORTRAIT_FIGHTER); addKillId(PORTRAIT_MAGE); addEnterZoneId(ROOM3_ZONE); if (ASSERT) if (!(ZoneManager.getInstance().getZoneById(ROOM3_ZONE) != null)) throw new RuntimeException(); //<zone id="12911" type="ScriptZone" shape="Cuboid" ... /> } public static void main(String[] args) { // now call the constructor (starts up the) new FinalEmperialTomb(-1, qn, "instances"); }}