Advertisement
lengend

Untitled

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