package client; import constants.GameConstants; import java.util.ArrayList; import java.util.List; import provider.MapleData; import provider.MapleDataTool; import server.MapleStatEffect; import server.Randomizer; import server.life.Element; import server.skill.冒险家.勇士; import server.skill.冒险家.牧师; import server.skill.冒险家.独行客; import tools.FileoutputUtil; import tools.Pair; /** * 技能类 载入技能相关 * */ public class Skill { private String name = ""; private final List<MapleStatEffect> effects = new ArrayList(); private List<MapleStatEffect> pvpEffects = null; private List<Integer> animation = null; private final List<Pair<String, Integer>> requiredSkill = new ArrayList<>(); private Element element = Element.NEUTRAL; private final int id; private int animationTime = 0; private int masterLevel = 0; private int maxLevel = 0; private int delay = 0; private int trueMax = 0; private int eventTamingMob = 0; private int skillType = 0; private boolean invisible = false; private boolean chargeskill = false; private boolean timeLimited = false; private boolean combatOrders = false; private boolean magic = false; private boolean casterMove = false; private boolean pushTarget = false; private boolean pullTarget = false; private boolean isBuffSkill = false; private boolean isSummonSkill = false; private boolean notRemoved = false; private int fixLevel; private int hyper = 0; private int reqLev = 0; private int maxDamageOver = 2147483647; private boolean petPassive = false; private int setItemReason; private int setItemPartsCount; private int vehicleID; public Skill(int id) { this.id = id; } public void setName(String name) { this.name = name; } public int getId() { return this.id; } public String getName() { return this.name; } public static Skill loadFromData(int id, MapleData data, MapleData delayData) { boolean showSkill = false; if (showSkill) { FileoutputUtil.log(FileoutputUtil.SkillsLog, "正在解析技能id: " + id + " 名字: " + SkillFactory.getSkillName(id), true); } Skill ret = new Skill(id); int skillType = MapleDataTool.getInt("skillType", data, -1); String elem = MapleDataTool.getString("elemAttr", data, null); if (elem != null) { ret.element = Element.getFromChar(elem.charAt(0)); } ret.skillType = skillType; ret.invisible = (MapleDataTool.getInt("invisible", data, 0) > 0); ret.notRemoved = (MapleDataTool.getInt("notRemoved", data, 0) > 0); ret.timeLimited = (MapleDataTool.getInt("timeLimited", data, 0) > 0); ret.combatOrders = (MapleDataTool.getInt("combatOrders", data, 0) > 0); ret.fixLevel = MapleDataTool.getInt("fixLevel", data, 0); ret.masterLevel = MapleDataTool.getInt("masterLevel", data, 0); ret.eventTamingMob = MapleDataTool.getInt("eventTamingMob", data, 0); ret.vehicleID = MapleDataTool.getInt("vehicleID", data, 0); ret.hyper = MapleDataTool.getInt("hyper", data, 0); ret.reqLev = MapleDataTool.getInt("reqLev", data, 0); ret.petPassive = (MapleDataTool.getInt("petPassive", data, 0) > 0); ret.setItemReason = MapleDataTool.getInt("setItemReason", data, 0); ret.setItemPartsCount = MapleDataTool.getInt("setItemPartsCount", data, 0); MapleData inf = data.getChildByPath("info"); if (inf != null) { ret.magic = (MapleDataTool.getInt("magicDamage", inf, 0) > 0); ret.casterMove = (MapleDataTool.getInt("casterMove", inf, 0) > 0); ret.pushTarget = (MapleDataTool.getInt("pushTarget", inf, 0) > 0); ret.pullTarget = (MapleDataTool.getInt("pullTarget", inf, 0) > 0); } MapleData effect = data.getChildByPath("effect"); boolean isBuff; if (skillType == 2) { isBuff = true; } else { MapleData action_ = data.getChildByPath("action"); MapleData hit = data.getChildByPath("hit"); MapleData ball = data.getChildByPath("ball"); boolean action = false; if ((action_ == null) && (data.getChildByPath("prepare/action") != null)) { action_ = data.getChildByPath("prepare/action"); action = true; } isBuff = (effect != null) && (hit == null) && (ball == null); String d; if (action_ != null) { if (action) { d = MapleDataTool.getString(action_, null); } else { d = MapleDataTool.getString("0", action_, null); } if (d != null) { isBuff |= d.equals("alert2"); MapleData dd = delayData.getChildByPath(d); if (dd != null) { for (MapleData del : dd) { ret.delay += Math.abs(MapleDataTool.getInt("delay", del, 0)); } if (ret.delay > 30) { ret.delay = (int) Math.round(ret.delay * 11.0D / 16.0D); ret.delay -= ret.delay % 30; } } if (SkillFactory.getDelay(d) != null) { ret.animation = new ArrayList(); ret.animation.add(SkillFactory.getDelay(d)); if (!action) { for (MapleData ddc : action_) { if ((!MapleDataTool.getString(ddc, d).equals(d)) && (!ddc.getName().contentEquals("delay"))) { String c = MapleDataTool.getString(ddc); if (SkillFactory.getDelay(c) != null) { ret.animation.add(SkillFactory.getDelay(c)); } } } } } } } switch (id) { case 1076: case 2111002: case 2111003: case 牧师.群体治愈: case 2321001: case 4301004: isBuff = false; break; case 93: case 1004: case 1026: case 勇士.斗气集中: case 1121016: case 1210016: case 1221014: case 1310016: case 1321014: case 2120010: case 2120012: case 2220010: case 2220013: case 2320011: case 2320012: case 3101004: case 3111011: case 3201004: case 3211012: case 独行客.敛财术: case 4221013: case 4330009: case 4341002: case 4341052: case 5001005: case 5100015: case 5111007: case 5120011: case 5120012: case 5121009: case 5211007: case 5220012: case 5220014: case 5220019: case 5221015: case 5311005: case 5320007: case 5321003: case 5321004: case 5711001: case 5711011: case 5720005: case 5720012: case 5721003: case 1121053://传说冒险家 case 1221053: case 1321053: case 2121053: case 2221053: case 2321053: case 3121053: case 3221053: case 3321053: case 4121053: case 4221053: case 5121053: case 5221053://传说冒险家 case 9001004: case 9101004: case 1221009: case 5121052: isBuff = true; } } ret.chargeskill = (data.getChildByPath("keydown") != null); // 技能等级数据 for (MapleData leve : data.getChildByPath("level")) { ret.effects.add(MapleStatEffect.loadSkillEffectFromData(leve, id, isBuff, Byte.parseByte(leve.getName()), null, ret.notRemoved)); } ret.maxLevel = ret.effects.size(); ret.trueMax = ret.effects.size(); MapleData reqDataRoot = data.getChildByPath("req"); if (reqDataRoot != null) { for (MapleData reqData : reqDataRoot.getChildren()) { ret.requiredSkill.add(new Pair<>(reqData.getName(), MapleDataTool.getInt(reqData, 1))); } } ret.animationTime = 0; if (effect != null) { for (MapleData effectEntry : effect) { ret.animationTime += MapleDataTool.getIntConvert("delay", effectEntry, 0); } } ret.isBuffSkill = isBuff; ret.isSummonSkill = (data.getChildByPath("summon") != null); return ret; } public MapleStatEffect getEffect(int level) { if (this.effects.size() < level) { if (this.effects.size() > 0) { return this.effects.get(this.effects.size() - 1); } return null; } if (level <= 0) { return this.effects.get(0); } return this.effects.get(level - 1); } public MapleStatEffect getPVPEffect(int level) { if (this.pvpEffects == null) { return getEffect(level); } if (this.pvpEffects.size() < level) { if (this.pvpEffects.size() > 0) { return (MapleStatEffect) this.pvpEffects.get(this.pvpEffects.size() - 1); } return null; } if (level <= 0) { return (MapleStatEffect) this.pvpEffects.get(0); } return (MapleStatEffect) this.pvpEffects.get(level - 1); } public int getSkillType() { return this.skillType; } public List<Integer> getAllAnimation() { return this.animation; } public int getAnimation() { if (this.animation == null) { return -1; } return (this.animation.get(Randomizer.nextInt(this.animation.size()))); } public boolean isChargeSkill() { return this.chargeskill; } public boolean isInvisible() { return this.invisible; } public boolean isNotRemoved() { return this.notRemoved; } public int getFixLevel() { return this.fixLevel; } public boolean is特性技能() { return this.fixLevel > 0; } public boolean hasRequiredSkill() { return this.requiredSkill.size() > 0; } public List<Pair<String, Integer>> getRequiredSkills() { return this.requiredSkill; } public int getMaxLevel() { return this.maxLevel; } public int getTrueMax() { return this.trueMax; } public boolean combatOrders() { return this.combatOrders; } public boolean canBeLearnedBy(int job) { int jid = job; int skillForJob = this.id / 10000; if (skillForJob == 0) { return GameConstants.is冒险家(job); } if (jid / 100 != skillForJob / 100) { return false; } if (jid / 1000 != skillForJob / 1000) { return false; } if ((GameConstants.is冒险家(skillForJob)) && (!GameConstants.is冒险家(job))) { return false; } if ((jid / 10 % 10 == 0) && (skillForJob / 10 % 10 > jid / 10 % 10)) { return false; } if ((skillForJob / 10 % 10 != 0) && (skillForJob / 10 % 10 != jid / 10 % 10)) { return false; } return skillForJob % 10 <= jid % 10; } public boolean isTimeLimited() { return this.timeLimited; } public Element getElement() { return this.element; } public int getvehicleID() { return this.vehicleID; } public int getAnimationTime() { return this.animationTime; } public int getMasterLevel() { return this.masterLevel; } public int getDelay() { return this.delay; } public int getTamingMob() { return this.eventTamingMob; } public int getHyper() { return this.hyper; } public int getReqLevel() { return this.reqLev; } public int getMaxDamageOver() { return this.maxDamageOver; } public boolean isMagic() { return this.magic; } public boolean isMovement() { return this.casterMove; } public boolean isPush() { return this.pushTarget; } public boolean isPull() { return this.pullTarget; } public boolean isBuffSkill() { return this.isBuffSkill; } public boolean isSummonSkill() { return this.isSummonSkill; } public boolean isAdminSkill() { int jobId = this.id / 10000; return (jobId == 800) || (jobId == 900); } public boolean isSpecialSkill() { int jobId = this.id / 10000; return (jobId == 7000) || (jobId == 7100) || (jobId == 8000) || (jobId == 9000) || (jobId == 9100) || (jobId == 9200) || (jobId == 9201) || (jobId == 9202) || (jobId == 9203) || (jobId == 9204); } public int getSkillByJobBook() { return getSkillByJobBook(this.id); } public int getSkillByJobBook(int skillid) { switch (skillid / 10000) { case 112: case 122: case 132: case 212: case 222: case 232: case 312: case 322: case 412: case 422: case 512: case 522: return 4; case 111: case 121: case 131: case 211: case 221: case 231: case 311: case 321: case 411: case 421: case 511: case 521: return 3; case 110: case 120: case 130: case 210: case 220: case 230: case 310: case 320: case 410: case 420: case 510: case 520: return 2; case 100: case 200: case 300: case 400: case 500: return 1; } return -1; } public boolean isPetPassive() { return this.petPassive; } public int getSetItemReason() { return this.setItemReason; } public int geSetItemPartsCount() { return this.setItemPartsCount; } }