/* * To change this template, choose Tools | Templates and open the template in * the editor. */ package javastory.game.quest; import java.util.List; import java.util.Map; import javastory.channel.ChannelCharacter; import javastory.scripting.NpcScriptManager; import javastory.tools.packets.ChannelPackets; import javastory.wz.WzData; import javastory.wz.WzDataProvider; import javastory.wz.WzDataProviderFactory; import javastory.wz.WzDataTool; import com.google.common.collect.Lists; import com.google.common.collect.Maps; /** * * @author shoftee */ public final class QuestInfoProvider { private static Map<Integer, QuestInfo> QUESTS = Maps.newLinkedHashMap(); // private static final WzDataProvider questData = WzDataProviderFactory.getDataProvider("Quest.wz"); private static final WzData actions = questData.getData("Act.img"); private static final WzData requirements = questData.getData("Check.img"); private static final WzData info = questData.getData("QuestInfo.img"); private QuestInfoProvider() { } private static QuestInfo loadQuest(final int questId) { final QuestInfo quest = new QuestInfo(); quest.questId = questId; quest.relevantMobs = Maps.newLinkedHashMap(); // read reqs final WzData questRequirements = requirements.getChildByPath(String.valueOf(questId)); final WzData questActions = actions.getChildByPath(String.valueOf(questId)); if (questRequirements == null || questActions == null) { return null; } //------------------------------------------------- final WzData startReqData = questRequirements.getChildByPath("0"); quest.startRequirements = Lists.newLinkedList(); if (startReqData != null) { for (final WzData startReq : startReqData.getChildren()) { final QuestRequirementType type = QuestRequirementType.getByWZName(startReq.getName()); if (type.equals(QuestRequirementType.INTERVAL)) { quest.repeatable = true; } final QuestRequirement req = new QuestRequirement(quest.questId, type, startReq); if (req.getType().equals(QuestRequirementType.MONSTER)) { for (final WzData mob : startReq.getChildren()) { quest.relevantMobs.put(WzDataTool.getInt(mob.getChildByPath("id")), WzDataTool.getInt(mob.getChildByPath("count"), 0)); } } quest.startRequirements.add(req); } } //------------------------------------------------- final WzData completeReqData = questRequirements.getChildByPath("1"); if (completeReqData != null) { if (completeReqData.getChildByPath("endscript") != null) { quest.customend = true; } quest.completionRequirements = Lists.newLinkedList(); for (final WzData completeReq : completeReqData.getChildren()) { final QuestRequirement req = new QuestRequirement(quest.questId, QuestRequirementType.getByWZName(completeReq.getName()), completeReq); if (req.getType().equals(QuestRequirementType.MONSTER)) { for (final WzData mob : completeReq.getChildren()) { quest.relevantMobs.put(WzDataTool.getInt(mob.getChildByPath("id")), WzDataTool.getInt(mob.getChildByPath("count"), 0)); } } quest.completionRequirements.add(req); } } // read acts final WzData startActionData = questActions.getChildByPath("0"); quest.startActions = Lists.newLinkedList(); if (startActionData != null) { for (final WzData startAct : startActionData.getChildren()) { final QuestAction action = new QuestAction(quest.questId, QuestActionType.getByWZName(startAct.getName()), startAct); quest.startActions.add(action); } } final WzData completeActionData = questActions.getChildByPath("1"); quest.completionActions = Lists.newLinkedList(); if (completeActionData != null) { for (final WzData completeAct : completeActionData.getChildren()) { final QuestAction action = new QuestAction(quest.questId, QuestActionType.getByWZName(completeAct.getName()), completeAct); quest.completionActions.add(action); } } final WzData questInfo = info.getChildByPath(String.valueOf(questId)); quest.autoStart = WzDataTool.getInt("autoStart", questInfo, 0) == 1; quest.autoPreComplete = WzDataTool.getInt("autoPreComplete", questInfo, 0) == 1; return quest; } public static QuestInfo getInfo(final int questId) { QuestInfo quest = QUESTS.get(questId); if (quest == null) { quest = loadQuest(questId); if (quest == null) { return null; } QUESTS.put(questId, quest); } return quest; } public static class QuestInfo { // private int questId; private List<QuestRequirement> startRequirements; private List<QuestRequirement> completionRequirements; private List<QuestAction> startActions; private List<QuestAction> completionActions; // private boolean autoStart; private boolean autoPreComplete; private boolean repeatable = false, customend = false; private Map<Integer, Integer> relevantMobs; private QuestInfo() { } public boolean canStart(final ChannelCharacter c, final Integer npcId) { final QuestStatus status = c.getQuestStatus(this.questId); final boolean isActive = status.getState() == 0; final boolean canRepeat = status.getState() == 2 && this.repeatable; if (isActive || !canRepeat) { return false; } for (final QuestRequirement requirement : this.startRequirements) { if (!requirement.check(c, npcId)) { return false; } } return true; } public boolean canComplete(final ChannelCharacter c, final Integer npcId) { final QuestStatus status = c.getQuestStatus(this.questId); if (status == null || status.getState() != 1) { return false; } for (final QuestRequirement requirement : this.completionRequirements) { if (!requirement.check(c, npcId)) { return false; } } return true; } public void restoreLostItems(final ChannelCharacter c, final int itemId) { for (final QuestAction action : this.startActions) { if (action.restoreLostItem(c, itemId)) { break; } } } public Map<Integer, Integer> getRelevantMobs() { return this.relevantMobs; } public void start(final ChannelCharacter c, final int npcId) { if ((this.autoStart || this.checkNpcOnMap(c, npcId)) && this.canStart(c, npcId)) { for (final QuestAction a : this.startActions) { a.runStart(c, null); } if (!this.customend) { c.startQuest(this.questId, npcId); } else { NpcScriptManager.getInstance().endQuest(c.getClient(), npcId, this.questId, true); } } } public void forfeit(final ChannelCharacter c) { final QuestStatus status = c.getQuestStatus(this.questId); if (status.getState() != 1) { return; } c.forfeitQuest(this.questId); } public void complete(final ChannelCharacter c, final int npcId) { this.complete(c, npcId, null); } public void complete(final ChannelCharacter c, final int npcId, final Integer selection) { if ((this.autoPreComplete || this.checkNpcOnMap(c, npcId)) && this.canComplete(c, npcId)) { for (final QuestAction a : this.completionActions) { if (!a.checkEnd(c, selection)) { return; } } for (final QuestAction a : this.completionActions) { a.runEnd(c, selection); } c.completeQuest(this.questId, npcId); // Quest completion c.getClient().write(ChannelPackets.showSpecialEffect(9)); c.getMap().broadcastMessage(c, ChannelPackets.showSpecialEffect(c.getId(), 9), false); } } private boolean checkNpcOnMap(final ChannelCharacter player, final int npcid) { return player.getMap().containsNPC(npcid) != -1; } } }