Advertisement
kolton

Untitled

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