Advertisement
kolton

Untitled

May 7th, 2012
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.30 KB | None | 0 0
  1. /**
  2. * @filename Attack.js
  3. * @author kolton
  4. * @desc handle player attacks
  5. */
  6.  
  7. var Attack = {
  8. classes: ["Amazon", "Sorceress", "Necromancer", "Paladin", "Barbarian", "Druid", "Assassin"],
  9. infinity: false,
  10. dodgeList: [],
  11.  
  12. // Initialize attacks
  13. init: function () {
  14. include("common/CollMap.js");
  15.  
  16. if (include("common/Attacks/" + this.classes[me.classid] + ".js")) {
  17. ClassAttack.init();
  18. }
  19.  
  20. if (Config.AttackSkill[1] < 0 && Config.AttackSkill[3] < 0) {
  21. showConsole();
  22. print("ÿc1No attack skills set. Don't expect your bot to attack.");
  23. }
  24.  
  25. if (me.gametype === 1) {
  26. this.checkInfinity();
  27. }
  28. },
  29.  
  30. // Check if player or his merc are using Infinity, and adjust resistance checks based on that
  31. checkInfinity: function () {
  32. var i, merc, items;
  33.  
  34. for (i = 0; !merc && i < 3; i += 1) {
  35. merc = me.getMerc();
  36.  
  37. delay(50);
  38. }
  39.  
  40. // Check merc infinity
  41.  
  42. if (merc) {
  43. items = merc.getItems();
  44.  
  45. if (items) {
  46. for (i = 0; i < items.length; i += 1) {
  47. if (items[i].getPrefix(20566)) {
  48. print("Infinity detected");
  49.  
  50. this.infinity = true;
  51.  
  52. return true;
  53. }
  54. }
  55. }
  56. }
  57.  
  58. // Check player infinity
  59.  
  60. items = me.findItems(-1, 1);
  61.  
  62. if (items) {
  63. for (i = 0; i < items.length; i += 1) {
  64. if (items[i].getPrefix(20566)) {
  65. print("Infinity detected");
  66.  
  67. this.infinity = true;
  68.  
  69. return true;
  70. }
  71. }
  72. }
  73.  
  74. return false;
  75. },
  76.  
  77. // Kill a monster based on its classId
  78. kill: function (classId) {
  79. if (Config.AttackSkill[1] < 0) {
  80. return false;
  81. }
  82.  
  83. var i, dodgeList, target,
  84. attackCount = 0;
  85.  
  86. for (i = 0; i < 3; i += 1) {
  87. target = getUnit(1, classId);
  88.  
  89. if (target) {
  90. break;
  91. }
  92.  
  93. delay(50);
  94. }
  95.  
  96. if (!target) {
  97. throw new Error("Attack.kill: Target not found");
  98. }
  99.  
  100. if (Config.MFLeader) {
  101. Pather.makePortal();
  102. say("kill " + classId);
  103. }
  104.  
  105. while (attackCount < 300 && this.checkMonster(target) && this.skipCheck(target)) {
  106. if (Config.Dodge) {
  107. this.dodgeList = this.buildDodgeList();
  108.  
  109. if (this.dodgeList.length) {
  110. this.dodgeList.sort(Sort.units);
  111.  
  112. if (getDistance(me, this.dodgeList[0]) < 10) {
  113. //this.dodge(target, 15, dodgeList);
  114. this.getIntoPosition(target, ClassAttack.skillRange[1], 0x4);
  115. }
  116.  
  117. this.dodgeList.sort(Sort.units);
  118.  
  119. if (getDistance(me, this.dodgeList[0]) < 10) {
  120. continue;
  121. }
  122. }
  123. }
  124.  
  125. Misc.townCheck(true);
  126.  
  127. if (ClassAttack.doAttack(target, attackCount % 15 === 0) < 2) {
  128. break;
  129. }
  130.  
  131. if (!copyUnit(target).x) { // Check if unit got invalidated, happens if necro raises a skeleton from the boss's corpse.
  132. return true;
  133. }
  134.  
  135. attackCount += 1;
  136. }
  137.  
  138. return (target.mode === 0 || target.mode === 12);
  139. },
  140.  
  141. // Clear monsters in a section based on range and spectype or clear monsters around a boss monster
  142. clear: function (range, spectype, bossId, sortfunc, pickit) { // probably going to change to passing an object
  143. if (Config.MFLeader && !!bossId) {
  144. Pather.makePortal();
  145. say("clear " + bossId);
  146. }
  147.  
  148. switch (arguments.length) {
  149. case 0:
  150. range = 25;
  151. spectype = 0;
  152. bossId = false;
  153. sortfunc = false;
  154. pickit = true;
  155.  
  156. break;
  157. case 1:
  158. spectype = 0;
  159. bossId = false;
  160. sortfunc = false;
  161. pickit = true;
  162.  
  163. break;
  164. case 2:
  165. bossId = false;
  166. sortfunc = false;
  167. pickit = true;
  168.  
  169. break;
  170. case 3:
  171. sortfunc = false;
  172. pickit = true;
  173.  
  174. break;
  175. case 4:
  176. pickit = true;
  177.  
  178. break;
  179. }
  180.  
  181. if (typeof (range) !== "number") {
  182. throw new Error("Attack.clear: range must be a number.");
  183. }
  184.  
  185. var i, boss, orgx, orgy, target, result, monsterList, dodgeList,
  186. gidAttack = [],
  187. attackCount = 0;
  188.  
  189. if (Config.AttackSkill[1] < 0 || Config.AttackSkill[me.classid === 4 ? 2 : 3] < 0) {
  190. return false;
  191. }
  192.  
  193. if (!sortfunc) {
  194. sortfunc = this.sortMonsters;
  195. }
  196.  
  197. if (bossId) {
  198. for (i = 0; !boss && i < 3; i += 1) {
  199. boss = getUnit(1, bossId);
  200.  
  201. delay(50);
  202. }
  203.  
  204. if (!boss) {
  205. throw new Error("Attack.clear: " + bossId + " not found");
  206. }
  207.  
  208. orgx = boss.x;
  209. orgy = boss.y;
  210. } else {
  211. orgx = me.x;
  212. orgy = me.y;
  213. }
  214.  
  215. monsterList = [];
  216. dodgeList = [];
  217. target = getUnit(1);
  218.  
  219. if (target) {
  220. do {
  221. if (this.checkMonster(target) && this.skipCheck(target)) {
  222. monsterList.push(copyUnit(target));
  223. }
  224. } while (target.getNext());
  225. }
  226.  
  227. while (monsterList.length > 0) {
  228. if (me.mode === 17) {
  229. return false;
  230. }
  231.  
  232. monsterList.sort(Sort.units);
  233. monsterList.sort(sortfunc);
  234.  
  235. target = copyUnit(monsterList[0]);
  236.  
  237. if (typeof target.x !== "undefined" && Math.abs(orgx - target.x) <= range && Math.abs(orgy - target.y) <= range && (!spectype || (target.spectype & spectype)) && this.checkMonster(target) && (me.getSkill(54, 1) || !checkCollision(me, target, 0x1))) {
  238. if (Config.Dodge) {
  239. if (attackCount % 5 === 0) {
  240. dodgeList = this.buildDodgeList();
  241. }
  242.  
  243. if (attackCount > 0 && dodgeList.length > 0) {
  244. dodgeList.sort(Sort.units);
  245.  
  246. if (getDistance(me, dodgeList[0]) < 8) {
  247. //this.dodge(dodgeList[0], 15, dodgeList);
  248. this.dodge(target, 15, dodgeList);
  249. }
  250. }
  251. }
  252.  
  253. Misc.townCheck(true);
  254. me.overhead("attacking " + target.name + " spectype " + target.spectype + " id " + target.classid);
  255.  
  256. result = ClassAttack.doAttack(target, attackCount % 15 === 0);
  257.  
  258. switch (result) {
  259. case 1:
  260. monsterList.shift();
  261. break;
  262. case 2:
  263. case 3:
  264. if (!(target.spectype & 0x7) && me.area !== 131) {
  265. for (i = 0; i < gidAttack.length; i += 1) {
  266. if (gidAttack[i].gid === target.gid) {
  267. break;
  268. }
  269. }
  270.  
  271. if (i === gidAttack.length) {
  272. gidAttack.push({gid: target.gid, attacks: 0});
  273. }
  274.  
  275. gidAttack[i].attacks += 1;
  276.  
  277. if (gidAttack[i].attacks > 12) {
  278. print("ÿc1Skipping " + target.name);
  279. monsterList.shift();
  280. }
  281. }
  282.  
  283. attackCount += 1;
  284.  
  285. if (target.mode === 0 || target.mode === 12) {
  286. Pickit.fastPick();
  287. }
  288.  
  289. break;
  290. default:
  291. return false;
  292. }
  293. } else {
  294. monsterList.shift();
  295. }
  296. }
  297.  
  298. ClassAttack.afterAttack();
  299. this.openChests(range);
  300.  
  301. if (attackCount > 0 && pickit) {
  302. Pickit.pickItems();
  303. }
  304.  
  305. return true;
  306. },
  307.  
  308. // Filter monsters based on classId, spectype and range
  309. getMob: function (classid, spectype, range) {
  310. var monsterList = [],
  311. monster = getUnit(1, classid);
  312.  
  313. if (monster) {
  314. do {
  315. if (getDistance(me, monster) <= range && (!spectype || (monster.spectype & spectype)) && this.checkMonster(monster)) {
  316. monsterList.push(copyUnit(monster));
  317. }
  318. } while (monster.getNext());
  319. }
  320.  
  321. if (!monsterList.length) {
  322. return false;
  323. }
  324.  
  325. return monsterList;
  326. },
  327.  
  328. // Clear an already formed array of monstas
  329. clearList: function (list, sortfunc) {
  330. var i, target, result, dodgeList,
  331. gidAttack = [],
  332. attackCount = 0,
  333. monsterList = list.slice(0);
  334.  
  335. if (!sortfunc) {
  336. sortfunc = this.sortMonsters;
  337. }
  338.  
  339. while (monsterList.length > 0) {
  340. monsterList.sort(Sort.units);
  341. monsterList.sort(sortfunc);
  342.  
  343. target = copyUnit(monsterList[0]);
  344.  
  345. if (typeof target.x !== "undefined" && this.checkMonster(target)) {
  346. if (Config.Dodge) {
  347. if (attackCount % 5 === 0) {
  348. dodgeList = this.buildDodgeList();
  349. }
  350.  
  351. if (attackCount > 0 && dodgeList.length > 0) {
  352. dodgeList.sort(Sort.units);
  353.  
  354. if (getDistance(me, dodgeList[0]) < 8) {
  355. //this.dodge(dodgeList[0], 15, dodgeList);
  356. this.dodge(target, 15, dodgeList);
  357. }
  358. }
  359. }
  360.  
  361. Misc.townCheck(true);
  362. me.overhead("attacking " + target.name + " spectype " + target.spectype + " id " + target.classid);
  363.  
  364. result = ClassAttack.doAttack(target, attackCount % 15 === 0);
  365.  
  366. switch (result) {
  367. case 1:
  368. monsterList.shift();
  369. break;
  370. case 2:
  371. case 3:
  372. if (!(target.spectype & 0x7) && me.area !== 131) {
  373. for (i = 0; i < gidAttack.length; i += 1) {
  374. if (gidAttack[i].gid === target.gid) {
  375. break;
  376. }
  377. }
  378.  
  379. if (i === gidAttack.length) {
  380. gidAttack.push({gid: target.gid, attacks: 0});
  381. }
  382.  
  383. gidAttack[i].attacks += 1;
  384.  
  385. if (gidAttack[i].attacks > 12) {
  386. print("ÿc1Skipping " + target.name);
  387. monsterList.shift();
  388. }
  389. }
  390.  
  391. attackCount += 1;
  392.  
  393. break;
  394. default:
  395. return false;
  396. }
  397. } else {
  398. monsterList.shift();
  399. }
  400. }
  401.  
  402. ClassAttack.afterAttack();
  403. this.openChests(30);
  404.  
  405. if (attackCount > 0) {
  406. Pickit.pickItems();
  407. }
  408.  
  409. return true;
  410. },
  411.  
  412. // Draw lines around a room on minimap
  413. markRoom: function (room, color) {
  414. new Line(room.x * 5, room.y * 5, room.x * 5, room.y * 5 + room.ysize, color, true);
  415. new Line(room.x * 5, room.y * 5, room.x * 5 + room.xsize, room.y * 5, color, true);
  416. new Line(room.x * 5 + room.xsize, room.y * 5, room.x * 5 + room.xsize, room.y * 5 + room.ysize, color, true);
  417. new Line(room.x * 5, room.y * 5 + room.ysize, room.x * 5 + room.xsize, room.y * 5 + room.ysize, color, true);
  418. },
  419.  
  420. // Clear an entire area based on monster spectype
  421. clearLevel: function (spectype) {
  422. if (Config.MFLeader) {
  423. Pather.makePortal();
  424. say("clearlevel " + getArea().name);
  425. }
  426.  
  427. var room, result, rooms;
  428.  
  429. room = getRoom();
  430.  
  431. if (!room) {
  432. return false;
  433. }
  434.  
  435. if (arguments.length < 1) {
  436. spectype = 0;
  437. }
  438.  
  439. rooms = [];
  440.  
  441. do {
  442. rooms.push([room.x * 5 + room.xsize / 2, room.y * 5 + room.ysize / 2]);
  443. } while (room.getNext());
  444.  
  445. while (rooms.length > 0) {
  446. rooms.sort(Sort.points);
  447. room = rooms.shift();
  448.  
  449. result = Pather.getNearestWalkable(room[0], room[1], 15, 2);
  450.  
  451. if (result) {
  452. //this.markRoom(getRoom(room[0], room[1]), 0x84);
  453. Pather.moveTo(result[0], result[1], 3);
  454.  
  455. if (!this.clear(30, spectype)) {
  456. return false;
  457. }
  458. }/* else {
  459. this.markRoom(getRoom(room[0], room[1]), 0x62);
  460. }*/
  461. }
  462.  
  463. CollMap.reset();
  464.  
  465. return true;
  466. },
  467.  
  468. // Sort monsters based on distance, spectype and classId (summoners are attacked first)
  469. sortMonsters: function (unitA, unitB) {
  470. var ids = [58, 59, 60, 61, 62, 101, 102, 103, 104, 105, 278, 279, 280, 281, 282, 298, 299, 300, 645, 646, 647, 662, 663, 664, 667, 668, 669, 670, 675, 676];
  471.  
  472. if (ids.indexOf(unitA.classid) > -1) {
  473. return -1;
  474. }
  475.  
  476. if (ids.indexOf(unitB.classid) > -1) {
  477. return 1;
  478. }
  479.  
  480. if (Config.BossPriority) {
  481. if (unitA.spectype & 0x5) {
  482. return -1;
  483. }
  484.  
  485. if (unitB.spectype & 0x5) {
  486. return 1;
  487. }
  488. }
  489.  
  490. return 1;
  491. },
  492.  
  493. // Check if a set of coords is valid/accessable
  494. validSpot: function (x, y) {
  495. var result;
  496.  
  497. if (!me.area) { // Just in case
  498. return false;
  499. }
  500.  
  501. try { // Treat thrown errors as invalid spot
  502. result = getCollision(me.area, x, y);
  503. } catch (e) {
  504. return false;
  505. }
  506.  
  507. // Avoid non-walkable spots, objects
  508. if (result === undefined || result & 0x1 || result & 0x400) {
  509. return false;
  510. }
  511.  
  512. return true;
  513. },
  514.  
  515. // Open chests when clearing
  516. openChests: function (range) {
  517. var i, unit,
  518. ids = ["chest", "weaponrack", "armorstand"];
  519.  
  520. for (i = 0; i < ids.length; i += 1) {
  521. unit = getUnit(2, ids[i]);
  522.  
  523. if (unit) {
  524. do {
  525. if ((getDistance(me, unit) <= range) && Misc.openChest(unit)) {
  526. Pickit.pickItems();
  527. }
  528. } while (unit.getNext());
  529. }
  530. }
  531. },
  532.  
  533. // Make a list of monsters that will be monitored for dodging
  534. buildDodgeList: function () {
  535. var ignoreList = [243, 544],
  536. monster = getUnit(1),
  537. list = [];
  538.  
  539. if (monster) {
  540. do {
  541. if (ignoreList.indexOf(monster.classid) === -1 && this.checkMonster(monster)) {
  542. list.push(copyUnit(monster));
  543. }
  544. } while (monster.getNext());
  545. }
  546.  
  547. return list;
  548. },
  549.  
  550. // Move away from a nearby monster into a more safe position
  551. dodge: function (unit, distance, list) {
  552. var i, j, coordx, coordy, count,
  553. maxcount = 99,
  554. coords = [],
  555. goodCoords = [],
  556. angles = [45, 90, 135, 180, 225, 270, 305, 360];
  557.  
  558. // step 1 - build possible dodge positions based on angles
  559.  
  560. for (i = 0; i < angles.length; i = i + 1) {
  561. coordx = Math.round((Math.cos(angles[i] * Math.PI / 180)) * distance + unit.x);
  562. coordy = Math.round((Math.sin(angles[i] * Math.PI / 180)) * distance + unit.y);
  563.  
  564. if (this.validSpot(coordx, coordy)) {
  565. coords.push([coordx, coordy]);
  566. }
  567. }
  568.  
  569. if (coords.length === 0) { // no valid positions - don't move
  570. me.overhead("Can't dodge :(");
  571. return true;
  572. }
  573.  
  574. coords.sort(Sort.points);
  575.  
  576. for (i = 0; i < coords.length; i += 1) {
  577. count = 0;
  578.  
  579. for (j = 0; j < list.length; j += 1) {
  580. if (list[j].hp > 0 && getDistance(list[j].x, list[j].y, coords[i][0], coords[i][1]) < 10) {
  581. count += 1;
  582. }
  583. }
  584.  
  585. if (count < maxcount) {
  586. goodCoords = [coords[i][0], coords[i][1]];
  587. maxcount = count;
  588.  
  589. if (count === 0) {
  590. break;
  591. }
  592. }
  593. }
  594.  
  595. if (goodCoords.length > 0) { // just in case goodCoords is empty (shouldn't happen)
  596. if (getDistance(me, goodCoords[0], goodCoords[1]) < 5) { // close enough
  597. return true;
  598. }
  599.  
  600. me.overhead("Dodge!");
  601. Pather.moveTo(goodCoords[0], goodCoords[1], 1);
  602. }
  603.  
  604. return true;
  605. },
  606.  
  607. // Check if a monster is attackable
  608. checkMonster: function (unit) {
  609. if (!unit) {
  610. return false;
  611. }
  612.  
  613. if (unit.type === 0 && unit.mode !== 17) { // Player
  614. return true;
  615. }
  616.  
  617. if (unit.mode === 0 || unit.mode === 12) { // Dead monster
  618. return false;
  619. }
  620.  
  621. if (unit.getStat(172) === 2) { // Friendly monster/NPC
  622. return false;
  623. }
  624.  
  625. if (unit.classid === 543 && me.area === 131) { // Baal in Throne
  626. return false;
  627. }
  628.  
  629. if (getBaseStat("monstats", unit.classid, "neverCount")) { // neverCount base stat - hydras, traps etc.
  630. return false;
  631. }
  632.  
  633. switch (unit.classid) {
  634. case 110: // Vultures
  635. case 111:
  636. case 112:
  637. case 113:
  638. case 114:
  639. case 179: // An evil force - cow (lol)
  640. return false;
  641. case 608:
  642. if (unit.mode === 8) { // Flying
  643. return false;
  644. }
  645.  
  646. break;
  647. case 68: // Sand Maggots
  648. case 69:
  649. case 70:
  650. case 71:
  651. case 72:
  652. case 679:
  653. case 258: // Water Watchers
  654. case 259:
  655. case 260:
  656. case 261:
  657. case 262:
  658. case 263:
  659. if (unit.mode === 14) { // Submerged/Burrowed
  660. return false;
  661. }
  662.  
  663. break;
  664. }
  665.  
  666. return true;
  667. },
  668.  
  669. skipCheck: function (unit) {
  670. if (me.area === 131) {
  671. return true;
  672. }
  673.  
  674. var i, j, rval,
  675. tempArray = [];
  676.  
  677. EnchantLoop: // Skip enchanted monsters
  678. for (i = 0; i < Config.SkipEnchant.length; i += 1) {
  679. tempArray = Config.SkipEnchant[i].toLowerCase().split(" and ");
  680.  
  681. for (j = 0; j < tempArray.length; j += 1) {
  682. switch (tempArray[j]) {
  683. case "extra strong":
  684. tempArray[j] = 5;
  685.  
  686. break;
  687. case "extra fast":
  688. tempArray[j] = 6;
  689.  
  690. break;
  691. case "cursed":
  692. tempArray[j] = 7;
  693.  
  694. break;
  695. case "magic resistant":
  696. tempArray[j] = 8;
  697.  
  698. break;
  699. case "fire enchanted":
  700. tempArray[j] = 9;
  701.  
  702. break;
  703. case "lightning enchanted":
  704. tempArray[j] = 17;
  705.  
  706. break;
  707. case "cold enchanted":
  708. tempArray[j] = 18;
  709.  
  710. break;
  711. case "mana burn":
  712. tempArray[j] = 25;
  713.  
  714. break;
  715. case "teleportation":
  716. tempArray[j] = 26;
  717.  
  718. break;
  719. case "spectral hit":
  720. tempArray[j] = 27;
  721.  
  722. break;
  723. case "stone skin":
  724. tempArray[j] = 28;
  725.  
  726. break;
  727. case "multiple shots":
  728. tempArray[j] = 29;
  729.  
  730. break;
  731. }
  732. }
  733.  
  734. for (j = 0; j < tempArray.length; j += 1) {
  735. if (!unit.getEnchant(tempArray[j])) {
  736. continue EnchantLoop;
  737. }
  738. }
  739.  
  740. //print("ÿc1Skipping " + unit.name + " (enchant skip -" + Config.SkipEnchant[i] + ")");
  741.  
  742. return false;
  743. }
  744.  
  745. ImmuneLoop: // Skip immune monsters
  746. for (i = 0; i < Config.SkipImmune.length; i += 1) {
  747. tempArray = Config.SkipImmune[i].toLowerCase().split(" and ");
  748.  
  749. for (j = 0; j < tempArray.length; j += 1) {
  750. if (this.checkResist(unit, tempArray[j])) { // Infinity calculations are built-in
  751. continue ImmuneLoop;
  752. }
  753. }
  754.  
  755. //print("ÿc1Skipping " + unit.name + " (immunity skip -" + Config.SkipImmune[i] + ")");
  756.  
  757. return false;
  758. }
  759.  
  760. AuraLoop: // Skip monsters with auras
  761. for (i = 0; i < Config.SkipAura.length; i += 1) {
  762. rval = true;
  763.  
  764. switch (Config.SkipAura[i].toLowerCase()) {
  765. case "fanaticism":
  766. if (unit.getState(49)) {
  767. rval = false;
  768. }
  769.  
  770. break;
  771. case "might":
  772. if (unit.getState(33)) {
  773. rval = false;
  774. }
  775.  
  776. break;
  777. case "holy fire":
  778. if (unit.getState(35)) {
  779. rval = false;
  780. }
  781.  
  782. break;
  783. case "blessed aim":
  784. if (unit.getState(40)) {
  785. rval = false;
  786. }
  787.  
  788. break;
  789. case "conviction":
  790. if (unit.getState(28)) {
  791. rval = false;
  792. }
  793.  
  794. break;
  795. case "holy freeze":
  796. if (unit.getState(43)) {
  797. rval = false;
  798. }
  799.  
  800. break;
  801. case "holy shock":
  802. if (unit.getState(46)) {
  803. rval = false;
  804. }
  805.  
  806. break;
  807. }
  808.  
  809. if (!rval) {
  810. //print("ÿc1Skipping " + unit.name + " (aura skip -" + Config.SkipAura[i] + ")");
  811.  
  812. return false;
  813. }
  814. }
  815.  
  816. return true;
  817. },
  818.  
  819. // Get element by skill number
  820. getSkillElement: function (skillId) {
  821. this.elements = ["physical", "fire", "lightning", "magic", "cold", "poison", "none"];
  822.  
  823. switch (skillId) {
  824. case 74: // Corpse Explosion
  825. case 147: // Frenzy
  826. case 500: // Summoner
  827. return "physical";
  828. case 101: // Holy Bolt
  829. return "holybolt"; // no need to use this.elements array because it returns before going over the array
  830. }
  831.  
  832. var eType = getBaseStat("skills", skillId, "etype");
  833.  
  834. if (typeof (eType) === "number") {
  835. return this.elements[eType];
  836. }
  837.  
  838. return false;
  839. },
  840.  
  841. // Get a monster's resistance to specified element
  842. getResist: function (unit, type) {
  843. if (unit.type === 0) { // player
  844. return 0;
  845. }
  846.  
  847. switch (type) {
  848. case "physical":
  849. return unit.getStat(36);
  850. case "fire":
  851. return unit.getStat(39);
  852. case "lightning":
  853. return unit.getStat(41);
  854. case "magic":
  855. return unit.getStat(37);
  856. case "cold":
  857. return unit.getStat(43);
  858. case "poison":
  859. return unit.getStat(45);
  860. case "none":
  861. return 0;
  862. case "holybolt": // check if a monster is undead
  863. if (getBaseStat("monstats", unit.classid, "lUndead") || getBaseStat("monstats", unit.classid, "hUndead")) {
  864. return 0;
  865. }
  866.  
  867. return 100;
  868. }
  869.  
  870. return 100;
  871. },
  872.  
  873. // Check if a monster is immune to specified attack type
  874. checkResist: function (unit, type) {
  875. if (unit.type === 0) { // player
  876. return true;
  877. }
  878.  
  879. if (this.infinity && ["fire", "lightning", "cold"].indexOf(type) > -1) {
  880. if (!unit.getState(28)) {
  881. return this.getResist(unit, type) < 117;
  882. } else {
  883. return this.getResist(unit, type) < 100;
  884. }
  885. }
  886.  
  887. return this.getResist(unit, type) < 100;
  888. },
  889.  
  890. // Detect use of bows/crossbows
  891. usingBow: function () {
  892. var item;
  893.  
  894. item = me.getItem(-1, 1);
  895.  
  896. if (item) {
  897. do {
  898. if (item.bodylocation === 4 || item.bodylocation === 5) {
  899. switch (item.itemType) {
  900. case 27: // Bows
  901. case 85: // Amazon Bows
  902. return "bow";
  903. case 35: // Crossbows
  904. return "crossbow";
  905. }
  906. }
  907. } while (item.getNext());
  908. }
  909.  
  910. return false;
  911. },
  912.  
  913. // Find an optimal attack position and move or walk to it
  914. getIntoPosition: function (unit, distance, coll, walk) {
  915. if (typeof walk === "undefined") {
  916. walk = false;
  917. }
  918.  
  919. var n, i, j, cx, cy, t, goodCoords,
  920. maxcount = 999,
  921. count = 0,
  922. coords = [],
  923. angle = Math.round(Math.atan2(me.y - unit.y, me.x - unit.x) * 180 / Math.PI),
  924. angles = [0, 45, 90, 135, 180, 225, 270, 305];
  925.  
  926. t = getTickCount();
  927.  
  928. for (n = 0; n < 3; n += 1) {
  929. if (n > 0) {
  930. distance = Math.floor(distance / 2);
  931. }
  932.  
  933. for (i = 0; i < angles.length; i += 1) {
  934. cx = Math.round((Math.cos((angle + angles[i]) * Math.PI / 180)) * distance + unit.x);
  935. cy = Math.round((Math.sin((angle + angles[i]) * Math.PI / 180)) * distance + unit.y);
  936.  
  937. if (!(CollMap.getColl(cx, cy) & 0x1) && !CollMap.checkColl(unit, {x: cx, y: cy}, coll)) {
  938. coords.push([cx, cy]);
  939. }
  940. }
  941.  
  942. //print("ÿc9potential spots: ÿc2" + coords.length);
  943.  
  944. if (coords.length > 0) {
  945. coords.sort(Sort.points); // sort angles by final spot distance
  946. } else { // no good final spots
  947. //print("reducing optimal spot range");
  948.  
  949. continue;
  950. }
  951.  
  952. for (i = 0; i < coords.length; i += 1) {
  953. count = 0;
  954.  
  955. for (j = 0; j < this.dodgeList.length; j += 1) {
  956. if (this.dodgeList[j].hp > 0 && getDistance(this.dodgeList[j].x, this.dodgeList[j].y, coords[i][0], coords[i][1]) < 10) {
  957. count += 1;
  958. }
  959. }
  960.  
  961. if (count < maxcount) {
  962. goodCoords = [coords[i][0], coords[i][1]];
  963. maxcount = count;
  964.  
  965. if (count === 0) {
  966. break;
  967. }
  968. }
  969. }
  970.  
  971. if (goodCoords.length > 0) { // just in case goodCoords is empty (shouldn't happen)
  972. if (getDistance(me, goodCoords[0], goodCoords[1]) < 5) { // close enough
  973. return true;
  974. }
  975.  
  976. //me.overhead("Dodge!");
  977. if (Pather.moveTo(goodCoords[0], goodCoords[1], 1)) {
  978. CollMap.reset();
  979.  
  980. return true;
  981. }
  982. }
  983. }
  984.  
  985. CollMap.reset();
  986. print("optimal pos fail. " + unit.name);
  987.  
  988. return false;
  989. }
  990. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement