Advertisement
kolton

Untitled

May 7th, 2012
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.10 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. if (typeof dodgeList === "undefined") {
  107. dodgeList = this.buildDodgeList();
  108. }
  109.  
  110. if (dodgeList.length) {
  111. dodgeList.sort(Sort.units);
  112.  
  113. if (getDistance(me, dodgeList[0]) < 13) {
  114. this.dodge(target, 15, dodgeList);
  115. }
  116.  
  117. dodgeList.sort(Sort.units);
  118.  
  119. if (getDistance(me, dodgeList[0]) < 13) {
  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. 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 (typeof dodgeList === "undefined") {
  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]) < 13) {
  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 (typeof dodgeList === "undefined") {
  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]) < 13) {
  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. angle = Math.round(Math.atan2(me.y - unit.y, me.x - unit.x) * 180 / Math.PI),
  556. angles = [45, 90, 135, 180, 225, 270, 305, 360];
  557.  
  558. // step 1 - build possible dodge positions based on angles
  559.  
  560. var t = getTickCount();
  561.  
  562. for (i = 0; i < angles.length; i = i + 1) {
  563. coordx = Math.round((Math.cos((angle + angles[i]) * Math.PI / 180)) * distance + unit.x);
  564. coordy = Math.round((Math.sin((angle + angles[i]) * Math.PI / 180)) * distance + unit.y);
  565.  
  566. if (this.validSpot(coordx, coordy)) {
  567. coords.push([coordx, coordy]);
  568. }
  569. }
  570.  
  571. if (coords.length === 0) { // no valid positions - don't move
  572. me.overhead("Can't dodge :(");
  573.  
  574. return true;
  575. }
  576.  
  577. coords.sort(Sort.points);
  578.  
  579. for (i = 0; i < coords.length; i += 1) {
  580. count = 0;
  581.  
  582. for (j = 0; j < list.length; j += 1) {
  583. if (list[j].hp > 0 && getDistance(list[j].x, list[j].y, coords[i][0], coords[i][1]) < 13) {
  584. count += 1;
  585. }
  586. }
  587.  
  588. if (count < maxcount) {
  589. goodCoords = [coords[i][0], coords[i][1]];
  590. maxcount = count;
  591.  
  592. if (count === 0) {
  593. print("zero count");
  594.  
  595. break;
  596. }
  597. }
  598.  
  599. print("count for " + i + ": " + count);
  600. }
  601.  
  602. if (goodCoords.length > 0) { // just in case goodCoords is empty (shouldn't happen)
  603. if (getDistance(me, goodCoords[0], goodCoords[1]) < 4) { // close enough
  604. return true;
  605. }
  606.  
  607. me.overhead("Dodge!");
  608. Pather.moveTo(goodCoords[0], goodCoords[1], 3);
  609. }
  610.  
  611. return true;
  612. },
  613.  
  614. // Check if a monster is attackable
  615. checkMonster: function (unit) {
  616. if (!unit) {
  617. return false;
  618. }
  619.  
  620. if (unit.type === 0 && unit.mode !== 17) { // Player
  621. return true;
  622. }
  623.  
  624. if (unit.mode === 0 || unit.mode === 12) { // Dead monster
  625. return false;
  626. }
  627.  
  628. if (unit.getStat(172) === 2) { // Friendly monster/NPC
  629. return false;
  630. }
  631.  
  632. if (unit.classid === 543 && me.area === 131) { // Baal in Throne
  633. return false;
  634. }
  635.  
  636. if (getBaseStat("monstats", unit.classid, "neverCount")) { // neverCount base stat - hydras, traps etc.
  637. return false;
  638. }
  639.  
  640. switch (unit.classid) {
  641. case 110: // Vultures
  642. case 111:
  643. case 112:
  644. case 113:
  645. case 114:
  646. case 179: // An evil force - cow (lol)
  647. return false;
  648. case 608:
  649. if (unit.mode === 8) { // Flying
  650. return false;
  651. }
  652.  
  653. break;
  654. case 68: // Sand Maggots
  655. case 69:
  656. case 70:
  657. case 71:
  658. case 72:
  659. case 679:
  660. case 258: // Water Watchers
  661. case 259:
  662. case 260:
  663. case 261:
  664. case 262:
  665. case 263:
  666. if (unit.mode === 14) { // Submerged/Burrowed
  667. return false;
  668. }
  669.  
  670. break;
  671. }
  672.  
  673. return true;
  674. },
  675.  
  676. skipCheck: function (unit) {
  677. if (me.area === 131) {
  678. return true;
  679. }
  680.  
  681. var i, j, rval,
  682. tempArray = [];
  683.  
  684. EnchantLoop: // Skip enchanted monsters
  685. for (i = 0; i < Config.SkipEnchant.length; i += 1) {
  686. tempArray = Config.SkipEnchant[i].toLowerCase().split(" and ");
  687.  
  688. for (j = 0; j < tempArray.length; j += 1) {
  689. switch (tempArray[j]) {
  690. case "extra strong":
  691. tempArray[j] = 5;
  692.  
  693. break;
  694. case "extra fast":
  695. tempArray[j] = 6;
  696.  
  697. break;
  698. case "cursed":
  699. tempArray[j] = 7;
  700.  
  701. break;
  702. case "magic resistant":
  703. tempArray[j] = 8;
  704.  
  705. break;
  706. case "fire enchanted":
  707. tempArray[j] = 9;
  708.  
  709. break;
  710. case "lightning enchanted":
  711. tempArray[j] = 17;
  712.  
  713. break;
  714. case "cold enchanted":
  715. tempArray[j] = 18;
  716.  
  717. break;
  718. case "mana burn":
  719. tempArray[j] = 25;
  720.  
  721. break;
  722. case "teleportation":
  723. tempArray[j] = 26;
  724.  
  725. break;
  726. case "spectral hit":
  727. tempArray[j] = 27;
  728.  
  729. break;
  730. case "stone skin":
  731. tempArray[j] = 28;
  732.  
  733. break;
  734. case "multiple shots":
  735. tempArray[j] = 29;
  736.  
  737. break;
  738. }
  739. }
  740.  
  741. for (j = 0; j < tempArray.length; j += 1) {
  742. if (!unit.getEnchant(tempArray[j])) {
  743. continue EnchantLoop;
  744. }
  745. }
  746.  
  747. //print("ÿc1Skipping " + unit.name + " (enchant skip -" + Config.SkipEnchant[i] + ")");
  748.  
  749. return false;
  750. }
  751.  
  752. ImmuneLoop: // Skip immune monsters
  753. for (i = 0; i < Config.SkipImmune.length; i += 1) {
  754. tempArray = Config.SkipImmune[i].toLowerCase().split(" and ");
  755.  
  756. for (j = 0; j < tempArray.length; j += 1) {
  757. if (this.checkResist(unit, tempArray[j])) { // Infinity calculations are built-in
  758. continue ImmuneLoop;
  759. }
  760. }
  761.  
  762. //print("ÿc1Skipping " + unit.name + " (immunity skip -" + Config.SkipImmune[i] + ")");
  763.  
  764. return false;
  765. }
  766.  
  767. AuraLoop: // Skip monsters with auras
  768. for (i = 0; i < Config.SkipAura.length; i += 1) {
  769. rval = true;
  770.  
  771. switch (Config.SkipAura[i].toLowerCase()) {
  772. case "fanaticism":
  773. if (unit.getState(49)) {
  774. rval = false;
  775. }
  776.  
  777. break;
  778. case "might":
  779. if (unit.getState(33)) {
  780. rval = false;
  781. }
  782.  
  783. break;
  784. case "holy fire":
  785. if (unit.getState(35)) {
  786. rval = false;
  787. }
  788.  
  789. break;
  790. case "blessed aim":
  791. if (unit.getState(40)) {
  792. rval = false;
  793. }
  794.  
  795. break;
  796. case "conviction":
  797. if (unit.getState(28)) {
  798. rval = false;
  799. }
  800.  
  801. break;
  802. case "holy freeze":
  803. if (unit.getState(43)) {
  804. rval = false;
  805. }
  806.  
  807. break;
  808. case "holy shock":
  809. if (unit.getState(46)) {
  810. rval = false;
  811. }
  812.  
  813. break;
  814. }
  815.  
  816. if (!rval) {
  817. //print("ÿc1Skipping " + unit.name + " (aura skip -" + Config.SkipAura[i] + ")");
  818.  
  819. return false;
  820. }
  821. }
  822.  
  823. return true;
  824. },
  825.  
  826. // Get element by skill number
  827. getSkillElement: function (skillId) {
  828. this.elements = ["physical", "fire", "lightning", "magic", "cold", "poison", "none"];
  829.  
  830. switch (skillId) {
  831. case 74: // Corpse Explosion
  832. case 147: // Frenzy
  833. case 500: // Summoner
  834. return "physical";
  835. case 101: // Holy Bolt
  836. return "holybolt"; // no need to use this.elements array because it returns before going over the array
  837. }
  838.  
  839. var eType = getBaseStat("skills", skillId, "etype");
  840.  
  841. if (typeof (eType) === "number") {
  842. return this.elements[eType];
  843. }
  844.  
  845. return false;
  846. },
  847.  
  848. // Get a monster's resistance to specified element
  849. getResist: function (unit, type) {
  850. if (unit.type === 0) { // player
  851. return 0;
  852. }
  853.  
  854. switch (type) {
  855. case "physical":
  856. return unit.getStat(36);
  857. case "fire":
  858. return unit.getStat(39);
  859. case "lightning":
  860. return unit.getStat(41);
  861. case "magic":
  862. return unit.getStat(37);
  863. case "cold":
  864. return unit.getStat(43);
  865. case "poison":
  866. return unit.getStat(45);
  867. case "none":
  868. return 0;
  869. case "holybolt": // check if a monster is undead
  870. if (getBaseStat("monstats", unit.classid, "lUndead") || getBaseStat("monstats", unit.classid, "hUndead")) {
  871. return 0;
  872. }
  873.  
  874. return 100;
  875. }
  876.  
  877. return 100;
  878. },
  879.  
  880. // Check if a monster is immune to specified attack type
  881. checkResist: function (unit, type) {
  882. if (unit.type === 0) { // player
  883. return true;
  884. }
  885.  
  886. if (this.infinity && ["fire", "lightning", "cold"].indexOf(type) > -1) {
  887. if (!unit.getState(28)) {
  888. return this.getResist(unit, type) < 117;
  889. } else {
  890. return this.getResist(unit, type) < 100;
  891. }
  892. }
  893.  
  894. return this.getResist(unit, type) < 100;
  895. },
  896.  
  897. // Detect use of bows/crossbows
  898. usingBow: function () {
  899. var item;
  900.  
  901. item = me.getItem(-1, 1);
  902.  
  903. if (item) {
  904. do {
  905. if (item.bodylocation === 4 || item.bodylocation === 5) {
  906. switch (item.itemType) {
  907. case 27: // Bows
  908. case 85: // Amazon Bows
  909. return "bow";
  910. case 35: // Crossbows
  911. return "crossbow";
  912. }
  913. }
  914. } while (item.getNext());
  915. }
  916.  
  917. return false;
  918. },
  919.  
  920. // Find an optimal attack position and move or walk to it
  921. getIntoPosition: function (unit, distance, coll, walk) {
  922. if (typeof walk === "undefined") {
  923. walk = false;
  924. }
  925.  
  926. var n, i, cx, cy, t,
  927. coords = [],
  928. angle = Math.round(Math.atan2(me.y - unit.y, me.x - unit.x) * 180 / Math.PI),
  929. angles = [0, 45, 90, 135, 180, 225, 270, 305];
  930.  
  931. t = getTickCount();
  932.  
  933. for (n = 0; n < 3; n += 1) {
  934. if (n > 0) {
  935. distance = Math.floor(distance / 2);
  936. }
  937.  
  938. for (i = 0; i < angles.length; i += 1) {
  939. cx = Math.round((Math.cos((angle + angles[i]) * Math.PI / 180)) * distance + unit.x);
  940. cy = Math.round((Math.sin((angle + angles[i]) * Math.PI / 180)) * distance + unit.y);
  941.  
  942. //if (!(CollMap.getColl(cx, cy) & 0x1)) {
  943. if (this.validSpot(cx, cy)) {
  944. coords.push([cx, cy]);
  945. }
  946. }
  947.  
  948. //print("ÿc9potential spots: ÿc2" + coords.length);
  949.  
  950. if (coords.length > 0) {
  951. coords.sort(Sort.points); // sort angles by final spot distance
  952. } else { // no good final spots
  953. //print("reducing optimal spot range");
  954.  
  955. continue;
  956. }
  957.  
  958. MainLoop:
  959. for (i = 0; i < coords.length; i += 1) { // sorted angles are coords[i][2]
  960. if (CollMap.checkColl(unit, {x: coords[i][0], y: coords[i][1]}, coll)) {
  961. continue MainLoop;
  962. }
  963.  
  964. //print("ÿc9optimal pos build time: ÿc2" + (getTickCount() - t) + " ÿc9distance from target: ÿc2" + getDistance(cx, cy, unit.x, unit.y));
  965. CollMap.reset();
  966.  
  967. return (walk ? Pather.walkTo(coords[i][0], coords[i][1]) : Pather.moveTo(coords[i][0], coords[i][1]));
  968. }
  969. }
  970.  
  971. CollMap.reset();
  972. //print("optimal pos fail. " + unit.name);
  973.  
  974. return false;
  975. }
  976. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement