QuestLink.java 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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 handlers.bypasshandlers;
  16. import java.util.List;
  17. import javolution.util.FastList;
  18. import com.l2jserver.Config;
  19. import com.l2jserver.gameserver.cache.HtmCache;
  20. import com.l2jserver.gameserver.handler.IBypassHandler;
  21. import com.l2jserver.gameserver.instancemanager.QuestManager;
  22. import com.l2jserver.gameserver.model.actor.L2Character;
  23. import com.l2jserver.gameserver.model.actor.L2Npc;
  24. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  25. import com.l2jserver.gameserver.model.quest.Quest;
  26. import com.l2jserver.gameserver.model.quest.QuestState;
  27. import com.l2jserver.gameserver.model.quest.State;
  28. import com.l2jserver.gameserver.network.SystemMessageId;
  29. import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
  30. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  31. import com.l2jserver.util.StringUtil;
  32. public class QuestLink implements IBypassHandler
  33. {
  34. private static final String[] COMMANDS =
  35. {
  36. "Quest"
  37. };
  38. public boolean useBypass(String command, L2PcInstance activeChar, L2Character target)
  39. {
  40. if (!(target instanceof L2Npc))
  41. return false;
  42. String quest = "";
  43. try
  44. {
  45. quest = command.substring(5).trim();
  46. }
  47. catch (IndexOutOfBoundsException ioobe)
  48. {
  49. }
  50. if (quest.length() == 0)
  51. showQuestWindow(activeChar, (L2Npc)target);
  52. else
  53. showQuestWindow(activeChar, (L2Npc)target, quest);
  54. return true;
  55. }
  56. /**
  57. * Open a choose quest window on client with all quests available of the L2NpcInstance.<BR><BR>
  58. * <B><U> Actions</U> :</B><BR><BR>
  59. * <li>Send a Server->Client NpcHtmlMessage containing the text of the L2NpcInstance to the L2PcInstance </li><BR><BR>
  60. * @param player The L2PcInstance that talk with the L2NpcInstance
  61. * @param npc The table containing quests of the L2NpcInstance
  62. * @param quests
  63. */
  64. public static void showQuestChooseWindow(L2PcInstance player, L2Npc npc, Quest[] quests)
  65. {
  66. final StringBuilder sb = StringUtil.startAppend(150, "<html><body>");
  67. String state = "";
  68. int questId = -1;
  69. for (Quest q : quests)
  70. {
  71. if (q == null)
  72. {
  73. continue;
  74. }
  75. StringUtil.append(sb, "<a action=\"bypass -h npc_", String.valueOf(npc.getObjectId()), "_Quest ", q.getName(), "\">[");
  76. final QuestState qs = player.getQuestState(q.getScriptName());
  77. if ((qs == null) || qs.isCreated())
  78. {
  79. state = q.isCustomQuest() ? "" : "01";
  80. }
  81. else if (qs.isStarted() && (qs.getInt("cond") > 0))
  82. {
  83. state = q.isCustomQuest() ? " (In Progress)" : "02";
  84. }
  85. else if (qs.isCompleted())
  86. {
  87. state = q.isCustomQuest() ? " (Done)" : "03";
  88. }
  89. if (q.isCustomQuest())
  90. {
  91. StringUtil.append(sb, q.getDescr(), state);
  92. }
  93. else
  94. {
  95. questId = q.getQuestIntId();
  96. if (q.getQuestIntId() > 10000)
  97. {
  98. questId -= 5000;
  99. }
  100. else if (questId == 146)
  101. {
  102. questId = 640;
  103. }
  104. StringUtil.append(sb, "<fstring>", String.valueOf(questId), state, "</fstring>");
  105. }
  106. sb.append("]</a><br>");
  107. }
  108. sb.append("</body></html>");
  109. // Send a Server->Client packet NpcHtmlMessage to the L2PcInstance in order to display the message of the L2NpcInstance
  110. npc.insertObjectIdAndShowChatWindow(player, sb.toString());
  111. }
  112. /**
  113. * Open a quest window on client with the text of the L2NpcInstance.<BR><BR>
  114. * <B><U> Actions</U> :</B><BR><BR>
  115. * <li>Get the text of the quest state in the folder data/scripts/quests/questId/stateId.htm </li>
  116. * <li>Send a Server->Client NpcHtmlMessage containing the text of the L2NpcInstance to the L2PcInstance </li>
  117. * <li>Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet </li><BR><BR>
  118. * @param player the L2PcInstance that talk with the {@code npc}.
  119. * @param npc the L2NpcInstance that chats with the {@code player}.
  120. * @param questId the Id of the quest to display the message.
  121. */
  122. public static void showQuestWindow(L2PcInstance player, L2Npc npc, String questId)
  123. {
  124. String content = null;
  125. Quest q = QuestManager.getInstance().getQuest(questId);
  126. // Get the state of the selected quest
  127. QuestState qs = player.getQuestState(questId);
  128. if (q != null)
  129. {
  130. if ((q.getQuestIntId() >= 1 && q.getQuestIntId() < 20000) && (player.getWeightPenalty() >= 3 || !player.isInventoryUnder80(true)))
  131. {
  132. player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.INVENTORY_LESS_THAN_80_PERCENT));
  133. return;
  134. }
  135. if (qs == null)
  136. {
  137. if (q.getQuestIntId() >= 1 && q.getQuestIntId() < 20000)
  138. {
  139. if (player.getAllActiveQuests().length > 40) // if too many ongoing quests, don't show window and send message
  140. {
  141. player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.TOO_MANY_QUESTS));
  142. return;
  143. }
  144. }
  145. // check for start point
  146. Quest[] qlst = npc.getTemplate().getEventQuests(Quest.QuestEventType.QUEST_START);
  147. if (qlst != null && qlst.length > 0)
  148. {
  149. for (Quest temp : qlst)
  150. {
  151. if (temp == q)
  152. {
  153. qs = q.newQuestState(player);
  154. break;
  155. }
  156. }
  157. }
  158. }
  159. }
  160. else
  161. content = Quest.getNoQuestMsg(player); // no quests found
  162. if (qs != null)
  163. {
  164. // If the quest is alreday started, no need to show a window
  165. if (!qs.getQuest().notifyTalk(npc, qs))
  166. return;
  167. questId = qs.getQuest().getName();
  168. String stateId = State.getStateName(qs.getState());
  169. String path = "data/scripts/quests/" + questId + "/" + stateId + ".htm";
  170. content = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), path); //TODO path for quests html
  171. if (Config.DEBUG)
  172. {
  173. if (content != null)
  174. {
  175. _log.fine("Showing quest window for quest " + questId + " html path: " + path);
  176. }
  177. else
  178. {
  179. _log.fine("File not exists for quest " + questId + " html path: " + path);
  180. }
  181. }
  182. }
  183. // Send a Server->Client packet NpcHtmlMessage to the L2PcInstance in order to display the message of the L2NpcInstance
  184. if (content != null)
  185. npc.insertObjectIdAndShowChatWindow(player, content);
  186. // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
  187. player.sendPacket(ActionFailed.STATIC_PACKET);
  188. }
  189. /**
  190. * Collect awaiting quests/start points and display a QuestChooseWindow (if several available) or QuestWindow.
  191. * @param player the L2PcInstance that talk with the {@code npc}.
  192. * @param npc the L2NpcInstance that chats with the {@code player}.
  193. */
  194. public static void showQuestWindow(L2PcInstance player, L2Npc npc)
  195. {
  196. // collect awaiting quests and start points
  197. List<Quest> options = new FastList<Quest>();
  198. QuestState[] awaits = player.getQuestsForTalk(npc.getTemplate().npcId);
  199. Quest[] starts = npc.getTemplate().getEventQuests(Quest.QuestEventType.QUEST_START);
  200. // Quests are limited between 1 and 999 because those are the quests that are supported by the client.
  201. // By limiting them there, we are allowed to create custom quests at higher IDs without interfering
  202. if (awaits != null)
  203. {
  204. for (QuestState x : awaits)
  205. {
  206. if (!options.contains(x.getQuest()))
  207. if ((x.getQuest().getQuestIntId() > 0) && (x.getQuest().getQuestIntId() < 20000))
  208. options.add(x.getQuest());
  209. }
  210. }
  211. if (starts != null)
  212. {
  213. for (Quest x : starts)
  214. {
  215. if (!options.contains(x))
  216. if ((x.getQuestIntId() > 0) && (x.getQuestIntId() < 20000))
  217. options.add(x);
  218. }
  219. }
  220. // Display a QuestChooseWindow (if several quests are available) or QuestWindow
  221. if (options.size() > 1)
  222. {
  223. showQuestChooseWindow(player, npc, options.toArray(new Quest[options.size()]));
  224. }
  225. else if (options.size() == 1)
  226. {
  227. showQuestWindow(player, npc, options.get(0).getName());
  228. }
  229. else
  230. {
  231. showQuestWindow(player, npc, "");
  232. }
  233. }
  234. public String[] getBypassList()
  235. {
  236. return COMMANDS;
  237. }
  238. }