/* OrpheusMS: MapleStory Private Server based on OdinMS Copyright (C) 2012 Aaron Weiss <aaron@deviant-core.net> Patrick Huy <patrick.huy@frz.cc> Matthias Butz <matze@odinms.de> Jan Christian Meyer <vimes@odinms.de> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package server.quest; import java.util.Calendar; import client.IItem; import client.MapleCharacter; import client.MapleInventoryType; import client.MapleJob; import client.MaplePet; import client.MapleQuestStatus; import java.util.ArrayList; import java.util.Collections; import java.util.List; import provider.MapleData; import provider.MapleDataTool; import server.MapleItemInformationProvider; /** * * @author Matze */ public class MapleQuestRequirement { private MapleQuestRequirementType type; private MapleData data; private MapleQuest quest; public MapleQuestRequirement(MapleQuest quest, MapleQuestRequirementType type, MapleData data) { this.type = type; this.data = data; this.quest = quest; } boolean check(MapleCharacter c, Integer npcid) { switch (getType()) { case END_DATE: String timeStr = MapleDataTool.getString(getData()); Calendar cal = Calendar.getInstance(); cal.set(Integer.parseInt(timeStr.substring(0, 4)), Integer.parseInt(timeStr.substring(4, 6)), Integer.parseInt(timeStr.substring(6, 8)), Integer.parseInt(timeStr.substring(8, 10)), 0); return cal.getTimeInMillis() >= System.currentTimeMillis(); case FIELD_ENTER: MapleData zeroField = getData().getChildByPath("0"); if (zeroField != null) { return MapleDataTool.getInt(zeroField) == c.getMapId(); } return false; case INTERVAL: return !c.getQuest(quest).getStatus().equals(MapleQuestStatus.Status.COMPLETED) || c.getQuest(quest).getCompletionTime() <= System.currentTimeMillis() - MapleDataTool.getInt(getData()) * 60 * 1000; case ITEM: MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); for (MapleData itemEntry : getData().getChildren()) { int itemId = MapleDataTool.getInt(itemEntry.getChildByPath("id")); short quantity = 0; MapleInventoryType iType = ii.getInventoryType(itemId); for (IItem item : c.getInventory(iType).listById(itemId)) quantity += item.getQuantity(); // Weird stuff, nexon made some quests only available when // wearing gm clothes. This enables us to accept it >< if (iType.equals(MapleInventoryType.EQUIP)) for (IItem item : c.getInventory(MapleInventoryType.EQUIPPED).listById(itemId)) quantity += item.getQuantity(); if (itemEntry.getChildByPath("count") != null) { if (quantity < MapleDataTool.getInt(itemEntry.getChildByPath("count"), 0) || MapleDataTool.getInt(itemEntry.getChildByPath("count"), 0) <= 0 && quantity > 0) { return false; } } else { if (quantity != 0) return false; } } return true; case JOB: for (MapleData jobEntry : getData().getChildren()) { if (c.getJob().equals(MapleJob.getById(MapleDataTool.getInt(jobEntry))) || c.isGM()) { return true; } } return false; case QUEST: for (MapleData questEntry : getData().getChildren()) { MapleQuestStatus q = c.getQuest(MapleQuest.getInstance(MapleDataTool.getInt(questEntry.getChildByPath("id")))); if (q == null && MapleQuestStatus.Status.getById(MapleDataTool.getInt(questEntry.getChildByPath("state"))).equals(MapleQuestStatus.Status.NOT_STARTED)) { continue; } if (q == null || !q.getStatus().equals(MapleQuestStatus.Status.getById(MapleDataTool.getInt(questEntry.getChildByPath("state"))))) { return false; } } return true; case MAX_LEVEL: return c.getLevel() <= MapleDataTool.getInt(getData()); case MIN_LEVEL: return c.getLevel() >= MapleDataTool.getInt(getData()); case MIN_PET_TAMENESS: MaplePet pet = c.getPet(0); if (pet == null) return false; return c.getPet(0).getCloseness() >= MapleDataTool.getInt(getData()); case MOB: for (MapleData mobEntry : getData().getChildren()) { int mobId = MapleDataTool.getInt(mobEntry.getChildByPath("id")); int killReq = MapleDataTool.getInt(mobEntry.getChildByPath("count")); if (Integer.parseInt(c.getQuest(quest).getProgress(mobId)) < killReq) { return false; } } return true; case MONSTER_BOOK: return c.getMonsterBook().getTotalCards() >= MapleDataTool.getInt(getData()); case NPC: return npcid == null || npcid == MapleDataTool.getInt(getData()); case INFO_EX: return c.getQuest(quest).getMedalProgress() >= quest.getInfoEx(); case COMPLETED_QUEST: return c.getCompletedQuests().size() >= MapleDataTool.getInt(getData()); default: return true; } } public MapleQuestRequirementType getType() { return type; } private MapleData getData() { return data; } public List<Integer> getQuestItemsToShowOnlyIfQuestIsActivated() { if (type != MapleQuestRequirementType.ITEM) { return null; } MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance(); List<Integer> delta = new ArrayList<Integer>(); for (MapleData itemEntry : getData().getChildren()) { int itemId = MapleDataTool.getInt(itemEntry.getChildByPath("id")); if (ii.isQuestItem(itemId)) { delta.add(itemId); } } return Collections.unmodifiableList(delta); } }