PageRenderTime 70ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/Trunk/src/net/sf/odinms/server/MapleStatEffect.java

https://github.com/system32/NinjaMS
Java | 1219 lines | 1064 code | 103 blank | 52 comment | 267 complexity | 1a4393236345da8ff7da0266a60cb65c MD5 | raw file
Possible License(s): AGPL-3.0
  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. * ItemEndEffect.java
  20. *
  21. * Created on 29. November 2007, 01:34
  22. *
  23. * To change this template, choose Tools | Template Manager and open the template in the editor.
  24. */
  25. package net.sf.odinms.server;
  26. import java.awt.Point;
  27. import java.awt.Rectangle;
  28. import java.io.Serializable;
  29. import java.lang.ref.WeakReference;
  30. import java.util.ArrayList;
  31. import java.util.Arrays;
  32. import java.util.Collections;
  33. import java.util.List;
  34. import java.util.Map;
  35. import java.util.concurrent.ScheduledFuture;
  36. import net.sf.odinms.client.Enums.MapleBuffStat;
  37. import net.sf.odinms.client.Enums.MapleJob;
  38. import net.sf.odinms.client.Enums.MapleStat;
  39. import net.sf.odinms.client.Inventory.IItem;
  40. import net.sf.odinms.client.ISkill;
  41. import net.sf.odinms.client.MapleCharacter;
  42. import net.sf.odinms.client.Inventory.MapleInventory;
  43. import net.sf.odinms.client.Inventory.MapleInventoryType;
  44. import net.sf.odinms.client.SkillFactory;
  45. import net.sf.odinms.server.constants.Skills;
  46. import net.sf.odinms.client.status.MonsterStatus;
  47. import net.sf.odinms.client.status.MonsterStatusEffect;
  48. import net.sf.odinms.net.MaplePacket;
  49. import net.sf.odinms.net.channel.ChannelServer;
  50. import net.sf.odinms.provider.MapleData;
  51. import net.sf.odinms.provider.MapleDataTool;
  52. import net.sf.odinms.server.life.MapleMonster;
  53. import net.sf.odinms.server.maps.MapleDoor;
  54. import net.sf.odinms.server.maps.MapleMap;
  55. import net.sf.odinms.server.maps.MapleMapObject;
  56. import net.sf.odinms.server.maps.MapleMapObjectType;
  57. import net.sf.odinms.server.maps.MapleMist;
  58. import net.sf.odinms.server.maps.MapleSummon;
  59. import net.sf.odinms.server.maps.SummonMovementType;
  60. import net.sf.odinms.tools.ArrayMap;
  61. import net.sf.odinms.tools.MaplePacketCreator;
  62. import net.sf.odinms.tools.Pair;
  63. /**
  64. * @author Matze
  65. * @author Frz
  66. */
  67. public class MapleStatEffect implements Serializable {
  68. static final long serialVersionUID = 9179541993413738569L;
  69. private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MapleStatEffect.class);
  70. private short watk, matk, wdef, mdef, acc, avoid, hands, speed, jump;
  71. private short hp, mp;
  72. private double hpR, mpR;
  73. private short mpCon, hpCon;
  74. private int duration;
  75. private boolean overTime;
  76. private int sourceid;
  77. private int moveTo;
  78. private boolean skill;
  79. private List<Pair<MapleBuffStat, Integer>> statups;
  80. private Map<MonsterStatus, Integer> monsterStatus;
  81. private int x, y, z;
  82. private double prop;
  83. private int itemCon, itemConNo;
  84. private int damage, attackCount, bulletCount, bulletConsume;
  85. private Point lt, rb;
  86. private int mobCount;
  87. private int moneyCon;
  88. private int cooldown;
  89. private int fixDamage;
  90. private int morphId = 0;
  91. private MapleStatEffect() {
  92. }
  93. public static MapleStatEffect loadSkillEffectFromData(MapleData source, int skillid, boolean overtime) {
  94. return loadFromData(source, skillid, true, overtime);
  95. }
  96. public static MapleStatEffect loadItemEffectFromData(MapleData source, int itemid) {
  97. return loadFromData(source, itemid, false, false);
  98. }
  99. private static void addBuffStatPairToListIfNotZero(List<Pair<MapleBuffStat, Integer>> list, MapleBuffStat buffstat, Integer val) {
  100. if (val.intValue() != 0) {
  101. list.add(new Pair<MapleBuffStat, Integer>(buffstat, val));
  102. }
  103. }
  104. private static MapleStatEffect loadFromData(MapleData source, int sourceid, boolean skill, boolean overTime) {
  105. MapleStatEffect ret = new MapleStatEffect();
  106. ret.duration = MapleDataTool.getInt("time", source, -1);
  107. ret.hp = (short) MapleDataTool.getInt("hp", source, 0);
  108. ret.hpR = MapleDataTool.getInt("hpR", source, 0) / 100.0;
  109. ret.mp = (short) MapleDataTool.getInt("mp", source, 0);
  110. ret.mpR = MapleDataTool.getInt("mpR", source, 0) / 100.0;
  111. ret.mpCon = (short) MapleDataTool.getInt("mpCon", source, 0);
  112. ret.hpCon = (short) MapleDataTool.getInt("hpCon", source, 0);
  113. int iprop = MapleDataTool.getInt("prop", source, 100);
  114. ret.prop = iprop / 100.0;
  115. ret.mobCount = MapleDataTool.getInt("mobCount", source, 1);
  116. ret.cooldown = MapleDataTool.getInt("cooltime", source, 0);
  117. ret.fixDamage = MapleDataTool.getInt("fixdamage", source, 0);
  118. ret.morphId = MapleDataTool.getInt("morph", source, 0);
  119. ret.sourceid = sourceid;
  120. ret.skill = skill;
  121. if (!ret.skill && ret.duration > -1) {
  122. ret.overTime = true;
  123. } else {
  124. ret.duration *= 1000;
  125. ret.overTime = overTime;
  126. }
  127. ArrayList<Pair<MapleBuffStat, Integer>> statups = new ArrayList<Pair<MapleBuffStat, Integer>>();
  128. ret.watk = (short) MapleDataTool.getInt("pad", source, 0);
  129. ret.wdef = (short) MapleDataTool.getInt("pdd", source, 0);
  130. ret.matk = (short) MapleDataTool.getInt("mad", source, 0);
  131. ret.mdef = (short) MapleDataTool.getInt("mdd", source, 0);
  132. ret.acc = (short) MapleDataTool.getIntConvert("acc", source, 0);
  133. ret.avoid = (short) MapleDataTool.getInt("eva", source, 0);
  134. ret.speed = (short) MapleDataTool.getInt("speed", source, 0);
  135. ret.jump = (short) MapleDataTool.getInt("jump", source, 0);
  136. if (ret.overTime && ret.getSummonMovementType() == null) {
  137. addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WATK, Integer.valueOf(ret.watk));
  138. addBuffStatPairToListIfNotZero(statups, MapleBuffStat.WDEF, Integer.valueOf(ret.wdef));
  139. addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MATK, Integer.valueOf(ret.matk));
  140. addBuffStatPairToListIfNotZero(statups, MapleBuffStat.MDEF, Integer.valueOf(ret.mdef));
  141. addBuffStatPairToListIfNotZero(statups, MapleBuffStat.ACC, Integer.valueOf(ret.acc));
  142. addBuffStatPairToListIfNotZero(statups, MapleBuffStat.AVOID, Integer.valueOf(ret.avoid));
  143. addBuffStatPairToListIfNotZero(statups, MapleBuffStat.SPEED, Integer.valueOf(ret.speed));
  144. addBuffStatPairToListIfNotZero(statups, MapleBuffStat.JUMP, Integer.valueOf(ret.jump));
  145. }
  146. MapleData ltd = source.getChildByPath("lt");
  147. if (ltd != null) {
  148. ret.lt = (Point) ltd.getData();
  149. ret.rb = (Point) source.getChildByPath("rb").getData();
  150. }
  151. int x = MapleDataTool.getInt("x", source, 0);
  152. ret.x = x;
  153. ret.y = MapleDataTool.getInt("y", source, 0);
  154. ret.z = MapleDataTool.getInt("z", source, 0);
  155. ret.damage = MapleDataTool.getIntConvert("damage", source, 100);
  156. ret.attackCount = MapleDataTool.getIntConvert("attackCount", source, 1);
  157. ret.bulletCount = MapleDataTool.getIntConvert("bulletCount", source, 1);
  158. ret.bulletConsume = MapleDataTool.getIntConvert("bulletConsume", source, 0);
  159. ret.moneyCon = MapleDataTool.getIntConvert("moneyCon", source, 0);
  160. ret.itemCon = MapleDataTool.getInt("itemCon", source, 0);
  161. ret.itemConNo = MapleDataTool.getInt("itemConNo", source, 0);
  162. ret.moveTo = MapleDataTool.getInt("moveTo", source, -1);
  163. Map<MonsterStatus, Integer> monsterStatus = new ArrayMap<MonsterStatus, Integer>();
  164. if (skill) {
  165. switch (sourceid) {
  166. case Skills.Magician.MagicGuard:
  167. case Skills.BlazeWizard1.MagicGuard:
  168. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.MAGIC_GUARD, Integer.valueOf(x)));
  169. break;
  170. case Skills.Cleric.Invincible:
  171. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.INVINCIBLE, Integer.valueOf(x)));
  172. break;
  173. case Skills.SuperGM.Hide:
  174. ret.duration = 2100000000;
  175. ret.overTime = true;
  176. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.GM_HIDE, Integer.valueOf(0)));
  177. break;
  178. case Skills.Rogue.DarkSight:
  179. case Skills.NightWalker1.DarkSight:
  180. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DARKSIGHT, Integer.valueOf(x)));
  181. break;
  182. case Skills.ChiefBandit.Pickpocket:
  183. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.PICKPOCKET, Integer.valueOf(x)));
  184. break;
  185. case Skills.ChiefBandit.MesoGuard:
  186. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.MESOGUARD, Integer.valueOf(x)));
  187. break;
  188. case Skills.Hermit.MesoUp:
  189. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.MESOUP, Integer.valueOf(x)));
  190. break;
  191. case Skills.Hermit.ShadowPartner:
  192. case Skills.NightWalker3.ShadowPartner:
  193. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.SHADOWPARTNER, Integer.valueOf(x)));
  194. break;
  195. case Skills.Hunter.SoulArrow:
  196. case Skills.CrossBowMan.SoulArrow:
  197. case Skills.WindArcher2.SoulArrow:
  198. case Skills.Priest.MysticDoor:
  199. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.SOULARROW, Integer.valueOf(x)));
  200. break;
  201. case Skills.WhiteKnight.BlizzardChargeBW:
  202. case Skills.WhiteKnight.IceChargeSword:
  203. case Skills.WhiteKnight.FlameChargeBW:
  204. case Skills.WhiteKnight.FireChargeSword:
  205. case Skills.WhiteKnight.LightningChargeBW:
  206. case Skills.WhiteKnight.ThunderChargeSword:
  207. case Skills.Paladin.DivineChargeBW:
  208. case Skills.Paladin.HolyChargeSword:
  209. case Skills.ThunderBreaker2.LightningCharge:
  210. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.WK_CHARGE, Integer.valueOf(x)));
  211. break;
  212. case Skills.Fighter.AxeBooster:
  213. case Skills.Fighter.SwordBooster:
  214. case Skills.Page.BWBooster:
  215. case Skills.Page.SwordBooster:
  216. case Skills.Spearman.PoleArmBooster:
  217. case Skills.Spearman.SpearBooster:
  218. case Skills.Hunter.BowBooster:
  219. case Skills.CrossBowMan.CrossbowBooster:
  220. case Skills.Assassin.ClawBooster:
  221. case Skills.Bandit.DaggerBooster:
  222. case Skills.FPMage.SpellBooster:
  223. case Skills.ILMage.SpellBooster:
  224. case Skills.Brawler.KnucklerBooster:
  225. case Skills.Gunslinger.GunBooster:
  226. case Skills.DawnWarrior2.SwordBooster:
  227. case Skills.BlazeWizard2.SpellBooster:
  228. case Skills.WindArcher2.BowBooster:
  229. case Skills.NightWalker2.ClawBooster:
  230. case Skills.ThunderBreaker2.KnuckleBooster:
  231. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.BOOSTER, Integer.valueOf(x)));
  232. break;
  233. case Skills.Fighter.PowerGuard:
  234. case Skills.Page.PowerGuard:
  235. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.POWERGUARD, Integer.valueOf(x)));
  236. break;
  237. case Skills.Spearman.HyperBody:
  238. case Skills.SuperGM.HyperBody:
  239. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.HYPERBODYHP, Integer.valueOf(x)));
  240. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.HYPERBODYMP, Integer.valueOf(ret.y)));
  241. break;
  242. case Skills.Beginner.Recovery:
  243. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.RECOVERY, Integer.valueOf(x)));
  244. break;
  245. case Skills.Crusader.ComboAttack:
  246. case Skills.DawnWarrior3.ComboAttack:
  247. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.COMBO, Integer.valueOf(1)));
  248. break;
  249. case Skills.Beginner.MonsterRider:
  250. case Skills.Noblesse.MonsterRider:
  251. case Skills.Corsair.Battleship:
  252. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.MONSTER_RIDING, Integer.valueOf(sourceid)));
  253. break;
  254. case Skills.DragonKnight.DragonRoar:
  255. ret.hpR = -x / 100.0;
  256. break;
  257. case Skills.DragonKnight.DragonBlood:
  258. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DRAGONBLOOD, Integer.valueOf(ret.x)));
  259. break;
  260. case Skills.Hero.MapleWarrior:
  261. case Skills.Paladin.MapleWarrior:
  262. case Skills.DarkKnight.MapleWarrior:
  263. case Skills.FPArchMage.MapleWarrior:
  264. case Skills.ILArchMage.MapleWarrior:
  265. case Skills.Bishop.MapleWarrior:
  266. case Skills.Bowmaster.MapleWarrior:
  267. case Skills.Marksman.MapleWarrior:
  268. case Skills.NightLord.MapleWarrior:
  269. case Skills.Shadower.MapleWarrior:
  270. case Skills.Buccaneer.MapleWarrior:
  271. case Skills.Corsair.MapleWarrior:
  272. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.MAPLE_WARRIOR, Integer.valueOf(ret.x)));
  273. break;
  274. case Skills.Bowmaster.SharpEyes:
  275. case Skills.Marksman.SharpEyes:
  276. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.SHARP_EYES, Integer.valueOf(ret.x << 8 | ret.y)));
  277. break;
  278. case Skills.Rogue.Disorder:
  279. monsterStatus.put(MonsterStatus.WATK, Integer.valueOf(ret.x));
  280. monsterStatus.put(MonsterStatus.WDEF, Integer.valueOf(ret.y));
  281. break;
  282. case Skills.Page.Threaten:
  283. monsterStatus.put(MonsterStatus.WATK, Integer.valueOf(ret.x));
  284. monsterStatus.put(MonsterStatus.WDEF, Integer.valueOf(ret.y));
  285. break;
  286. case Skills.Crusader.Shout:
  287. case Skills.Crusader.SwordComa:
  288. case Skills.Crusader.AxeComa:
  289. case Skills.WhiteKnight.ChargedBlow:
  290. case Skills.Hunter.ArrowBomb:
  291. case Skills.ChiefBandit.Assaulter:
  292. case Skills.Shadower.BoomerangStep:
  293. case Skills.Brawler.BackspinBlow:
  294. case Skills.Brawler.DoubleUppercut:
  295. case Skills.Buccaneer.Demolition:
  296. case Skills.Buccaneer.Snatch:
  297. case Skills.Buccaneer.Barrage:
  298. case Skills.Gunslinger.BlankShot:
  299. case Skills.DawnWarrior3.Coma:
  300. monsterStatus.put(MonsterStatus.STUN, Integer.valueOf(1));
  301. break;
  302. case Skills.ILMagician.ColdBeam:
  303. case Skills.ILMage.IceStrike:
  304. case Skills.ILMage.ElementComposition:
  305. case Skills.ILArchMage.Blizzard:
  306. case Skills.Sniper.Blizzard:
  307. case Skills.Outlaw.IceSplitter:
  308. monsterStatus.put(MonsterStatus.FREEZE, Integer.valueOf(1));
  309. ret.duration *= 2;
  310. break;
  311. case Skills.FPMagician.Slow:
  312. case Skills.ILMagician.Slow:
  313. case Skills.BlazeWizard2.Slow:
  314. monsterStatus.put(MonsterStatus.SPEED, Integer.valueOf(ret.x));
  315. break;
  316. case Skills.FPMagician.PoisonBreath:
  317. case Skills.FPMage.ElementComposition:
  318. monsterStatus.put(MonsterStatus.POISON, Integer.valueOf(1));
  319. break;
  320. case Skills.Priest.Doom:
  321. monsterStatus.put(MonsterStatus.DOOM, Integer.valueOf(1));
  322. break;
  323. case Skills.Ranger.Puppet:
  324. case Skills.Sniper.Puppet:
  325. case Skills.WindArcher3.Puppet:
  326. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.PUPPET, Integer.valueOf(1)));
  327. break;
  328. case Skills.Ranger.SilverHawk:
  329. case Skills.Sniper.GoldenEagle:
  330. monsterStatus.put(MonsterStatus.STUN, Integer.valueOf(1));
  331. case Skills.FPArchMage.Elquines:
  332. case Skills.Marksman.Frostprey:
  333. monsterStatus.put(MonsterStatus.FREEZE, Integer.valueOf(1));
  334. case Skills.ILArchMage.Ifrit:
  335. case Skills.Priest.SummonDragon:
  336. case Skills.Bishop.Bahamut:
  337. case Skills.Bowmaster.Phoenix:
  338. case Skills.Outlaw.Octopus:
  339. case Skills.Outlaw.Gaviota:
  340. case Skills.Corsair.WrathOfTheOctopi:
  341. case Skills.DawnWarrior1.Soul:
  342. case Skills.BlazeWizard1.Flame:
  343. case Skills.BlazeWizard3.Ifrit:
  344. case Skills.WindArcher1.Storm:
  345. case Skills.NightWalker1.Darkness:
  346. case Skills.ThunderBreaker1.Lightning:
  347. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.SUMMON, Integer.valueOf(1)));
  348. break;
  349. case Skills.Priest.HolySymbol:
  350. case Skills.SuperGM.HolySymbol:
  351. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.HOLY_SYMBOL, Integer.valueOf(x)));
  352. break;
  353. case Skills.FPMage.Seal:
  354. case Skills.ILMage.Seal:
  355. case Skills.BlazeWizard3.Seal:
  356. monsterStatus.put(MonsterStatus.SEAL, 1);
  357. break;
  358. case Skills.Hermit.ShadowWeb:
  359. case Skills.NightWalker3.ShadowWeb:
  360. monsterStatus.put(MonsterStatus.SHADOW_WEB, 1);
  361. break;
  362. case Skills.NightLord.ShadowStars:
  363. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.SHADOW_CLAW, Integer.valueOf(0)));
  364. break;
  365. case Skills.FPArchMage.Infinity:
  366. case Skills.ILArchMage.Infinity:
  367. case Skills.Bishop.Infinity:
  368. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.INFINITY, Integer.valueOf(x)));
  369. break;
  370. case Skills.Hero.PowerStance:
  371. case Skills.Paladin.PowerStance:
  372. case Skills.DarkKnight.PowerStance:
  373. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.STANCE, Integer.valueOf(iprop)));
  374. break;
  375. case Skills.Beginner.EchoOfHero:
  376. case Skills.Noblesse.EchoOfHero:
  377. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.ECHO_OF_HERO, Integer.valueOf(ret.x)));
  378. break;
  379. case Skills.Bishop.HolyShield:
  380. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.HOLY_SHIELD, Integer.valueOf(x)));
  381. break;
  382. case Skills.Bowmaster.Hamstring:
  383. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.HAMSTRING, Integer.valueOf(x)));
  384. monsterStatus.put(MonsterStatus.SPEED, x);
  385. break;
  386. case Skills.Marksman.Blind:
  387. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.BLIND, Integer.valueOf(x)));
  388. monsterStatus.put(MonsterStatus.ACC, x);
  389. break;
  390. case Skills.Brawler.OakBarrel:
  391. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.MORPH, Integer.valueOf(ret.morphId)));
  392. break;
  393. case Skills.Marauder.Transformation:
  394. case Skills.Buccaneer.SuperTransformation:
  395. case Skills.WindArcher3.EagleEye:
  396. case Skills.ThunderBreaker3.Transformation:
  397. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.MORPH, Integer.valueOf(ret.morphId)));
  398. break;
  399. case Skills.Pirate.Dash:
  400. case Skills.ThunderBreaker1.Dash:
  401. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DASH, Integer.valueOf(x)));
  402. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DASH2, Integer.valueOf(ret.y)));
  403. break;
  404. case Skills.Buccaneer.SpeedInfusion:
  405. case Skills.ThunderBreaker3.SpeedInfusion:
  406. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.SPEED_INFUSION, Integer.valueOf(x)));
  407. break;
  408. case Skills.Marauder.EnergyCharge:
  409. case Skills.ThunderBreaker2.EnergyCharge:
  410. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.ENERGY_CHARGE, Integer.valueOf(0)));
  411. case Skills.Outlaw.HomingBeacon:
  412. case Skills.Corsair.Bullseye:
  413. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.HOMING_BEACON, Integer.valueOf(0)));
  414. break;
  415. default:
  416. // nothing needs to be added, that's ok
  417. }
  418. }
  419. if (ret.isMorph()) {
  420. statups.add(new Pair<MapleBuffStat, Integer>(MapleBuffStat.MORPH, Integer.valueOf(ret.getMorph())));
  421. }
  422. ret.monsterStatus = monsterStatus;
  423. statups.trimToSize();
  424. ret.statups = statups;
  425. return ret;
  426. }
  427. /**
  428. * @param applyto
  429. * @param obj
  430. * @param attack damage done by the skill
  431. */
  432. public void applyPassive(MapleCharacter applyto, MapleMapObject obj, int attack) {
  433. if (makeChanceResult()) {
  434. switch (sourceid) {
  435. // MP eater
  436. case Skills.FPMagician.MPEater:
  437. case Skills.ILMagician.MPEater:
  438. case Skills.Cleric.MPEater:
  439. if (obj == null || obj.getType() != MapleMapObjectType.MONSTER) {
  440. return;
  441. }
  442. MapleMonster mob = (MapleMonster) obj;
  443. // x is absorb percentage
  444. if (!mob.isBoss()) {
  445. int absorbMp = Math.min((int) (mob.getMaxMp() * (getX() / 100.0)), mob.getMp());
  446. if (absorbMp > 0) {
  447. mob.setMp(mob.getMp() - absorbMp);
  448. applyto.addMP(absorbMp);
  449. applyto.getClient().getSession().write(MaplePacketCreator.showOwnBuffEffect(sourceid, 1));
  450. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.showBuffeffect(applyto.getId(), sourceid, 1), false);
  451. }
  452. }
  453. break;
  454. }
  455. }
  456. }
  457. public boolean applyTo(MapleCharacter chr) {
  458. return applyTo(chr, chr, true, null, 0);
  459. }
  460. public boolean applyTo(MapleCharacter chr, Point pos) {
  461. return applyTo(chr, chr, true, pos, 0);
  462. }
  463. public boolean applyTo(MapleCharacter chr, Point pos, int addedInfo) {
  464. return applyTo(chr, chr, true, pos, addedInfo);
  465. }
  466. private boolean applyTo(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary, Point pos, int addedInfo) {
  467. int hpchange = calcHPChange(applyfrom, primary);
  468. int mpchange = calcMPChange(applyfrom, primary);
  469. if (primary) {
  470. if (itemConNo != 0) {
  471. MapleInventoryType type = MapleItemInformationProvider.getInstance().getInventoryType(itemCon);
  472. MapleInventoryManipulator.removeById(applyto.getClient(), type, itemCon, itemConNo, false, true);
  473. }
  474. }
  475. List<Pair<MapleStat, Integer>> hpmpupdate = new ArrayList<Pair<MapleStat, Integer>>(2);
  476. if (!primary && isResurrection()) {
  477. hpchange = applyto.getMaxHp();
  478. applyto.setStance(4); // credits to me for finding the right standing up stance :P ()
  479. final MapleCharacter applytoo = applyto;
  480. TimerManager.getInstance().schedule(new Runnable() {
  481. @Override
  482. public void run() {
  483. applytoo.getMap().broadcastMessage(applytoo, MaplePacketCreator.removePlayerFromMap(applytoo.getObjectId()), false);
  484. applytoo.getMap().broadcastMessage(applytoo, MaplePacketCreator.spawnPlayerMapobject(applytoo), false);
  485. MapleCharacter mc = applytoo;
  486. if (mc.getChalkboard() != null) {
  487. mc.getMap().broadcastMessage(mc, (MaplePacketCreator.useChalkboard(mc, false)), false);
  488. }
  489. } // credits destinyms for giving me the crappy inspiration to do it like this.
  490. }, 1000); // allow one second so the ressurection effect shows
  491. }
  492. if (isDispel() && makeChanceResult() && !isGmBuff()) {
  493. applyto.dispelDebuffs();
  494. }
  495. if (isDispel() && makeChanceResult() && isGmBuff()) {
  496. applyto.dispelAllDebuffs();
  497. }
  498. if (applyto.getMapId() != 910000001 || applyto.isJounin() || isGmBuff()) {
  499. if (hpchange != 0) {
  500. if (hpchange < 0 && (-hpchange) > applyto.getHp()) {
  501. return false;
  502. }
  503. int newHp = applyto.getHp() + hpchange;
  504. if (newHp < 1) {
  505. newHp = 1;
  506. }
  507. applyto.setHp(newHp);
  508. hpmpupdate.add(new Pair<MapleStat, Integer>(MapleStat.HP, Integer.valueOf(applyto.getHp())));
  509. }
  510. } else {
  511. applyto.dropMessage("You cannot pot in this Map");
  512. }
  513. if (mpchange != 0) {
  514. if (mpchange < 0 && (-mpchange) > applyto.getMp()) {
  515. return false;
  516. }
  517. applyto.setMp(applyto.getMp() + mpchange);
  518. hpmpupdate.add(new Pair<MapleStat, Integer>(MapleStat.MP, Integer.valueOf(applyto.getMp())));
  519. }
  520. applyto.getClient().getSession().write(MaplePacketCreator.updatePlayerStats(hpmpupdate, true));
  521. if (moveTo != -1) {
  522. MapleMap target;
  523. if (moveTo == 999999999) {
  524. target = applyto.getMap().getReturnMap();
  525. } else {
  526. target = ChannelServer.getInstance(applyto.getClient().getChannel()).getMapFactory().getMap(moveTo);
  527. if (target.getId() / 10000000 != 21 && applyto.getMapId() / 10000000 != 20) {
  528. if (target.getId() / 10000000 != applyto.getMapId() / 10000000) {
  529. log.info("Player {} is trying to use a return scroll to an illegal location ({}->{})", new Object[]{applyto.getName(), applyto.getMapId(), target.getId()});
  530. return false;
  531. }
  532. }
  533. }
  534. applyto.changeMap(target, target.getPortal(0));
  535. }
  536. if (isShadowClaw()) {
  537. MapleInventory use = applyto.getInventory(MapleInventoryType.USE);
  538. MapleItemInformationProvider mii = MapleItemInformationProvider.getInstance();
  539. int projectile = 0;
  540. for (int i = 0; i < 255; i++) { // impose order...
  541. IItem item = use.getItem((byte) i);
  542. if (item != null) {
  543. boolean isStar = mii.isThrowingStar(item.getItemId());
  544. if (isStar && item.getQuantity() >= 200) {
  545. projectile = item.getItemId();
  546. break;
  547. }
  548. }
  549. }
  550. if (projectile == 0) {
  551. return false;
  552. } else {
  553. MapleInventoryManipulator.removeById(applyto.getClient(), MapleInventoryType.USE, projectile, 200, false, true);
  554. }
  555. }
  556. if (overTime) {
  557. applyBuffEffect(applyfrom, applyto, primary, addedInfo);
  558. }
  559. if (primary && (overTime || isHeal())) {
  560. applyBuff(applyfrom, addedInfo);
  561. }
  562. if (primary && isMonsterBuff()) {
  563. applyMonsterBuff(applyfrom);
  564. }
  565. SummonMovementType summonMovementType = getSummonMovementType();
  566. if (summonMovementType != null && pos != null) {
  567. final MapleSummon tosummon = new MapleSummon(applyfrom, sourceid, pos, summonMovementType);
  568. if (!tosummon.isPuppet()) {
  569. applyfrom.getCheatTracker().resetSummonAttack();
  570. }
  571. applyfrom.getMap().spawnSummon(tosummon);
  572. applyfrom.getSummons().put(sourceid, tosummon);
  573. tosummon.addHP(x);
  574. }
  575. // Magic Door
  576. if (isMagicDoor()) {
  577. //applyto.cancelMagicDoor();
  578. Point doorPosition = new Point(applyto.getPosition());
  579. //doorPosition.y -= 280;
  580. MapleDoor door = new MapleDoor(applyto, doorPosition);
  581. applyto.getMap().spawnDoor(door);
  582. applyto.addDoor(door);
  583. door = new MapleDoor(door);
  584. applyto.addDoor(door);
  585. door.getTown().spawnDoor(door);
  586. if (applyto.getParty() != null) {
  587. // update town doors
  588. applyto.silentPartyUpdate();
  589. }
  590. applyto.disableDoor();
  591. } else if (isMist()) {
  592. Rectangle bounds = calculateBoundingBox(applyfrom.getPosition(), applyfrom.isFacingLeft());
  593. MapleMist mist = new MapleMist(bounds, applyfrom, this);
  594. applyfrom.getMap().spawnMist(mist, getDuration(), sourceid == Skills.FPMage.PoisonMist, false);
  595. }
  596. return true;
  597. }
  598. private void applyBuff(MapleCharacter applyfrom, int addedInfo) {
  599. if (isPartyBuff() && (applyfrom.getParty() != null || isGmBuff())) {
  600. Rectangle bounds = calculateBoundingBox(applyfrom.getPosition(), applyfrom.isFacingLeft());
  601. List<MapleMapObject> affecteds = applyfrom.getMap().getMapObjectsInBox(bounds, Arrays.asList(MapleMapObjectType.PLAYER));
  602. List<MapleCharacter> affectedp = new ArrayList<MapleCharacter>(affecteds.size());
  603. for (MapleMapObject affectedmo : affecteds) {
  604. MapleCharacter affected = (MapleCharacter) affectedmo;
  605. if (affected != applyfrom && (isGmBuff() || applyfrom.getParty().equals(affected.getParty()))) {
  606. boolean isRessurection = isResurrection();
  607. if ((isRessurection && !affected.isAlive()) || (!isRessurection && affected.isAlive())) {
  608. affectedp.add(affected);
  609. }
  610. }
  611. }
  612. for (MapleCharacter affected : affectedp) {
  613. // TODO actually heal (and others) shouldn't recalculate everything
  614. // for heal this is an actual bug since heal hp is decreased with the number
  615. // of affected players
  616. applyTo(applyfrom, affected, false, null, addedInfo);
  617. affected.getClient().getSession().write(MaplePacketCreator.showOwnBuffEffect(sourceid, 2));
  618. affected.getMap().broadcastMessage(affected, MaplePacketCreator.showBuffeffect(affected.getId(), sourceid, 2), false);
  619. }
  620. }
  621. }
  622. private void applyMonsterBuff(MapleCharacter applyfrom) {
  623. Rectangle bounds = calculateBoundingBox(applyfrom.getPosition(), applyfrom.isFacingLeft());
  624. List<MapleMapObject> affected = applyfrom.getMap().getMapObjectsInBox(bounds, Arrays.asList(MapleMapObjectType.MONSTER));
  625. ISkill skill_ = SkillFactory.getSkill(sourceid);
  626. int i = 0;
  627. for (MapleMapObject mo : affected) {
  628. MapleMonster monster = (MapleMonster) mo;
  629. if (makeChanceResult()) {
  630. monster.applyStatus(applyfrom, new MonsterStatusEffect(getMonsterStati(), skill_, false), isPoison(), getDuration());
  631. }
  632. i++;
  633. if (i >= mobCount) {
  634. break;
  635. }
  636. }
  637. }
  638. private Rectangle calculateBoundingBox(Point posFrom, boolean facingLeft) {
  639. Point mylt;
  640. Point myrb;
  641. if (facingLeft) {
  642. mylt = new Point(lt.x + posFrom.x, lt.y + posFrom.y);
  643. myrb = new Point(rb.x + posFrom.x, rb.y + posFrom.y);
  644. } else {
  645. myrb = new Point(lt.x * -1 + posFrom.x, rb.y + posFrom.y);
  646. mylt = new Point(rb.x * -1 + posFrom.x, lt.y + posFrom.y);
  647. }
  648. Rectangle bounds = new Rectangle(mylt.x, mylt.y, myrb.x - mylt.x, myrb.y - mylt.y);
  649. return bounds;
  650. }
  651. public void silentApplyBuff(MapleCharacter chr, long starttime) {
  652. int localDuration = duration;
  653. localDuration = alchemistModifyVal(chr, localDuration, false);
  654. CancelEffectAction cancelAction = new CancelEffectAction(chr, this, starttime);
  655. ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + localDuration) - System.currentTimeMillis()));
  656. chr.registerEffect(this, starttime, schedule);
  657. SummonMovementType summonMovementType = getSummonMovementType();
  658. if (summonMovementType != null) {
  659. final MapleSummon tosummon = new MapleSummon(chr, sourceid, chr.getPosition(), summonMovementType);
  660. if (!tosummon.isPuppet()) {
  661. chr.getCheatTracker().resetSummonAttack();
  662. chr.getSummons().put(sourceid, tosummon);
  663. tosummon.addHP(x);
  664. }
  665. }
  666. }
  667. private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary, int addedInfo) {
  668. applyto.cancelEffect(this, true, -1);
  669. List<Pair<MapleBuffStat, Integer>> localstatups = statups;
  670. int localDuration = duration;
  671. if (isMonsterRiding() || isBattleship()) {
  672. int mountId = 0;
  673. IItem mount = applyfrom.getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -18);
  674. if (mount != null) {
  675. mountId = mount.getItemId();
  676. }
  677. if (isBattleship()) {
  678. mountId = 1932000;
  679. }
  680. applyto.getClient().getSession().write(MaplePacketCreator.giveMountBuff(sourceid, mountId));
  681. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.showMountBuff(applyto.getId(), sourceid, mountId), false);
  682. long starttime = System.currentTimeMillis();
  683. CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime);
  684. ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, localDuration);
  685. applyto.registerEffect(this, starttime, schedule);
  686. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.showBuffeffect(applyto.getId(), sourceid, 1), false);
  687. return;
  688. }
  689. if (isSkillMorph()) {
  690. localstatups = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.MORPH, getMorph(applyto)));
  691. }
  692. if (primary) {
  693. localDuration = alchemistModifyVal(applyfrom, localDuration, false);
  694. }
  695. if (localstatups.size() > 0) {
  696. MaplePacket buff = MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), localDuration, localstatups);
  697. if (isDash()) {
  698. buff = MaplePacketCreator.givePirateBuff(sourceid, localDuration / 1000, localstatups);
  699. }
  700. if (isEnergyCharge()) {
  701. localstatups = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.ENERGY_CHARGE, 10000));
  702. buff = MaplePacketCreator.givePirateBuff(sourceid, localDuration / 1000, localstatups);
  703. }
  704. if (isSpeedInfusion()) {
  705. buff = MaplePacketCreator.giveSpeedInfusion(sourceid, localDuration / 1000, localstatups, addedInfo);
  706. }
  707. applyto.getClient().getSession().write(buff);
  708. } else {
  709. // log.warn(MapleClient.getLogMessage(applyto, "Applying empty statups (skill {}, id {})", skill, sourceid));
  710. }
  711. if (isDash() || isEnergyCharge()) {
  712. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.showPirateBuff(applyto.getId(), sourceid, localDuration, localstatups), false);
  713. }
  714. if (isSpeedInfusion()) {
  715. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.showSpeedInfusion(applyto.getId(), sourceid, localDuration, localstatups), false);
  716. }
  717. if (isDs()) {
  718. List<Pair<MapleBuffStat, Integer>> dsstat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DARKSIGHT, 0));
  719. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.giveForeignBuff(applyto.getId(), dsstat, false), false);
  720. }
  721. if (isCombo()) {
  722. List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.COMBO, 1));
  723. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.giveForeignBuff(applyto.getId(), stat, false), false);
  724. }
  725. if (isShadowPartner()) {
  726. List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.SHADOWPARTNER, 0));
  727. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.giveForeignBuff(applyto.getId(), stat, false), false);
  728. }
  729. if (isSoulArrow()) {
  730. List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.SOULARROW, 0));
  731. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.giveForeignBuff(applyto.getId(), stat, false), false);
  732. }
  733. if (isEnrage()) {
  734. applyto.handleOrbconsume();
  735. }
  736. if (isMorph()) {
  737. List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.MORPH, Integer.valueOf(getMorph(applyto))));
  738. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.giveForeignBuff(applyto.getId(), stat, true), false);
  739. }
  740. if (localstatups.size() > 0) {
  741. long starttime = System.currentTimeMillis();
  742. CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime);
  743. ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, localDuration);
  744. applyto.registerEffect(this, starttime, schedule);
  745. }
  746. if (primary) {
  747. applyto.getMap().broadcastMessage(applyto, MaplePacketCreator.showBuffeffect(applyto.getId(), sourceid, 1, (byte) 3, isMorph()), false);
  748. }
  749. }
  750. private int calcHPChange(MapleCharacter applyfrom, boolean primary) {
  751. int hpchange = 0;
  752. if (hp != 0) {
  753. if (!skill) {
  754. if (primary) {
  755. hpchange += alchemistModifyVal(applyfrom, hp, true);
  756. } else {
  757. hpchange += hp;
  758. }
  759. } else { // assumption: this is heal
  760. hpchange += makeHealHP(hp / 100.0, applyfrom.getTotalMagic(), 3, 5);
  761. }
  762. }
  763. if (hpR != 0) {
  764. hpchange += (int) (applyfrom.getCurrentMaxHp() * hpR);
  765. }
  766. // actually receivers probably never get any hp when it's not heal but whatever
  767. if (primary) {
  768. if (hpCon != 0) {
  769. hpchange -= hpCon;
  770. }
  771. }
  772. if (isChakra()) {
  773. hpchange += makeHealHP(getY() / 100.0, applyfrom.getTotalLuk(), 2.3, 3.5);
  774. }
  775. return hpchange;
  776. }
  777. private int makeHealHP(double rate, double stat, double lowerfactor, double upperfactor) {
  778. int maxHeal = (int) (stat * upperfactor * rate);
  779. int minHeal = (int) (stat * lowerfactor * rate);
  780. return (int) ((Math.random() * (maxHeal - minHeal + 1)) + minHeal);
  781. }
  782. private int calcMPChange(MapleCharacter applyfrom, boolean primary) {
  783. int mpchange = 0;
  784. if (mp != 0) {
  785. if (primary) {
  786. mpchange += alchemistModifyVal(applyfrom, mp, true);
  787. } else {
  788. mpchange += mp;
  789. }
  790. }
  791. if (mpR != 0) {
  792. mpchange += (int) (applyfrom.getCurrentMaxMp() * mpR);
  793. }
  794. if (primary) {
  795. if (mpCon != 0) {
  796. double mod = 1.0;
  797. boolean isAFpMage = applyfrom.getJob().isA(MapleJob.FP_MAGE);
  798. if (isAFpMage || applyfrom.getJob().isA(MapleJob.IL_MAGE)) {
  799. ISkill amp;
  800. if (isAFpMage) {
  801. amp = SkillFactory.getSkill(Skills.FPMage.ElementAmplification);
  802. } else {
  803. amp = SkillFactory.getSkill(Skills.ILMage.ElementAmplification);
  804. }
  805. int ampLevel = applyfrom.getSkillLevel(amp);
  806. if (ampLevel > 0) {
  807. MapleStatEffect ampStat = amp.getEffect(ampLevel);
  808. mod = ampStat.getX() / 100.0;
  809. }
  810. }
  811. mpchange -= mpCon * mod;
  812. if (applyfrom.getBuffedValue(MapleBuffStat.INFINITY) != null) {
  813. mpchange = 0;
  814. }
  815. }
  816. }
  817. return mpchange;
  818. }
  819. private int alchemistModifyVal(MapleCharacter chr, int val, boolean withX) {
  820. if (!skill && (chr.getJob().isA(MapleJob.HERMIT) || chr.getJob().isA(MapleJob.NIGHTWALKER3))) {
  821. MapleStatEffect alchemistEffect = getAlchemistEffect(chr, chr.getJob().isA(MapleJob.NIGHTWALKER3));
  822. if (alchemistEffect != null) {
  823. return (int) (val * ((withX ? alchemistEffect.getX() : alchemistEffect.getY()) / 100.0));
  824. }
  825. }
  826. return val;
  827. }
  828. private MapleStatEffect getAlchemistEffect(MapleCharacter chr, boolean cygnus) {
  829. ISkill alchemist = SkillFactory.getSkill(cygnus == true ? Skills.NightWalker3.Alchemist : Skills.Hermit.Alchemist);
  830. int alchemistLevel = chr.getSkillLevel(alchemist);
  831. if (alchemistLevel == 0) {
  832. return null;
  833. }
  834. return alchemist.getEffect(alchemistLevel);
  835. }
  836. private boolean isGmBuff() {
  837. switch (sourceid) {
  838. case Skills.Beginner.EchoOfHero:
  839. case Skills.Noblesse.EchoOfHero:
  840. case Skills.SuperGM.Bless:
  841. case Skills.SuperGM.Haste:
  842. case Skills.SuperGM.HealDispel:
  843. case Skills.SuperGM.HolySymbol:
  844. case Skills.SuperGM.HyperBody:
  845. case Skills.SuperGM.Resurrection:
  846. return true;
  847. default:
  848. return false;
  849. }
  850. }
  851. private boolean isMonsterBuff() {
  852. if (!skill) {
  853. return false;
  854. }
  855. switch (sourceid) {
  856. case Skills.Page.Threaten:
  857. case Skills.FPMagician.Slow:
  858. case Skills.ILMagician.Slow:
  859. case Skills.FPMage.Seal:
  860. case Skills.ILMage.Seal:
  861. case Skills.Priest.Doom:
  862. case Skills.Hermit.ShadowWeb:
  863. case Skills.NightWalker3.ShadowWeb:
  864. return true;
  865. default:
  866. return false;
  867. }
  868. }
  869. private boolean isPartyBuff() {
  870. if (lt == null || rb == null) {
  871. return false;
  872. }
  873. switch (sourceid) {
  874. case Skills.WhiteKnight.BlizzardChargeBW:
  875. case Skills.WhiteKnight.IceChargeSword:
  876. case Skills.WhiteKnight.FlameChargeBW:
  877. case Skills.WhiteKnight.FireChargeSword:
  878. case Skills.WhiteKnight.LightningChargeBW:
  879. case Skills.WhiteKnight.ThunderChargeSword:
  880. case Skills.Paladin.DivineChargeBW:
  881. case Skills.Paladin.HolyChargeSword:
  882. case Skills.DawnWarrior3.SoulCharge:
  883. return false;
  884. }
  885. return true;
  886. }
  887. public boolean isHeal() {
  888. return skill && (sourceid == Skills.Cleric.Heal || sourceid == Skills.SuperGM.HealDispel || sourceid == Skills.SuperGM.Resurrection);
  889. }
  890. public boolean isResurrection() {
  891. return skill && (sourceid == Skills.SuperGM.Resurrection || sourceid == Skills.Bishop.Resurrection || sourceid == Skills.SuperGM.HealDispel);
  892. }
  893. public boolean isDash() {
  894. return skill && (sourceid == Skills.Pirate.Dash || sourceid == Skills.ThunderBreaker1.Dash);
  895. }
  896. public boolean isEnergyCharge() {
  897. return skill && (sourceid == Skills.Marauder.EnergyCharge || sourceid == Skills.ThunderBreaker2.EnergyCharge);
  898. }
  899. public boolean isSpeedInfusion() {
  900. return skill && (sourceid == Skills.Buccaneer.SpeedInfusion || sourceid == Skills.ThunderBreaker3.SpeedInfusion);
  901. }
  902. public boolean isBattleship() {
  903. return skill && (sourceid == Skills.Corsair.Battleship);
  904. }
  905. public boolean isHide() {
  906. return skill && sourceid == Skills.SuperGM.Hide;
  907. }
  908. public boolean isDragonBlood() {
  909. return skill && sourceid == Skills.DragonKnight.DragonBlood;
  910. }
  911. private boolean isDs() {
  912. return skill && (sourceid == Skills.Rogue.DarkSight || sourceid == Skills.NightWalker1.DarkSight);
  913. }
  914. private boolean isCombo() {
  915. return skill && sourceid == Skills.Crusader.ComboAttack;
  916. }
  917. private boolean isEnrage() {
  918. return skill && sourceid == Skills.Hero.Enrage;
  919. }
  920. private boolean isShadowPartner() {
  921. return skill && (sourceid == Skills.Hermit.ShadowPartner || sourceid == Skills.NightWalker3.ShadowPartner);
  922. }
  923. private boolean isChakra() {
  924. return skill && sourceid == Skills.ChiefBandit.Chakra;
  925. }
  926. public boolean isMonsterRiding() {
  927. return skill && (sourceid == Skills.Beginner.MonsterRider || sourceid == Skills.Noblesse.MonsterRider);
  928. }
  929. public boolean isMagicDoor() {
  930. return skill && sourceid == Skills.Priest.MysticDoor;
  931. }
  932. public boolean isMesoGuard() {
  933. return skill && sourceid == Skills.ChiefBandit.MesoGuard;
  934. }
  935. public boolean isCharge() {
  936. if (skill) {
  937. switch (sourceid) {
  938. case Skills.WhiteKnight.BlizzardChargeBW:
  939. case Skills.WhiteKnight.IceChargeSword:
  940. case Skills.WhiteKnight.FlameChargeBW:
  941. case Skills.WhiteKnight.FireChargeSword:
  942. case Skills.WhiteKnight.LightningChargeBW:
  943. case Skills.WhiteKnight.ThunderChargeSword:
  944. case Skills.Paladin.DivineChargeBW:
  945. case Skills.Paladin.HolyChargeSword:
  946. return true;
  947. default:
  948. return false;
  949. }
  950. }
  951. return false;
  952. }
  953. public boolean isPoison() {
  954. return skill && (sourceid == Skills.FPMagician.PoisonBreath || sourceid == Skills.FPMage.ElementComposition || sourceid == Skills.FPMage.PoisonMist);
  955. }
  956. private boolean isMist() {
  957. return skill && (sourceid == Skills.FPMage.PoisonMist || sourceid == Skills.Shadower.Smokescreen); // poison mist and smokescreen
  958. }
  959. private boolean isSoulArrow() {
  960. return skill && (sourceid == Skills.Hunter.SoulArrow || sourceid == Skills.CrossBowMan.SoulArrow || sourceid == Skills.WindArcher2.SoulArrow); // bow and crossbow
  961. }
  962. private boolean isShadowClaw() {
  963. return skill && sourceid == Skills.NightLord.ShadowStars;
  964. }
  965. private boolean isDispel() {
  966. return skill && (sourceid == Skills.Priest.Dispel || sourceid == Skills.SuperGM.HealDispel);
  967. }
  968. private boolean isSkillMorph() {
  969. return skill && (sourceid == Skills.Marauder.Transformation || sourceid == Skills.Buccaneer.SuperTransformation || sourceid == Skills.ThunderBreaker3.Transformation || sourceid == Skills.WindArcher3.EagleEye);
  970. }
  971. public boolean isMorph() {
  972. return morphId > 0;
  973. }
  974. public short getWatk() {
  975. return watk;
  976. }
  977. public short getMatk() {
  978. return matk;
  979. }
  980. public short getWdef() {
  981. return wdef;
  982. }
  983. public short getMdef() {
  984. return mdef;
  985. }
  986. public short getAcc() {
  987. return acc;
  988. }
  989. public short getAvoid() {
  990. return avoid;
  991. }
  992. public short getHands() {
  993. return hands;
  994. }
  995. public short getSpeed() {
  996. return speed;
  997. }
  998. public short getJump() {
  999. return jump;
  1000. }
  1001. public int getDuration() {
  1002. return duration;
  1003. }
  1004. public boolean isOverTime() {
  1005. return overTime;
  1006. }
  1007. public List<Pair<MapleBuffStat, Integer>> getStatups() {
  1008. return statups;
  1009. }
  1010. public boolean sameSource(MapleStatEffect effect) {
  1011. return this.sourceid == effect.sourceid && this.skill == effect.skill;
  1012. }
  1013. public int getX() {
  1014. return x;
  1015. }
  1016. public int getY() {
  1017. return y;
  1018. }
  1019. public int getZ() {
  1020. return z;
  1021. }
  1022. public int getDamage() {
  1023. return damage;
  1024. }
  1025. public int getAttackCount() {
  1026. return attackCount;
  1027. }
  1028. public int getBulletCount() {
  1029. return bulletCount;
  1030. }
  1031. public int getBulletConsume() {
  1032. return bulletConsume;
  1033. }
  1034. public int getMoneyCon() {
  1035. return moneyCon;
  1036. }
  1037. public int getCooldown() {
  1038. return cooldown;
  1039. }
  1040. public int getFixedDamage() {
  1041. return fixDamage;
  1042. }
  1043. public Map<MonsterStatus, Integer> getMonsterStati() {
  1044. return monsterStatus;
  1045. }
  1046. public int getMorph(MapleCharacter chr) {
  1047. return skill ? (morphId + (chr.getGender() * 100)) : morphId;
  1048. }
  1049. public SummonMovementType getSummonMovementType() {
  1050. if (!skill) {
  1051. return null;
  1052. }
  1053. switch (sourceid) {
  1054. case Skills.Ranger.Puppet:
  1055. case Skills.Sniper.Puppet:
  1056. case Skills.Outlaw.Octopus:
  1057. case Skills.Corsair.WrathOfTheOctopi:
  1058. case Skills.WindArcher3.Puppet:
  1059. return SummonMovementType.STATIONARY;
  1060. case Skills.Priest.SummonDragon:
  1061. case Skills.Ranger.SilverHawk:
  1062. case Skills.Sniper.GoldenEagle:
  1063. case Skills.Bowmaster.Phoenix:
  1064. case Skills.Marksman.Frostprey:
  1065. case Skills.Outlaw.Gaviota:
  1066. return SummonMovementType.CIRCLE_FOLLOW;
  1067. case Skills.FPArchMage.Elquines:
  1068. case Skills.ILArchMage.Ifrit:
  1069. case Skills.Bishop.Bahamut:
  1070. case Skills.DawnWarrior1.Soul:
  1071. case Skills.BlazeWizard1.Flame:
  1072. case Skills.BlazeWizard3.Ifrit:
  1073. case Skills.WindArcher1.Storm:
  1074. case Skills.NightWalker1.Darkness:
  1075. case Skills.ThunderBreaker1.Lightning:
  1076. return SummonMovementType.FOLLOW;
  1077. }
  1078. return null;
  1079. }
  1080. public boolean isSkill() {
  1081. return skill;
  1082. }
  1083. public int getSourceId() {
  1084. return sourceid;
  1085. }
  1086. /**
  1087. *
  1088. * @return true if the effect should happen based on it's probablity, false otherwise
  1089. */
  1090. public boolean makeChanceResult() {
  1091. return prop == 1.0 || Math.random() < prop;
  1092. }
  1093. public static class CancelEffectAction implements Runnable {
  1094. private MapleStatEffect effect;
  1095. private WeakReference<MapleCharacter> target;
  1096. private long startTime;
  1097. public CancelEffectAction(MapleCharacter target, MapleStatEffect effect, long startTime) {
  1098. this.effect = effect;
  1099. this.target = new WeakReference<MapleCharacter>(target);
  1100. this.startTime = startTime;
  1101. }
  1102. @Override
  1103. public void run() {
  1104. MapleCharacter realTarget = target.get();
  1105. if (realTarget != null) {
  1106. realTarget.cancelEffect(effect, false, startTime);
  1107. }
  1108. }
  1109. }
  1110. public int getMorph() {
  1111. return morphId;
  1112. }
  1113. }