Advertisement
kolton

Untitled

May 10th, 2012
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.88 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. }
  119.  
  120. Misc.townCheck(true);
  121.  
  122. if (ClassAttack.doAttack(target, attackCount % 15 === 0) < 2) {
  123. break;
  124. }
  125.  
  126. if (!copyUnit(target).x) { // Check if unit got invalidated, happens if necro raises a skeleton from the boss's corpse.
  127. return true;
  128. }
  129.  
  130. attackCount += 1;
  131. }
  132.  
  133. return (target.mode === 0 || target.mode === 12);
  134. },
  135.  
  136. // Clear monsters in a section based on range and spectype or clear monsters around a boss monster
  137. clear: function (range, spectype, bossId, sortfunc, pickit) { // probably going to change to passing an object
  138. if (Config.MFLeader && !!bossId) {
  139. Pather.makePortal();
  140. say("clear " + bossId);
  141. }
  142.  
  143. switch (arguments.length) {
  144. case 0:
  145. range = 25;
  146. spectype = 0;
  147. bossId = false;
  148. sortfunc = false;
  149. pickit = true;
  150.  
  151. break;
  152. case 1:
  153. spectype = 0;
  154. bossId = false;
  155. sortfunc = false;
  156. pickit = true;
  157.  
  158. break;
  159. case 2:
  160. bossId = false;
  161. sortfunc = false;
  162. pickit = true;
  163.  
  164. break;
  165. case 3:
  166. sortfunc = false;
  167. pickit = true;
  168.  
  169. break;
  170. case 4:
  171. pickit = true;
  172.  
  173. break;
  174. }
  175.  
  176. if (typeof (range) !== "number") {
  177. throw new Error("Attack.clear: range must be a number.");
  178. }
  179.  
  180. var i, boss, orgx, orgy, target, result, monsterList, dodgeList,
  181. gidAttack = [],
  182. attackCount = 0;
  183.  
  184. if (Config.AttackSkill[1] < 0 || Config.AttackSkill[me.classid === 4 ? 2 : 3] < 0) {
  185. return false;
  186. }
  187.  
  188. if (!sortfunc) {
  189. sortfunc = this.sortMonsters;
  190. }
  191.  
  192. if (bossId) {
  193. for (i = 0; !boss && i < 3; i += 1) {
  194. boss = getUnit(1, bossId);
  195.  
  196. delay(50);
  197. }
  198.  
  199. if (!boss) {
  200. throw new Error("Attack.clear: " + bossId + " not found");
  201. }
  202.  
  203. orgx = boss.x;
  204. orgy = boss.y;
  205. } else {
  206. orgx = me.x;
  207. orgy = me.y;
  208. }
  209.  
  210. monsterList = [];
  211. target = getUnit(1);
  212.  
  213. if (target) {
  214. do {
  215. if (this.checkMonster(target) && this.skipCheck(target)) {
  216. monsterList.push(copyUnit(target));
  217. }
  218. } while (target.getNext());
  219. }
  220.  
  221. while (monsterList.length > 0) {
  222. if (me.mode === 17) {
  223. return false;
  224. }
  225.  
  226. monsterList.sort(Sort.units);
  227. monsterList.sort(sortfunc);
  228.  
  229. target = copyUnit(monsterList[0]);
  230.  
  231. 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))) {
  232. if (Config.Dodge) {
  233. if (attackCount % 5 === 0) {
  234. dodgeList = this.buildDodgeList();
  235. }
  236.  
  237. if (attackCount > 0 && dodgeList.length > 0) {
  238. dodgeList.sort(Sort.units);
  239.  
  240. if (getDistance(me, dodgeList[0]) < 13) {
  241. //this.dodge(dodgeList[0], 15, dodgeList);
  242. this.dodge(target, 20, dodgeList);
  243. }
  244. }
  245. }
  246.  
  247. Misc.townCheck(true);
  248. me.overhead("attacking " + target.name + " spectype " + target.spectype + " id " + target.classid);
  249.  
  250. result = ClassAttack.doAttack(target, attackCount % 15 === 0);
  251.  
  252. switch (result) {
  253. case 1:
  254. monsterList.shift();
  255. break;
  256. case 2:
  257. case 3:
  258. if (!(target.spectype & 0x7) && me.area !== 131) {
  259. for (i = 0; i < gidAttack.length; i += 1) {
  260. if (gidAttack[i].gid === target.gid) {
  261. break;
  262. }
  263. }
  264.  
  265. if (i === gidAttack.length) {
  266. gidAttack.push({gid: target.gid, attacks: 0});
  267. }
  268.  
  269. gidAttack[i].attacks += 1;
  270.  
  271. if (gidAttack[i].attacks > 12) {
  272. print("ÿc1Skipping " + target.name);
  273. monsterList.shift();
  274. }
  275. }
  276.  
  277. attackCount += 1;
  278.  
  279. if (target.mode === 0 || target.mode === 12) {
  280. Pickit.fastPick();
  281. }
  282.  
  283. break;
  284. default:
  285. return false;
  286. }
  287. } else {
  288. monsterList.shift();
  289. }
  290. }
  291.  
  292. ClassAttack.afterAttack();
  293. this.openChests(range);
  294.  
  295. if (attackCount > 0 && pickit) {
  296. Pickit.pickItems();
  297. }
  298.  
  299. return true;
  300. },
  301.  
  302. // Filter monsters based on classId, spectype and range
  303. getMob: function (classid, spectype, range) {
  304. var monsterList = [],
  305. monster = getUnit(1, classid);
  306.  
  307. if (monster) {
  308. do {
  309. if (getDistance(me, monster) <= range && (!spectype || (monster.spectype & spectype)) && this.checkMonster(monster)) {
  310. monsterList.push(copyUnit(monster));
  311. }
  312. } while (monster.getNext());
  313. }
  314.  
  315. if (!monsterList.length) {
  316. return false;
  317. }
  318.  
  319. return monsterList;
  320. },
  321.  
  322. // Clear an already formed array of monstas
  323. clearList: function (list, sortfunc) {
  324. var i, target, result, dodgeList,
  325. gidAttack = [],
  326. attackCount = 0,
  327. monsterList = list.slice(0);
  328.  
  329. if (!sortfunc) {
  330. sortfunc = this.sortMonsters;
  331. }
  332.  
  333. while (monsterList.length > 0) {
  334. monsterList.sort(Sort.units);
  335. monsterList.sort(sortfunc);
  336.  
  337. target = copyUnit(monsterList[0]);
  338.  
  339. if (typeof target.x !== "undefined" && this.checkMonster(target)) {
  340. if (Config.Dodge) {
  341. if (attackCount % 5 === 0) {
  342. dodgeList = this.buildDodgeList();
  343. }
  344.  
  345. if (attackCount > 0 && dodgeList.length > 0) {
  346. dodgeList.sort(Sort.units);
  347.  
  348. if (getDistance(me, dodgeList[0]) < 13) {
  349. //this.dodge(dodgeList[0], 15, dodgeList);
  350. this.dodge(target, 20, dodgeList);
  351. }
  352. }
  353. }
  354.  
  355. Misc.townCheck(true);
  356. me.overhead("attacking " + target.name + " spectype " + target.spectype + " id " + target.classid);
  357.  
  358. result = ClassAttack.doAttack(target, attackCount % 15 === 0);
  359.  
  360. switch (result) {
  361. case 1:
  362. monsterList.shift();
  363. break;
  364. case 2:
  365. case 3:
  366. if (!(target.spectype & 0x7) && me.area !== 131) {
  367. for (i = 0; i < gidAttack.length; i += 1) {
  368. if (gidAttack[i].gid === target.gid) {
  369. break;
  370. }
  371. }
  372.  
  373. if (i === gidAttack.length) {
  374. gidAttack.push({gid: target.gid, attacks: 0});
  375. }
  376.  
  377. gidAttack[i].attacks += 1;
  378.  
  379. if (gidAttack[i].attacks > 12) {
  380. print("ÿc1Skipping " + target.name);
  381. monsterList.shift();
  382. }
  383. }
  384.  
  385. attackCount += 1;
  386.  
  387. break;
  388. default:
  389. return false;
  390. }
  391. } else {
  392. monsterList.shift();
  393. }
  394. }
  395.  
  396. ClassAttack.afterAttack();
  397. this.openChests(30);
  398.  
  399. if (attackCount > 0) {
  400. Pickit.pickItems();
  401. }
  402.  
  403. return true;
  404. },
  405.  
  406. // Draw lines around a room on minimap
  407. /*markRoom: function (room, color) {
  408. new Line(room.x * 5, room.y * 5, room.x * 5, room.y * 5 + room.ysize, color, true);
  409. new Line(room.x * 5, room.y * 5, room.x * 5 + room.xsize, room.y * 5, color, true);
  410. new Line(room.x * 5 + room.xsize, room.y * 5, room.x * 5 + room.xsize, room.y * 5 + room.ysize, color, true);
  411. new Line(room.x * 5, room.y * 5 + room.ysize, room.x * 5 + room.xsize, room.y * 5 + room.ysize, color, true);
  412. },*/
  413.  
  414. // Clear an entire area based on monster spectype
  415. clearLevel: function (spectype) {
  416. if (Config.MFLeader) {
  417. Pather.makePortal();
  418. say("clearlevel " + getArea().name);
  419. }
  420.  
  421. var room, result, rooms;
  422.  
  423. room = getRoom();
  424.  
  425. if (!room) {
  426. return false;
  427. }
  428.  
  429. if (arguments.length < 1) {
  430. spectype = 0;
  431. }
  432.  
  433. rooms = [];
  434.  
  435. do {
  436. rooms.push([room.x * 5 + room.xsize / 2, room.y * 5 + room.ysize / 2]);
  437. } while (room.getNext());
  438.  
  439. while (rooms.length > 0) {
  440. rooms.sort(Sort.points);
  441. room = rooms.shift();
  442.  
  443. result = Pather.getNearestWalkable(room[0], room[1], 15, 2);
  444.  
  445. if (result) {
  446. //this.markRoom(getRoom(room[0], room[1]), 0x84);
  447. Pather.moveTo(result[0], result[1], 3);
  448.  
  449. if (!this.clear(30, spectype)) {
  450. return false;
  451. }
  452. }/* else {
  453. this.markRoom(getRoom(room[0], room[1]), 0x62);
  454. }*/
  455. }
  456.  
  457. CollMap.reset();
  458.  
  459. return true;
  460. },
  461.  
  462. // Sort monsters based on distance, spectype and classId (summoners are attacked first)
  463. sortMonsters: function (unitA, unitB) {
  464. 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];
  465.  
  466. if (ids.indexOf(unitA.classid) > -1) {
  467. return -1;
  468. }
  469.  
  470. if (ids.indexOf(unitB.classid) > -1) {
  471. return 1;
  472. }
  473.  
  474. if (Config.BossPriority) {
  475. if (unitA.spectype & 0x5) {
  476. return -1;
  477. }
  478.  
  479. if (unitB.spectype & 0x5) {
  480. return 1;
  481. }
  482. }
  483.  
  484. return 1;
  485. },
  486.  
  487. // Check if a set of coords is valid/accessable
  488. validSpot: function (x, y) {
  489. var result;
  490.  
  491. if (!me.area) { // Just in case
  492. return false;
  493. }
  494.  
  495. try { // Treat thrown errors as invalid spot
  496. result = getCollision(me.area, x, y);
  497. } catch (e) {
  498. return false;
  499. }
  500.  
  501. // Avoid non-walkable spots, objects
  502. if (result === undefined || result & 0x1 || result & 0x400) {
  503. return false;
  504. }
  505.  
  506. return true;
  507. },
  508.  
  509. // Open chests when clearing
  510. openChests: function (range) {
  511. var i, unit,
  512. ids = ["chest", "weaponrack", "armorstand"];
  513.  
  514. for (i = 0; i < ids.length; i += 1) {
  515. unit = getUnit(2, ids[i]);
  516.  
  517. if (unit) {
  518. do {
  519. if ((getDistance(me, unit) <= range) && Misc.openChest(unit)) {
  520. Pickit.pickItems();
  521. }
  522. } while (unit.getNext());
  523. }
  524. }
  525. },
  526.  
  527. // Make a list of monsters that will be monitored for dodging
  528. buildDodgeList: function () {
  529. var ignoreList = [243, 544],
  530. monster = getUnit(1),
  531. list = [];
  532.  
  533. if (monster) {
  534. do {
  535. if (ignoreList.indexOf(monster.classid) === -1 && this.checkMonster(monster)) {
  536. list.push(copyUnit(monster));
  537. }
  538. } while (monster.getNext());
  539. }
  540.  
  541. return list;
  542. },
  543.  
  544. // Move away from a nearby monster into a more safe position
  545. dodge: function (unit, distance, list) {
  546. var i, j, coordx, coordy, count, t,
  547. maxcount = 99,
  548. coords = [],
  549. goodCoords = [],
  550. angle = Math.round(Math.atan2(me.y - unit.y, me.x - unit.x) * 180 / Math.PI),
  551. angles = [0, 30, -30, 60, -60, 90, -90, 120, -120, 150, -150, 180];
  552.  
  553. // step 1 - build possible dodge positions based on angles
  554.  
  555. t = getTickCount();
  556.  
  557. for (i = 0; i < angles.length; i = i + 1) {
  558. coordx = Math.round((Math.cos((angle + angles[i]) * Math.PI / 180)) * distance + unit.x);
  559. coordy = Math.round((Math.sin((angle + angles[i]) * Math.PI / 180)) * distance + unit.y);
  560.  
  561. if (this.validSpot(coordx, coordy)) {
  562. coords.push([coordx, coordy]);
  563. }
  564. }
  565.  
  566. print("dodge build time " + (getTickCount() - t));
  567.  
  568. if (coords.length === 0) { // no valid positions - don't move
  569. me.overhead("Can't dodge :(");
  570.  
  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]) < 13) {
  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]) < 4) { // close enough
  597. return true;
  598. }
  599.  
  600. me.overhead("Dodge!");
  601. Pather.moveTo(goodCoords[0], goodCoords[1], 3);
  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, cx, cy, t,
  920. coords = [],
  921. angle = Math.round(Math.atan2(me.y - unit.y, me.x - unit.x) * 180 / Math.PI),
  922. angles = [0, 45, 90, 135, 180, 225, 270, 305];
  923.  
  924. t = getTickCount();
  925.  
  926. for (n = 0; n < 3; n += 1) {
  927. if (n > 0) {
  928. distance = Math.floor(distance / 2);
  929. }
  930.  
  931. for (i = 0; i < angles.length; i += 1) {
  932. cx = Math.round((Math.cos((angle + angles[i]) * Math.PI / 180)) * distance + unit.x);
  933. cy = Math.round((Math.sin((angle + angles[i]) * Math.PI / 180)) * distance + unit.y);
  934.  
  935. //if (!(CollMap.getColl(cx, cy) & 0x1)) {
  936. if (this.validSpot(cx, cy)) {
  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.  
  946. for (i = 0; i < coords.length; i += 1) { // sorted angles are coords[i][2]
  947. if (!CollMap.checkColl(unit, {x: coords[i][0], y: coords[i][1]}, coll)) {
  948. //print("ÿc9optimal pos build time: ÿc2" + (getTickCount() - t) + " ÿc9distance from target: ÿc2" + getDistance(cx, cy, unit.x, unit.y));
  949. CollMap.reset();
  950.  
  951. return (walk ? Pather.walkTo(coords[i][0], coords[i][1]) : Pather.moveTo(coords[i][0], coords[i][1]));
  952. }
  953. }
  954. }
  955. }
  956.  
  957. CollMap.reset();
  958. print("optimal pos fail. " + unit.name);
  959.  
  960. return false;
  961. }
  962. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement