441 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			441 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| /*
 | |
|  * 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.DarkCloudMansion;
 | |
| 
 | |
| import java.util.List;
 | |
| 
 | |
| import com.l2jmobius.commons.util.CommonUtil;
 | |
| import com.l2jmobius.gameserver.enums.ChatType;
 | |
| 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.holders.SkillHolder;
 | |
| import com.l2jmobius.gameserver.model.instancezone.Instance;
 | |
| import com.l2jmobius.gameserver.network.NpcStringId;
 | |
| 
 | |
| import instances.AbstractInstance;
 | |
| 
 | |
| /**
 | |
|  * Dark Cloud Mansion instance.
 | |
|  * @author malyelfik
 | |
|  */
 | |
| public final class DarkCloudMansion extends AbstractInstance
 | |
| {
 | |
| 	// NPCs
 | |
| 	private static final int YIYEN = 32282;
 | |
| 	private static final int FAITH = 32288; // Symbol of Faith
 | |
| 	private static final int ADVERSITY = 32289; // Symbol of Adversity
 | |
| 	private static final int ADVENTURE = 32290; // Symbol of Adventure
 | |
| 	private static final int TRUTH = 32291; // Symbol of Truth
 | |
| 	private static final int MONOLITH = 32324; // Black Stone Monolith
 | |
| 	private static final int COLUMN = 22402; // Shadow Column
 | |
| 	// Mobs
 | |
| 	private static final int PARME_HEALER = 22400;
 | |
| 	private static final int[] BELETH_SUBORDINATE =
 | |
| 	{
 | |
| 		22272,
 | |
| 		22273,
 | |
| 		22274
 | |
| 	};
 | |
| 	private static final int[] MONOLITH_PRIVATES =
 | |
| 	{
 | |
| 		18369,
 | |
| 		18370
 | |
| 	};
 | |
| 	private static final int[] BELETH_SAMPLE =
 | |
| 	{
 | |
| 		18371,
 | |
| 		18372,
 | |
| 		18373,
 | |
| 		18374,
 | |
| 		18375,
 | |
| 		18376,
 | |
| 		18377
 | |
| 	};
 | |
| 	// Skill
 | |
| 	private static final SkillHolder INCARNATION = new SkillHolder(5441, 1);
 | |
| 	// Items
 | |
| 	private static final int CC = 9690; // Contaminated Crystal
 | |
| 	// Doors
 | |
| 	private static final int START_DOOR = 24230001; // Starting Room
 | |
| 	private static final int ROOM_A_DOOR = 24230002; // First Room
 | |
| 	private static final int ROOM_B_DOOR = 24230005; // Second Room
 | |
| 	private static final int ROOM_C_DOOR = 24230003; // Third Room
 | |
| 	private static final int ROOM_D_DOOR = 24230004; // Forth Room
 | |
| 	private static final int ROOM_E_DOOR = 24230006; // Fifth Room
 | |
| 	// Messages
 | |
| 	private static final NpcStringId[] SPAWN_CHAT =
 | |
| 	{
 | |
| 		NpcStringId.I_M_THE_REAL_ONE,
 | |
| 		NpcStringId.PICK_ME,
 | |
| 		NpcStringId.TRUST_ME,
 | |
| 		NpcStringId.NOT_THAT_DUDE_I_M_THE_REAL_ONE,
 | |
| 		NpcStringId.DON_T_BE_FOOLED_DON_T_BE_FOOLED_I_M_THE_REAL_ONE
 | |
| 	};
 | |
| 	private static final NpcStringId[] DECAY_CHAT =
 | |
| 	{
 | |
| 		NpcStringId.I_M_THE_REAL_ONE_PHEW,
 | |
| 		NpcStringId.CAN_T_YOU_EVEN_FIND_OUT,
 | |
| 		NpcStringId.FIND_ME
 | |
| 	};
 | |
| 	private static final NpcStringId[] SUCCESS_CHAT =
 | |
| 	{
 | |
| 		NpcStringId.HUH_HOW_DID_YOU_KNOW_IT_WAS_ME,
 | |
| 		NpcStringId.EXCELLENT_CHOICE_TEEHEE,
 | |
| 		NpcStringId.YOU_VE_DONE_WELL,
 | |
| 		NpcStringId.OH_VERY_SENSIBLE
 | |
| 	};
 | |
| 	private static final NpcStringId[] FAIL_CHAT =
 | |
| 	{
 | |
| 		NpcStringId.YOU_VE_BEEN_FOOLED,
 | |
| 		NpcStringId.SORRY_BUT_I_M_THE_FAKE_ONE
 | |
| 	};
 | |
| 	
 | |
| 	// Misc
 | |
| 	private static final int TEMPLATE_ID = 9;
 | |
| 	
 | |
| 	public DarkCloudMansion()
 | |
| 	{
 | |
| 		addStartNpc(YIYEN);
 | |
| 		addFirstTalkId(MONOLITH, TRUTH, FAITH, ADVERSITY, ADVENTURE);
 | |
| 		addTalkId(YIYEN, TRUTH);
 | |
| 		addAttackId(COLUMN, PARME_HEALER);
 | |
| 		addAttackId(BELETH_SAMPLE);
 | |
| 		addKillId(COLUMN, PARME_HEALER);
 | |
| 		addKillId(BELETH_SAMPLE);
 | |
| 		addKillId(BELETH_SUBORDINATE);
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
 | |
| 	{
 | |
| 		final Instance world = npc.getInstanceWorld();
 | |
| 		if (world != null)
 | |
| 		{
 | |
| 			switch (event)
 | |
| 			{
 | |
| 				case "DELETE_ONE":
 | |
| 					npc.deleteMe();
 | |
| 					break;
 | |
| 				case "DELETE":
 | |
| 				{
 | |
| 					world.getNpcs(BELETH_SAMPLE).stream().filter(n -> n != npc).forEach(L2Npc::deleteMe);
 | |
| 					world.setParameter("blocked", false);
 | |
| 					spawnRoomE(world);
 | |
| 					break;
 | |
| 				}
 | |
| 				case "CHAT":
 | |
| 					world.getNpcs(BELETH_SAMPLE).stream().filter(n -> n.isScriptValue(1)).forEach(n -> n.broadcastSay(ChatType.NPC_GENERAL, DECAY_CHAT[getRandom(DECAY_CHAT.length)]));
 | |
| 					break;
 | |
| 			}
 | |
| 		}
 | |
| 		return null;
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public String onTalk(L2Npc npc, L2PcInstance player)
 | |
| 	{
 | |
| 		if (npc.getId() == YIYEN)
 | |
| 		{
 | |
| 			enterInstance(player, npc, TEMPLATE_ID);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			final Instance world = npc.getInstanceWorld();
 | |
| 			if (world != null)
 | |
| 			{
 | |
| 				teleportPlayerOut(player, world);
 | |
| 			}
 | |
| 		}
 | |
| 		return null;
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public String onFirstTalk(L2Npc npc, L2PcInstance player)
 | |
| 	{
 | |
| 		final Instance world = npc.getInstanceWorld();
 | |
| 		if (world != null)
 | |
| 		{
 | |
| 			switch (npc.getId())
 | |
| 			{
 | |
| 				case FAITH:
 | |
| 				{
 | |
| 					world.openCloseDoor(ROOM_A_DOOR, true);
 | |
| 					npc.showChatWindow(player);
 | |
| 					break;
 | |
| 				}
 | |
| 				case MONOLITH:
 | |
| 				{
 | |
| 					if (world.isStatus(4) && !npc.isScriptValue(-1))
 | |
| 					{
 | |
| 						int current = world.getParameters().getInt("current", 0);
 | |
| 						if (npc.isScriptValue(current))
 | |
| 						{
 | |
| 							npc.setScriptValue(-1);
 | |
| 							npc.doCast(INCARNATION.getSkill());
 | |
| 							world.setParameter("current", ++current);
 | |
| 							
 | |
| 							if (current == 6)
 | |
| 							{
 | |
| 								world.setStatus(5);
 | |
| 								world.spawnGroup("roomBClear");
 | |
| 								world.spawnGroup("hall");
 | |
| 								world.getNpcs(MONOLITH).forEach(L2Npc::deleteMe);
 | |
| 							}
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							addSpawn(MONOLITH_PRIVATES[getRandom(MONOLITH_PRIVATES.length)], npc, false, 0, false, world.getId());
 | |
| 						}
 | |
| 						world.openCloseDoor(ROOM_B_DOOR, false);
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				case ADVERSITY:
 | |
| 				{
 | |
| 					world.openCloseDoor(ROOM_B_DOOR, true);
 | |
| 					npc.showChatWindow(player);
 | |
| 					break;
 | |
| 				}
 | |
| 				case ADVENTURE:
 | |
| 				{
 | |
| 					if (world.isStatus(7))
 | |
| 					{
 | |
| 						world.spawnGroup("roomC").forEach(n -> n.setScriptValue(8));
 | |
| 						world.setStatus(8);
 | |
| 						world.openCloseDoor(ROOM_D_DOOR, true);
 | |
| 					}
 | |
| 					npc.showChatWindow(player);
 | |
| 					break;
 | |
| 				}
 | |
| 				case TRUTH:
 | |
| 				{
 | |
| 					if (!hasQuestItems(player, CC))
 | |
| 					{
 | |
| 						giveItems(player, CC, 1);
 | |
| 					}
 | |
| 					npc.showChatWindow(player);
 | |
| 					break;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		return null;
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
 | |
| 	{
 | |
| 		final Instance world = npc.getInstanceWorld();
 | |
| 		if (world != null)
 | |
| 		{
 | |
| 			switch (npc.getId())
 | |
| 			{
 | |
| 				case PARME_HEALER:
 | |
| 				{
 | |
| 					if (world.isStatus(2) && (attacker.getY() < 179986))
 | |
| 					{
 | |
| 						world.openCloseDoor(ROOM_A_DOOR, false);
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				case COLUMN:
 | |
| 				{
 | |
| 					if (world.isStatus(7))
 | |
| 					{
 | |
| 						world.openCloseDoor(ROOM_D_DOOR, false);
 | |
| 						if (npc.isHpBlocked() && (getRandom(100) < 12))
 | |
| 						{
 | |
| 							addSpawn(BELETH_SUBORDINATE[getRandom(BELETH_SUBORDINATE.length)], npc, false, 0, false, world.getId());
 | |
| 						}
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				default:
 | |
| 				{
 | |
| 					if (world.isStatus(9))
 | |
| 					{
 | |
| 						handleRoomE(world, npc);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		return super.onAttack(npc, attacker, damage, isSummon);
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
 | |
| 	{
 | |
| 		final Instance world = npc.getInstanceWorld();
 | |
| 		if (world != null)
 | |
| 		{
 | |
| 			switch (world.getStatus())
 | |
| 			{
 | |
| 				case 0: // Start room
 | |
| 				{
 | |
| 					if (world.getAliveNpcs().isEmpty())
 | |
| 					{
 | |
| 						world.setStatus(1);
 | |
| 						world.spawnGroup("hall");
 | |
| 						world.openCloseDoor(START_DOOR, true);
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				case 1: // Hall
 | |
| 				{
 | |
| 					if (world.getAliveNpcs().isEmpty())
 | |
| 					{
 | |
| 						world.setStatus(2);
 | |
| 						world.spawnGroup("roomA");
 | |
| 						world.openCloseDoor(ROOM_A_DOOR, true);
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				case 2: // Room A - cleared
 | |
| 				{
 | |
| 					if (world.getAliveNpcs().isEmpty())
 | |
| 					{
 | |
| 						world.setStatus(3);
 | |
| 						world.spawnGroup("roomAClear");
 | |
| 						world.spawnGroup("hall");
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				case 3: // Hall
 | |
| 				{
 | |
| 					if (world.getAliveNpcs(BELETH_SUBORDINATE).isEmpty())
 | |
| 					{
 | |
| 						world.setStatus(4);
 | |
| 						world.openCloseDoor(ROOM_B_DOOR, true);
 | |
| 						
 | |
| 						int current = 0;
 | |
| 						final List<L2Npc> desks = world.spawnGroup("roomB");
 | |
| 						while (!desks.isEmpty())
 | |
| 						{
 | |
| 							final L2Npc desk = desks.remove(getRandom(desks.size()));
 | |
| 							desk.setScriptValue(current++);
 | |
| 						}
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				case 5: // Hall
 | |
| 				{
 | |
| 					if (world.getAliveNpcs(BELETH_SUBORDINATE).isEmpty())
 | |
| 					{
 | |
| 						world.setStatus(6);
 | |
| 						world.spawnGroup("roomC");
 | |
| 						world.openCloseDoor(ROOM_C_DOOR, true);
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				case 6: // Room C
 | |
| 				{
 | |
| 					if (world.getAliveNpcs(BELETH_SUBORDINATE).isEmpty())
 | |
| 					{
 | |
| 						world.setStatus(7);
 | |
| 						world.spawnGroup("roomD");
 | |
| 						world.openCloseDoor(ROOM_D_DOOR, true);
 | |
| 						for (int i = 1; i <= 7; i++)
 | |
| 						{
 | |
| 							final List<L2Npc> row = world.spawnGroup("roomD" + i);
 | |
| 							for (int x = 0; x < 2; x++)
 | |
| 							{
 | |
| 								final L2Npc col = row.remove(getRandom(row.size()));
 | |
| 								col.setIsInvul(true);
 | |
| 							}
 | |
| 						}
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				case 8: // Room C
 | |
| 				{
 | |
| 					final long roomClear = world.getAliveNpcs(BELETH_SUBORDINATE).stream().filter(n -> n.isScriptValue(8)).count();
 | |
| 					if (roomClear == 0)
 | |
| 					{
 | |
| 						world.setStatus(9);
 | |
| 						world.openCloseDoor(ROOM_E_DOOR, true);
 | |
| 						spawnRoomE(world);
 | |
| 					}
 | |
| 					break;
 | |
| 				}
 | |
| 				case 9:
 | |
| 					handleRoomE(world, npc);
 | |
| 					break;
 | |
| 			}
 | |
| 		}
 | |
| 		return null;
 | |
| 	}
 | |
| 	
 | |
| 	private void spawnRoomE(Instance world)
 | |
| 	{
 | |
| 		final List<L2Npc> npcs = world.spawnGroup("roomE");
 | |
| 		for (L2Npc n : npcs)
 | |
| 		{
 | |
| 			n.broadcastSay(ChatType.NPC_GENERAL, SPAWN_CHAT[getRandom(SPAWN_CHAT.length)]);
 | |
| 		}
 | |
| 		for (int i = 0; i < 3; i++)
 | |
| 		{
 | |
| 			final L2Npc n = npcs.remove(getRandom(npcs.size()));
 | |
| 			n.setScriptValue(1);
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	private void handleRoomE(Instance world, L2Npc npc)
 | |
| 	{
 | |
| 		if (CommonUtil.contains(BELETH_SAMPLE, npc.getId()))
 | |
| 		{
 | |
| 			final StatsSet params = world.getParameters();
 | |
| 			if (!params.getBoolean("blocked", false))
 | |
| 			{
 | |
| 				if (npc.isScriptValue(1))
 | |
| 				{
 | |
| 					final int found = params.getInt("found", 0) + 1;
 | |
| 					world.setParameter("found", found);
 | |
| 					
 | |
| 					npc.setScriptValue(-1);
 | |
| 					npc.broadcastSay(ChatType.NPC_GENERAL, SUCCESS_CHAT[getRandom(SUCCESS_CHAT.length)]);
 | |
| 					
 | |
| 					if (found != 3)
 | |
| 					{
 | |
| 						startQuestTimer("DELETE_ONE", 1500, npc, null);
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						world.setStatus(10);
 | |
| 						world.getNpcs().forEach(L2Npc::deleteMe);
 | |
| 						world.spawnGroup("roomEClear");
 | |
| 					}
 | |
| 				}
 | |
| 				else if (!npc.isScriptValue(-1))
 | |
| 				{
 | |
| 					world.setParameter("blocked", true);
 | |
| 					world.setParameter("found", 0);
 | |
| 					
 | |
| 					npc.broadcastSay(ChatType.NPC_GENERAL, FAIL_CHAT[getRandom(FAIL_CHAT.length)]);
 | |
| 					npc.setScriptValue(-1);
 | |
| 					startQuestTimer("CHAT", 4000, npc, null);
 | |
| 					startQuestTimer("DELETE", 4500, npc, null);
 | |
| 				}
 | |
| 				world.openCloseDoor(ROOM_E_DOOR, false);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	public static void main(String[] args)
 | |
| 	{
 | |
| 		new DarkCloudMansion();
 | |
| 	}
 | |
| } | 
