Q511_AwlUnderFoot.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package quests.Q511_AwlUnderFoot;
  16. import gnu.trove.TIntObjectHashMap;
  17. import com.l2jserver.gameserver.ThreadPoolManager;
  18. import com.l2jserver.gameserver.instancemanager.InstanceManager;
  19. import com.l2jserver.gameserver.instancemanager.InstanceManager.InstanceWorld;
  20. import com.l2jserver.gameserver.model.L2Party;
  21. import com.l2jserver.gameserver.model.actor.L2Npc;
  22. import com.l2jserver.gameserver.model.actor.L2Playable;
  23. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  24. import com.l2jserver.gameserver.model.actor.instance.L2RaidBossInstance;
  25. import com.l2jserver.gameserver.model.entity.Fort;
  26. import com.l2jserver.gameserver.model.entity.Instance;
  27. import com.l2jserver.gameserver.model.quest.Quest;
  28. import com.l2jserver.gameserver.model.quest.QuestState;
  29. import com.l2jserver.gameserver.model.quest.State;
  30. import com.l2jserver.gameserver.network.SystemMessageId;
  31. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  32. import com.l2jserver.gameserver.skills.SkillHolder;
  33. import com.l2jserver.gameserver.util.Util;
  34. import com.l2jserver.util.Rnd;
  35. /**
  36. *
  37. * @author Gigiikun
  38. *
  39. */
  40. public final class Q511_AwlUnderFoot extends Quest
  41. {
  42. private class FAUWorld extends InstanceWorld
  43. {
  44. }
  45. public static class FortDungeon
  46. {
  47. private final int INSTANCEID;
  48. private long _reEnterTime = 0;
  49. public FortDungeon(int iId)
  50. {
  51. INSTANCEID = iId;
  52. }
  53. public int getInstanceId()
  54. {
  55. return INSTANCEID;
  56. }
  57. public long getReEnterTime()
  58. {
  59. return _reEnterTime;
  60. }
  61. public void setReEnterTime(long time)
  62. {
  63. _reEnterTime = time;
  64. }
  65. }
  66. private static final String qn = "Q511_AwlUnderFoot";
  67. private static final boolean debug = false;
  68. private static final long REENTERTIME = 14400000;
  69. private static final long RAID_SPAWN_DELAY = 120000;
  70. private TIntObjectHashMap<FortDungeon> _fortDungeons = new TIntObjectHashMap<FortDungeon>(21);
  71. // QUEST ITEMS
  72. private static final int DL_MARK = 9797;
  73. // REWARDS
  74. private static final int KNIGHT_EPALUETTE = 9912;
  75. // MONSTER TO KILL -- Only last 3 Raids (lvl ordered) give DL_MARK
  76. private static final int[] RAIDS1 = { 25572, 25575, 25578 };
  77. private static final int[] RAIDS2 = { 25579, 25582, 25585, 25588 };
  78. private static final int[] RAIDS3 = { 25589, 25592, 25593 };
  79. private static final SkillHolder RAID_CURSE = new SkillHolder(5456, 1);
  80. private String checkConditions(L2PcInstance player)
  81. {
  82. if (debug)
  83. return null;
  84. L2Party party = player.getParty();
  85. if (party == null)
  86. return "FortressWarden-03.htm";
  87. if (party.getLeader() != player)
  88. return getHtm(player.getHtmlPrefix(), "FortressWarden-04.htm").replace("%leader%", party.getLeader().getName());
  89. for (L2PcInstance partyMember : party.getPartyMembers())
  90. {
  91. QuestState st = partyMember.getQuestState(qn);
  92. if (st == null || st.getInt("cond") < 1)
  93. return getHtm(player.getHtmlPrefix(), "FortressWarden-05.htm").replace("%player%", partyMember.getName());
  94. if (!Util.checkIfInRange(1000, player, partyMember, true))
  95. return getHtm(player.getHtmlPrefix(), "FortressWarden-06.htm").replace("%player%", partyMember.getName());
  96. }
  97. return null;
  98. }
  99. private void teleportPlayer(L2PcInstance player, int[] coords, int instanceId)
  100. {
  101. player.setInstanceId(instanceId);
  102. player.teleToLocation(coords[0], coords[1], coords[2]);
  103. }
  104. protected String enterInstance(L2PcInstance player, String template, int[] coords, FortDungeon dungeon, String ret)
  105. {
  106. //check for existing instances for this player
  107. InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
  108. //existing instance
  109. if (world != null)
  110. {
  111. if (!(world instanceof FAUWorld))
  112. {
  113. player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.ALREADY_ENTERED_ANOTHER_INSTANCE_CANT_ENTER));
  114. return "";
  115. }
  116. teleportPlayer(player, coords, world.instanceId);
  117. return "";
  118. }
  119. //New instance
  120. else
  121. {
  122. if (ret != null)
  123. return ret;
  124. ret = checkConditions(player);
  125. if (ret != null)
  126. return ret;
  127. L2Party party = player.getParty();
  128. int instanceId = InstanceManager.getInstance().createDynamicInstance(template);
  129. Instance ins = InstanceManager.getInstance().getInstance(instanceId);
  130. ins.setSpawnLoc(new int[]{player.getX(),player.getY(),player.getZ()});
  131. world = new FAUWorld();
  132. world.instanceId = instanceId;
  133. world.templateId = dungeon.getInstanceId();
  134. world.status = 0;
  135. dungeon.setReEnterTime(System.currentTimeMillis() + REENTERTIME);
  136. InstanceManager.getInstance().addWorld(world);
  137. _log.info("Fortress AwlUnderFoot started " + template + " Instance: " + instanceId + " created by player: " + player.getName());
  138. ThreadPoolManager.getInstance().scheduleGeneral(new spawnRaid((FAUWorld) world), RAID_SPAWN_DELAY);
  139. // teleport players
  140. if (player.getParty() == null)
  141. {
  142. teleportPlayer(player, coords, instanceId);
  143. world.allowed.add(player.getObjectId());
  144. }
  145. else
  146. {
  147. for (L2PcInstance partyMember : party.getPartyMembers())
  148. {
  149. teleportPlayer(partyMember, coords, instanceId);
  150. world.allowed.add(partyMember.getObjectId());
  151. if (partyMember.getQuestState(qn) == null)
  152. newQuestState(partyMember);
  153. }
  154. }
  155. return getHtm(player.getHtmlPrefix(), "FortressWarden-08.htm").replace("%clan%", player.getClan().getName());
  156. }
  157. }
  158. private class spawnRaid implements Runnable
  159. {
  160. private FAUWorld _world;
  161. public spawnRaid(FAUWorld world)
  162. {
  163. _world = world;
  164. }
  165. public void run()
  166. {
  167. try
  168. {
  169. int spawnId;
  170. if (_world.status == 0)
  171. spawnId = RAIDS1[Rnd.get(RAIDS1.length)];
  172. else if (_world.status == 1)
  173. spawnId = RAIDS2[Rnd.get(RAIDS2.length)];
  174. else
  175. spawnId = RAIDS3[Rnd.get(RAIDS3.length)];
  176. L2Npc raid = addSpawn(spawnId,53319,245814,-6576,0,false,0,false, _world.instanceId);
  177. if (raid instanceof L2RaidBossInstance)
  178. ((L2RaidBossInstance)raid).setUseRaidCurse(false);
  179. }
  180. catch (Exception e)
  181. {
  182. _log.warning("Fortress AwlUnderFoot Raid Spawn error: " + e);
  183. }
  184. }
  185. }
  186. private String checkFortCondition(L2PcInstance player, L2Npc npc, boolean isEnter)
  187. {
  188. Fort fortress = npc.getFort();
  189. FortDungeon dungeon = _fortDungeons.get(npc.getNpcId());
  190. if (player == null || fortress == null || dungeon == null)
  191. return "FortressWarden-01.htm";
  192. if (player.getClan() == null || player.getClan().getHasFort() != fortress.getFortId())
  193. return "FortressWarden-01.htm";
  194. else if (fortress.getFortState() == 0)
  195. return "FortressWarden-02a.htm";
  196. else if (fortress.getFortState() == 2)
  197. return "FortressWarden-02b.htm";
  198. else if (isEnter && dungeon.getReEnterTime() > System.currentTimeMillis())
  199. return "FortressWarden-07.htm";
  200. return null;
  201. }
  202. private void rewardPlayer(L2PcInstance player)
  203. {
  204. QuestState st = player.getQuestState(qn);
  205. if (st.getInt("cond") == 1)
  206. {
  207. st.giveItems(DL_MARK, 140);
  208. st.playSound("ItemSound.quest_itemget");
  209. }
  210. }
  211. @Override
  212. public String onAdvEvent (String event, L2Npc npc, L2PcInstance player)
  213. {
  214. String htmltext = event;
  215. if (event.equalsIgnoreCase("enter"))
  216. {
  217. int[] tele = new int[3];
  218. tele[0] = 53322;
  219. tele[1] = 246380;
  220. tele[2] = -6580;
  221. return enterInstance(player, "fortdungeon.xml", tele, _fortDungeons.get(npc.getNpcId()), checkFortCondition(player, npc, true));
  222. }
  223. QuestState st = player.getQuestState(qn);
  224. if (st == null)
  225. st = newQuestState(player);
  226. int cond = st.getInt("cond");
  227. if (event.equalsIgnoreCase("FortressWarden-10.htm"))
  228. {
  229. if (cond == 0)
  230. {
  231. st.set("cond","1");
  232. st.setState(State.STARTED);
  233. st.playSound("ItemSound.quest_accept");
  234. }
  235. }
  236. else if (event.equalsIgnoreCase("FortressWarden-15.htm"))
  237. {
  238. st.playSound("ItemSound.quest_finish");
  239. st.exitQuest(true);
  240. }
  241. return htmltext;
  242. }
  243. @Override
  244. public String onTalk (L2Npc npc, L2PcInstance player)
  245. {
  246. String htmltext = Quest.getNoQuestMsg(player);
  247. QuestState st = player.getQuestState(qn);
  248. String ret = checkFortCondition(player, npc, false);
  249. if (ret != null)
  250. return ret;
  251. else if (st != null)
  252. {
  253. int npcId = npc.getNpcId();
  254. int cond = 0;
  255. if (st.getState() == State.CREATED)
  256. st.set("cond","0");
  257. else
  258. cond = st.getInt("cond");
  259. if (_fortDungeons.containsKey(npcId) && cond == 0)
  260. {
  261. if (player.getLevel() >= 60)
  262. htmltext = "FortressWarden-09.htm";
  263. else
  264. {
  265. htmltext = "FortressWarden-00.htm";
  266. st.exitQuest(true);
  267. }
  268. }
  269. else if (_fortDungeons.containsKey(npcId) && cond > 0 && st.getState() == State.STARTED)
  270. {
  271. long count = st.getQuestItemsCount(DL_MARK);
  272. if (cond == 1 && count > 0)
  273. {
  274. htmltext = "FortressWarden-14.htm";
  275. st.takeItems(DL_MARK,count);
  276. st.rewardItems(KNIGHT_EPALUETTE, count);
  277. }
  278. else if (cond == 1 && count == 0)
  279. htmltext = "FortressWarden-10.htm";
  280. }
  281. }
  282. return htmltext;
  283. }
  284. @Override
  285. public String onAttack(L2Npc npc,L2PcInstance player, int damage, boolean isPet)
  286. {
  287. L2Playable attacker = (isPet ? player.getPet() : player);
  288. if (attacker.getLevel() - npc.getLevel() >= 9)
  289. {
  290. if (attacker.getBuffCount() > 0 || attacker.getDanceCount() > 0)
  291. {
  292. npc.setTarget(attacker);
  293. npc.doSimultaneousCast(RAID_CURSE.getSkill());
  294. }
  295. else if (player.getParty() != null)
  296. for(L2PcInstance pmember : player.getParty().getPartyMembers())
  297. {
  298. if (pmember.getBuffCount() > 0 || pmember.getDanceCount() > 0)
  299. {
  300. npc.setTarget(pmember);
  301. npc.doSimultaneousCast(RAID_CURSE.getSkill());
  302. }
  303. }
  304. }
  305. return super.onAttack(npc, player, damage, isPet);
  306. }
  307. @Override
  308. public String onKill(L2Npc npc, L2PcInstance player, boolean isPet)
  309. {
  310. InstanceWorld tmpworld = InstanceManager.getInstance().getWorld(npc.getInstanceId());
  311. if (tmpworld instanceof FAUWorld)
  312. {
  313. FAUWorld world = (FAUWorld) tmpworld;
  314. if (Util.contains(RAIDS3, npc.getNpcId()))
  315. {
  316. if (player.getParty() != null)
  317. for (L2PcInstance pl : player.getParty().getPartyMembers())
  318. rewardPlayer(pl);
  319. else
  320. rewardPlayer(player);
  321. Instance instanceObj = InstanceManager.getInstance().getInstance(world.instanceId);
  322. instanceObj.setDuration(360000);
  323. instanceObj.removeNpcs();
  324. }
  325. else
  326. {
  327. world.status++;
  328. ThreadPoolManager.getInstance().scheduleGeneral(new spawnRaid(world), RAID_SPAWN_DELAY);
  329. }
  330. }
  331. return null;
  332. }
  333. public Q511_AwlUnderFoot(int questId, String name, String descr)
  334. {
  335. super(questId, name, descr);
  336. _fortDungeons.put(35666, new FortDungeon(22));
  337. _fortDungeons.put(35698, new FortDungeon(23));
  338. _fortDungeons.put(35735, new FortDungeon(24));
  339. _fortDungeons.put(35767, new FortDungeon(25));
  340. _fortDungeons.put(35804, new FortDungeon(26));
  341. _fortDungeons.put(35835, new FortDungeon(27));
  342. _fortDungeons.put(35867, new FortDungeon(28));
  343. _fortDungeons.put(35904, new FortDungeon(29));
  344. _fortDungeons.put(35936, new FortDungeon(30));
  345. _fortDungeons.put(35974, new FortDungeon(31));
  346. _fortDungeons.put(36011, new FortDungeon(32));
  347. _fortDungeons.put(36043, new FortDungeon(33));
  348. _fortDungeons.put(36081, new FortDungeon(34));
  349. _fortDungeons.put(36118, new FortDungeon(35));
  350. _fortDungeons.put(36149, new FortDungeon(36));
  351. _fortDungeons.put(36181, new FortDungeon(37));
  352. _fortDungeons.put(36219, new FortDungeon(38));
  353. _fortDungeons.put(36257, new FortDungeon(39));
  354. _fortDungeons.put(36294, new FortDungeon(40));
  355. _fortDungeons.put(36326, new FortDungeon(41));
  356. _fortDungeons.put(36364, new FortDungeon(42));
  357. for(int i : _fortDungeons.keys())
  358. {
  359. addStartNpc(i);
  360. addTalkId(i);
  361. }
  362. for(int i : RAIDS1)
  363. addKillId(i);
  364. for(int i : RAIDS2)
  365. addKillId(i);
  366. for(int i : RAIDS3)
  367. addKillId(i);
  368. for(int i = 25572; i <= 25595; i++)
  369. addAttackId(i);
  370. }
  371. public static void main(String[] args)
  372. {
  373. // now call the constructor (starts up the)
  374. new Q511_AwlUnderFoot(511,qn,"instances");
  375. }
  376. }