MapleQuestAction.java
上传用户:gwt600
上传日期:2021-06-03
资源大小:704k
文件大小:11k
源码类别:

游戏

开发平台:

Java

  1. /*
  2. This file is part of the OdinMS Maple Story Server
  3. Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
  4. Matthias Butz <matze@odinms.de>
  5. Jan Christian Meyer <vimes@odinms.de>
  6. This program is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU Affero General Public License version 3
  8. as published by the Free Software Foundation. You may not use, modify
  9. or distribute this program under any other version of the
  10. GNU Affero General Public License.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU Affero General Public License for more details.
  15. You should have received a copy of the GNU Affero General Public License
  16. along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18. /*
  19.  * MapleQuestAction.java
  20.  *
  21.  * Created on 11. Dezember 2007, 23:04
  22.  */
  23. package net.sf.odinms.server.quest;
  24. import java.util.HashMap;
  25. import java.util.Map;
  26. import java.util.Random;
  27. import net.sf.odinms.client.ISkill;
  28. import net.sf.odinms.client.InventoryException;
  29. import net.sf.odinms.client.MapleCharacter;
  30. import net.sf.odinms.client.MapleInventoryType;
  31. import net.sf.odinms.client.MapleJob;
  32. import net.sf.odinms.client.MapleQuestStatus;
  33. import net.sf.odinms.client.MapleStat;
  34. import net.sf.odinms.client.SkillFactory;
  35. import net.sf.odinms.client.messages.ServernoticeMapleClientMessageCallback;
  36. import net.sf.odinms.net.channel.ChannelServer;
  37. import net.sf.odinms.provider.MapleData;
  38. import net.sf.odinms.provider.MapleDataTool;
  39. import net.sf.odinms.server.MapleInventoryManipulator;
  40. import net.sf.odinms.server.MapleItemInformationProvider;
  41. import net.sf.odinms.tools.MaplePacketCreator;
  42. /**
  43.  *
  44.  * @author Matze
  45.  */
  46. public class MapleQuestAction {
  47.     private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MapleQuestAction.class);
  48.     private MapleQuestActionType type;
  49.     private MapleData data;
  50.     private MapleQuest quest;
  51.     /** Creates a new instance of MapleQuestAction */
  52.     public MapleQuestAction(MapleQuestActionType type, MapleData data, MapleQuest quest) {
  53.         this.type = type;
  54.         this.data = data;
  55.         this.quest = quest;
  56.     }
  57.     public boolean check(MapleCharacter c) {
  58.         switch (type) {
  59.             case MESO:
  60.                 int mesars = MapleDataTool.getInt(data);
  61.                 if (c.getMeso() + mesars < 0) {
  62.                     return false;
  63.                 }
  64.                 break;
  65.         }
  66.         return true;
  67.     }
  68.     private boolean canGetItem(MapleData item, MapleCharacter c) {
  69.         if (item.getChildByPath("gender") != null) {
  70.             int gender = MapleDataTool.getInt(item.getChildByPath("gender"));
  71.             if (gender != 2 && gender != c.getGender()) {
  72.                 return false;
  73.             }
  74.         }
  75.         if (item.getChildByPath("job") != null) {
  76.             int job = MapleDataTool.getInt(item.getChildByPath("job"));
  77.             if (job < 100) {
  78.                 // koreans suck.
  79.                 if (MapleJob.getBy5ByteEncoding(job).getId() / 100 != c.getJob().getId() / 100) {
  80.                     return false;
  81.                 }
  82.             } else {
  83.                 if (job != c.getJob().getId()) {
  84.                     return false;
  85.                 }
  86.             }
  87.         }
  88.         return true;
  89.     }
  90.     public void run(MapleCharacter c, Integer extSelection) {
  91.         MapleQuestStatus status;
  92.         ServernoticeMapleClientMessageCallback snmcmc = new ServernoticeMapleClientMessageCallback(5, c.getClient());
  93.         switch (type) {
  94.             case EXP:
  95.                 status = c.getQuest(quest);
  96.                 if (status.getStatus() == MapleQuestStatus.Status.NOT_STARTED && status.getForfeited() > 0) {
  97.                     break;
  98.                 }
  99.                 c.gainExp(MapleDataTool.getInt(data) * ChannelServer.getInstance(c.getClient().getChannel()).getExpRate(), true, true);
  100.                 break;
  101.             case ITEM:
  102.                 MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
  103.                 // first check for randomness in item selection
  104.                 Map<Integer, Integer> props = new HashMap<Integer, Integer>();
  105.                 for (MapleData iEntry : data.getChildren()) {
  106.                     if (iEntry.getChildByPath("prop") != null && MapleDataTool.getInt(iEntry.getChildByPath("prop")) != -1 && canGetItem(iEntry, c)) {
  107.                         for (int i = 0; i < MapleDataTool.getInt(iEntry.getChildByPath("prop")); i++) {
  108.                             props.put(props.size(), MapleDataTool.getInt(iEntry.getChildByPath("id")));
  109.                         }
  110.                     }
  111.                 }
  112.                 int selection = 0;
  113.                 int extNum = 0;
  114.                 if (props.size() > 0) {
  115.                     Random r = new Random();
  116.                     selection = props.get(r.nextInt(props.size()));
  117.                 }
  118.                 for (MapleData iEntry : data.getChildren()) {
  119.                     if (!canGetItem(iEntry, c)) {
  120.                         continue;
  121.                     }
  122.                     if (iEntry.getChildByPath("prop") != null) {
  123.                         if (MapleDataTool.getInt(iEntry.getChildByPath("prop")) == -1) {
  124.                             if (extSelection != extNum++) {
  125.                                 continue;
  126.                             }
  127.                         } else if (MapleDataTool.getInt(iEntry.getChildByPath("id")) != selection) {
  128.                             continue;
  129.                         }
  130.                     }
  131.                     if (MapleDataTool.getInt(iEntry.getChildByPath("count")) < 0) { // remove items
  132.                         int itemId = MapleDataTool.getInt(iEntry.getChildByPath("id"));
  133.                         MapleInventoryType iType = ii.getInventoryType(itemId);
  134.                         short quantity = (short) (MapleDataTool.getInt(iEntry.getChildByPath("count")) * -1);
  135.                         try {
  136.                             MapleInventoryManipulator.removeById(c.getClient(), iType, itemId, quantity, true, false);
  137.                         } catch (InventoryException ie) {
  138.                             // it's better to catch this here so we'll atleast try to remove the other items
  139.                             log.warn("[h4x] Completing a quest without meeting the requirements", ie);
  140.                         }
  141.                         c.getClient().getSession().write(MaplePacketCreator.getShowItemGain(itemId, (short) MapleDataTool.getInt(iEntry.getChildByPath("count")), true));
  142.                     } else { // add items
  143.                         int itemId = MapleDataTool.getInt(iEntry.getChildByPath("id"));
  144.                         short quantity = (short) MapleDataTool.getInt(iEntry.getChildByPath("count"));
  145.                         MapleInventoryManipulator.addById(c.getClient(), itemId, quantity, null, -1);
  146.                         c.getClient().getSession().write(MaplePacketCreator.getShowItemGain(itemId, quantity, true));
  147.                     }
  148.                 }
  149.                 break;
  150. // case NEXTQUEST:
  151. // int nextquest = MapleDataTool.getInt(data);
  152. // Need to somehow make the chat popup for the next quest...
  153. // break;
  154.             case MESO:
  155.                 status = c.getQuest(quest);
  156.                 if (status.getStatus() == MapleQuestStatus.Status.NOT_STARTED && status.getForfeited() > 0) {
  157.                     break;
  158.                 }
  159.                 c.gainMeso(MapleDataTool.getInt(data), true, false, true);
  160.                 break;
  161.             case QUEST:
  162.                 for (MapleData qEntry : data) {
  163.                     int questid = MapleDataTool.getInt(qEntry.getChildByPath("id"));
  164.                     int stat = MapleDataTool.getInt(qEntry.getChildByPath("state"));
  165.                     c.updateQuest(new MapleQuestStatus(MapleQuest.getInstance(questid), MapleQuestStatus.Status.getById(stat)));
  166.                 }
  167.                 break;
  168.             case SKILL:
  169.                 //TODO needs gain/lost message?
  170.                 for (MapleData sEntry : data) {
  171.                     int skillid = MapleDataTool.getInt(sEntry.getChildByPath("id"));
  172.                     int skillLevel = MapleDataTool.getInt(sEntry.getChildByPath("skillLevel"));
  173.                     int masterLevel = MapleDataTool.getInt(sEntry.getChildByPath("masterLevel"));
  174.                     ISkill skillObject = SkillFactory.getSkill(skillid);
  175.                     boolean shouldLearn = false;
  176.                     MapleData applicableJobs = sEntry.getChildByPath("job");
  177.                     for (MapleData applicableJob : applicableJobs) {
  178.                         MapleJob job = MapleJob.getById(MapleDataTool.getInt(applicableJob));
  179.                         if (c.getJob() == job) {
  180.                             shouldLearn = true;
  181.                             break;
  182.                         }
  183.                     }
  184.                     if (skillObject.isBeginnerSkill()) {
  185.                         shouldLearn = true;
  186.                     }
  187.                     skillLevel = Math.max(skillLevel, c.getSkillLevel(skillObject));
  188.                     masterLevel = Math.max(masterLevel, c.getMasterLevel(skillObject));
  189.                     if (shouldLearn) {
  190.                         c.changeSkillLevel(skillObject, skillLevel, masterLevel);
  191.                         snmcmc.dropMessage("You have learned " + SkillFactory.getSkillName(skillid) + " with level " + skillLevel + " and with max level " + masterLevel);
  192.                     }
  193.                 }
  194.                 break;
  195.             case FAME:
  196.                 status = c.getQuest(quest);
  197.                 if (status.getStatus() == MapleQuestStatus.Status.NOT_STARTED && status.getForfeited() > 0) {
  198.                     break;
  199.                 }
  200.                 c.addFame(MapleDataTool.getInt(data));
  201.                 c.updateSingleStat(MapleStat.FAME, c.getFame());
  202.                 int fameGain = MapleDataTool.getInt(data);
  203.                 c.getClient().getSession().write(MaplePacketCreator.getShowFameGain(fameGain));
  204.                 break;
  205.             case BUFF:
  206.                 status = c.getQuest(quest);
  207.                 if (status.getStatus() == MapleQuestStatus.Status.NOT_STARTED && status.getForfeited() > 0) {
  208.                     break;
  209.                 }
  210.                 MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
  211.                 mii.getItemEffect(MapleDataTool.getInt(data)).applyTo(c);
  212.                 break;
  213.             default:
  214.         }
  215.     }
  216.     public MapleQuestActionType getType() {
  217.         return type;
  218.     }
  219.     @Override
  220.     public String toString() {
  221.         return type + ": " + data;
  222.     }
  223. }