package server; import client.MapleBuffStat; import client.MapleCharacter; import client.MapleCoolDownValueHolder; import client.MapleDisease; import client.MapleStat; import client.PlayerStats; import client.Skill; import client.SkillFactory; import client.inventory.Item; import client.inventory.MapleInventory; import client.inventory.MapleInventoryType; import client.status.MonsterStatus; import client.status.MonsterStatusEffect; import constants.GameConstants; import constants.ItemConstants; import constants.SkillConstants; import handling.channel.ChannelServer; import handling.world.party.MaplePartyCharacter; import java.awt.Point; import java.awt.Rectangle; import java.io.Serializable; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.EnumMap; import java.util.List; import java.util.Map; import java.util.concurrent.ScheduledFuture; import org.apache.log4j.Logger; import provider.MapleData; import provider.MapleDataTool; import provider.wz.MapleDataType; import server.life.MapleMonster; import server.maps.MapleDefender; import server.maps.MapleDoor; import server.maps.MapleExtractor; import server.maps.MapleMap; import server.maps.MapleMapObject; import server.maps.MapleMapObjectType; import server.maps.MapleSummon; import server.maps.SummonMovementType; import server.skill.冒险家.*; import tools.FileoutputUtil; import tools.MaplePacketCreator; import tools.Pair; import tools.Triple; import tools.packet.BuffPacket; import tools.packet.SkillPacket; public class MapleStatEffect implements Serializable { private static final long serialVersionUID = 9179541993413738569L; private static final Logger log = Logger.getLogger(MapleStatEffect.class); public Map<MapleStatInfo, Integer> info; private boolean overTime; private boolean skill; private boolean partyBuff; private boolean notRemoved; public ArrayList<Pair<MapleBuffStat, Integer>> statups; private ArrayList<Pair<Integer, Integer>> availableMap; private EnumMap<MonsterStatus, Integer> monsterStatus; private Point lt; private Point rb; private byte level; private List<MapleDisease> cureDebuffs; private List<Integer> petsCanConsume; private List<Integer> familiars; private List<Integer> randomPickup; private List<Triple<Integer, Integer, Integer>> rewardItem; private byte slotCount; private byte slotPerLine; private byte expR; private byte familiarTarget; private byte recipeUseCount; private byte recipeValidDay; private byte reqSkillLevel; private byte effectedOnAlly; private byte effectedOnEnemy; private byte type; private byte preventslip; private byte immortal; private byte bs; private short ignoreMob; private short mesoR; private short thaw; private short fatigueChange; private short lifeId; private short imhp; private short immp; private short inflation; private short useLevel; private short indiePdd; private short indieMdd; private short incPVPdamage; private short mobSkill; private short mobSkillLevel; private double hpR; private double mpR; private int sourceid; private int recipe; private int moveTo; private int moneyCon; private int morphId; private int expinc; private int exp; private int consumeOnPickup; private int charColor; private int interval; private int rewardMeso; private int totalprob; private int cosmetic; private int expBuff; private int itemup; private int mesoup; private int cashup; private int berserk; private int illusion; private int booster; private int berserk2; private int cp; private int nuffSkill; public boolean isfirst = true; public int times = 0; public int bufftime = 0; public MapleStatEffect() { this.partyBuff = true; this.morphId = 0; } public static MapleStatEffect loadSkillEffectFromData(MapleData source, int skillid, boolean overtime, int level, String variables, boolean notRemoved) { return loadFromData(source, skillid, true, overtime, level, variables, notRemoved); } public static MapleStatEffect loadItemEffectFromData(MapleData source, int itemid) { return loadFromData(source, itemid, false, false, 1, null, false); } private static void addBuffStatPairToListIfNotZero(List<Pair<MapleBuffStat, Integer>> list, MapleBuffStat buffstat, Integer val) { if (val != 0) { list.add(new Pair(buffstat, val)); } } private static int parseEval(String path, MapleData source, int def, String variables, int level) { if (variables == null) { return MapleDataTool.getIntConvert(path, source, def); } MapleData dd = source.getChildByPath(path); if (dd == null) { return def; } if (dd.getType() != MapleDataType.STRING) { return MapleDataTool.getIntConvert(path, source, def); } FileoutputUtil.log("到这里就囧了!"); return 0; /* String dddd = MapleDataTool.getString(dd).replace(variables, String.valueOf(level)); switch (dddd.substring(0, 1)) { case "-": if ((dddd.substring(1, 2).equals("u")) || (dddd.substring(1, 2).equals("d"))) { dddd = "n(" + dddd.substring(1, dddd.length()) + ")"; } else { dddd = "n" + dddd.substring(1, dddd.length()); } break; case "=": dddd = dddd.substring(1, dddd.length()); break; } if (dddd.contains("y")) { // FileoutputUtil.log(dddd); dddd = dddd.replaceAll("y", "0"); } int result = (int) new CaltechEval(dddd).evaluate(); return result; */ } // 读入技能等级信息 private static MapleStatEffect loadFromData(MapleData source, int sourceid, boolean skill, boolean overTime, int level, String variables, boolean notRemoved) { MapleStatEffect ret = new MapleStatEffect(); ret.sourceid = sourceid; ret.skill = skill; ret.level = (byte) level; if (source == null) { return ret; } ret.info = new EnumMap(MapleStatInfo.class); // 这里效率有点低 for (MapleStatInfo i : MapleStatInfo.values()) { if (i.isSpecial()) { ret.info.put(i, parseEval(i.name().substring(0, i.name().length() - 1), source, i.getDefault(), variables, level)); } else { ret.info.put(i, parseEval(i.name(), source, i.getDefault(), variables, level)); } } ret.hpR = (parseEval("hpR", source, 0, variables, level) / 100.0D); ret.mpR = (parseEval("mpR", source, 0, variables, level) / 100.0D); ret.ignoreMob = (short) parseEval("ignoreMobpdpR", source, 0, variables, level); ret.thaw = (short) parseEval("thaw", source, 0, variables, level); ret.interval = parseEval("interval", source, 0, variables, level); ret.expinc = parseEval("expinc", source, 0, variables, level); ret.exp = parseEval("exp", source, 0, variables, level); ret.morphId = parseEval("morph", source, 0, variables, level); ret.cp = parseEval("cp", source, 0, variables, level); ret.cosmetic = parseEval("cosmetic", source, 0, variables, level); ret.slotCount = (byte) parseEval("slotCount", source, 0, variables, level); ret.slotPerLine = (byte) parseEval("slotPerLine", source, 0, variables, level); ret.preventslip = (byte) parseEval("preventslip", source, 0, variables, level); ret.useLevel = (short) parseEval("useLevel", source, 0, variables, level); ret.nuffSkill = parseEval("nuffSkill", source, 0, variables, level); ret.familiarTarget = (byte) (parseEval("familiarPassiveSkillTarget", source, 0, variables, level) + 1); ret.immortal = (byte) parseEval("immortal", source, 0, variables, level); ret.type = (byte) parseEval("type", source, 0, variables, level); ret.bs = (byte) parseEval("bs", source, 0, variables, level); ret.indiePdd = (short) parseEval("indiePdd", source, 0, variables, level); ret.indieMdd = (short) parseEval("indieMdd", source, 0, variables, level); ret.expBuff = parseEval("expBuff", source, 0, variables, level); ret.cashup = parseEval("cashBuff", source, 0, variables, level); ret.itemup = parseEval("itemupbyitem", source, 0, variables, level); ret.mesoup = parseEval("mesoupbyitem", source, 0, variables, level); ret.berserk = parseEval("berserk", source, 0, variables, level); ret.berserk2 = parseEval("berserk2", source, 0, variables, level); ret.booster = parseEval("booster", source, 0, variables, level); ret.lifeId = (short) parseEval("lifeId", source, 0, variables, level); ret.inflation = (short) parseEval("inflation", source, 0, variables, level); ret.imhp = (short) parseEval("imhp", source, 0, variables, level); ret.immp = (short) parseEval("immp", source, 0, variables, level); ret.illusion = parseEval("illusion", source, 0, variables, level); ret.consumeOnPickup = parseEval("consumeOnPickup", source, 0, variables, level); if ((ret.consumeOnPickup == 1) && (parseEval("party", source, 0, variables, level) > 0)) { ret.consumeOnPickup = 2; } ret.recipe = parseEval("recipe", source, 0, variables, level); ret.recipeUseCount = (byte) parseEval("recipeUseCount", source, 0, variables, level); ret.recipeValidDay = (byte) parseEval("recipeValidDay", source, 0, variables, level); ret.reqSkillLevel = (byte) parseEval("reqSkillLevel", source, 0, variables, level); ret.effectedOnAlly = (byte) parseEval("effectedOnAlly", source, 0, variables, level); ret.effectedOnEnemy = (byte) parseEval("effectedOnEnemy", source, 0, variables, level); ret.incPVPdamage = (short) parseEval("incPVPDamage", source, 0, variables, level); ret.moneyCon = parseEval("moneyCon", source, 0, variables, level); ret.moveTo = parseEval("moveTo", source, -1, variables, level); ret.charColor = 0; String cColor = MapleDataTool.getString("charColor", source, null); if (cColor != null) { ret.charColor |= Integer.parseInt("0x" + cColor.substring(0, 2)); ret.charColor |= Integer.parseInt("0x" + cColor.substring(2, 4) + "00"); ret.charColor |= Integer.parseInt("0x" + cColor.substring(4, 6) + "0000"); ret.charColor |= Integer.parseInt("0x" + cColor.substring(6, 8) + "000000"); } List cure = new ArrayList(5); if (parseEval("poison", source, 0, variables, level) > 0) { cure.add(MapleDisease.中毒); } if (parseEval("seal", source, 0, variables, level) > 0) { cure.add(MapleDisease.封印); } if (parseEval("darkness", source, 0, variables, level) > 0) { cure.add(MapleDisease.黑暗); } if (parseEval("weakness", source, 0, variables, level) > 0) { cure.add(MapleDisease.虚弱); } if (parseEval("curse", source, 0, variables, level) > 0) { cure.add(MapleDisease.诅咒); } ret.cureDebuffs = cure; ret.petsCanConsume = new ArrayList(); for (int i = 0;; i++) { int dd = parseEval(String.valueOf(i), source, 0, variables, level); if (dd <= 0) { break; } ret.petsCanConsume.add(dd); } MapleData mdd = source.getChildByPath("0"); if ((mdd != null) && (mdd.getChildren().size() > 0)) { ret.mobSkill = (short) parseEval("mobSkill", mdd, 0, variables, level); ret.mobSkillLevel = (short) parseEval("level", mdd, 0, variables, level); } else { ret.mobSkill = 0; ret.mobSkillLevel = 0; } MapleData pd = source.getChildByPath("randomPickup"); if (pd != null) { ret.randomPickup = new ArrayList(); for (MapleData p : pd) { ret.randomPickup.add(MapleDataTool.getInt(p)); } } MapleData ltd = source.getChildByPath("lt"); if (ltd != null) { ret.lt = ((Point) ltd.getData()); ret.rb = ((Point) source.getChildByPath("rb").getData()); } MapleData ltc = source.getChildByPath("con"); if (ltc != null) { ret.availableMap = new ArrayList(); for (MapleData ltb : ltc) { ret.availableMap.add(new Pair(MapleDataTool.getInt("sMap", ltb, 0), MapleDataTool.getInt("eMap", ltb, 999999999))); } } MapleData ltb = source.getChildByPath("familiar"); if (ltb != null) { ret.fatigueChange = (short) (parseEval("incFatigue", ltb, 0, variables, level) - parseEval("decFatigue", ltb, 0, variables, level)); ret.familiarTarget = (byte) parseEval("target", ltb, 0, variables, level); MapleData lta = ltb.getChildByPath("targetList"); if (lta != null) { ret.familiars = new ArrayList(); for (MapleData ltz : lta) { ret.familiars.add(MapleDataTool.getInt(ltz, 0)); } } } else { ret.fatigueChange = 0; } int totalprob = 0; MapleData lta = source.getChildByPath("reward"); if (lta != null) { ret.rewardMeso = parseEval("meso", lta, 0, variables, level); MapleData ltz = lta.getChildByPath("case"); if (ltz != null) { ret.rewardItem = new ArrayList(); for (MapleData lty : ltz) { ret.rewardItem.add(new Triple(MapleDataTool.getInt("id", lty, 0), MapleDataTool.getInt("count", lty, 0), MapleDataTool.getInt("prop", lty, 0))); totalprob += MapleDataTool.getInt("prob", lty, 0); } } } else { ret.rewardMeso = 0; } ret.totalprob = totalprob; if (ret.skill) { int priceUnit = (ret.info.get(MapleStatInfo.priceUnit)); if (priceUnit > 0) { int price = (ret.info.get(MapleStatInfo.price)); int extendPrice = (ret.info.get(MapleStatInfo.extendPrice)); ret.info.put(MapleStatInfo.price, price * priceUnit); ret.info.put(MapleStatInfo.extendPrice, extendPrice * priceUnit); } switch (sourceid) { case 1100002: case 1120013: case 1200002: case 1300002: case 2111007: case 2211007: case 2311007: case 3100001: case 3120008: case 3200001: ret.info.put(MapleStatInfo.mobCount, Integer.valueOf(6)); break; } if (GameConstants.isNoDelaySkill(sourceid)) { ret.info.put(MapleStatInfo.mobCount, 6); } } if ((!ret.skill) && ((ret.info.get(MapleStatInfo.time)) > -1)) { ret.overTime = true; } else { ret.info.put(MapleStatInfo.time, (ret.info.get(MapleStatInfo.time)) * 1000); ret.info.put(MapleStatInfo.subTime, (ret.info.get(MapleStatInfo.subTime)) * 1000); ret.overTime = overTime || ret.isMorph() || ret.getSummonMovementType() != null || ret.is带BUFF技能(); ret.notRemoved = notRemoved; } ret.monsterStatus = new EnumMap(MonsterStatus.class); ret.statups = new ArrayList(); if (ret.overTime && ret.getSummonMovementType() == null) { addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.物理攻击力, ret.info.get(MapleStatInfo.pad)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.增加物理防御, ret.info.get(MapleStatInfo.pdd)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.魔法攻击力, ret.info.get(MapleStatInfo.mad)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.魔法防御力, ret.info.get(MapleStatInfo.mdd)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.命中率, ret.info.get(MapleStatInfo.acc)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.回避率, ret.info.get(MapleStatInfo.eva)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.移动速度, ret.info.get(MapleStatInfo.speed)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.跳跃力, ret.info.get(MapleStatInfo.jump)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.神圣之火_最大体力百分比, ret.info.get(MapleStatInfo.mhpR)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.神圣之火_最大魔力百分比, ret.info.get(MapleStatInfo.mmpR)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.攻击加速, ret.booster); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.GIANT_POTION, Integer.valueOf(ret.inflation)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.魔法攻击力增加, ret.info.get(MapleStatInfo.indieMad)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.最大体力, Integer.valueOf(ret.imhp)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.最大魔力, Integer.valueOf(ret.immp)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.最大体力, ret.info.get(MapleStatInfo.indieMhp)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.最大魔力, ret.info.get(MapleStatInfo.indieMmp)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.命中值增加, ret.info.get(MapleStatInfo.indieAcc)); addBuffStatPairToListIfNotZero(ret.statups, MapleBuffStat.HP减少无效, ret.info.get(MapleStatInfo.thaw)); } if (ret.skill) { switch (sourceid) { // 战士 case 战士.圣甲术: case 魔法师.魔法铠甲: ret.statups.add(new Pair(MapleBuffStat.增加物理防御, ret.info.get(MapleStatInfo.pdd))); break; case 剑客.快速剑: case 剑客.快速斧: case 准骑士.快速剑: case 准骑士.快速钝器: case 枪战士.快速枪: case 枪战士.快速矛: case 猎人.快速箭: case 弩弓手.快速弩: case 刺客.快速暗器: case 侠客.快速短刀: ret.statups.add(new Pair(MapleBuffStat.攻击加速, ret.info.get(MapleStatInfo.x))); break; case 剑客.愤怒之火: ret.statups.add(new Pair(MapleBuffStat.攻击力增加, ret.info.get(MapleStatInfo.pad))); ret.statups.add(new Pair(MapleBuffStat.增加物理防御, ret.info.get(MapleStatInfo.pdd))); break; case 剑客.伤害反击: case 准骑士.伤害反击: ret.statups.add(new Pair(MapleBuffStat.伤害反击,ret.info.get(MapleStatInfo.x))); break; case 枪战士.极限防御: ret.statups.add(new Pair(MapleBuffStat.增加物理防御, ret.info.get(MapleStatInfo.pdd))); ret.statups.add(new Pair(MapleBuffStat.魔法防御力, ret.info.get(MapleStatInfo.mdd))); break; case 枪战士.神圣之火: ret.statups.add(new Pair(MapleBuffStat.神圣之火_最大体力百分比, ret.info.get(MapleStatInfo.x))); ret.statups.add(new Pair(MapleBuffStat.神圣之火_最大魔力百分比, ret.info.get(MapleStatInfo.y))); break; case 勇士.斗气集中: ret.statups.add(new Pair(MapleBuffStat.斗气集中, ret.info.get(MapleStatInfo.x))); break; case 勇士.黑暗之剑: case 勇士.黑暗之斧: ret.monsterStatus.put(MonsterStatus.恐慌, ret.info.get(MapleStatInfo.prop)); break; case 勇士.气绝剑: case 勇士.气绝斧: case 勇士.虎咆哮: case 骑士.属性攻击: ret.monsterStatus.put(MonsterStatus.眩晕, ret.info.get(MapleStatInfo.prop)); break; case 勇士.防御崩坏: ret.monsterStatus.put(MonsterStatus.物理防御无效, ret.info.get(MapleStatInfo.prop)); break; case 骑士.魔击无效: ret.monsterStatus.put(MonsterStatus.魔法防御无效, ret.info.get(MapleStatInfo.prop)); break; case 龙骑士.龙之魂: ret.statups.add(new Pair(MapleBuffStat.攻击力增加, ret.info.get(MapleStatInfo.pad))); break; // 法师 case 魔法师.魔法盾: ret.statups.add(new Pair(MapleBuffStat.魔法盾, ret.info.get(MapleStatInfo.x))); break; case 火毒魔法师.精神力: case 冰雷魔法师.精神力: ret.statups.add(new Pair(MapleBuffStat.魔法攻击力, ret.info.get(MapleStatInfo.mad))); break; case 火毒魔法师.缓速术: case 冰雷魔法师.缓速术: ret.monsterStatus.put(MonsterStatus.速度, ret.info.get(MapleStatInfo.x)); break; case 火毒魔法师.毒雾术: case 火毒巫师.火毒合击: ret.monsterStatus.put(MonsterStatus.中毒, ret.info.get(MapleStatInfo.mad)); break; case 牧师.神之保护: ret.statups.add(new Pair(MapleBuffStat.神之保护, ret.info.get(MapleStatInfo.x))); break; case 牧师.祝福: ret.statups.add(new Pair(MapleBuffStat.牧师祝福, (int) ret.level)); break; case 火毒巫师.魔力激化: case 冰雷巫师.魔力激化: ret.statups.add(new Pair(MapleBuffStat.魔法攻击力, ret.info.get(MapleStatInfo.y))); break; case 火毒巫师.致命毒雾: ret.monsterStatus.put(MonsterStatus.中毒, ret.info.get(MapleStatInfo.mad)); break; case 火毒巫师.封印术: case 冰雷巫师.封印术: ret.monsterStatus.put(MonsterStatus.封印, ret.info.get(MapleStatInfo.prop)); break; case 火毒巫师.魔法狂暴: case 冰雷巫师.魔法狂暴: ret.statups.add(new Pair(MapleBuffStat.攻击加速, ret.info.get(MapleStatInfo.x))); break; case 冰雷魔法师.冰冻术: case 冰雷巫师.冰咆哮: case 冰雷巫师.冰雷合击: ret.monsterStatus.put(MonsterStatus.结冰, 1); break; case 祭司.时空门: ret.statups.add(new Pair(MapleBuffStat.时空门, 1)); break; case 祭司.神圣祈祷: ret.statups.add(new Pair(MapleBuffStat.神圣祈祷, ret.info.get(MapleStatInfo.x))); break; case 祭司.巫毒术: ret.monsterStatus.put(MonsterStatus.速度, -20); ret.monsterStatus.put(MonsterStatus.物攻, 1); ret.monsterStatus.put(MonsterStatus.魔攻, 1); break; // 弓箭手 case 弓箭手.集中术: ret.statups.add(new Pair(MapleBuffStat.命中率,ret.info.get(MapleStatInfo.acc))); ret.statups.add(new Pair(MapleBuffStat.回避率,ret.info.get(MapleStatInfo.eva))); break; case 猎人.无形箭: case 弩弓手.无形箭: ret.statups.add(new Pair(MapleBuffStat.无形箭弩, ret.info.get(MapleStatInfo.x))); break; case 射手.疾风步: case 游侠.疾风步: ret.statups.add(new Pair(MapleBuffStat.移动速度,ret.info.get(MapleStatInfo.speed))); break; case 射手.替身术: case 游侠.替身术: ret.statups.add(new Pair(MapleBuffStat.替身,ret.info.get(MapleStatInfo.x))); break; case 射手.银鹰召唤: case 游侠.金鹰召唤: ret.monsterStatus.put(MonsterStatus.眩晕, 1); break; case 游侠.寒冰箭: ret.monsterStatus.put(MonsterStatus.结冰, 1); break; // 飞侠 case 飞侠.诅咒术: case 准骑士.压制术: ret.monsterStatus.put(MonsterStatus.物攻, ret.info.get(MapleStatInfo.x)); ret.monsterStatus.put(MonsterStatus.物防, ret.info.get(MapleStatInfo.y)); break; case 飞侠.隐身术: ret.statups.add(new Pair(MapleBuffStat.隐身术, ret.info.get(MapleStatInfo.x))); ret.statups.add(new Pair(MapleBuffStat.移动速度, ret.info.get(MapleStatInfo.speed))); break; case 刺客.轻功: case 侠客.轻功: ret.statups.add(new Pair(MapleBuffStat.移动速度, ret.info.get(MapleStatInfo.speed))); ret.statups.add(new Pair(MapleBuffStat.跳跃力, ret.info.get(MapleStatInfo.jump))); break; case 无影人.聚财术: case 独行客.敛财术: ret.statups.add(new Pair(MapleBuffStat.敛财术, ret.info.get(MapleStatInfo.x))); break; case 无影人.影分身: case 独行客.分身术: ret.statups.add(new Pair(MapleBuffStat.影分身, ret.info.get(MapleStatInfo.x))); break; case 无影人.影网术: ret.monsterStatus.put(MonsterStatus.影网, 1); break; case 独行客.落叶斩: ret.monsterStatus.put(MonsterStatus.眩晕, 1); break; case 独行客.金钱护盾: ret.statups.add(new Pair(MapleBuffStat.金钱护盾, ret.info.get(MapleStatInfo.x))); break; } } else { // 非skill switch (sourceid) { case 2022746: case 2022747: case 2022823: case 2023189: case 2023150: case 2023148: case 2023149: ret.statups.clear(); int value = sourceid == 2022823 ? 12 : sourceid == 2022747 ? 10 : sourceid == 2022746 ? 5 : sourceid == 2023189 ? 16 : sourceid == 2023150 ? 15 : sourceid == 2023148 ? 6 : sourceid == 20231489 ? 13 : 0; if (value <= 0) { break; } ret.statups.add(new Pair(MapleBuffStat.攻击力增加, value)); ret.statups.add(new Pair(MapleBuffStat.魔法攻击力增加, value)); if (sourceid == 2023150 || sourceid == 2023149 || sourceid == 2023148) { ret.statups.add(new Pair(MapleBuffStat.最大体力, sourceid == 2023150 ? 20 : sourceid == 2023149 ? 10 : 5)); ret.statups.add(new Pair(MapleBuffStat.最大魔力, sourceid == 2023150 ? 20 : sourceid == 2023149 ? 10 : 5)); } break; } } if (ret.isPoison()) { ret.monsterStatus.put(MonsterStatus.中毒, 1); } if (ret.getSummonMovementType() != null) { ret.statups.add(new Pair(MapleBuffStat.召唤兽, 1)); } ret.statups.trimToSize(); return ret; } public void applyPassive(MapleCharacter applyto, MapleMapObject obj) { if (makeChanceResult()) { switch (this.sourceid) { case 2100000: case 2200000: case 2300000: if ((obj == null) || (obj.getType() != MapleMapObjectType.MONSTER)) { return; } MapleMonster mob = (MapleMonster) obj; if (mob.getStats().isBoss()) { break; } int absorbMp = Math.min((int) (mob.getMobMaxMp() * (getX() / 100.0D)), mob.getMp()); if (absorbMp <= 0) { break; } mob.setMp(mob.getMp() - absorbMp); applyto.getStat().setMp(applyto.getStat().getMp() + absorbMp); applyto.getClient().getSession().write(MaplePacketCreator.showOwnBuffEffect(this.sourceid, 1, applyto.getLevel(), this.level)); applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.showBuffeffect(applyto, this.sourceid, 1, applyto.getLevel(), this.level), false); } } } public boolean applyTo(MapleCharacter chr) { return applyTo(chr, chr, true, null, getDuration(chr), false); } public boolean applyTo(MapleCharacter chr, boolean passive) { return applyTo(chr, chr, true, null, getDuration(chr), passive); } public boolean applyTo(MapleCharacter chr, Point pos) { return applyTo(chr, chr, true, pos, getDuration(chr), false); } public boolean applyTo(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary, Point pos, int newDuration) { return applyTo(applyfrom, applyto, primary, pos, newDuration, false); } /** * 处理技能的效果值 * @param applyfrom * @param applyto * @param primary * @param pos * @param newDuration * @param passive * @return */ public boolean applyTo(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary, Point pos, int newDuration, boolean passive) { //TODO applyTo BUFF 写法不太理想 需要重新写算法 if ((!applyfrom.isAdmin()) && (applyfrom.getMap().isMarketMap())) { applyfrom.getClient().getSession().write(MaplePacketCreator.enableActions()); return false; } if ((this.sourceid == 4341006) && (applyfrom.getBuffedValue(MapleBuffStat.影分身) == null)) { applyfrom.getClient().getSession().write(MaplePacketCreator.enableActions()); return false; } int hpchange = calcHPChange(applyfrom, primary); // 计算消耗的值 int mpchange = calcMPChange(applyfrom, primary); PlayerStats stat = applyto.getStat(); if (primary) { if (((this.info.get(MapleStatInfo.itemConNo)) != 0) ) { if (!applyto.haveItem((this.info.get(MapleStatInfo.itemCon)), (this.info.get(MapleStatInfo.itemConNo)), false, true)) { applyto.getClient().getSession().write(MaplePacketCreator.enableActions()); return false; } MapleInventoryManipulator.removeById(applyto.getClient(), ItemConstants.getInventoryType((this.info.get(MapleStatInfo.itemCon))), (this.info.get(MapleStatInfo.itemCon)), (this.info.get(MapleStatInfo.itemConNo)), false, true); } } else if ((!primary) && (is复活术())) { hpchange = stat.getMaxHp(); applyto.setStance(0); } if ((is净化()) && (makeChanceResult())) { if (applyto.dispelDebuffs()) { if (sourceid == 祭司.净化 && applyfrom.getParty() != null) { applyfrom.getParty().givePartyBuff(祭司.净化, applyfrom.getId(), applyto.getId()); } else { // applyfrom.减少冷却时间(祭司.神圣保护, 60); } } }else if (this.cureDebuffs.size() > 0) { for (MapleDisease debuff : this.cureDebuffs) { applyfrom.dispelDebuff(debuff); } } else if (is龙之献祭()) { // applyto.dispelSkill(1301013); applyto.cancelEffectFromBuffStat(MapleBuffStat.灵魂助力); if (applyto.skillisCooling(1321013)) { applyto.removeCooldown(1321013); applyto.getClient().getSession().write(MaplePacketCreator.skillCooldown(1321013, 0)); } } Map hpmpupdate = new EnumMap(MapleStat.class); if (hpchange != 0) { if ((hpchange < 0) && (-hpchange > stat.getHp())) { applyto.getClient().getSession().write(MaplePacketCreator.enableActions()); return false; } stat.setHp(stat.getHp() + hpchange); } if (mpchange != 0 && !isNotuseMp()) { if ((mpchange < 0) && (-mpchange > stat.getMp())) { applyto.getClient().getSession().write(MaplePacketCreator.enableActions()); return false; } stat.setMp(stat.getMp() + mpchange); hpmpupdate.put(MapleStat.MP, (long) stat.getMp()); } // 消耗的处理完毕 hpmpupdate.put(MapleStat.HP, (long) stat.getHp()); applyto.getClient().getSession().write(MaplePacketCreator.updatePlayerStats(hpmpupdate, true, applyto)); if ((this.useLevel > 0) && (!this.skill)) { applyto.setExtractor(new MapleExtractor(applyto, this.sourceid, this.useLevel * 50, 1440)); applyto.getMap().spawnExtractor(applyto.getExtractor()); } else { int i; if (is迷雾爆发()) { i = (this.info.get(MapleStatInfo.y)); for (MapleDefender mist : applyto.getMap().getAllMistsThreadsafe()) { if ((mist.getOwnerId() == applyto.getId()) && (mist.getSourceSkill().getId() == 2111003)) { if (mist.getSchedule() != null) { mist.getSchedule().cancel(false); mist.setSchedule(null); } if (mist.getPoisonSchedule() != null) { mist.getPoisonSchedule().cancel(false); mist.setPoisonSchedule(null); } applyto.getMap().broadcastMessage(MaplePacketCreator.removeMist(mist.getObjectId(), true)); applyto.getMap().removeMapObject(mist); i--; if (i <= 0) { break; } } } } else if (this.cosmetic > 0) { if (this.cosmetic >= 30000) { applyto.setHair(this.cosmetic); applyto.updateSingleStat(MapleStat.发型, this.cosmetic); } else if (this.cosmetic >= 20000) { applyto.setFace(this.cosmetic); applyto.updateSingleStat(MapleStat.脸型, this.cosmetic); } else if (this.cosmetic < 100) { applyto.setSkinColor((byte) this.cosmetic); applyto.updateSingleStat(MapleStat.皮肤, this.cosmetic); } applyto.equipChanged(); } else if (this.bs > 0) { int xx = Integer.parseInt(applyto.getEventInstance().getProperty(String.valueOf(applyto.getId()))); applyto.getEventInstance().setProperty(String.valueOf(applyto.getId()), String.valueOf(xx + this.bs)); applyto.getClient().getSession().write(MaplePacketCreator.getPVPScore(xx + this.bs, false)); } else if ((this.info.get(MapleStatInfo.iceGageCon)) > 0) { int x = Integer.parseInt(applyto.getEventInstance().getProperty("icegage")); if (x < (this.info.get(MapleStatInfo.iceGageCon))) { return false; } applyto.getEventInstance().setProperty("icegage", String.valueOf(x - (this.info.get(MapleStatInfo.iceGageCon)))); applyto.getClient().getSession().write(MaplePacketCreator.getPVPIceGage(x - (this.info.get(MapleStatInfo.iceGageCon)))); applyto.applyIceGage(x - (this.info.get(MapleStatInfo.iceGageCon))); } else if (this.recipe > 0) { if ((applyto.getSkillLevel(this.recipe) > 0)) { return false; } applyto.changeSingleSkillLevel(SkillFactory.getCraft(this.recipe), 2147483647, this.recipeUseCount, this.recipeValidDay > 0 ? System.currentTimeMillis() + this.recipeValidDay * 24L * 60L * 60L * 1000L : -1L); }else if (is暗器伤人()) { MapleInventory use = applyto.getInventory(MapleInventoryType.USE); boolean itemz = false; int bulletConsume = (this.info.get(MapleStatInfo.bulletConsume)); for (i = 0; i < use.getSlotLimit(); i++) { Item item = use.getItem((short) (byte) i); if ((item == null) || (!ItemConstants.is飞镖道具(item.getItemId())) || (item.getQuantity() < bulletConsume)) { continue; } MapleInventoryManipulator.removeFromSlot(applyto.getClient(), MapleInventoryType.USE, (short) i, (short) bulletConsume, false, true); itemz = true; break; } if (!itemz) { return false; } } else if (is神圣之火()){ int localst = applyto.getStat().getMaxHp(); int maxst = localst + ((localst*this.info.get(MapleStatInfo.x))/100); applyto.getStat().setCurrentMaxHp(maxst); localst = applyto.getStat().getMaxMp(); maxst = localst + ((localst*this.info.get(MapleStatInfo.y))/100); applyto.getStat().setCurrentMaxMp(maxst); } else { MapleCarnivalFactory.MCSkill skil; MapleDisease dis; if ((this.nuffSkill != 0) && (applyto.getParty() != null)) { skil = MapleCarnivalFactory.getInstance().getSkill(this.nuffSkill); if (skil != null) { dis = skil.getDisease(); for (MapleCharacter chr : applyto.getMap().getCharactersThreadsafe()) { if (((applyto.getParty() == null) || (chr.getParty() == null) || (chr.getParty().getId() != applyto.getParty().getId())) && ((skil.targetsAll) || (Randomizer.nextBoolean()))) { if (dis == null) { chr.dispel(); } else if (skil.getSkill() == null) { chr.giveDebuff(dis, 1, 30000L, dis.getDisease(), 1); } else { chr.giveDebuff(dis, skil.getSkill()); } if (!skil.targetsAll) { break; } } } } } else { int types; if (((this.effectedOnEnemy > 0) || (this.effectedOnAlly > 0)) && (primary) ) { types = Integer.parseInt(applyto.getEventInstance().getProperty("type")); if ((types > 0) || (this.effectedOnEnemy > 0)) { for (MapleCharacter chr : applyto.getMap().getCharactersThreadsafe()) { if ((chr.getId() != applyto.getId()) && (this.effectedOnAlly > 0 ? chr.getTeam() != applyto.getTeam() : (chr.getTeam() != applyto.getTeam()) || (types == 0))) { applyTo(applyto, chr, false, pos, newDuration); } } } } else if ((this.randomPickup != null) && (this.randomPickup.size() > 0)) { MapleItemInformationProvider.getInstance().getItemEffect((this.randomPickup.get(Randomizer.nextInt(this.randomPickup.size())))).applyTo(applyto); } } } } if ((primary) && (this.availableMap != null)) { for (Pair e : this.availableMap) { if ((applyto.getMapId() < ((Integer) e.left)) || (applyto.getMapId() > ((Integer) e.right))) { applyto.getClient().getSession().write(MaplePacketCreator.enableActions()); return true; } } } if ((this.overTime)) { if ((getSummonMovementType() != null)) { applySummonEffect(applyfrom, primary, pos, newDuration, 0); } else { applyBuffEffect(applyfrom, applyto, primary, newDuration, passive); } } if (this.skill) { //removeMonsterBuff(applyfrom); } if (primary) { if (((this.overTime) || (is群体治愈()))) { applyBuff(applyfrom, newDuration); // 大部分走了这里 } if (isMonsterBuff()) { applyMonsterBuff(applyfrom); } } if (is时空门()) { //召唤时空门 MapleDoor door = new MapleDoor(applyto, new Point(applyto.getTruePosition()), sourceid); // Current Map door if (door.getTownPortal() != null) { applyto.getMap().spawnDoor(door); applyto.addDoor(door); MapleDoor townDoor = new MapleDoor(door); applyto.addDoor(townDoor); door.getTown().spawnDoor(townDoor); door.first = false; if (applyto.getParty() != null) { applyto.silentPartyUpdate(); } } else { applyto.dropMessage(5, "村庄里已经没有可创造时空门的位置。"); } } else if (isMist()) { // 迷雾类技能 int addx = 0; Rectangle bounds = calculateBoundingBox(pos != null ? pos : applyfrom.getPosition(), applyfrom.isFacingLeft(), addx); MapleDefender mist = new MapleDefender(bounds, applyfrom, this); if (getCooldown(applyfrom) > 0) { applyfrom.getClient().getSession().write(MaplePacketCreator.skillCooldown(this.sourceid, getCooldown(applyfrom))); applyfrom.addCooldown(this.sourceid, System.currentTimeMillis(), getCooldown(applyfrom) * 1000); } applyfrom.getMap().spawnMist(mist, getDuration(), false); } else if (is伺机待发()) { for (MapleCoolDownValueHolder i : applyto.getCooldowns()) { if (i.skillId != 5121010) { applyto.removeCooldown(i.skillId); applyto.getClient().getSession().write(MaplePacketCreator.skillCooldown(i.skillId, 0)); } } } if ((this.fatigueChange != 0) && (applyto.getSummonedFamiliar() != null) && ((this.familiars == null) || (this.familiars.contains(applyto.getSummonedFamiliar().getFamiliar())))) { applyto.getSummonedFamiliar().addFatigue(applyto, this.fatigueChange); } if (this.rewardMeso != 0) { applyto.gainMeso(this.rewardMeso, false); } if ((this.rewardItem != null) && (this.totalprob > 0)) { for (Triple reward : this.rewardItem) { if ((MapleInventoryManipulator.checkSpace(applyto.getClient(), ((Integer) reward.left), ((Integer) reward.mid), "")) && (((Integer) reward.right) > 0) && (Randomizer.nextInt(this.totalprob) < ((Integer) reward.right))) { if (ItemConstants.getInventoryType(((Integer) reward.left)) == MapleInventoryType.EQUIP) { Item item = MapleItemInformationProvider.getInstance().getEquipById(((Integer) reward.left).intValue()); item.setGMLog("Reward item (effect): " + this.sourceid + " on " + FileoutputUtil.CurrentReadable_Date()); MapleInventoryManipulator.addbyItem(applyto.getClient(), item); } else { MapleInventoryManipulator.addById(applyto.getClient(), ((Integer) reward.left), ((Integer) reward.mid).shortValue(), "Reward item (effect): " + this.sourceid + " on " + FileoutputUtil.CurrentReadable_Date()); } } } } if ((this.familiarTarget == 2) && (applyfrom.getParty() != null) && (primary)) { for (MaplePartyCharacter mpc : applyfrom.getParty().getMembers()) { if ((mpc.getId() != applyfrom.getId()) && (mpc.getChannel() == applyfrom.getClient().getChannel()) && (mpc.getMapid() == applyfrom.getMapId()) && (mpc.isOnline())) { MapleCharacter player = applyfrom.getMap().getCharacterById(mpc.getId()); if (player != null) { applyTo(applyfrom, player, false, null, newDuration); } } } } else if ((this.familiarTarget == 3) && (primary)) { for (MapleCharacter player : applyfrom.getMap().getCharactersThreadsafe()) { if (player.getId() != applyfrom.getId()) { applyTo(applyfrom, player, false, null, newDuration); } } } return true; } /** * 处理召唤兽效果 * * @param applyto 角色 * @param primary * @param pos 坐标 * @param newDuration 时间 * @param monid 怪物的ID * @return 布尔值 */ public boolean applySummonEffect(MapleCharacter applyto, boolean primary, Point pos, int newDuration, int monid) { SummonMovementType summonMovementType = getSummonMovementType(); if ((summonMovementType == null) || ((this.sourceid == 32111006) )) { return false; } byte[] buff = null; int summonSkillId = this.sourceid; int localDuration = newDuration; List localstatups = this.statups; if (applyto.isShowPacket()) { applyto.dropSpouseMessage(10, "开始召唤召唤兽 - 召唤兽技能: " + summonSkillId + " 持续时间: " + newDuration); } if (this.sourceid != 35111002) { applyto.cancelEffect(this, true, -1L, localstatups); } // 召唤兽处理 MapleSummon tosummon = new MapleSummon(applyto, summonSkillId, getLevel(), new Point(pos == null ? applyto.getTruePosition() : pos), summonMovementType); tosummon.setLinkmonid(monid); applyto.getMap().spawnSummon(tosummon); applyto.addSummon(tosummon); if ((this.info.get(MapleStatInfo.hcSummonHp)) > 0) { tosummon.setSummonHp((this.info.get(MapleStatInfo.hcSummonHp))); } else if (this.sourceid == 3221014) { tosummon.setSummonHp((this.info.get(MapleStatInfo.x))); } if (this.sourceid == 4341006) { applyto.cancelEffectFromBuffStat(MapleBuffStat.影分身); } else if (this.sourceid == 1301013) { List stat = Collections.singletonList(new Pair(MapleBuffStat.灵魂助力, Integer.valueOf(level))); buff = BuffPacket.giveBuff(this.sourceid, localDuration, stat); } long startTime = System.currentTimeMillis(); if (localDuration > 0) { CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, startTime, localstatups); ScheduledFuture schedule = Timer.BuffTimer.getInstance().schedule(cancelAction, localDuration); applyto.registerEffect(this, startTime, schedule, localstatups, false, localDuration, applyto.getId()); } int cooldown = getCooldown(applyto); if (cooldown > 0) { applyto.getClient().getSession().write(MaplePacketCreator.skillCooldown(this.sourceid, cooldown)); applyto.addCooldown(this.sourceid, startTime, cooldown * 1000); } if (buff != null) { applyto.getClient().getSession().write(buff); } return true; } public boolean applyReturnScroll(MapleCharacter applyto) { if (this.moveTo != -1) { if ((this.sourceid != 2031010) || (this.sourceid != 2030021)) { MapleMap target = null; boolean nearest = false; if (this.moveTo == 999999999) { nearest = true; if (applyto.getMap().getReturnMapId() != 999999999) { target = applyto.getMap().getReturnMap(); } } else { target = ChannelServer.getInstance(applyto.getClient().getChannel()).getMapFactory().getMap(this.moveTo); if ((target.getId() == 931050500) && (target != applyto.getMap())) { applyto.changeMap(target, target.getPortal(0)); return true; } int targetMapId = target.getId() / 10000000; int charMapId = applyto.getMapId() / 10000000; if ((targetMapId != 60) && (charMapId != 61) && (targetMapId != 21) && (charMapId != 20) && (targetMapId != 12) && (charMapId != 10) && (targetMapId != 10) && (charMapId != 12) && (targetMapId != charMapId)) { FileoutputUtil.log("玩家 " + applyto.getName() + " 尝试回到一个非法的位置 (" + applyto.getMapId() + "->" + target.getId() + ")"); return false; } } if ((target == applyto.getMap()) || ((nearest) && (applyto.getMap().isTown()))) { return false; } applyto.changeMap(target, target.getPortal(0)); return true; } } return false; } private void applyBuff(MapleCharacter applyfrom, int newDuration) { List<MapleCharacter> awarded = new ArrayList(); // if ((isPartyBuff()) && ((applyfrom.getParty() != null) || (isGmBuff()))) { Rectangle bounds = calculateBoundingBox(applyfrom.getTruePosition(), applyfrom.isFacingLeft()); List<MapleMapObject> affecteds = applyfrom.getMap().getMapObjectsInRect(bounds, Arrays.asList(new MapleMapObjectType[]{MapleMapObjectType.PLAYER})); for (MapleMapObject affectedmo : affecteds) { MapleCharacter affected = (MapleCharacter) affectedmo; if ((affected.getId() != applyfrom.getId()) && ((isGmBuff()) || ((affected.getTeam() == applyfrom.getTeam()) && (Integer.parseInt(applyfrom.getEventInstance().getProperty("type")) != 0)) || ((applyfrom.getParty() != null) && (affected.getParty() != null) && (applyfrom.getParty().getId() == affected.getParty().getId())))) { awarded.add(affected); } } // } for (MapleCharacter chr : awarded) { if (isPartyBuff() && chr.getParty() != null && !is群体治愈()) { chr.getParty().givePartyBuff(this.sourceid, applyfrom.getId(), chr.getId()); } if (((is复活术()) && (!chr.isAlive())) || ((!is复活术()) && (chr.isAlive()))) { applyTo(applyfrom, chr, false, null, newDuration); chr.getClient().getSession().write(MaplePacketCreator.showOwnBuffEffect(this.sourceid, 3/*, applyfrom.getLevel()*/, this.level));//2+1 119 chr.getMap().broadcastMessage(chr, MaplePacketCreator.showBuffeffect(chr, this.sourceid, 3, applyfrom.getLevel(), this.level), false);//2+1 119 } if (is伺机待发()) { for (MapleCoolDownValueHolder i : chr.getCooldowns()) { if (i.skillId != 5121010) { chr.removeCooldown(i.skillId); chr.getClient().getSession().write(MaplePacketCreator.skillCooldown(i.skillId, 0)); } } } } if (is净化()) { if (applyfrom.getParty() == null) { return; } int time = applyfrom.getParty().getPartyBuffs(applyfrom.getId()) * 60; if (time > 0) { // applyfrom.减少冷却时间(祭司.神圣保护, time); } for (MaplePartyCharacter mc : applyfrom.getParty().getMembers()) { applyfrom.getParty().cancelPartyBuff(sourceid, mc.getId()); } } else if (isPartyBuff() && !is群体治愈() && !is复活术()) { if (applyfrom.getParty() != null) { applyfrom.getParty().givePartyBuff(sourceid, applyfrom.getId(), applyfrom.getId()); } // MapleStatEffect.apply祈祷众生(applyfrom); } } public static void applyDoubleDefense(final MapleCharacter applyfrom) {//双重防御 int skilllevel = applyfrom.getSkillLevel(36111003); Skill skills = SkillFactory.getSkill(36111003); MapleStatEffect infoEffect = skills.getEffect(skilllevel); int i = 0; infoEffect.times = infoEffect.getX() - (infoEffect.getProb() - infoEffect.getStatups().get(0).right) / infoEffect.getY(); if (infoEffect.times <= 0) { infoEffect.isfirst = true; applyfrom.cancelEffect(skills.getEffect(1), false, -1L); //applyfrom.cancelEffect(infoEffect, false, -1L); } else { infoEffect.isfirst = false; infoEffect.applyBuffEffect(applyfrom, 2100000000); } } private void removeMonsterBuff(MapleCharacter applyfrom) { List<MonsterStatus> cancel = new ArrayList(); switch (this.sourceid) { case 1121016://魔击无效 case 1221014: case 1321014: case 1211009: case 1111007: case 1311007: // cancel.add(MonsterStatus.物防提升); // cancel.add(MonsterStatus.魔防提升); // cancel.add(MonsterStatus.物攻提升); // cancel.add(MonsterStatus.魔攻提升); break; default: return; } Rectangle bounds = calculateBoundingBox(applyfrom.getTruePosition(), applyfrom.isFacingLeft()); List<MapleMapObject> affected = applyfrom.getMap().getMapObjectsInRect(bounds, Arrays.asList(new MapleMapObjectType[]{MapleMapObjectType.MONSTER})); int i = 0; for (MapleMapObject mo : affected) { if (makeChanceResult()) { for (MonsterStatus stat : cancel) { ((MapleMonster) mo).cancelStatus(stat); } } i++; if (i >= (this.info.get(MapleStatInfo.mobCount))) { break; } } } /** * 给怪物加BUFF * @param applyfrom */ public void applyMonsterBuff(MapleCharacter applyfrom) { Rectangle bounds = calculateBoundingBox(applyfrom.getTruePosition(), applyfrom.isFacingLeft()); MapleMapObjectType types = MapleMapObjectType.MONSTER; List<MapleMapObject> affected = applyfrom.getMap().getMapObjectsInRect(bounds, Arrays.asList(new MapleMapObjectType[]{types})); int i = 0; for (MapleMapObject mo : affected) { if (makeChanceResult()) { for (Map.Entry stat : getMonsterStati().entrySet()) { MapleMonster mons = (MapleMonster) mo; mons.applyStatus(applyfrom, new MonsterStatusEffect((MonsterStatus) stat.getKey(), (Integer) stat.getValue(), this.sourceid, null, false), isPoison(), getDuration(), true, this); } } i++; if ((i >= (this.info.get(MapleStatInfo.mobCount))) && (this.sourceid != 35111005)) { break; } } } public Rectangle calculateBoundingBox(Point posFrom, boolean facingLeft) { return calculateBoundingBox(posFrom, facingLeft, this.lt, this.rb, (this.info.get(MapleStatInfo.range))); } public Rectangle calculateBoundingBox(Point posFrom, boolean facingLeft, int addedRange) { return calculateBoundingBox(posFrom, facingLeft, this.lt, this.rb, (this.info.get(MapleStatInfo.range)) + addedRange); } public static Rectangle calculateBoundingBox(Point posFrom, boolean facingLeft, Point lt, Point rb, int range) { if ((lt == null) || (rb == null)) { return new Rectangle((facingLeft ? -200 - range : 0) + posFrom.x, -100 - range + posFrom.y, 200 + range, 100 + range); } Point myrb; Point mylt; if (facingLeft) { mylt = new Point(lt.x + posFrom.x - range, lt.y + posFrom.y); myrb = new Point(rb.x + posFrom.x, rb.y + posFrom.y); } else { myrb = new Point(lt.x * -1 + posFrom.x + range, rb.y + posFrom.y); mylt = new Point(rb.x * -1 + posFrom.x, lt.y + posFrom.y); } return new Rectangle(mylt.x, mylt.y, myrb.x - mylt.x, myrb.y - mylt.y); } public double getMaxDistanceSq() { int maxX = Math.max(Math.abs(this.lt == null ? 0 : this.lt.x), Math.abs(this.rb == null ? 0 : this.rb.x)); int maxY = Math.max(Math.abs(this.lt == null ? 0 : this.lt.y), Math.abs(this.rb == null ? 0 : this.rb.y)); return maxX * maxX + maxY * maxY; } public void setDuration(int d) { this.info.put(MapleStatInfo.time, d); } public void silentApplyBuff(MapleCharacter chr, long starttime, int localDuration, List<Pair<MapleBuffStat, Integer>> statup, int chrId) { int maskedDuration = 0; int newDuration = (int) (starttime + localDuration - System.currentTimeMillis()); if (is终极无限()) { maskedDuration = alchemistModifyVal(chr, 4000, false); } ScheduledFuture schedule = Timer.BuffTimer.getInstance().schedule(new CancelEffectAction(chr, this, starttime, statup), newDuration); chr.registerEffect(this, starttime, schedule, statup, true, localDuration, chrId); SummonMovementType summonMovementType = getSummonMovementType(); if (summonMovementType != null) { MapleSummon summon = new MapleSummon(chr, this, chr.getTruePosition(), summonMovementType); if (!summon.is替身术()) { chr.getMap().spawnSummon(summon); chr.addSummon(summon); summon.addSummonHp((this.info.get(MapleStatInfo.x)).shortValue()); if (is灵魂助力()) { summon.addSummonHp(1); } } } } public void applyBuffEffect(MapleCharacter chr, int newDuration) { applyBuffEffect(chr, chr, false, newDuration, false); } private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary, int newDuration) { applyBuffEffect(applyfrom, applyto, primary, newDuration, false); } private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary, int newDuration, boolean passive) { //TODO 写法太不理想 造成严重的冗余 if ((!applyto.isAdmin()) && (applyto.getMap().isMarketMap())) { applyto.getClient().getSession().write(MaplePacketCreator.enableActions()); return; } int localDuration = newDuration; if (localDuration == 1000) { // 如果持续时间为1s,那么表示需要服务端自动取消buff newDuration = localDuration = 65535000; } this.bufftime = newDuration; if (primary) { localDuration = Math.max(newDuration, alchemistModifyVal(applyfrom, localDuration, false)); } if (applyfrom.isShowPacket()) { applyfrom.dropSpouseMessage(10, "开始 => applyBuffEffect ID: " + this.sourceid + " 持续时间: " + localDuration); } List localstatups = statups; List maskedStatups = null; boolean normal = true; boolean showEffect = primary; int maskedDuration = 0; int rate = 1; byte[] buff = null; byte[] foreignbuff = null; if (is神圣之火()) { localstatups = new ArrayList(); localstatups.add(new Pair(MapleBuffStat.神圣之火_最大体力百分比, (this.info.get(MapleStatInfo.x)))); localstatups.add(new Pair(MapleBuffStat.神圣之火_最大魔力百分比, (this.info.get(MapleStatInfo.x)))); } else if (is隐身术()) { List stat = Collections.singletonList(new Pair(MapleBuffStat.隐身术, 0)); foreignbuff = BuffPacket.giveForeignBuff(applyto.getId(), stat, this); } else if (this.sourceid == 1210016) { List stat = Collections.singletonList(new Pair(MapleBuffStat.祝福护甲, 0)); foreignbuff = BuffPacket.giveForeignBuff(applyto.getId(), stat, this); } else if (is斗气集中()) { List stat = Collections.singletonList(new Pair(MapleBuffStat.斗气集中, 0)); foreignbuff = BuffPacket.giveForeignBuff(applyto.getId(), stat, this); } else if ((this.sourceid == 3101004) || (this.sourceid == 3201004)) { List stat = Collections.singletonList(new Pair(MapleBuffStat.无形箭弩, 0)); foreignbuff = BuffPacket.giveForeignBuff(applyto.getId(), stat, this); /*} else if (this.sourceid == 2321005) { applyto.cancelEffectFromBuffStat(MapleBuffStat.牧师祝福);*/ } else if (is影分身()) { List stat = Collections.singletonList(new Pair(MapleBuffStat.影分身, this.info.get(MapleStatInfo.x))); foreignbuff = BuffPacket.giveForeignBuff(applyto.getId(), stat, this); } else if (this.sourceid == 1121010) { applyto.handleOrbconsume(1); }else if (isMorph()) { if (is冰骑士()) { List stat = Collections.singletonList(new Pair(MapleBuffStat.冰骑士, Integer.valueOf(2))); buff = BuffPacket.giveBuff(0, localDuration, stat); } List stat = Collections.singletonList(new Pair(MapleBuffStat.变身术, Integer.valueOf(getMorph(applyto)))); foreignbuff = BuffPacket.giveForeignBuff(applyto.getId(), stat, this); } else if (isInflation()) { List stat = Collections.singletonList(new Pair(MapleBuffStat.GIANT_POTION, Integer.valueOf(this.inflation))); foreignbuff = BuffPacket.giveForeignBuff(applyto.getId(), stat, this); } else if (is骑兽技能()) { localDuration = 2100000000; localstatups = new ArrayList(this.statups); int mountid = parseMountInfo(applyto, this.sourceid); int mountid2 = parseMountInfo_Pure(applyto, this.sourceid); if ((mountid != 0) && (mountid2 != 0)) { // localstatups.add(new Pair(MapleBuffStat.骑兽技能, mountid2)); // List stat = Collections.singletonList(new Pair(MapleBuffStat.骑兽技能, 0)); // foreignbuff = BuffPacket.showMonsterRiding(applyto.getId(), stat, mountid, this.sourceid); } else { if (applyto.isShowPacket()) { applyto.dropSpouseMessage(10, "骑宠BUFF " + this.sourceid + " 错误,未找到这个骑宠的外形ID。"); } return; } } else if (sourceid == 3110012) { //精神集中 showEffect = true; // int healRate = applyto.getBuffedIntValue(MapleBuffStat.精神集中) + 1; // this.getStatups().set(0, new Pair(MapleBuffStat.精神集中, healRate)); //List stat = Collections.singletonList(new Pair(MapleBuffStat.精神集中, applyto.getBuffedIntValue(MapleBuffStat.精神集中))); buff = BuffPacket.giveBuff(this.sourceid, localDuration, localstatups); foreignbuff = BuffPacket.giveForeignBuff(applyto.getId(), localstatups, this); } if (!is骑兽技能()) { //applyto.cancelEffect(this, true, -1L, localstatups); } if ((showEffect) && (!applyto.isHidden())) { // TODO 发送 [SHOW_FOREIGN_EFFECT] applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.showBuffeffect(applyto, this.sourceid, 1, applyto.getLevel(), this.level), false); } if (buff != null) { // TODO 发送 [GIVE_BUFF] applyfrom.dropMessage(5,"发送技能:GIVE_BUFF"); applyto.getClient().getSession().write(buff); } else if (normal && localstatups.size() > 0) { //自动使用? FileoutputUtil.log("发送技能:GIVE_BUFF|null"+sourceid); applyto.getClient().getSession().write(BuffPacket.giveBuff(skill ? sourceid : -sourceid, localDuration, maskedStatups == null ? localstatups : maskedStatups)); } if ((foreignbuff != null) && (!applyto.isHidden())) { // TODO 发送 [GIVE_FOREIGN_BUFF] applyto.getMap().broadcastMessage(foreignbuff); } long startTime = System.currentTimeMillis(); if (localDuration > 0) { CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, startTime, localstatups); ScheduledFuture schedule = Timer.BuffTimer.getInstance().schedule(cancelAction, maskedDuration > 0 ? maskedDuration : localDuration); applyto.registerEffect(this, startTime, schedule, localstatups, true, maskedDuration > 0 ? maskedDuration : localDuration, applyfrom.getId()); } int cooldown = getCooldown(applyto); if (cooldown > 0) { if (SkillConstants.is触发性冷却技能(this.sourceid)) { return; } if (!applyto.skillisCooling(this.sourceid)) { applyto.getClient().getSession().write(MaplePacketCreator.skillCooldown(this.sourceid, cooldown)); applyto.addCooldown(this.sourceid, startTime, cooldown * 1000); } } } public static int parseMountInfo(MapleCharacter player, int skillid) { if ((skillid == 80001000) || (GameConstants.is骑兽技能(skillid))) { if ((player.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -123) != null) && (player.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -124) != null)) { return player.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -123).getItemId(); } return parseMountInfo_Pure(player, skillid); } return GameConstants.getMountItem(skillid, player); } public static int parseMountInfo_Pure(MapleCharacter player, int skillid) { if ((skillid == 80001000) || (GameConstants.is骑兽技能(skillid))) { if ((player.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -18) != null) && (player.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -19) != null)) { return player.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -18).getItemId(); } return 0; } return GameConstants.getMountItem(skillid, player); } private int getHpMpChange(MapleCharacter applyfrom, boolean hpchange) { int change = 0; if ((this.hpR != 0.0D) || (this.mpR != 0.0D)) { double healHpRate = this.hpR; if (applyfrom.isShowPacket()) { applyfrom.dropMessage(-5, "HpMpChange => 默认: " + this.hpR + " - " + healHpRate); } int maxChange = this.mpR < 1.0D ? Math.min((int) Math.floor(GameConstants.MAX_HP/2), (int) Math.floor(GameConstants.MAX_HP * (hpchange ? healHpRate : this.mpR))) : GameConstants.MAX_HP; int current = applyfrom.getStat().getCurrentMaxHp(); change = (int) (current * (hpchange ? healHpRate : this.mpR)) > maxChange ? maxChange : (int) (current * (hpchange ? healHpRate : this.mpR)); } return change; } /** * 计算血量变化 * @param applyfrom * @param primary * @return */ private int calcHPChange(MapleCharacter applyfrom, boolean primary) { int hpchange = 0; if ((this.info.get(MapleStatInfo.hp)) != 0) { if (!this.skill) { if (primary) { hpchange += alchemistModifyVal(applyfrom, (this.info.get(MapleStatInfo.hp)), true); } else { hpchange += (this.info.get(MapleStatInfo.hp)); } } else { hpchange += makeHealHP((this.info.get(MapleStatInfo.hp)) / 100.0D, applyfrom.getStat().getTotalMagic(), 3.0D, 5.0D); } } if (this.hpR != 0.0D) { hpchange += (int) (applyfrom.getStat().getCurrentMaxHp() * hpR); } if ((primary) && ((this.info.get(MapleStatInfo.hpCon)) != 0)) { hpchange -= (this.info.get(MapleStatInfo.hpCon)); } if ((applyfrom.getTotalSkillLevel(21120043) > 0)) { hpchange = 0; } if (this.sourceid == 独行客.转化术) { hpchange += this.info.get(MapleStatInfo.y) * this.info.get(MapleStatInfo.mpCon); } return hpchange; } private static int makeHealHP(double rate, double stat, double lowerfactor, double upperfactor) { return (int) (Math.random() * ((int) (stat * upperfactor * rate) - (int) (stat * lowerfactor * rate) + 1) + (int) (stat * lowerfactor * rate)); } private int calcMPChange(MapleCharacter applyfrom, boolean primary) { int mpchange = 0; if ((this.info.get(MapleStatInfo.mp)) != 0) { if (primary) { mpchange += alchemistModifyVal(applyfrom, (this.info.get(MapleStatInfo.mp)), true); } else { mpchange += (this.info.get(MapleStatInfo.mp)); } } if (this.mpR != 0.0D) { mpchange += (int) (applyfrom.getStat().getCurrentMaxMp() * mpR); } if (primary) { if (((this.info.get(MapleStatInfo.mpCon)) != 0)) { boolean free = false; if ((applyfrom.getJob() == 411) || (applyfrom.getJob() == 412)) { Skill expert = SkillFactory.getSkill(4110012); if (applyfrom.getTotalSkillLevel(expert) > 0) { MapleStatEffect eff = expert.getEffect(applyfrom.getTotalSkillLevel(expert)); if (eff.makeChanceResult()) { free = true; } } } if (!free) { mpchange = (int) (mpchange - ((this.info.get(MapleStatInfo.mpCon)) - (this.info.get(MapleStatInfo.mpCon)) * applyfrom.getStat().mpconReduce / 100) * (applyfrom.getStat().mpconPercent / 100.0D)); } } else if (((this.info.get(MapleStatInfo.forceCon)) != 0)) { mpchange -= (this.info.get(MapleStatInfo.forceCon)); } } if ((applyfrom.getTotalSkillLevel(21120043) > 0)) { mpchange = 0; } return mpchange; } public int alchemistModifyVal(MapleCharacter chr, int val, boolean withX) { if (!this.skill) { return val * (withX ? chr.getStat().RecoveryUP : chr.getStat().BuffUP) / 100; } return val * (withX ? chr.getStat().RecoveryUP : chr.getStat().BuffUP_Skill + (getSummonMovementType() == null ? 0 : chr.getStat().BuffUP_Summon)) / 100 * chr.getStat().BuffTimeR / 100; } private int calcPowerChange(MapleCharacter applyfrom) { return 0; } public void setSourceId(int newid) { this.sourceid = newid; } public boolean isGmBuff() { switch (this.sourceid) { case 9001000: case 9001001: case 9001002: case 9001003: case 9001005: case 9001008: case 9101000: case 9101001: case 9101002: case 9101003: case 9101005: case 9101008: case 10001075: return true; } return (GameConstants.is新手职业(this.sourceid / 10000)) && (this.sourceid % 10000 == 1005); } public boolean isInflation() { return this.inflation > 0; } public int getInflation() { return this.inflation; } /** * 是否对怪物的BUFF * @return */ private boolean isMonsterBuff() { switch (this.sourceid) { case 准骑士.压制术: case 火毒魔法师.缓速术: case 冰雷魔法师.缓速术: case 冰雷巫师.封印术: case 火毒巫师.封印术: case 祭司.巫毒术: case 无影人.影网术: return this.skill; } return false; } public void setPartyBuff(boolean pb) { this.partyBuff = pb; } public boolean isPartyBuff() { switch (this.sourceid) { //TODO 设置非组队BUFF case 1201011: case 1201012: case 1211008: case 1221004: case 4341002: case 4341052: case 1221054: case 4111002: return false; } return !GameConstants.isNoDelaySkill(this.sourceid); } public boolean is神圣之火() { return (this.skill) && (this.sourceid == 1301007); } public boolean is不倦神酒() { return (this.skill) && (this.sourceid == 1301007); } public boolean is神秘瞄准术() { return (this.skill) && ((this.sourceid == 2320011) || (this.sourceid == 2220010) || (this.sourceid == 2120010)); } public boolean is群体治愈() { return (this.skill) && ((this.sourceid == 牧师.群体治愈) || (this.sourceid == 9101000) || (this.sourceid == 9001000)); } public boolean is复活术() { return (this.skill) && ((this.sourceid == 9001005) || (this.sourceid == 9101005) || (this.sourceid == 2321006)); } public boolean is伺机待发() { return (this.skill) && (this.sourceid == 5121010); } public int getHp() { return (this.info.get(MapleStatInfo.hp)); } public int getMp() { return (this.info.get(MapleStatInfo.mp)); } public int getDOTStack() { return (this.info.get(MapleStatInfo.dotSuperpos)); } public double getHpR() { return this.hpR; } public double getMpR() { return this.mpR; } public int getMastery() { return (this.info.get(MapleStatInfo.mastery)); } public int getWatk() { return (this.info.get(MapleStatInfo.pad)); } public int getMatk() { return (this.info.get(MapleStatInfo.mad)); } public int getWdef() { return (this.info.get(MapleStatInfo.pdd)); } public int getMdef() { return (this.info.get(MapleStatInfo.mdd)); } public int getAcc() { return (this.info.get(MapleStatInfo.acc)); } public int getAvoid() { return (this.info.get(MapleStatInfo.eva)); } public int getSpeed() { return (this.info.get(MapleStatInfo.speed)); } public int getJump() { return (this.info.get(MapleStatInfo.jump)); } public int getSpeedMax() { return (this.info.get(MapleStatInfo.speedMax)); } public int getPassiveSpeed() { return (this.info.get(MapleStatInfo.psdSpeed)); } public int getPassiveJump() { return (this.info.get(MapleStatInfo.psdJump)); } public int getDuration() { return (this.info.get(MapleStatInfo.time)); } public int getDuration(MapleCharacter applyfrom) { int time = this.skill ? applyfrom.getStat().getDuration(this.sourceid) : 0; return (this.info.get(MapleStatInfo.time)) + time; } public int getSubTime() { return (this.info.get(MapleStatInfo.subTime)); } public boolean isOverTime() { return this.overTime; } public boolean isNotRemoved() { return this.notRemoved; } public List<Pair<MapleBuffStat, Integer>> getStatups() { return this.statups; } public boolean sameSource(MapleStatEffect effect) { return (effect != null) && (this.sourceid == effect.sourceid) && (this.skill == effect.skill); } public int getT() { return (this.info.get(MapleStatInfo.t)); } public int getU() { return (this.info.get(MapleStatInfo.u)); } public int getV() { return (this.info.get(MapleStatInfo.v)); } public int getW() { return (this.info.get(MapleStatInfo.w)); } public int getX() { return (this.info.get(MapleStatInfo.x)); } public int getY() { return (this.info.get(MapleStatInfo.y)); } public int getZ() { return (this.info.get(MapleStatInfo.z)); } public int getDamage() { return (this.info.get(MapleStatInfo.damage)); } public int getPVPDamage() { return (this.info.get(MapleStatInfo.PVPdamage)); } public int getAttackCount() { return (this.info.get(MapleStatInfo.attackCount)); } public int getAttackCount(MapleCharacter applyfrom) { int addcount = (applyfrom.getSkillLevel(3220015) > 0) && (getAttackCount() >= 2) ? 1 : 0; return (this.info.get(MapleStatInfo.attackCount)) + applyfrom.getStat().getAttackCount(this.sourceid) + addcount; } public int getBulletCount() { return (this.info.get(MapleStatInfo.bulletCount)); } public int getBulletCount(MapleCharacter applyfrom) { int addcount = (applyfrom.getSkillLevel(3220015) > 0) && (getBulletCount() >= 2) ? 1 : 0; return (this.info.get(MapleStatInfo.bulletCount)) + applyfrom.getStat().getAttackCount(this.sourceid) + addcount; } public int getBulletConsume() { return (this.info.get(MapleStatInfo.bulletConsume)); } public int getMobCount() { return (this.info.get(MapleStatInfo.mobCount)); } public int getMobCount(MapleCharacter applyfrom) { return (this.info.get(MapleStatInfo.mobCount)) + applyfrom.getStat().getMobCount(this.sourceid); } public int getMoneyCon() { return this.moneyCon; } public int getCooltimeReduceR() { return (this.info.get(MapleStatInfo.coolTimeR)); } public int getMesoAcquisition() { return (this.info.get(MapleStatInfo.mesoR)); } public boolean isNoTCoolDown(MapleCharacter applyfrom) {//TODO 设置条件技能不冷却时间为 if (is神枪降临() && applyfrom.getBuffSource(MapleBuffStat.百分比无视防御) == 1321015 || ((this.sourceid == 1321013 || this.sourceid == 27121303))) { return true; } return false; } public int getCooldown(MapleCharacter applyfrom) { if (isNoTCoolDown(applyfrom)) { return 0; } if ((this.info.get(MapleStatInfo.cooltime)) >= 5) { int cooldownX = (int) ((this.info.get(MapleStatInfo.cooltime)) * (applyfrom.getStat().getCoolTimeR() / 100.0D)); int coolTimeR = (int) ((this.info.get(MapleStatInfo.cooltime)) * (applyfrom.getStat().getReduceCooltimeRate(this.sourceid) / 100.0D)); if (applyfrom.isShowPacket()) { applyfrom.dropMessage(-5, "技能冷却时间 => 默认: " + this.info.get(MapleStatInfo.cooltime) + " [减少百分比: " + applyfrom.getStat().getCoolTimeR() + "% - " + cooldownX + "] [减少时间: " + applyfrom.getStat().getReduceCooltime() + "] [超级技能减少百分比: " + applyfrom.getStat().getReduceCooltimeRate(this.sourceid) + "% 减少时间: " + coolTimeR + "]"); } return Math.max(0, (this.info.get(MapleStatInfo.cooltime)) - applyfrom.getStat().getReduceCooltime() - (cooldownX > 5 ? 5 : cooldownX) - coolTimeR); } return (this.info.get(MapleStatInfo.cooltime)); } public Map<MonsterStatus, Integer> getMonsterStati() { return this.monsterStatus; } public int getBerserk() { return this.berserk; } public boolean is神枪降临() { return (this.skill) && (this.sourceid == 1321013); } public boolean is隐藏术() { return (this.skill) && ((this.sourceid == 9001004) || (this.sourceid == 9101004)); } public boolean is隐身术() { return (this.skill) && ((this.sourceid == 9001004) || (this.sourceid == 9101004) || (this.sourceid == 4001003) || (this.sourceid == 14001003) || (this.sourceid == 4330001)); } public boolean is龙之力() { return (this.skill) && (this.sourceid == 龙骑士.龙之魂); } public boolean is龙之献祭() { return (this.skill) && (this.sourceid == 1311005); } public boolean is团队治疗() { return (this.skill) && ((this.sourceid == 1001) || (this.sourceid == 10001001) || (this.sourceid == 20001001) || (this.sourceid == 20011001) || (this.sourceid == 35121005)); } public boolean is重生契约() { return (this.skill) && (this.sourceid == 1320016 || this.sourceid == 1320019); } public boolean is灵魂助力() { return (this.skill) && (this.sourceid == 1301013); } public boolean is灵魂助力统治() { return (this.skill) && (this.sourceid == 1311013); } public boolean is能量激发() { return (this.skill) && (this.sourceid == 5121054); } public boolean is极限射箭() { return (this.skill) && ((this.sourceid == 3111011) || (this.sourceid == 3211012)); } public boolean is终极无限() { return (this.skill) && ((this.sourceid == 2121004) || (this.sourceid == 2221004) || (this.sourceid == 2321004)); } public boolean is骑兽技能_() { return (this.skill) && ((GameConstants.is骑兽技能(this.sourceid)) || (this.sourceid == 80001000) || this.getvehicleID() > 0); } public boolean is骑兽技能() { return (this.skill) && ((is骑兽技能_()) || (GameConstants.getMountItem(this.sourceid, null) != 0)); } public boolean is时空门() { return (this.skill) && ((this.sourceid == 2311002) || (this.sourceid % 10000 == 8001)); } public boolean is金钱护盾() { return (this.skill) && (this.sourceid == 4201011); } public boolean is影子闪避() { return (this.skill) && (this.sourceid == 4330009); } public boolean isCharge() { switch (this.sourceid) { case 1211008: case 12101005: case 21101006: return this.skill; } return false; } public boolean isPoison() { return ((this.info.get(MapleStatInfo.dot)) > 0) && ((this.info.get(MapleStatInfo.dotTime)) > 0); } /** * * @return */ private boolean isMist() { switch (this.sourceid) { case 火毒巫师.致命毒雾: case 2311011: case 4121015: case 4221006: return true; } return false; } private boolean is暗器伤人() { return (this.skill) && ((this.sourceid == 4111009)); } private boolean is无限子弹() { return (this.skill) && (this.sourceid == 5201008); } private boolean is净化() { return (this.skill) && ((this.sourceid == 祭司.净化) || (this.sourceid == 9001000) || (this.sourceid == 9101000)); } public boolean is侠盗本能() { return (this.skill) && (this.sourceid == 4221013); } public boolean is斗气集中() { switch (this.sourceid) { case 1111002: return this.skill; } return false; } public boolean isMorph() { return this.morphId > 0; } public int getMorph() { return this.morphId; } public boolean is金刚霸体() { return (this.skill) && (GameConstants.is新手职业(this.sourceid / 10000)) && (this.sourceid % 10000 == 1010); } public boolean is祝福护甲() { switch (this.sourceid) { case 1210016: return this.skill; } return false; } public boolean is狂暴战魂() { return (this.skill) && (GameConstants.is新手职业(this.sourceid / 10000)) && (this.sourceid % 10000 == 1011); } public int getMorph(MapleCharacter chr) { int morph = getMorph(); switch (morph) { case 1000: case 1001: case 1003: return morph + (chr.getGender() == 1 ? 100 : 0); case 1002: } return morph; } public byte getLevel() { return this.level; } public SummonMovementType getSummonMovementType() { if (!this.skill) { return null; } switch (this.sourceid) { case 游侠.替身术: case 射手.替身术: return SummonMovementType.不会移动; case 射手.银鹰召唤: case 游侠.金鹰召唤: case 祭司.圣龙召唤: return SummonMovementType.飞行跟随; case 5210015: case 5210016: case 5210017: case 5210018: return SummonMovementType.移动跟随; } return null; } public boolean is带BUFF技能() { switch (this.sourceid) { case 2321052: return this.skill; } return false; } public boolean isSkill() { return this.skill; } public int getSourceId() { return this.sourceid; } public boolean is冰骑士() { return (this.skill) && (GameConstants.is新手职业(this.sourceid / 10000)) && (this.sourceid % 10000 == 1105); } public boolean isSoaring() { return (isSoaring_Normal()) || (isSoaring_Mount()); } public boolean isSoaring_Normal() { return (this.skill) && (GameConstants.is新手职业(this.sourceid / 10000)) && (this.sourceid % 10000 == 1026); } public boolean isSoaring_Mount() { return (this.skill) && (((GameConstants.is新手职业(this.sourceid / 10000)) && (this.sourceid % 10000 == 1142)) || (this.sourceid == 80001089)); } public boolean is迷雾爆发() { return (this.skill) && (this.sourceid == 2121003); } public boolean is影分身() { switch (this.sourceid) { case 4111002: case 4211008: case 4331002: case 14111000: case 36111006: return this.skill; } return false; } public int getShadowDamage() { switch (this.sourceid) { case 4111002: case 4211008: case 4331002: case 14111000: return (this.info.get(MapleStatInfo.x)); case 36111006: return (this.info.get(MapleStatInfo.y)); } return (this.info.get(MapleStatInfo.x)); } public boolean isMechPassive() { switch (this.sourceid) { case 35001001: case 35101009: case 35111004: case 35121005: case 35121013: case 35121054: return true; } return false; } public boolean makeChanceResult() { return ((this.info.get(MapleStatInfo.prop)) >= 100) || (Randomizer.nextInt(100) < (this.info.get(MapleStatInfo.prop))); } public boolean makeAngelReborn() { return ((this.info.get(MapleStatInfo.onActive)) >= 100) || (Randomizer.nextInt(100) < (this.info.get(MapleStatInfo.onActive))); } public boolean makeChanceResult(MapleCharacter applyfrom) { int prop = (this.info.get(MapleStatInfo.prop)); return (prop >= 100) || (Randomizer.nextInt(100) < prop); } public int getProb() { return (this.info.get(MapleStatInfo.prop)); } public short getIgnoreMob() { return this.ignoreMob; } public int getEnhancedHP() { return (this.info.get(MapleStatInfo.emhp)); } public int getEnhancedMP() { return (this.info.get(MapleStatInfo.emmp)); } public int getEnhancedWatk() { return (this.info.get(MapleStatInfo.epad)); } public int getEnhancedMatk() { return (this.info.get(MapleStatInfo.emad)); } public int getEnhancedWdef() { return (this.info.get(MapleStatInfo.pdd)); } public int getEnhancedMdef() { return (this.info.get(MapleStatInfo.emdd)); } public int getDOT() { return (this.info.get(MapleStatInfo.dot)); } public int getDOTTime() { return (this.info.get(MapleStatInfo.dotTime)); } public int getCritical() { return (this.info.get(MapleStatInfo.cr)); } public int getCriticalMax() { return (this.info.get(MapleStatInfo.criticaldamageMax)); } public int getCriticalMin() { return (this.info.get(MapleStatInfo.criticaldamageMin)); } public int getArRate() { return (this.info.get(MapleStatInfo.ar)); } public int getASRRate() { return (this.info.get(MapleStatInfo.asrR)); } public int getTERRate() { return (this.info.get(MapleStatInfo.terR)); } public int getDAMRate() { return (this.info.get(MapleStatInfo.damR)); } public int getMdRate() { return (this.info.get(MapleStatInfo.mdR)); } public int getPercentDamageRate() { return (this.info.get(MapleStatInfo.pdR)); } public short getMesoRate() { return this.mesoR; } public int getEXP() { return this.exp; } public int getWdefToMdef() { return (this.info.get(MapleStatInfo.pdd2mdd)); } public int getMdefToWdef() { return (this.info.get(MapleStatInfo.mdd2pdd)); } public int getAvoidToHp() { return (this.info.get(MapleStatInfo.eva2hp)); } public int getAccToMp() { return (this.info.get(MapleStatInfo.acc2mp)); } public int getStrToDex() { return (this.info.get(MapleStatInfo.str2dex)); } public int getDexToStr() { return (this.info.get(MapleStatInfo.dex2str)); } public int getIntToLuk() { return (this.info.get(MapleStatInfo.int2luk)); } public int getLukToDex() { return (this.info.get(MapleStatInfo.luk2dex)); } public int getHpToDamageX() { return (this.info.get(MapleStatInfo.mhp2damX)); } public int getMpToDamageX() { return (this.info.get(MapleStatInfo.mmp2damX)); } public int getLevelToMaxHp() { return (this.info.get(MapleStatInfo.lv2mhp)); } public int getLevelToMaxMp() { return (this.info.get(MapleStatInfo.lv2mmp)); } public int getLevelToDamageX() { return (this.info.get(MapleStatInfo.lv2damX)); } public int getLevelToWatk() { return (this.info.get(MapleStatInfo.lv2pad)); } public int getLevelToMatk() { return (this.info.get(MapleStatInfo.lv2mad)); } public int getLevelToWatkX() { return (this.info.get(MapleStatInfo.lv2pdX)); } public int getLevelToMatkX() { return (this.info.get(MapleStatInfo.lv2mdX)); } public int getEXPLossRate() { return (this.info.get(MapleStatInfo.expLossReduceR)); } public int getBuffTimeRate() { return (this.info.get(MapleStatInfo.bufftimeR)); } public int getSuddenDeathR() { return (this.info.get(MapleStatInfo.suddenDeathR)); } public int getSummonTimeInc() { return (this.info.get(MapleStatInfo.summonTimeR)); } public int getMPConsumeEff() { return (this.info.get(MapleStatInfo.mpConEff)); } public int getAttackX() { return (this.info.get(MapleStatInfo.padX)); } public int getMagicX() { return (this.info.get(MapleStatInfo.madX)); } public int getPercentHP() { return (this.info.get(MapleStatInfo.mhpR)); } public int getPercentMP() { return (this.info.get(MapleStatInfo.mmpR)); } public int getIgnoreMobDamR() { return (this.info.get(MapleStatInfo.ignoreMobDamR)); } public int getConsume() { return this.consumeOnPickup; } public int getSelfDestruction() { return (this.info.get(MapleStatInfo.selfDestruction)); } public int getCharColor() { return this.charColor; } public List<Integer> getPetsCanConsume() { return this.petsCanConsume; } public boolean isReturnScroll() { return (this.skill) && ((this.sourceid == 20031203) || (this.sourceid == 80001040) || (this.sourceid == 20021110)); } public boolean isMechChange() { switch (this.sourceid) { case 35001001: case 35101009: case 35111004: case 35121005: case 35121013: case 35121054: return this.skill; } return false; } public int getRange() { return (this.info.get(MapleStatInfo.range)); } public int getER() { return (this.info.get(MapleStatInfo.er)); } public int getPrice() { return (this.info.get(MapleStatInfo.price)); } public int getExtendPrice() { return (this.info.get(MapleStatInfo.extendPrice)); } public int getPeriod() { return (this.info.get(MapleStatInfo.period)); } public int getReqGuildLevel() { return (this.info.get(MapleStatInfo.reqGuildLevel)); } public byte getEXPRate() { return this.expR; } public short getLifeID() { return this.lifeId; } public short getUseLevel() { return this.useLevel; } public byte getSlotCount() { return this.slotCount; } public byte getSlotPerLine() { return this.slotPerLine; } public int getStr() { return (this.info.get(MapleStatInfo.str)); } public int getStrX() { return (this.info.get(MapleStatInfo.strX)); } public int getStrFX() { return (this.info.get(MapleStatInfo.strFX)); } public int getStrRate() { return (this.info.get(MapleStatInfo.strR)); } public int getDex() { return (this.info.get(MapleStatInfo.dex)); } public int getDexX() { return (this.info.get(MapleStatInfo.dexX)); } public int getDexFX() { return (this.info.get(MapleStatInfo.dexFX)); } public int getDexRate() { return (this.info.get(MapleStatInfo.dexR)); } public int getInt() { return (this.info.get(MapleStatInfo.int_)); } public int getIntX() { return (this.info.get(MapleStatInfo.intX)); } public int getIntFX() { return (this.info.get(MapleStatInfo.intFX)); } public int getIntRate() { return (this.info.get(MapleStatInfo.intR)); } public int getLuk() { return (this.info.get(MapleStatInfo.luk)); } public int getLukX() { return (this.info.get(MapleStatInfo.lukX)); } public int getLukFX() { return (this.info.get(MapleStatInfo.lukFX)); } public int getLukRate() { return (this.info.get(MapleStatInfo.lukR)); } public int getMaxHpX() { return (this.info.get(MapleStatInfo.mhpX)); } public int getMaxMpX() { return (this.info.get(MapleStatInfo.mmpX)); } public int getAccX() { return (this.info.get(MapleStatInfo.accX)); } public int getPercentAcc() { return (this.info.get(MapleStatInfo.accR)); } public int getAvoidX() { return (this.info.get(MapleStatInfo.evaX)); } public int getPercentAvoid() { return (this.info.get(MapleStatInfo.evaR)); } public int getWdefX() { return (this.info.get(MapleStatInfo.pddX)); } public int getMdefX() { return (this.info.get(MapleStatInfo.mddX)); } public int getIndieMHp() { return (this.info.get(MapleStatInfo.indieMhp)); } public int getIndieMMp() { return (this.info.get(MapleStatInfo.indieMmp)); } public int getIndieMhpR() { return (this.info.get(MapleStatInfo.indieMhpR)); } public int getIndieMmpR() { return (this.info.get(MapleStatInfo.indieMmpR)); } public int getIndieAllStat() { return (this.info.get(MapleStatInfo.indieAllStat)); } public int getIndieCr() { return (this.info.get(MapleStatInfo.indieCr)); } public short getIndiePdd() { return this.indiePdd; } public short getIndieMdd() { return this.indieMdd; } public int getIndieDamR() { return (this.info.get(MapleStatInfo.indieDamR)); } public byte getType() { return this.type; } public int getBossDamage() { return (this.info.get(MapleStatInfo.bdR)); } public int getMobCountDamage() { return (this.info.get(MapleStatInfo.mobCountDamR)); } public int getInterval() { return this.interval; } public ArrayList<Pair<Integer, Integer>> getAvailableMaps() { return this.availableMap; } public int getWDEFRate() { return (this.info.get(MapleStatInfo.pddR)); } public int getMDEFRate() { return (this.info.get(MapleStatInfo.mddR)); } public int getKillSpree() { return (this.info.get(MapleStatInfo.kp)); } public int getMaxDamageOver() { return (this.info.get(MapleStatInfo.MDamageOver)); } public int getIndieMaxDamageOver() { return (this.info.get(MapleStatInfo.indieMaxDamageOver)); } public int getCostMpRate() { return (this.info.get(MapleStatInfo.costmpR)); } public int getMPConReduce() { return (this.info.get(MapleStatInfo.mpConReduce)); } public int getIndieMaxDF() { return (this.info.get(MapleStatInfo.MDF)); } public int getTargetPlus() { return (this.info.get(MapleStatInfo.targetPlus)); } public int getForceCon() { return (this.info.get(MapleStatInfo.forceCon)); } public int gethcHp() { return (this.info.get(MapleStatInfo.hcHp)); } public int getsubProp() { return (this.info.get(MapleStatInfo.subProp)); } public int getvehicleID() { Skill skil = SkillFactory.getSkill(sourceid); return skil.getvehicleID(); } public boolean isNotuseMp() { //TODO 添加 不消耗MP技能 switch (this.sourceid) { case 95001000: case 13100022: case 13120003: case 13110022: case 13121054: case 36101001: case 2121054: case 4221052: case 2221012: return true; } return false; } public int setbufftime(int time) { return (this.bufftime = time); } public int settimes(int time) { return (this.times = time); } public static class CancelEffectAction implements Runnable { private final MapleStatEffect effect; private final WeakReference<MapleCharacter> target; private final long startTime; private final List<Pair<MapleBuffStat, Integer>> statup; public CancelEffectAction(MapleCharacter target, MapleStatEffect effect, long startTime, List<Pair<MapleBuffStat, Integer>> statup) { this.effect = effect; this.target = new WeakReference(target); this.startTime = startTime; this.statup = statup; } @Override public void run() { MapleCharacter realTarget = (MapleCharacter) this.target.get(); if (realTarget != null) { realTarget.cancelEffect(this.effect, false, this.startTime, this.statup); } } } }