Advertisement
kolton

Untitled

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