├── README.md └── kolbot ├── D2BotBlank.dbj ├── D2BotChannel.dbj ├── D2BotFollow.dbj ├── D2BotGameAction.dbj ├── D2BotLead.dbj ├── D2BotMap.dbj ├── D2BotMule.dbj ├── D2BotMuleLog.dbj ├── D2BotPubJoin.dbj ├── console ├── data ├── deleteme ├── secure │ └── deleteme └── web │ ├── deleteme │ └── limedrop.json ├── default.dbj ├── libs ├── AutoMule.js ├── CraftingSystem.js ├── Gambling.js ├── GameAction.js ├── GameData.js ├── MuleLogger.js ├── NTItemAlias.dbl ├── NTItemParser.dbl ├── OOG.js ├── Polyfill.js ├── TorchSystem.js ├── bots │ ├── Abaddon.js │ ├── AncientTunnels.js │ ├── Andariel.js │ ├── AutoBaal.js │ ├── Baal.js │ ├── BaalAssistant.js │ ├── BaalHelper.js │ ├── BattleOrders.js │ ├── BoBarbHelper.js │ ├── BoneAsh.js │ ├── Bonesaw.js │ ├── ChestMania.js │ ├── ClassicChaosAssistant.js │ ├── ClearAnyArea.js │ ├── Coldcrow.js │ ├── Coldworm.js │ ├── Corpsefire.js │ ├── Countess.js │ ├── Cows.js │ ├── Crafting.js │ ├── CrushTele.js │ ├── Diablo.js │ ├── DiabloHelper.js │ ├── Duriel.js │ ├── Eldritch.js │ ├── Enchant.js │ ├── Endugu.js │ ├── Eyeback.js │ ├── FastDiablo.js │ ├── Follower.js │ ├── Frozenstein.js │ ├── Gamble.js │ ├── GetKeys.js │ ├── GhostBusters.js │ ├── Hephasto.js │ ├── IPHunter.js │ ├── Icehawk.js │ ├── Izual.js │ ├── KillDclone.js │ ├── KurastTemples.js │ ├── MFHelper.js │ ├── MaggotLair.js │ ├── Manual.js │ ├── Mapper.js │ ├── Mausoleum.js │ ├── Mephisto.js │ ├── Nihlathak.js │ ├── OrgTorch.js │ ├── OuterSteppes.js │ ├── Pindleskin.js │ ├── Pit.js │ ├── Questing.js │ ├── Radament.js │ ├── Rakanishu.js │ ├── Rushee.js │ ├── Rusher.js │ ├── SealLeader.js │ ├── SealLeecher.js │ ├── SharpTooth.js │ ├── ShopBot.js │ ├── Smith.js │ ├── Snapchip.js │ ├── StonyTomb.js │ ├── Stormtree.js │ ├── Summoner.js │ ├── Synch.js │ ├── Synch2.js │ ├── Test.js │ ├── ThreshSocket.js │ ├── Tombs.js │ ├── Travincal.js │ ├── TravincalLeech.js │ ├── Treehead.js │ ├── Tristram.js │ ├── TristramLeech.js │ ├── UndergroundPassage.js │ ├── UserAddon.js │ ├── Vizier.js │ ├── WPGetter.js │ ├── Wakka.js │ └── Worldstone.js ├── common │ ├── Attack.js │ ├── Attacks │ │ ├── Amazon.js │ │ ├── Assassin.js │ │ ├── Barbarian.js │ │ ├── Druid.js │ │ ├── Necromancer.js │ │ ├── Paladin.js │ │ ├── Sorceress.js │ │ └── Wereform.js │ ├── AutoAssign.js │ ├── AutoBuild.js │ ├── AutoSkill.js │ ├── AutoStat.js │ ├── CollMap.js │ ├── Config.js │ ├── Cubing.js │ ├── Loader.js │ ├── Misc.js │ ├── Pather.js │ ├── Pickit.js │ ├── Precast.js │ ├── Prototypes.js │ ├── Runewords.js │ ├── Storage.js │ ├── Town.js │ └── Util.js ├── config │ ├── Amazon.js │ ├── Assassin.js │ ├── Barbarian.js │ ├── Builds │ │ ├── Class.Build.js │ │ ├── README.txt │ │ └── Sorceress.ExampleBuild.js │ ├── Druid.js │ ├── Necromancer.js │ ├── Paladin.js │ ├── Sorceress.js │ ├── Templates │ │ ├── Attacks.txt │ │ ├── AutoSkillExampleBuilds.txt │ │ ├── AutoStatExampleBuilds.txt │ │ ├── Cubing.txt │ │ ├── Runewords.txt │ │ ├── ShopBot.txt │ │ └── chestlist.txt │ ├── ThrowBarb.js │ ├── _BaseConfigFile.js │ └── _CustomConfig.js ├── json2.js ├── modules │ ├── Deltas.js │ ├── Events.js │ ├── HTTP.js │ ├── Messaging.js │ ├── Promise.js │ ├── SimpleParty.js │ ├── Socket.js │ ├── Team.js │ ├── Worker.js │ └── sdk.js └── require.js ├── mules └── deleteme ├── pickit ├── Autoequip │ ├── READ.txt │ └── sorceress.xpac.nip ├── Jewelery.nip ├── Jun2020.nip ├── LLD.nip ├── Magic.nip ├── Misc.nip ├── New.nip ├── Rare.nip ├── Set.nip ├── Unid.nip ├── White.nip ├── bs.nip ├── classic.nip ├── follower.nip ├── gold.nip ├── keyorg.nip ├── kolton.nip ├── pd2Misc.nip ├── pd2kolton.nip ├── pots.nip ├── redix.nip └── shopbot.nip ├── sdk ├── LocaleStringID.js ├── Shrines.txt ├── SuperUniques.txt ├── Unit.d.ts ├── areas.txt ├── basestats.txt ├── bodylocations.txt ├── commandRef.htm ├── data │ └── global │ │ └── excel │ │ └── states.txt ├── enchants.txt ├── getskillinfo.txt ├── globals.d.ts ├── itemflags.txt ├── miscscreenmodes.txt ├── modes.txt ├── monster classID's.txt ├── npcmenuid.txt ├── quests.txt ├── roomstats.txt ├── skills.txt ├── states.txt ├── stats.txt ├── stats_skills.txt ├── stats_tabs.txt ├── superunique_presetunitids.txt ├── tile.d2l ├── uiflag.txt └── waypoints.txt ├── test file - remove this.txt └── tools ├── AntiHostile.js ├── AutoBuildThread.js ├── CloneKilla.js ├── HeartBeat.js ├── MapHelper.js ├── MapThread.js ├── Party.js ├── PickThread.js ├── RushThread.js ├── ToolsThread.js └── TownChicken.js /kolbot/D2BotBlank.dbj: -------------------------------------------------------------------------------- 1 | // Blank starter used for testin 2 | function main() { 3 | include("json2.js"); 4 | include("OOG.js"); 5 | include("common/misc.js"); 6 | include("common/util.js"); 7 | 8 | var handle, 9 | isUp = "no"; 10 | 11 | this.copyDataEvent = function (mode, msg) { 12 | var obj; 13 | 14 | switch (msg) { 15 | case "Handle": 16 | handle = mode; 17 | 18 | break; 19 | } 20 | 21 | switch (mode) { 22 | case 3: // request game 23 | obj = JSON.parse(msg); 24 | 25 | if (me.gameReady) { 26 | D2Bot.joinMe(obj.profile, me.gamename.toLowerCase(), "", me.gamepassword.toLowerCase(), isUp); 27 | } 28 | 29 | break; 30 | case 4: 31 | // Heartbeat ping 32 | if (msg === "pingreq") { 33 | sendCopyData(null, me.windowtitle, 4, "pingrep"); 34 | } 35 | 36 | break; 37 | } 38 | }; 39 | 40 | 41 | addEventListener('copydata', this.copyDataEvent); 42 | 43 | while (!handle) { 44 | delay(100); 45 | } 46 | 47 | DataFile.updateStats("handle", handle); 48 | delay(500); 49 | D2Bot.init(); 50 | load("tools/heartbeat.js"); 51 | 52 | if (!FileTools.exists("data/" + me.profile + ".json")) { 53 | DataFile.create(); 54 | } 55 | 56 | while (true) { 57 | if (me.ingame) { 58 | isUp = "yes"; 59 | } else { 60 | isUp = "no"; 61 | } 62 | 63 | delay(1000); 64 | } 65 | } -------------------------------------------------------------------------------- /kolbot/D2BotMap.dbj: -------------------------------------------------------------------------------- 1 | function main () { 2 | include("json2.js"); 3 | include("OOG.js"); 4 | include("common/misc.js"); 5 | include("common/util.js"); 6 | 7 | var handle, 8 | isUp = "no"; 9 | 10 | function copyDataEvent (mode, msg) { 11 | switch (msg) { 12 | case "Handle": 13 | handle = mode; 14 | 15 | break; 16 | } 17 | 18 | switch (mode) { 19 | case 3: // request game 20 | var obj = JSON.parse(msg); 21 | 22 | if (me.gameReady) { 23 | D2Bot.joinMe(obj.profile, me.gamename.toLowerCase(), "", me.gamepassword.toLowerCase(), isUp); 24 | } 25 | 26 | break; 27 | case 4: 28 | // Heartbeat ping 29 | if (msg === "pingreq") { 30 | sendCopyData(null, me.windowtitle, 4, "pingrep"); 31 | } 32 | 33 | break; 34 | } 35 | } 36 | 37 | addEventListener('copydata', copyDataEvent); 38 | 39 | while (!handle) { 40 | delay(100); 41 | } 42 | 43 | DataFile.updateStats("handle", handle); 44 | delay(500); 45 | D2Bot.init(); 46 | load("tools/heartbeat.js"); 47 | 48 | while (true) { 49 | if (me.gameReady) { 50 | if (isUp === "no") { 51 | isUp = "yes"; 52 | } 53 | } else { 54 | isUp = "no"; 55 | } 56 | 57 | delay(1000); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /kolbot/console: -------------------------------------------------------------------------------- 1 | function main () { 2 | print('ÿc2D2BSÿc0 :: Started Console Script'); 3 | 4 | while (true) { 5 | delay(10000); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /kolbot/data/deleteme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Borega/pd2bs-scripts/fb578879d11c7726039f34325d727882e2e9ca31/kolbot/data/deleteme -------------------------------------------------------------------------------- /kolbot/data/secure/deleteme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Borega/pd2bs-scripts/fb578879d11c7726039f34325d727882e2e9ca31/kolbot/data/secure/deleteme -------------------------------------------------------------------------------- /kolbot/data/web/deleteme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Borega/pd2bs-scripts/fb578879d11c7726039f34325d727882e2e9ca31/kolbot/data/web/deleteme -------------------------------------------------------------------------------- /kolbot/data/web/limedrop.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Borega/pd2bs-scripts/fb578879d11c7726039f34325d727882e2e9ca31/kolbot/data/web/limedrop.json -------------------------------------------------------------------------------- /kolbot/libs/Gambling.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Gambling.js 3 | * @author kolton 4 | * @desc multi-profile gambling system 5 | */ 6 | 7 | var Gambling = { 8 | Teams: { 9 | //#################################################################################################### 10 | /* Gambling system for kolbot 11 | 12 | Allows lower level characters to get a steady income of gold to gamble LLD/VLLD items 13 | Not recommended for rings/amulets because of their high price (unless you want 3 gold finders to supply one gambler) 14 | It's possible to have multiple teams of gamblers/gold finders. Individual entries are separated by commas. 15 | 16 | Setting up: 17 | 18 | "Gamble Team 1": { // Put a unique team name here. 19 | 20 | goldFinders: ["GF Profile 1", "GF Profile 2"], // List of gold finder PROFILE names. They will join gamble games to drop gold 21 | 22 | gamblers: ["Gambler 1", "Gambler 2"], // List of gambler PROFILE names. They will keep gambling and picking up gold from gold finders. 23 | 24 | gambleGames: ["Gambling-", "HeyIGamble-"], // Games that gold finders will join, don't use numbers. 25 | 26 | goldTrigger: 2500000, // Minimum amount of gold before giving it to gamblers. 27 | 28 | goldReserve: 200000 // Amount of gold to keep after dropping. 29 | } 30 | 31 | Once set up properly, the gold finders will run their own games and join gamblers' games when they're out of gold. 32 | */ 33 | 34 | "Gamble Team 1": { 35 | goldFinders: [""], 36 | gamblers: [""], 37 | gambleGames: [""], 38 | 39 | goldTrigger: 2500000, 40 | goldReserve: 200000 41 | } 42 | 43 | //#################################################################################################### 44 | }, 45 | 46 | inGame: false, 47 | 48 | getInfo: function (profile) { 49 | var i, j; 50 | 51 | if (!profile) { 52 | profile = me.profile; 53 | } 54 | 55 | for (i in this.Teams) { 56 | if (this.Teams.hasOwnProperty(i)) { 57 | for (j = 0; j < this.Teams[i].goldFinders.length; j += 1) { 58 | if (this.Teams[i].goldFinders[j].toLowerCase() === profile.toLowerCase()) { 59 | this.Teams[i].goldFinder = true; 60 | this.Teams[i].gambler = false; 61 | 62 | return this.Teams[i]; 63 | } 64 | } 65 | 66 | for (j = 0; j < this.Teams[i].gamblers.length; j += 1) { 67 | if (this.Teams[i].gamblers[j].toLowerCase() === profile.toLowerCase()) { 68 | this.Teams[i].goldFinder = false; 69 | this.Teams[i].gambler = true; 70 | 71 | return this.Teams[i]; 72 | } 73 | } 74 | } 75 | } 76 | 77 | return false; 78 | }, 79 | 80 | inGameCheck: function () { 81 | var i, 82 | info = this.getInfo(); 83 | 84 | if (info && info.goldFinder) { 85 | for (i = 0; i < info.gambleGames.length; i += 1) { 86 | if (info.gambleGames[i] && me.gamename.match(info.gambleGames[i], "i")) { 87 | this.dropGold(); 88 | DataFile.updateStats("gold"); 89 | delay(5000); 90 | quit(); 91 | //delay(10000); 92 | 93 | return true; 94 | } 95 | } 96 | } 97 | 98 | return false; 99 | }, 100 | 101 | dropGold: function () { 102 | var info = this.getInfo(); 103 | 104 | if (info && info.goldFinder) { 105 | Town.goToTown(1); 106 | Town.move("stash"); 107 | 108 | while (me.getStat(14) + me.getStat(15) > info.goldReserve) { 109 | gold(me.getStat(14)); // drop current gold 110 | Town.openStash(); 111 | 112 | if (me.getStat(15) <= me.getStat(12) * 1e4) { // check stashed gold vs max carrying capacity 113 | gold(me.getStat(15) - info.goldReserve, 4); // leave minGold in stash, pick the rest 114 | } else { 115 | gold(me.getStat(12) * 1e4, 4); // pick max carrying capacity 116 | } 117 | 118 | delay(1000); 119 | } 120 | } 121 | }, 122 | 123 | outOfGameCheck: function () { 124 | var game, 125 | info = this.getInfo(); 126 | 127 | if (info && info.goldFinder && DataFile.getStats().gold >= info.goldTrigger) { 128 | game = this.getGame(); 129 | 130 | if (game) { 131 | D2Bot.printToConsole("Joining gold drop game.", 7); 132 | 133 | this.inGame = true; 134 | me.blockMouse = true; 135 | 136 | delay(2000); 137 | joinGame(game[0], game[1]); 138 | 139 | me.blockMouse = false; 140 | 141 | delay(5000); 142 | 143 | while (me.ingame) { 144 | delay(1000); 145 | } 146 | 147 | this.inGame = false; 148 | 149 | return true; 150 | } 151 | } 152 | 153 | return false; 154 | }, 155 | 156 | getGame: function () { 157 | var i, game, 158 | info = this.getInfo(); 159 | 160 | if (!info || !info.goldFinder) { 161 | return false; 162 | } 163 | 164 | function CheckEvent(mode, msg) { 165 | var i; 166 | 167 | if (mode === 4) { 168 | for (i = 0; i < info.gambleGames.length; i += 1) { 169 | if (info.gambleGames[i] && msg.match(info.gambleGames[i], "i")) { 170 | game = msg.split('/'); 171 | 172 | break; 173 | } 174 | } 175 | } 176 | } 177 | 178 | addEventListener('copydata', CheckEvent); 179 | 180 | game = null; 181 | 182 | for (i = 0; i < info.gamblers.length; i += 1) { 183 | sendCopyData(null, info.gamblers[i], 0, me.profile); 184 | delay(100); 185 | 186 | if (game) { 187 | break; 188 | } 189 | } 190 | 191 | removeEventListener('copydata', CheckEvent); 192 | 193 | return game; 194 | } 195 | }; -------------------------------------------------------------------------------- /kolbot/libs/bots/Abaddon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Abaddon.js 3 | * @author kolton 4 | * @desc clear Abaddon 5 | */ 6 | 7 | function Abaddon() { 8 | Town.doChores(); 9 | Pather.useWaypoint(111); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToPreset(111, 2, 60) || !Pather.usePortal(125)) { 13 | throw new Error("Failed to move to Abaddon"); 14 | } 15 | 16 | Attack.clearLevel(Config.ClearType); 17 | 18 | return true; 19 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/AncientTunnels.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename AncientTunnels.js 3 | * @author kolton 4 | * @desc clear Ancient Tunnels 5 | */ 6 | 7 | function AncientTunnels() { 8 | Town.doChores(); 9 | Pather.useWaypoint(44); 10 | Precast.doPrecast(true); 11 | 12 | if (Config.AncientTunnels.OpenChest && Pather.moveToPreset(me.area, 2, 580) && Misc.openChests(5)) { 13 | Pickit.pickItems(); 14 | } 15 | 16 | if (Config.AncientTunnels.KillDarkElder && getPresetUnit(me.area, 1, 751) && Pather.moveToPreset(me.area, 1, 751)) { 17 | Attack.clear(15, 0, getLocaleString(2886)); 18 | } 19 | 20 | if (!Pather.moveToExit(65, true)) { 21 | throw new Error("Failed to move to Ancient Tunnels"); 22 | } 23 | 24 | Attack.clearLevel(Config.ClearType); 25 | 26 | return true; 27 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Andariel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Andariel.js 3 | * @author kolton 4 | * @desc kill Andariel 5 | */ 6 | 7 | function Andariel() { 8 | this.killAndariel = function () { 9 | var i, 10 | target = getUnit(1, 156); 11 | 12 | if (!target) { 13 | throw new Error("Andariel not found."); 14 | } 15 | 16 | if (Config.MFLeader) { 17 | Pather.makePortal(); 18 | say("kill " + 156); 19 | } 20 | 21 | for (i = 0; i < 300; i += 1) { 22 | ClassAttack.doAttack(target); 23 | 24 | if (target.dead) { 25 | return true; 26 | } 27 | 28 | if (getDistance(me, target) <= 10) { 29 | Pather.moveTo(me.x > 22548 ? 22535 : 22560, 9520); 30 | } 31 | } 32 | 33 | return target.dead; 34 | }; 35 | Town.doChores(); 36 | Pather.useWaypoint(35); 37 | Precast.doPrecast(true); 38 | 39 | if (!Pather.moveToExit([36, 37], true)) { 40 | throw new Error("Failed to move to Catacombs Level 4"); 41 | } 42 | 43 | Pather.moveTo(22549, 9520); 44 | 45 | if (me.classid === 1 && me.gametype === 0) { 46 | this.killAndariel(); 47 | } else { 48 | Attack.kill(156); // Andariel 49 | } 50 | 51 | delay(2000); // Wait for minions to die. 52 | Pickit.pickItems(); 53 | return true; 54 | } 55 | -------------------------------------------------------------------------------- /kolbot/libs/bots/BattleOrders.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename BattleOrders.js 3 | * @author kolton, jmichelsen 4 | * @desc give or receive Battle Orders buff 5 | */ 6 | 7 | function BattleOrders () { 8 | this.checkForPlayers = function () { 9 | if (Misc.getPlayerCount() <= 1) { 10 | throw new Error("Empty game"); // Alone in game 11 | } 12 | }; 13 | 14 | this.amTardy = function () { 15 | let party = getParty(); 16 | 17 | AreaInfoLoop: 18 | while (true) { 19 | try { 20 | this.checkForPlayers(); 21 | } catch (e) { 22 | if (Config.BattleOrders.Wait) { 23 | print("Waiting " + Config.BattleOrders.Wait + " seconds for other players..."); 24 | 25 | while (getTickCount() - tick < Config.BattleOrders.Wait * 1000) { 26 | me.overhead("Waiting " + Math.round(((tick + (Config.BattleOrders.Wait * 1000)) - getTickCount()) / 1000) + " Seconds for other players"); 27 | delay(1000); 28 | } 29 | 30 | this.checkForPlayers(); 31 | } 32 | } 33 | 34 | if (party) { 35 | do { 36 | if (party.name !== me.name && party.area) { 37 | break AreaInfoLoop; // Can read player area 38 | } 39 | } while (party.getNext()); 40 | } 41 | } 42 | 43 | if (party) { 44 | do { 45 | if (party.area === 131 || party.area === 132 || party.area === 108 || party.area === 39) { 46 | // Player is in Throne of Destruction, Worldstone Chamber, Chaos Sanctuary, or Cows 47 | print("ÿc1I'm late to BOs. Moving on..."); 48 | 49 | return true; 50 | } 51 | } while (party.getNext()); 52 | } 53 | 54 | return false; // Not late; wait. 55 | }; 56 | 57 | this.giveBO = function (list) { 58 | let i, 59 | unit, 60 | failTimer = 60, 61 | tick = getTickCount(); 62 | 63 | for (i = 0; i < list.length; i += 1) { 64 | unit = getUnit(0, list[i]); 65 | 66 | if (unit) { 67 | while (!unit.getState(32) && copyUnit(unit).x) { 68 | if (getTickCount() - tick >= failTimer * 1000) { 69 | showConsole(); 70 | print("ÿc1BO timeout fail."); 71 | 72 | if (Config.BattleOrders.QuitOnFailure) { 73 | quit(); 74 | } 75 | 76 | break; 77 | } 78 | 79 | Precast.doPrecast(true); 80 | delay(1000); 81 | } 82 | } 83 | } 84 | 85 | return true; 86 | }; 87 | 88 | Town.doChores(); 89 | 90 | try { 91 | Pather.useWaypoint(35, true); // catacombs 92 | } catch (wperror) { 93 | showConsole(); 94 | print("ÿc1Failed to take waypoint."); 95 | 96 | if (Config.BattleOrders.QuitOnFailure) { 97 | quit(); 98 | } 99 | 100 | return false; 101 | } 102 | 103 | Pather.moveTo(me.x + 6, me.y + 6); 104 | 105 | let i, 106 | tick = getTickCount(), 107 | failTimer = 60; 108 | 109 | MainLoop: 110 | while (true) { 111 | if (Config.BattleOrders.SkipIfTardy && this.amTardy()) { 112 | break; 113 | } 114 | 115 | switch (Config.BattleOrders.Mode) { 116 | case 0: // Give BO 117 | for (i = 0; i < Config.BattleOrders.Getters.length; i += 1) { 118 | while (!Misc.inMyParty(Config.BattleOrders.Getters[i]) || !getUnit(0, Config.BattleOrders.Getters[i])) { 119 | if (getTickCount() - tick >= failTimer * 1000) { 120 | showConsole(); 121 | print("ÿc1BO timeout fail."); 122 | 123 | if (Config.BattleOrders.QuitOnFailure) { 124 | quit(); 125 | } 126 | 127 | break MainLoop; 128 | } 129 | 130 | delay(500); 131 | } 132 | } 133 | 134 | if (this.giveBO(Config.BattleOrders.Getters)) { 135 | break MainLoop; 136 | } 137 | 138 | break; 139 | case 1: // Get BO 140 | if (me.getState(32)) { 141 | delay(1000); 142 | 143 | break MainLoop; 144 | } 145 | 146 | if (getTickCount() - tick >= failTimer * 1000) { 147 | showConsole(); 148 | print("ÿc1BO timeout fail."); 149 | 150 | if (Config.BattleOrders.QuitOnFailure) { 151 | quit(); 152 | } 153 | 154 | break MainLoop; 155 | } 156 | 157 | break; 158 | } 159 | 160 | delay(500); 161 | } 162 | 163 | Pather.useWaypoint(1); 164 | 165 | if (Config.BattleOrders.Mode === 0 && Config.BattleOrders.Idle) { 166 | for (i = 0; i < Config.BattleOrders.Getters.length; i += 1) { 167 | while (Misc.inMyParty(Config.BattleOrders.Getters[i])) { 168 | delay(500); 169 | } 170 | } 171 | } 172 | 173 | return true; 174 | } 175 | -------------------------------------------------------------------------------- /kolbot/libs/bots/BoBarbHelper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename BoBarbHelper.js 3 | * @author nag0k 4 | * @desc give Battle Orders buff modded for hardcore, with barbarian waiting whole game on Catacombs 2 wp by default 5 | * get the required lines for character config files from ...\libs\config\_BaseConfigFile.js 6 | */ 7 | 8 | const BoBarbHelper = () => { 9 | if (me.classid !== 4 && Config.BoBarbHelper.Mode !== 0) { 10 | return true; 11 | } 12 | 13 | const townNearbyMonster = true; // go to town if monsters nearby 14 | const townLowMana = 20; // go refill mana if mana drops below this percent 15 | 16 | const shouldHealMana = amount => me.mp < Math.floor(me.mpmax * amount / 100) 17 | 18 | const healMana = () => { 19 | Pather.useWaypoint(1); 20 | Town.initNPC("Heal", "heal"); 21 | Pather.useWaypoint(Config.BoBarbHelper.Wp); 22 | }; 23 | 24 | const shouldBuff = unit => ( 25 | Misc.inMyParty(unit) && 26 | getDistance(me, unit) < 10 && 27 | unit.name !== me.name && 28 | !unit.dead && 29 | !unit.inTown 30 | ) 31 | 32 | const giveBuff = () => { 33 | const unit = getUnit(0); 34 | 35 | do { 36 | if (shouldBuff(unit)) { 37 | Precast.doPrecast(true); 38 | delay(50); 39 | } 40 | } while(unit.getNext()); 41 | }; 42 | 43 | const monsterNear = () => { 44 | const unit = getUnit(1); 45 | 46 | if (unit) { 47 | do { 48 | if (Attack.checkMonster(unit) && getDistance(me, unit) < 20) { 49 | return true; 50 | } 51 | } while(unit.getNext()); 52 | } 53 | 54 | return false; 55 | }; 56 | 57 | if (!Config.QuitList) { 58 | showConsole(); 59 | print('set Config.QuitList in character settings'); 60 | print('if you don\'t I will idle indefinitely'); 61 | } 62 | 63 | if (me.playertype == 1 && Config.LifeChicken <= 0) { 64 | showConsole(); 65 | print('on HARDCORE'); 66 | print('you should set Config.LifeChicken'); 67 | print('monsters can find their way to wps ...'); 68 | delay(2000); 69 | hideConsole(); 70 | me.overhead('set LifeChiken to 40'); 71 | Config.LifeChicken = 40; 72 | } 73 | 74 | if (shouldHealMana(townLowMana)) { 75 | Town.initNPC("Heal", "heal"); 76 | } 77 | 78 | Town.heal(); // in case our life is low as well 79 | 80 | try { 81 | Pather.useWaypoint(Config.BoBarbHelper.Wp); 82 | } catch (e) { 83 | showConsole(); 84 | print('Failed to move to BO WP'); 85 | print('make sure I have ' + Pather.getAreaName(Config.BoBarbHelper.Wp) + ' waypoint'); 86 | delay(20000); 87 | 88 | return true; 89 | } 90 | 91 | Pather.moveTo(me.x + 4, me.y + 4); 92 | 93 | while (true) { 94 | giveBuff(); 95 | 96 | if (townNearbyMonster && monsterNear()) { 97 | if (!Pather.useWaypoint(1)) { 98 | break; 99 | } 100 | } 101 | 102 | if (shouldHealMana(townLowMana)) { 103 | healMana(); 104 | } 105 | 106 | delay(25); 107 | } 108 | 109 | Town.goToTown(); 110 | 111 | return true; 112 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/BoneAsh.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename BoneAsh.js 3 | * @author kolton 4 | * @desc kill Bone Ash 5 | */ 6 | 7 | function BoneAsh() { 8 | Town.doChores(); 9 | Pather.useWaypoint(32); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveTo(20047, 4898)) { 13 | throw new Error("Failed to move to Bone Ash"); 14 | } 15 | 16 | Attack.kill(getLocaleString(2878)); // Bone Ash 17 | Pickit.pickItems(); 18 | 19 | return true; 20 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Bonesaw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Bonesaw.js 3 | * @author kolton 4 | * @desc kill Bonesaw Breaker 5 | */ 6 | 7 | function Bonesaw() { 8 | Town.doChores(); 9 | Pather.useWaypoint(115); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToPreset(115, 2, 455, 15, 15)) { 13 | throw new Error("Failed to move to Bonesaw"); 14 | } 15 | 16 | Attack.clear(15, 0, getLocaleString(22502)); // Bonesaw Breaker 17 | 18 | if (Config.Bonesaw.ClearDrifterCavern && Pather.moveToExit(116, true)) { 19 | Attack.clearLevel(Config.ClearType); 20 | } 21 | 22 | return true; 23 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/ChestMania.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename ChestMania.js 3 | * @author kolton 4 | * @desc Open chests in configured areas 5 | */ 6 | 7 | function ChestMania() { 8 | var prop, i; 9 | 10 | Town.doChores(); 11 | 12 | for (prop in Config.ChestMania) { 13 | if (Config.ChestMania.hasOwnProperty(prop)) { 14 | for (i = 0; i < Config.ChestMania[prop].length; i += 1) { 15 | Pather.journeyTo(Config.ChestMania[prop][i]); 16 | Precast.doPrecast(i == 0 ? true : false); 17 | Misc.openChestsInArea(Config.ChestMania[prop][i]); 18 | } 19 | 20 | Town.doChores(); 21 | } 22 | } 23 | 24 | return true; 25 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/ClassicChaosAssistant.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename ClassicChaosAssistant.js 3 | * @author YGM 4 | * @desc Assistant to help sorcs in public chaos runs games on classic. 5 | */ 6 | function Idle() { 7 | 8 | var stargo, infgo, seisgo, vizgo, infseal, seisseal, vizseal, diablopickup, normalpickup = false, i, tick, seal, boss, n, target, positions, trapCheck; 9 | 10 | this.getLayout = function (seal, value) { 11 | var sealPreset = getPresetUnit(108, 2, seal); 12 | 13 | if (!seal) { 14 | throw new Error("Seal preset not found. Can't continue."); 15 | } 16 | 17 | if (sealPreset.roomy * 5 + sealPreset.y === value || sealPreset.roomx * 5 + sealPreset.x === value) { 18 | return 1; 19 | } 20 | 21 | return 2; 22 | }; 23 | 24 | this.initLayout = function () { 25 | this.vizLayout = this.getLayout(396, 5275); 26 | this.seisLayout = this.getLayout(394, 7773); 27 | this.infLayout = this.getLayout(392, 7893); 28 | }; 29 | 30 | this.openSeal = function (id) { 31 | Pather.moveToPreset(108, 2, id, id === 394 ? 5 : 2, id === 394 ? 5 : 0); 32 | 33 | seal = getUnit(2, id); 34 | 35 | if (seal) { 36 | for (i = 0; i < 3; i += 1) { 37 | 38 | if (id === 394) { 39 | Misc.click(0, 0, seal); 40 | } else { 41 | seal.interact(); 42 | } 43 | 44 | tick = getTickCount(); 45 | 46 | while (getTickCount() - tick < 500) { 47 | if (seal.mode) { 48 | return true; 49 | } 50 | 51 | delay(10); 52 | } 53 | } 54 | } 55 | 56 | return false; 57 | }; 58 | 59 | addEventListener("keyup", 60 | 61 | function (key) { 62 | if (key === 97) { // Numpad 1 63 | stargo = true; 64 | } 65 | if (key === 98) { // Numpad 2 66 | infgo = true; 67 | } 68 | if (key === 99) { // Numpad 3 69 | infseal = true; 70 | } 71 | if (key === 100) { // Numpad 4 72 | seisgo = true; 73 | } 74 | if (key === 101) { // Numpad 5 (YOU MUST DISABLE KOLTONS MULETRIGGER!) 75 | seisseal = true; 76 | } 77 | if (key === 102) { // Numpad 6 78 | vizgo = true; 79 | } 80 | if (key === 103) { // Numpad 7 81 | vizseal = true; 82 | } 83 | if (key === 104) { // Numpad 8 (Open last seal, teleport to star and pickup for 30 seconds) 84 | diablopickup = true; 85 | } 86 | if (key === 105) { // Numpad 9 (Pickup at current location) 87 | normalpickup = true; 88 | } 89 | }); 90 | 91 | while (true) { 92 | if (stargo) { 93 | switch (me.area) { 94 | case 107: 95 | Precast.doPrecast(true); 96 | Pather.moveToPreset(108, 2, 255); 97 | this.initLayout(); 98 | break; 99 | } 100 | stargo = false; 101 | } 102 | 103 | if (infgo) { 104 | switch (me.area) { 105 | case 108: 106 | if (this.infLayout === 1) { 107 | Pather.moveTo(7893, 5306); 108 | } else { 109 | Pather.moveTo(7929, 5294); 110 | } 111 | Pather.makePortal(); 112 | say("Infector of Souls TP Up!"); 113 | break; 114 | } 115 | infgo = false; 116 | } 117 | 118 | if (seisgo) { 119 | switch (me.area) { 120 | case 108: 121 | if (this.seisLayout === 1) { 122 | Pather.moveTo(7773, 5191); 123 | } else { 124 | Pather.moveTo(7794, 5189); 125 | } 126 | Pather.makePortal(); 127 | say("Lord De Seis TP Up!"); 128 | break; 129 | } 130 | seisgo = false; 131 | } 132 | 133 | if (vizgo) { 134 | switch (me.area) { 135 | case 108: 136 | if (this.vizLayout === 1) { 137 | Pather.moveTo(7681, 5302); 138 | } else { 139 | Pather.moveTo(7675, 5305); 140 | } 141 | Pather.makePortal(); 142 | say("Grand Vizier of Chaos TP Up!"); 143 | break; 144 | } 145 | vizgo = false; 146 | } 147 | 148 | if (infseal) { 149 | switch (me.area) { 150 | case 108: 151 | this.openSeal(393) 152 | this.openSeal(392) 153 | say("Infector of Souls spawned!"); 154 | if (this.infLayout === 1) { 155 | Pather.moveTo(7893, 5306); 156 | } else { 157 | Pather.moveTo(7929, 5294); 158 | } 159 | break; 160 | } 161 | infseal = false; 162 | } 163 | 164 | if (seisseal) { 165 | switch (me.area) { 166 | case 108: 167 | this.openSeal(394) 168 | say("Lord De Seis spawned!"); 169 | if (this.seisLayout === 1) { 170 | Pather.moveTo(7773, 5191); 171 | } else { 172 | Pather.moveTo(7794, 5189); 173 | } 174 | break; 175 | } 176 | seisseal = false; 177 | } 178 | 179 | if (vizseal) { 180 | switch (me.area) { 181 | case 108: 182 | this.openSeal(396) 183 | say("Grand Vizier of Chaos spawned!"); 184 | if (this.vizLayout === 1) { 185 | Pather.moveTo(7681, 5302); 186 | } else { 187 | Pather.moveTo(7675, 5305); 188 | } 189 | break; 190 | } 191 | vizseal = false; 192 | } 193 | 194 | if (diablopickup) { 195 | switch (me.area) { 196 | case 108: 197 | this.openSeal(395) 198 | Pather.moveToPreset(108, 2, 255); 199 | for (i = 0; i < 300; i += 1) { 200 | Pickit.pickItems(); 201 | delay(100); 202 | } 203 | break; 204 | } 205 | diablopickup = false; 206 | } 207 | 208 | if (normalpickup) { 209 | switch (me.area) { 210 | case 108: 211 | Pickit.pickItems(); 212 | break; 213 | } 214 | normalpickup = false; 215 | } 216 | 217 | delay(10); 218 | } 219 | 220 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/ClearAnyArea.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename ClearAnyArea.js 3 | * @author kolton 4 | * @desc Clears any area 5 | */ 6 | 7 | function ClearAnyArea() { 8 | var i; 9 | 10 | Town.doChores(); 11 | 12 | for (i = 0; i < Config.ClearAnyArea.AreaList.length; i += 1) { 13 | if (Pather.journeyTo(Config.ClearAnyArea.AreaList[i])) { 14 | Attack.clearLevel(Config.ClearType); 15 | } 16 | } 17 | 18 | return true; 19 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Coldcrow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Coldcrow.js 3 | * @author njomnjomnjom 4 | * @desc kill Coldcrow 5 | */ 6 | 7 | function Coldcrow() { 8 | Town.doChores(); 9 | Pather.useWaypoint(3); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit(9, true, false)) { 13 | throw new Error("Failed to move to Cave"); 14 | } 15 | 16 | if (!Pather.moveToPreset(me.area, 1, 921, 0, 0, false)) { 17 | throw new Error("Failed to move to Coldcrow"); 18 | } 19 | 20 | Attack.clear(15, 0, getLocaleString(2871)); // Coldcrow 21 | 22 | return true; 23 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Coldworm.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Coldworm.js 3 | * @author kolton, edited by 13ack.Stab 4 | * @desc kill Coldworm; optionally kill Beetleburst and clear Maggot Lair 5 | */ 6 | 7 | function Coldworm() { 8 | var i; 9 | 10 | Town.doChores(); 11 | Pather.useWaypoint(43); 12 | Precast.doPrecast(true); 13 | 14 | // Beetleburst, added by 13ack.Stab 15 | if (Config.Coldworm.KillBeetleburst) { 16 | if (!Pather.moveToPreset(me.area, 1, 747)) { 17 | throw new Error("Failed to move to Beetleburst"); 18 | } 19 | 20 | Attack.clear(15, 0, getLocaleString(2882)); 21 | } 22 | 23 | for (i = 62; i <= 64; i += 1) { 24 | if (!Pather.moveToExit(i, true)) { 25 | throw new Error("Failed to move to Coldworm"); 26 | } 27 | 28 | if (Config.Coldworm.ClearMaggotLair) { 29 | Attack.clearLevel(Config.ClearType); 30 | } 31 | } 32 | 33 | if (!Config.Coldworm.ClearMaggotLair) { 34 | if (!Pather.moveToPreset(me.area, 2, 356)) { 35 | throw new Error("Failed to move to Coldworm"); 36 | } 37 | 38 | Attack.clear(15, 0, 284); 39 | } 40 | 41 | return true; 42 | } 43 | -------------------------------------------------------------------------------- /kolbot/libs/bots/Corpsefire.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Corpsefire.js 3 | * @author kolton 4 | * @desc kill Corpsefire and optionally clear Den of Evil 5 | */ 6 | 7 | function Corpsefire() { 8 | Town.doChores(); 9 | Pather.useWaypoint(3); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit([2, 8], true) || !Pather.moveToPreset(me.area, 1, 959, 0, 0, false, true)) { 13 | throw new Error("Failed to move to Corpsefire"); 14 | } 15 | 16 | Attack.clear(15, 0, getLocaleString(3319)); // Corpsefire 17 | 18 | if (Config.Corpsefire.ClearDen) { 19 | Attack.clearLevel(); 20 | } 21 | 22 | return true; 23 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Countess.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Countess.js 3 | * @author kolton 4 | * @desc kill The Countess and optionally kill Ghosts along the way 5 | */ 6 | 7 | function Countess() { 8 | var i, poi; 9 | 10 | Town.doChores(); 11 | Pather.useWaypoint(6); 12 | Precast.doPrecast(true); 13 | 14 | if (!Pather.moveToExit([20, 21, 22, 23, 24, 25], true)) { 15 | throw new Error("Failed to move to Countess"); 16 | } 17 | 18 | poi = getPresetUnit(me.area, 2, 580); 19 | 20 | if (!poi) { 21 | throw new Error("Failed to move to Countess (preset not found)"); 22 | } 23 | 24 | switch (poi.roomx * 5 + poi.x) { 25 | case 12565: 26 | Pather.moveTo(12578, 11043); 27 | break; 28 | case 12526: 29 | Pather.moveTo(12548, 11083); 30 | break; 31 | } 32 | 33 | Attack.clear(20, 0, getLocaleString(2875)); // The Countess 34 | 35 | if (Config.OpenChests) { 36 | Misc.openChestsInArea(); 37 | } 38 | 39 | return true; 40 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Cows.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Cows.js 3 | * @author kolton 4 | * @desc clear the Moo Moo Farm without killing the Cow King 5 | */ 6 | 7 | function Cows() { 8 | this.buildCowRooms = function () { 9 | var i, j, room, kingPreset, badRooms, badRooms2, 10 | finalRooms = [], 11 | indexes = []; 12 | 13 | kingPreset = getPresetUnit(me.area, 1, 893); 14 | badRooms = [];//getRoom(kingPreset.roomx * 5 + kingPreset.x, kingPreset.roomy * 5 + kingPreset.y).getNearby(); 15 | 16 | /* 17 | for (i = 0; i < badRooms.length; i += 1) { 18 | badRooms2 = badRooms[i].getNearby(); 19 | 20 | for (j = 0; j < badRooms2.length; j += 1) { 21 | if (indexes.indexOf(badRooms2[j].x + "" + badRooms2[j].y) === -1) { 22 | indexes.push(badRooms2[j].x + "" + badRooms2[j].y); 23 | } 24 | } 25 | } 26 | */ 27 | 28 | room = getRoom(); 29 | 30 | do { 31 | if (indexes.indexOf(room.x + "" + room.y) === -1) { 32 | finalRooms.push([room.x * 5 + room.xsize / 2, room.y * 5 + room.ysize / 2]); 33 | } 34 | } while (room.getNext()); 35 | 36 | return finalRooms; 37 | }; 38 | 39 | this.clearCowLevel = function () { 40 | if (Config.MFLeader) { 41 | Pather.makePortal(); 42 | say("cows"); 43 | } 44 | 45 | var room, result, myRoom, 46 | rooms = this.buildCowRooms(); 47 | 48 | function RoomSort(a, b) { 49 | return getDistance(myRoom[0], myRoom[1], a[0], a[1]) - getDistance(myRoom[0], myRoom[1], b[0], b[1]); 50 | } 51 | 52 | while (rooms.length > 0) { 53 | // get the first room + initialize myRoom var 54 | if (!myRoom) { 55 | room = getRoom(me.x, me.y); 56 | } 57 | 58 | if (room) { 59 | if (room instanceof Array) { // use previous room to calculate distance 60 | myRoom = [room[0], room[1]]; 61 | } else { // create a new room to calculate distance (first room, done only once) 62 | myRoom = [room.x * 5 + room.xsize / 2, room.y * 5 + room.ysize / 2]; 63 | } 64 | } 65 | 66 | rooms.sort(RoomSort); 67 | room = rooms.shift(); 68 | 69 | result = Pather.getNearestWalkable(room[0], room[1], 10, 2); 70 | 71 | if (result) { 72 | Pather.moveTo(result[0], result[1], 3); 73 | 74 | if (!Attack.clear(30)) { 75 | return false; 76 | } 77 | } 78 | } 79 | 80 | return true; 81 | }; 82 | 83 | this.getLeg = function () { 84 | var i, portal, wirt, leg, gid; 85 | 86 | if (me.getItem(NTIPAliasClassID["leg"])) { 87 | return me.getItem(NTIPAliasClassID["leg"]); 88 | } 89 | 90 | Pather.useWaypoint(4); 91 | Precast.doPrecast(true); 92 | Pather.moveToPreset(me.area, 1, 922, 10, 10); 93 | 94 | for (i = 0; i < 6; i += 1) { 95 | portal = Pather.getPortal(38); 96 | 97 | if (portal) { 98 | Pather.usePortal(null, null, portal); 99 | 100 | break; 101 | } 102 | 103 | delay(500); 104 | } 105 | 106 | if (!portal) { 107 | throw new Error("Tristram portal not found"); 108 | } 109 | 110 | Pather.moveTo(25048, 5177); 111 | 112 | wirt = getUnit(2, 268); 113 | 114 | for (i = 0; i < 8; i += 1) { 115 | wirt.interact(); 116 | delay(500); 117 | 118 | leg = getUnit(4, NTIPAliasClassID["leg"]); 119 | 120 | if (leg) { 121 | gid = leg.gid; 122 | 123 | Pickit.pickItem(leg); 124 | Town.goToTown(); 125 | 126 | return me.getItem(-1, -1, gid); 127 | } 128 | } 129 | 130 | throw new Error("Failed to get the leg"); 131 | }; 132 | 133 | this.getTome = function () { 134 | var tome, 135 | myTome = me.findItem("tbk", 0, 3), 136 | akara = Town.initNPC("Shop"); 137 | 138 | tome = me.getItem("tbk"); 139 | 140 | if (tome) { 141 | do { 142 | if (!myTome || tome.gid !== myTome.gid) { 143 | return copyUnit(tome); 144 | } 145 | } while (tome.getNext()); 146 | } 147 | 148 | if (!akara) { 149 | throw new Error("Failed to buy tome"); 150 | } 151 | 152 | tome = akara.getItem("tbk"); 153 | 154 | if (tome.buy()) { 155 | tome = me.getItem("tbk"); 156 | 157 | if (tome) { 158 | do { 159 | if (!myTome || tome.gid !== myTome.gid) { 160 | return copyUnit(tome); 161 | } 162 | } while (tome.getNext()); 163 | } 164 | } 165 | 166 | throw new Error("Failed to buy tome"); 167 | }; 168 | 169 | this.openPortal = function (leg, tome) { 170 | var i; 171 | 172 | if (!Town.openStash()) { 173 | throw new Error("Failed to open stash"); 174 | } 175 | 176 | if (!Cubing.emptyCube()) { 177 | throw new Error("Failed to empty cube"); 178 | } 179 | 180 | if (!Storage.Cube.MoveTo(leg) || !Storage.Cube.MoveTo(tome) || !Cubing.openCube()) { 181 | throw new Error("Failed to cube leg and tome"); 182 | } 183 | 184 | transmute(); 185 | delay(500); 186 | 187 | for (i = 0; i < 10; i += 1) { 188 | if (Pather.getPortal(39)) { 189 | return true; 190 | } 191 | 192 | delay(200); 193 | } 194 | 195 | throw new Error("Portal not found"); 196 | }; 197 | 198 | var leg, tome; 199 | 200 | // we can begin now 201 | if (!me.getQuest(4, 0)) { 202 | throw new Error("Cain quest incomplete"); 203 | } 204 | 205 | switch (me.gametype) { 206 | case 0: // classic 207 | if (!me.getQuest(26, 0)) { // diablo not completed 208 | throw new Error("Diablo quest incomplete."); 209 | } 210 | 211 | break; 212 | case 1: // expansion 213 | if (!me.getQuest(40, 0)) { // baal not completed 214 | throw new Error("Baal quest incomplete."); 215 | } 216 | 217 | break; 218 | } 219 | 220 | Town.goToTown(1); 221 | Town.doChores(); 222 | 223 | leg = this.getLeg(); 224 | tome = this.getTome(); 225 | 226 | this.openPortal(leg, tome); 227 | Pather.usePortal(39); 228 | Precast.doPrecast(false); 229 | this.clearCowLevel(); 230 | 231 | return true; 232 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/CrushTele.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename CrushTele.js 3 | * @author kolton 4 | * @desc Auto tele for classic rush only 5 | * Hit the "-" numpad in strategic areas. 6 | */ 7 | 8 | function CrushTele() { 9 | var go = false; 10 | 11 | addEventListener("keyup", 12 | function (key) { 13 | if (key === 109) { 14 | go = true; 15 | } 16 | } 17 | ); 18 | 19 | while (true) { 20 | if (go) { 21 | switch (me.area) { 22 | case 35: 23 | Pather.moveToExit([36, 37], true); 24 | break; 25 | case 57: 26 | Pather.moveToExit(60, true); 27 | Pather.moveToPreset(me.area, 2, 354); 28 | break; 29 | case 43: 30 | Pather.moveToExit([62, 63, 64], true); 31 | Pather.moveToPreset(me.area, 2, 356); 32 | break; 33 | case 44: 34 | Pather.moveToExit([45, 58, 61], true); 35 | break; 36 | case 46: 37 | Pather.moveToExit(getRoom().correcttomb, true); 38 | Pather.moveToPreset(me.area, 2, 152); 39 | break; 40 | case 74: 41 | Pather.moveToPreset(me.area, 2, 357, 0, 0, false , true); 42 | break; 43 | case 101: 44 | Pather.moveToExit(102, true); 45 | break; 46 | case 107: 47 | Pather.moveToPreset(108, 2, 255); 48 | break; 49 | } 50 | 51 | go = false; 52 | } 53 | 54 | delay(10); 55 | } 56 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Duriel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Duriel.js 3 | * @author kolton 4 | * @desc kill Duriel 5 | */ 6 | 7 | function Duriel () { 8 | this.killDuriel = function () { 9 | var i, target; 10 | 11 | for (i = 0; i < 3; i += 1) { 12 | target = getUnit(1, 211); 13 | 14 | if (target) { 15 | break; 16 | } 17 | 18 | delay(500); 19 | } 20 | 21 | if (!target) { 22 | throw new Error("Duriel not found."); 23 | } 24 | 25 | if (Config.MFLeader) { 26 | Pather.makePortal(); 27 | say("kill " + 211); 28 | } 29 | 30 | for (i = 0; i < 300; i += 1) { 31 | ClassAttack.doAttack(target); 32 | 33 | if (target.dead) { 34 | return true; 35 | } 36 | 37 | if (getDistance(me, target) <= 10) { 38 | Pather.moveTo(22638, me.y < target.y ? 15722 : 15693); 39 | } 40 | } 41 | 42 | return target.dead; 43 | }; 44 | 45 | var i, unit; 46 | 47 | if (me.area !== 46) { 48 | Town.doChores(); 49 | Pather.useWaypoint(46); 50 | } 51 | 52 | Precast.doPrecast(true); 53 | 54 | if (!Pather.moveToExit(getRoom().correcttomb, true)) { 55 | throw new Error("Failed to move to Tal Rasha's Tomb"); 56 | } 57 | 58 | if (!Pather.moveToPreset(me.area, 2, 152, -11, 3)) { 59 | throw new Error("Failed to move to Orifice"); 60 | } 61 | 62 | for (i = 0; i < 10; i += 1) { 63 | if (getUnit(2, 100)) { 64 | break; 65 | } 66 | 67 | delay(500); 68 | } 69 | 70 | if (me.gametype === 1 && me.classid !== 1) { 71 | Attack.clear(5); 72 | } 73 | 74 | unit = getUnit(2, 100); 75 | 76 | if (unit) { 77 | for (i = 0; i < 3; i += 1) { 78 | if (me.area === unit.area) { 79 | Skill.cast(43, 0, unit); 80 | } 81 | 82 | if (me.area === 73) { 83 | break; 84 | } 85 | } 86 | } 87 | 88 | if (me.area !== 73 && !Pather.useUnit(2, 100, 73)) { 89 | Attack.clear(10); 90 | Pather.useUnit(2, 100, 73); 91 | } 92 | 93 | if (me.area !== 73) { 94 | throw new Error("Failed to move to Duriel"); 95 | } 96 | 97 | if (me.classid === 1 && me.gametype === 0) { 98 | this.killDuriel(); 99 | } else { 100 | Attack.kill(211); // Duriel 101 | } 102 | 103 | Pickit.pickItems(); 104 | 105 | return true; 106 | } 107 | -------------------------------------------------------------------------------- /kolbot/libs/bots/Eldritch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Eldritch.js 3 | * @author kolton 4 | * @desc kill Eldritch the Rectifier, optionally kill Shenk the Overseer, Dac Farren and open chest 5 | */ 6 | 7 | function Eldritch() { 8 | var chest; 9 | 10 | Town.doChores(); 11 | Pather.useWaypoint(111); 12 | Precast.doPrecast(true); 13 | Pather.moveTo(3745, 5084); 14 | Attack.clear(15, 0, getLocaleString(22500)); // Eldritch the Rectifier 15 | 16 | if (Config.Eldritch.OpenChest) { 17 | chest = getPresetUnit(me.area, 2, 455); 18 | 19 | if (chest) { 20 | Pather.moveToUnit(chest); 21 | 22 | chest = getUnit(2, 455); 23 | 24 | if (Misc.openChest(chest)) { 25 | Pickit.pickItems(); 26 | } 27 | } 28 | } 29 | 30 | if (Config.Eldritch.KillShenk) { 31 | Pather.moveTo(3876, 5130); 32 | Attack.clear(15, 0, getLocaleString(22435)); // Shenk the Overseer 33 | } 34 | 35 | if (Config.Eldritch.KillDacFarren) { 36 | Pather.moveTo(4478, 5108); 37 | Attack.clear(15, 0, getLocaleString(22501)); // Dac Farren 38 | } 39 | 40 | return true; 41 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Endugu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Endugu.js 3 | * @author kolton 4 | * @desc kill Witch Doctor Endugu 5 | */ 6 | 7 | function Endugu() { 8 | Town.doChores(); 9 | Pather.useWaypoint(78); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit([88, 89, 91], true) || !Pather.moveToPreset(me.area, 2, 406)) { 13 | throw new Error("Failed to move to Endugu"); 14 | } 15 | 16 | Attack.clear(15, 0, getLocaleString(2867)); // Witch Doctor Endugu 17 | 18 | return true; 19 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Eyeback.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Eyeback.js 3 | * @author kolton 4 | * @desc kill Eyeback the Unleashed 5 | */ 6 | 7 | function Eyeback() { 8 | Town.doChores(); 9 | Pather.useWaypoint(112); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToPreset(111, 1, 784)) { 13 | throw new Error("Failed to move to Eyeback the Unleashed"); 14 | } 15 | 16 | Attack.clear(15, 0, getLocaleString(22499)); // Eyeback the Unleashed 17 | 18 | return true; 19 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Frozenstein.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Frozenstein.js 3 | * @author kolton 4 | * @desc kill Frozensteinand optionally clear Frozen River 5 | */ 6 | 7 | function Frozenstein() { 8 | Town.doChores(); 9 | Pather.useWaypoint(113); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit(114, true) || !Pather.moveToPreset(me.area, 2, 460, -5, -5)) { 13 | throw new Error("Failed to move to Frozenstein"); 14 | } 15 | 16 | Attack.clear(15, 0, getLocaleString(22504)); // Frozenstein 17 | 18 | if (Config.Frozenstein.ClearFrozenRiver) { 19 | Attack.clearLevel(Config.ClearType); 20 | } 21 | 22 | return true; 23 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Gamble.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Gamble.js 3 | * @author kolton 4 | * @desc keep gambling while other players supply you with gold 5 | */ 6 | 7 | function Gamble() { 8 | var gold, 9 | info = Gambling.getInfo(), 10 | needGold = false; 11 | 12 | if (!info) { 13 | throw new Error("Bad Gambling System config."); 14 | } 15 | 16 | me.maxgametime = 0; 17 | Town.goToTown(1); 18 | 19 | addEventListener('copydata', 20 | function (mode, msg) { 21 | if (needGold && mode === 0 && info.goldFinders.indexOf(msg) > -1) { 22 | print("Got game request from " + msg); 23 | sendCopyData(null, msg, 4, me.gamename + "/" + me.gamepassword); 24 | } 25 | }); 26 | 27 | while (true) { 28 | if (Town.needGamble()) { 29 | Town.gamble(); 30 | } else { 31 | needGold = true; 32 | } 33 | 34 | Town.move("stash"); 35 | 36 | while (needGold) { 37 | while (true) { 38 | if (Town.needGamble()) { 39 | needGold = false; 40 | } 41 | 42 | Town.stash(); 43 | 44 | gold = getUnit(4, 523, 3); 45 | 46 | if (!gold || !Pickit.canPick(gold)) { 47 | break; 48 | } 49 | 50 | Pickit.pickItem(gold); 51 | delay(500); 52 | } 53 | 54 | delay(500); 55 | } 56 | 57 | delay(1000); 58 | } 59 | 60 | return true; 61 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/GetKeys.js: -------------------------------------------------------------------------------- 1 | function GetKeys() { 2 | Town.doChores(); 3 | 4 | if (!me.findItems("pk1") || me.findItems("pk1").length < 3) { 5 | try { 6 | print("ÿc2Countess"); 7 | Pather.useWaypoint(6); 8 | Precast.doPrecast(true); 9 | Pather.journeyTo(25); 10 | Pather.moveToPreset(me.area, 2, 580); 11 | Attack.kill(getLocaleString(2875)); 12 | Pickit.pickItems(); 13 | } catch (countessError) { 14 | print("ÿc1Countess failed"); 15 | } 16 | } 17 | 18 | if (!me.findItems("pk2") || me.findItems("pk2").length < 3) { 19 | try { 20 | print("ÿc2Summoner"); 21 | Town.goToTown(); 22 | Town.doChores(); 23 | Pather.useWaypoint(74); 24 | Precast.doPrecast(true); 25 | Pather.moveToPreset(me.area, 2, 357, -3, -3); 26 | Attack.kill(250); 27 | Pickit.pickItems(); 28 | } catch (summonerError) { 29 | print("ÿc1Summoner failed"); 30 | } 31 | } 32 | 33 | if (!me.findItems("pk3") || me.findItems("pk3").length < 3) { 34 | try { 35 | print("ÿc2Nihlathak"); 36 | Town.goToTown(); 37 | Town.doChores(); 38 | Pather.useWaypoint(123); 39 | Precast.doPrecast(true); 40 | Pather.moveToExit(124, true); 41 | Pather.moveToPreset(me.area, 2, 462); 42 | Attack.kill(526); 43 | Pickit.pickItems(); 44 | } catch (nihlathakError) { 45 | print("ÿc1Nihlathak failed"); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/GhostBusters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename GhostBusters.js 3 | * @author kolton 4 | * @desc who you gonna call? 5 | */ 6 | 7 | function GhostBusters() { 8 | this.clearGhosts = function () { 9 | var room, result, rooms, monster, monList; 10 | 11 | room = getRoom(); 12 | 13 | if (!room) { 14 | return false; 15 | } 16 | 17 | rooms = []; 18 | 19 | do { 20 | rooms.push([room.x * 5 + room.xsize / 2, room.y * 5 + room.ysize / 2]); 21 | } while (room.getNext()); 22 | 23 | while (rooms.length > 0) { 24 | rooms.sort(Sort.points); 25 | room = rooms.shift(); 26 | 27 | result = Pather.getNearestWalkable(room[0], room[1], 15, 2); 28 | 29 | if (result) { 30 | Pather.moveTo(result[0], result[1], 3); 31 | 32 | monList = []; 33 | monster = getUnit(1); 34 | 35 | if (monster) { 36 | do { 37 | if ([38, 39, 40, 41, 42, 631, 632, 633].indexOf(monster.classid) > -1 && getDistance(me, monster) <= 30 && Attack.checkMonster(monster)) { 38 | monList.push(copyUnit(monster)); 39 | } 40 | } while (monster.getNext()); 41 | } 42 | 43 | if (!Attack.clearList(monList)) { 44 | return false; 45 | } 46 | } 47 | } 48 | 49 | return true; 50 | }; 51 | 52 | this.cellar = function () { // black marsh wp 53 | var i; 54 | 55 | Pather.useWaypoint(6); 56 | Precast.doPrecast(true); 57 | 58 | for (i = 20; i <= 25; i += 1) { 59 | Pather.moveToExit(i, true); 60 | this.clearGhosts(); 61 | } 62 | 63 | return true; 64 | }; 65 | 66 | this.jail = function () { // gonna use inner cloister wp and travel backwards 67 | var i; 68 | 69 | Pather.useWaypoint(32); 70 | Precast.doPrecast(true); 71 | 72 | for (i = 31; i >= 29; i -= 1) { 73 | Pather.moveToExit(i, true); 74 | this.clearGhosts(); 75 | } 76 | 77 | return true; 78 | }; 79 | 80 | this.cathedral = function () { // inner cloister wp 81 | Pather.useWaypoint(32); 82 | Precast.doPrecast(true); 83 | Pather.moveToExit(33, true); 84 | this.clearGhosts(); 85 | 86 | return true; 87 | }; 88 | 89 | this.tombs = function () { // canyon wp 90 | var i; 91 | 92 | Pather.useWaypoint(46); 93 | Precast.doPrecast(true); 94 | 95 | for (i = 66; i <= 72; i += 1) { 96 | Pather.moveToExit(i, true); 97 | this.clearGhosts(); 98 | Pather.moveToExit(46, true); 99 | } 100 | 101 | return true; 102 | }; 103 | 104 | this.flayerDungeon = function () { // flayer jungle wp 105 | var areas = [88, 89, 91]; 106 | 107 | Pather.useWaypoint(78); 108 | Precast.doPrecast(true); 109 | 110 | while (areas.length) { 111 | Pather.moveToExit(areas.shift(), true); 112 | this.clearGhosts(); 113 | } 114 | 115 | return true; 116 | }; 117 | 118 | this.crystalinePassage = function () { // crystaline passage wp 119 | Pather.useWaypoint(113); 120 | Precast.doPrecast(true); 121 | this.clearGhosts(); 122 | Pather.moveToExit(114, true); // frozen river 123 | this.clearGhosts(); 124 | 125 | return true; 126 | }; 127 | 128 | this.glacialTrail = function () { // glacial trail wp 129 | Pather.useWaypoint(115); 130 | Precast.doPrecast(true); 131 | this.clearGhosts(); 132 | Pather.moveToExit(116, true); // drifter 133 | this.clearGhosts(); 134 | 135 | return true; 136 | }; 137 | 138 | this.icyCellar = function () { // glacial trail wp 139 | Pather.useWaypoint(118); 140 | Precast.doPrecast(true); 141 | Pather.moveToExit(119, true); // drifter 142 | this.clearGhosts(); 143 | 144 | return true; 145 | }; 146 | 147 | var i, 148 | sequence = ["cellar", "jail", "cathedral", "tombs", "flayerDungeon", "crystalinePassage", "glacialTrail", "icyCellar"]; 149 | 150 | for (i = 0; i < sequence.length; i += 1) { 151 | Town.doChores(); 152 | 153 | try { 154 | this[sequence[i]](); 155 | } finally { 156 | Town.goToTown(); 157 | } 158 | } 159 | 160 | return true; 161 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Hephasto.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Hephasto.js 3 | * @author kolton 4 | * @desc kill Hephasto the Armorer 5 | */ 6 | 7 | function Hephasto() { 8 | Town.doChores(); 9 | Pather.useWaypoint(107); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToPreset(me.area, 2, 376)) { 13 | throw new Error("Failed to move to Hephasto"); 14 | } 15 | 16 | try { 17 | Attack.kill(getLocaleString(1067)); // Hephasto The Armorer 18 | } catch (e) { 19 | print("Heph not found. Carry on"); 20 | } 21 | Pickit.pickItems(); 22 | 23 | if (Config.Hephasto.ClearRiver) { 24 | Attack.clearLevel(Config.Hephasto.ClearType); 25 | } 26 | 27 | return true; 28 | } 29 | -------------------------------------------------------------------------------- /kolbot/libs/bots/IPHunter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename IPHunter.js 3 | * @author kolton, Mercoory 4 | * @desc search for a "hot" IP and stop if the correct server is found 5 | * @changes 2020.01 - more beeps and movements (anti drop measure) when IP is found; overhead messages with countdown timer; logs to D2Bot console 6 | */ 7 | 8 | function IPHunter() { 9 | let ip = Number(me.gameserverip.split(".")[3]); 10 | 11 | if (Config.IPHunter.IPList.indexOf(ip) > -1) { 12 | D2Bot.printToConsole("IPHunter: IP found! - [" + ip + "] Game is : " + me.gamename + "//" + me.gamepassword, 7); 13 | print("IP found! - [" + ip + "] Game is : " + me.gamename + "//" + me.gamepassword); 14 | me.overhead(":D IP found! - [" + ip + "]"); 15 | me.maxgametime = 0; 16 | 17 | for (let i = 12; i > 0; i -= 1) { 18 | me.overhead(":D IP found! - [" + ip + "]" + (i - 1) + " beep left"); 19 | beep(); // works if windows sounds are enabled 20 | delay(250); 21 | } 22 | 23 | while (true) { 24 | 25 | /* // remove comment if you want beeps at every movement 26 | for (let i = 12; i != 0; i -= 1) { 27 | me.overhead(":D IP found! - [" + ip + "]" + (i-1) + " beep left"); 28 | beep(); // works if windows sounds are enabled 29 | delay(250); 30 | } 31 | */ 32 | 33 | me.overhead(":D IP found! - [" + ip + "]"); 34 | try { 35 | Town.move("waypoint"); 36 | Town.move("stash"); 37 | } catch (e) { 38 | // ensure it doesnt leave game by failing to walk due to desyncing. 39 | } 40 | 41 | for (let i = (12 * 60); i > 0; i -= 1) { 42 | me.overhead(":D IP found! - [" + ip + "] Next movement in: " + i + " sec."); 43 | delay(1000); 44 | } 45 | } 46 | } 47 | 48 | for (let i = (Config.IPHunter.GameLength * 60); i > 0; i -= 1) { 49 | me.overhead(":( IP : [" + (ip) + "] NG: " + i + " sec"); 50 | delay(1000); 51 | } 52 | 53 | D2Bot.printToConsole("IPHunter: IP was [" + ip + "]", 10); 54 | 55 | return true; 56 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Icehawk.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Icehawk.js 3 | * @author kolton 4 | * @desc kill Icehawk Riftwing 5 | */ 6 | 7 | function Icehawk() { 8 | Town.doChores(); 9 | Pather.useWaypoint(80); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit([92, 93], false)) { 13 | throw new Error("Failed to move to Icehawk"); 14 | } 15 | 16 | Attack.clear(15, 0, getLocaleString(2864)); // Icehawk Riftwing 17 | 18 | return true; 19 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Izual.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Izual.js 3 | * @author kolton 4 | * @desc kill Izual 5 | */ 6 | 7 | function Izual() { 8 | Town.doChores(); 9 | Pather.useWaypoint(106); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToPreset(105, 1, 256)) { 13 | throw new Error("Failed to move to Izual."); 14 | } 15 | 16 | Attack.kill(256); // Izual 17 | Pickit.pickItems(); 18 | 19 | return true; 20 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/KillDclone.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename KillDclone.js 3 | * @author kolton 4 | * @desc Got to Palace Cellar level 3 and kill Diablo Clone. 5 | */ 6 | 7 | function KillDclone() { 8 | //Town.doChores(); 9 | Pather.useWaypoint(74); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.usePortal(null)) { 13 | throw new Error("Failed to move to Palace Cellar"); 14 | } 15 | 16 | Attack.kill(333); 17 | Pickit.pickItems(); 18 | 19 | if (AutoMule.getInfo() && AutoMule.getInfo().hasOwnProperty("torchMuleInfo")) { 20 | scriptBroadcast("muleAnni"); 21 | } 22 | 23 | return true; 24 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/KurastTemples.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename KurastTemples.js 3 | * @author kolton 4 | * @desc clear Kurast Temples 5 | */ 6 | 7 | function KurastTemples() { 8 | Town.doChores(); 9 | Pather.useWaypoint(80); 10 | Precast.doPrecast(true); 11 | 12 | var i, 13 | areas = [94, 95, 96, 97, 98, 99]; 14 | 15 | for (i = 0; i < 6; i += 1) { 16 | if (me.area !== 80 + Math.floor(i / 2)) { 17 | if (!Pather.moveToExit(80 + Math.floor(i / 2), true)) { 18 | throw new Error("Failed to change area"); 19 | } 20 | } 21 | 22 | if (!Pather.moveToExit(areas[i], true)) { 23 | throw new Error("Failed to move to the temple"); 24 | } 25 | 26 | if (i === 3) { 27 | Precast.doPrecast(true); 28 | } 29 | 30 | Attack.clearLevel(Config.ClearType); 31 | 32 | if (i < 5 && !Pather.moveToExit(80 + Math.floor(i / 2), true)) { 33 | throw new Error("Failed to move out of the temple"); 34 | } 35 | } 36 | 37 | return true; 38 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/MaggotLair.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename MaggotLair.js 3 | * @author marketfresh 4 | * @desc Clear Maggot Lair level 2 and 3 5 | */ 6 | 7 | function MaggotLair() { 8 | var i; 9 | 10 | Town.doChores(); 11 | Pather.useWaypoint(43); 12 | Precast.doPrecast(true); 13 | 14 | if (!(Pather.moveToExit([62, 63], true))) { 15 | throw new Error("Failed to move to Maggot Lair 2"); 16 | } 17 | 18 | Attack.clearLevel(Config.MaggotLair.ClearType); 19 | 20 | if (!(Pather.moveToExit([64], true))) { 21 | throw new Error("Failed to Move to Maggot Lair 3"); 22 | } 23 | 24 | Attack.clearLevel(Config.MaggotLair.ClearType); 25 | 26 | return true; 27 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Mausoleum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Mausoleum.js 3 | * @author kolton 4 | * @desc clear Mausoleum 5 | */ 6 | 7 | function Mausoleum() { 8 | Town.doChores(); 9 | Pather.useWaypoint(3); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit(17, true)) { 13 | throw new Error("Failed to move to Burial Grounds"); 14 | } 15 | 16 | if (Config.Mausoleum.KillBloodRaven) { 17 | Pather.moveToPreset(17, 1, 991); 18 | Attack.kill(getLocaleString(3111)); // Blood Raven 19 | Pickit.pickItems(); 20 | } 21 | 22 | if (!Pather.moveToExit(19, true)) { 23 | throw new Error("Failed to move to Mausoleum"); 24 | } 25 | 26 | Attack.clearLevel(Config.ClearType); 27 | 28 | if (Config.Mausoleum.ClearCrypt) { 29 | // Crypt exit is... awkward 30 | if (!(Pather.moveToExit(17, true) && Pather.moveToPreset(17, 5, 6) && Pather.moveToExit(18, true))) { 31 | throw new Error("Failed to move to Crypt"); 32 | } 33 | 34 | Attack.clearLevel(Config.ClearType); 35 | } 36 | 37 | return true; 38 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Mephisto.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Mephisto.js 3 | * @author kolton, njomnjomnjom 4 | * @desc kill Mephisto 5 | */ 6 | 7 | function Mephisto() { 8 | this.killMephisto = function () { 9 | var i, angle, angles, 10 | pos = {}, 11 | attackCount = 0, 12 | meph = getUnit(1, 242); 13 | 14 | if (!meph) { 15 | throw new Error("Mephisto not found!"); 16 | } 17 | 18 | if (Config.MFLeader) { 19 | Pather.makePortal(); 20 | say("kill " + meph.classid); 21 | } 22 | 23 | while (attackCount < 300 && Attack.checkMonster(meph)) { 24 | //if (getUnit(3, 276)) { 25 | if (meph.mode === 5) { 26 | //if (attackCount % 2 === 0) { 27 | angle = Math.round(Math.atan2(me.y - meph.y, me.x - meph.x) * 180 / Math.PI); 28 | angles = me.y > meph.y ? [-30, -60, -90] : [30, 60, 90]; 29 | 30 | for (i = 0; i < angles.length; i += 1) { 31 | //pos.dist = Math.round(getDistance(me, meph)); 32 | pos.dist = 18; 33 | pos.x = Math.round((Math.cos((angle + angles[i]) * Math.PI / 180)) * pos.dist + meph.x); 34 | pos.y = Math.round((Math.sin((angle + angles[i]) * Math.PI / 180)) * pos.dist + meph.y); 35 | 36 | if (Attack.validSpot(pos.x, pos.y)) { 37 | me.overhead("move, bitch!"); 38 | Pather.moveTo(pos.x, pos.y); 39 | 40 | break; 41 | } 42 | } 43 | } 44 | 45 | if (ClassAttack.doAttack(meph) < 2) { 46 | break; 47 | } 48 | 49 | attackCount += 1; 50 | } 51 | 52 | return (meph.mode === 0 || meph.mode === 12); 53 | }; 54 | 55 | this.moat = function () { 56 | var count, distance, mephisto; 57 | 58 | count = 0; 59 | 60 | delay(350); 61 | Pather.moveTo(17563, 8072); 62 | 63 | mephisto = getUnit(1, 242); 64 | 65 | if (!mephisto) { 66 | throw new Error("Mephisto not found."); 67 | } 68 | 69 | delay(350); 70 | Pather.moveTo(17575, 8086); 71 | delay(350); 72 | Pather.moveTo(17584, 8091); 73 | delay(1200); 74 | Pather.moveTo(17600, 8095); 75 | delay(550); 76 | Pather.moveTo(17610, 8094); 77 | delay(2500); 78 | Attack.clear(10); 79 | Pather.moveTo(17610, 8094); 80 | 81 | distance = getDistance(me, mephisto); 82 | 83 | while (distance > 27) { 84 | count += 1; 85 | 86 | Pather.moveTo(17600, 8095); 87 | delay(150); 88 | Pather.moveTo(17584, 8091); 89 | delay(150); 90 | Pather.moveTo(17575, 8086); 91 | delay(150); 92 | Pather.moveTo(17563, 8072); 93 | delay(350); 94 | Pather.moveTo(17575, 8086); 95 | delay(350); 96 | Pather.moveTo(17584, 8091); 97 | delay(1200); 98 | Pather.moveTo(17600, 8095); 99 | delay(550); 100 | Pather.moveTo(17610, 8094); 101 | delay(2500); 102 | Attack.clear(10); 103 | Pather.moveTo(17610, 8094); 104 | 105 | distance = getDistance(me, mephisto); 106 | 107 | if (count >= 5) { 108 | throw new Error("Failed to lure Mephisto."); 109 | } 110 | } 111 | 112 | return true; 113 | }; 114 | 115 | this.killCouncil = function () { 116 | var i, 117 | coords = [17600, 8125, 17600, 8015, 17643, 8068]; 118 | 119 | for (i = 0; i < coords.length; i += 2) { 120 | Pather.moveTo(coords[i], coords[i + 1]); 121 | 122 | if (Config.MFLeader) { 123 | Pather.makePortal(); 124 | say("council " + i); 125 | } 126 | 127 | Attack.clearList(Attack.getMob([345, 346, 347], 0, 40)); 128 | } 129 | 130 | return true; 131 | }; 132 | 133 | Town.doChores(); 134 | Pather.useWaypoint(101); 135 | Precast.doPrecast(true); 136 | 137 | if (!Pather.moveToExit(102, true)) { 138 | throw new Error("Failed to move to Durance Level 3"); 139 | } 140 | 141 | if (Config.Mephisto.KillCouncil) { 142 | this.killCouncil(); 143 | } 144 | 145 | if (Config.Mephisto.TakeRedPortal) { 146 | Pather.moveTo(17590, 8068); 147 | delay(400); // Activate the bridge tile 148 | } else { 149 | Pather.moveTo(17566, 8069); 150 | } 151 | 152 | if (me.classid === 1) { 153 | if (Config.Mephisto.MoatTrick) { 154 | this.moat(); 155 | 156 | Skill.usePvpRange = true; 157 | 158 | Attack.kill(242); // Mephisto 159 | 160 | Skill.usePvpRange = false; 161 | } else { 162 | //this.killMephisto(); 163 | Attack.kill(242); // Mephisto 164 | } 165 | } else { 166 | Attack.kill(242); // Mephisto 167 | } 168 | 169 | Pickit.pickItems(); 170 | 171 | if (Config.OpenChests) { 172 | Pather.moveTo(17572, 8011); 173 | Attack.openChests(5); 174 | Pather.moveTo(17572, 8125); 175 | Attack.openChests(5); 176 | Pather.moveTo(17515, 8061); 177 | Attack.openChests(5); 178 | } 179 | 180 | if (Config.Mephisto.TakeRedPortal) { 181 | Pather.moveTo(17590, 8068); 182 | let tick = getTickCount(), time = 0; 183 | 184 | // Wait until bridge is there 185 | while (getCollision(me.area, 17601, 8070, 17590, 8068) !== 0 && (time = getTickCount() - tick) < 2000) { 186 | Pather.moveTo(17590, 8068); // Activate it 187 | delay(3); 188 | } 189 | 190 | // If bridge is there, and we can move to the location 191 | if (time < 2000 && Pather.moveTo(17601, 8070)) { 192 | Pather.usePortal(null); 193 | } 194 | } 195 | 196 | return true; 197 | } 198 | -------------------------------------------------------------------------------- /kolbot/libs/bots/Nihlathak.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Nihlathak.js 3 | * @author kolton 4 | * @desc kill Nihlathak 5 | */ 6 | 7 | function Nihlathak() { 8 | Town.doChores(); 9 | Pather.useWaypoint(123); 10 | Precast.doPrecast(false); 11 | 12 | if (!Pather.moveToExit(124, true)) { 13 | throw new Error("Failed to go to Nihlathak"); 14 | } 15 | 16 | Pather.moveToPreset(me.area, 2, 462, 0, 0, false, true); 17 | 18 | if (Config.Nihlathak.ViperQuit && getUnit(1, 597)) { 19 | print("Tomb Vipers found."); 20 | 21 | return true; 22 | } 23 | 24 | Attack.kill(526); // Nihlathak 25 | Pickit.pickItems(); 26 | 27 | return true; 28 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/OuterSteppes.js: -------------------------------------------------------------------------------- 1 | function OuterSteppes() { 2 | Town.goToTown(4); 3 | Town.doChores(); 4 | 5 | if (!Pather.moveToExit(104, true)) { 6 | throw new Error("Failed to move to Outer Steppes"); 7 | } 8 | 9 | Precast.doPrecast(true); 10 | Attack.clearLevel(Config.ClearType); 11 | 12 | return true; 13 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Pindleskin.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Pindleskin.js 3 | * @author kolton 4 | * @desc kill Pindleskin and optionally Nihlathak 5 | */ 6 | 7 | function Pindleskin() { 8 | var anya; 9 | 10 | Town.goToTown(Config.Pindleskin.UseWaypoint ? undefined : 5); 11 | Town.doChores(); 12 | 13 | if (Config.Pindleskin.UseWaypoint) { 14 | Pather.useWaypoint(123); 15 | Precast.doPrecast(true); 16 | 17 | if (!Pather.moveToExit([122, 121], true)) { 18 | throw new Error("Failed to move to Nihlahak's Temple"); 19 | } 20 | } else { 21 | Town.move(NPC.Anya); 22 | 23 | if (!Pather.getPortal(121) && me.getQuest(37, 1)) { 24 | anya = getUnit(1, NPC.Anya); 25 | 26 | if (anya) { 27 | anya.openMenu(); 28 | me.cancel(); 29 | } 30 | } 31 | 32 | if (!Pather.usePortal(121)) { 33 | throw new Error("Failed to use portal."); 34 | } 35 | 36 | Precast.doPrecast(true); 37 | } 38 | 39 | Pather.moveTo(10058, 13234); 40 | 41 | try { 42 | Attack.clear(15, 0, getLocaleString(22497)); // Pindleskin 43 | } catch (e) { 44 | print(e); 45 | } 46 | 47 | if (Config.Pindleskin.KillNihlathak) { 48 | if (!Pather.moveToExit([122, 123, 124], true)) { 49 | throw new Error("Failed to move to Halls of Vaught"); 50 | } 51 | 52 | Pather.moveToPreset(me.area, 2, 462, 10, 10); 53 | 54 | if (Config.Pindleskin.ViperQuit && getUnit(1, 597)) { 55 | print("Tomb Vipers found."); 56 | 57 | return true; 58 | } 59 | 60 | if (Config.Pindleskin.ClearVipers) { 61 | Attack.clearList(Attack.getMob(597, 0, 20)); 62 | } 63 | 64 | Attack.kill(526); // Nihlathak 65 | //Attack.clear(15, 0, 526); 66 | Pickit.pickItems(); 67 | } 68 | 69 | return true; 70 | } 71 | -------------------------------------------------------------------------------- /kolbot/libs/bots/Pit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Pit.js 3 | * @author kolton 4 | * @desc clear Pit 5 | */ 6 | 7 | function Pit() { 8 | Town.doChores(); 9 | Pather.useWaypoint(6); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit([7, 12], true)) { 13 | throw new Error("Failed to move to Pit level 1"); 14 | } 15 | 16 | if (Config.Pit.ClearPit1) { 17 | Attack.clearLevel(Config.ClearType); 18 | } 19 | 20 | if (!Pather.moveToExit(16, true, Config.Pit.ClearPath)) { 21 | throw new Error("Failed to move to Pit level 2"); 22 | } 23 | 24 | Attack.clearLevel(); 25 | 26 | return true; 27 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Questing.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Questing.js 3 | * @author kolton 4 | * @desc Do quests, only most popular ones for now 5 | */ 6 | 7 | function Questing() { 8 | var i, j, 9 | quests = [ 10 | [1, "clearDen"], 11 | [9, "killRadament"], 12 | [17, "lamEssen"], 13 | [25, "killIzual"], 14 | [35, "killShenk"], 15 | [37, "freeAnya"] 16 | ]; 17 | 18 | this.checkQuest = function (id, state) { 19 | sendPacket(1, 0x40); 20 | delay(500); 21 | 22 | return me.getQuest(id, state); 23 | }; 24 | 25 | this.clearDen = function () { 26 | print("starting den"); 27 | 28 | var akara; 29 | 30 | if (!Town.goToTown(1) || !Pather.moveToExit([2, 8], true)) { 31 | throw new Error(); 32 | } 33 | 34 | Precast.doPrecast(true); 35 | Attack.clearLevel(); 36 | Town.goToTown(); 37 | Town.move(NPC.Akara); 38 | 39 | akara = getUnit(1, NPC.Akara); 40 | 41 | akara.openMenu(); 42 | me.cancel(); 43 | 44 | return true; 45 | }; 46 | 47 | this.killRadament = function () { 48 | if (!Pather.accessToAct(2)) { 49 | return false; 50 | } 51 | 52 | print("starting radament"); 53 | 54 | var book, atma; 55 | 56 | if (!Town.goToTown() || !Pather.useWaypoint(48, true)) { 57 | throw new Error(); 58 | } 59 | 60 | Precast.doPrecast(true); 61 | 62 | if (!Pather.moveToExit(49, true) || !Pather.moveToPreset(me.area, 2, 355)) { 63 | throw new Error(); 64 | } 65 | 66 | Attack.kill(229); // Radament 67 | 68 | book = getUnit(4, 552); 69 | 70 | if (book) { 71 | Pickit.pickItem(book); 72 | delay(300); 73 | clickItem(1, book); 74 | } 75 | 76 | Town.goToTown(); 77 | Town.move(NPC.Atma); 78 | 79 | atma = getUnit(1, NPC.Atma); 80 | 81 | atma.openMenu(); 82 | me.cancel(); 83 | 84 | return true; 85 | }; 86 | 87 | this.killIzual = function () { 88 | if (!Pather.accessToAct(4)) { 89 | return false; 90 | } 91 | 92 | print("starting izual"); 93 | 94 | var tyrael; 95 | 96 | if (!Town.goToTown() || !Pather.useWaypoint(106, true)) { 97 | throw new Error(); 98 | } 99 | 100 | Precast.doPrecast(true); 101 | 102 | if (!Pather.moveToPreset(105, 1, 256)) { 103 | return false; 104 | } 105 | 106 | Attack.kill(256); // Izual 107 | Town.goToTown(); 108 | Town.move(NPC.Tyrael); 109 | 110 | tyrael = getUnit(1, NPC.Tyrael); 111 | 112 | tyrael.openMenu(); 113 | me.cancel(); 114 | 115 | if (getUnit(2, 566)) { 116 | Pather.useUnit(2, 566, 109); 117 | } 118 | 119 | return true; 120 | }; 121 | 122 | this.lamEssen = function () { 123 | if (!Pather.accessToAct(3)) { 124 | return false; 125 | } 126 | 127 | print("starting lam essen"); 128 | 129 | var stand, book, alkor; 130 | 131 | if (!Town.goToTown() || !Pather.useWaypoint(80, true)) { 132 | throw new Error(); 133 | } 134 | 135 | Precast.doPrecast(true); 136 | 137 | if (!Pather.moveToExit(94, true) || !Pather.moveToPreset(me.area, 2, 193)) { 138 | throw new Error(); 139 | } 140 | 141 | stand = getUnit(2, 193); 142 | 143 | Misc.openChest(stand); 144 | delay(300); 145 | 146 | book = getUnit(4, 548); 147 | 148 | Pickit.pickItem(book); 149 | Town.goToTown(); 150 | Town.move(NPC.Alkor); 151 | 152 | alkor = getUnit(1, NPC.Alkor); 153 | 154 | alkor.openMenu(); 155 | me.cancel(); 156 | 157 | return true; 158 | }; 159 | 160 | this.killShenk = function () { 161 | if (!Pather.accessToAct(5)) { 162 | return false; 163 | } 164 | 165 | if (this.checkQuest(35, 1)) { 166 | return true; 167 | } 168 | 169 | print("starting shenk"); 170 | 171 | if (!Town.goToTown() || !Pather.useWaypoint(111, true)) { 172 | throw new Error(); 173 | } 174 | 175 | Precast.doPrecast(true); 176 | Pather.moveTo(3883, 5113); 177 | Attack.kill(getLocaleString(22435)); // Shenk the Overseer 178 | Town.goToTown(); 179 | 180 | return true; 181 | }; 182 | 183 | this.freeAnya = function () { 184 | if (!Pather.accessToAct(5)) { 185 | return false; 186 | } 187 | 188 | if (this.checkQuest(37, 1)) { 189 | return true; 190 | } 191 | 192 | print("starting anya"); 193 | 194 | var anya, malah, scroll; 195 | 196 | if (!Town.goToTown() || !Pather.useWaypoint(113, true)) { 197 | throw new Error(); 198 | } 199 | 200 | Precast.doPrecast(true); 201 | 202 | if (!Pather.moveToExit(114, true) || !Pather.moveToPreset(me.area, 2, 460)) { 203 | throw new Error(); 204 | } 205 | 206 | delay(1000); 207 | 208 | anya = getUnit(2, 558); 209 | 210 | Pather.moveToUnit(anya); 211 | //anya.interact(); 212 | sendPacket(1, 0x13, 4, 0x2, 4, anya.gid); 213 | delay(300); 214 | me.cancel(); 215 | Town.goToTown(); 216 | Town.move(NPC.Malah); 217 | 218 | malah = getUnit(1, NPC.Malah); 219 | 220 | malah.openMenu(); 221 | me.cancel(); 222 | Town.move("portalspot"); 223 | Pather.usePortal(114, me.name); 224 | anya.interact(); 225 | delay(300); 226 | me.cancel(); 227 | Town.goToTown(); 228 | Town.move(NPC.Malah); 229 | malah.openMenu(); 230 | me.cancel(); 231 | delay(500); 232 | 233 | scroll = me.getItem(646); 234 | 235 | if (scroll) { 236 | clickItem(1, scroll); 237 | } 238 | 239 | return true; 240 | }; 241 | 242 | for (i = 0; i < quests.length; i += 1) { 243 | if (me.inTown) { 244 | Town.doChores(); 245 | } 246 | 247 | for (j = 0; j < 3; j += 1) { 248 | if (!this.checkQuest(quests[i][0], 0)) { 249 | try { 250 | if (this[quests[i][1]]()) { 251 | break; 252 | } 253 | } catch (e) { 254 | 255 | } 256 | } else { 257 | break; 258 | } 259 | } 260 | 261 | if (j === 3) { 262 | D2Bot.printToConsole("Quest " + quests[i][1] + " failed."); 263 | } 264 | } 265 | 266 | D2Bot.printToConsole("All quests done. Stopping profile."); 267 | D2Bot.stop(); 268 | 269 | return true; 270 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Radament.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Radament.js 3 | * @author kolton 4 | * @desc kill Radament 5 | */ 6 | 7 | function Radament() { 8 | Town.doChores(); 9 | Pather.useWaypoint(48); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit(49, true) || !Pather.moveToPreset(me.area, 2, 355)) { 13 | throw new Error("Failed to move to Radament"); 14 | } 15 | 16 | Attack.kill(229); // Radament 17 | Pickit.pickItems(); 18 | Attack.openChests(20); 19 | 20 | return true; 21 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Rakanishu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Rakanishu.js 3 | * @author kolton 4 | * @desc kill Rakanishu and optionally Griswold 5 | */ 6 | 7 | function Rakanishu() { 8 | Town.doChores(); 9 | Pather.useWaypoint(4); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToPreset(me.area, 1, 922, 0, 0, false, true)) { 13 | throw new Error("Failed to move to Rakanishu"); 14 | } 15 | 16 | Attack.clear(15, 0, getLocaleString(2872)); // Rakanishu 17 | 18 | if (Config.Rakanishu.KillGriswold && me.getQuest(4, 4)) { 19 | if (!Pather.usePortal(38)) { 20 | throw new Error("Failed to move to Tristram"); 21 | } 22 | 23 | Pather.moveTo(25149, 5180); 24 | Attack.clear(20, 0xF, 365); // Griswold 25 | } 26 | 27 | return true; 28 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Rusher.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Rusher.js 3 | * @author kolton 4 | * @desc Rusher script. 5 | * Chat commands: 6 | * master - assigns player as master and listens to his commands 7 | * release - resets master 8 | * pause - pause the rusher 9 | * resume - resume the rusher 10 | * do sequence - stop current action and start the given sequence. 11 | * supported sequences are: andariel, cube, amulet, staff, summoner, duriel, travincal, mephisto, diablo 12 | * example: do travincal 13 | */ 14 | 15 | function Rusher() { 16 | load("tools/rushthread.js"); 17 | delay(500); 18 | 19 | var i, rushThread, command, master, commandSplit0, 20 | commands = [], 21 | sequence = [ 22 | "andariel", "radament", "cube", "amulet", "staff", "summoner", "duriel", "lamesen", 23 | "travincal", "mephisto", "izual", "diablo", "shenk", "anya", "ancients", "baal" 24 | ]; 25 | rushThread = getScript("tools/rushthread.js"); 26 | 27 | this.reloadThread = function () { 28 | rushThread = getScript("tools/rushthread.js"); 29 | 30 | if (rushThread) { 31 | rushThread.stop(); 32 | } 33 | 34 | delay(500); 35 | load("tools/rushthread.js"); 36 | 37 | rushThread = getScript("tools/rushthread.js"); 38 | 39 | delay(500); 40 | }; 41 | 42 | this.getPlayerCount = function () { 43 | var count = 0, 44 | party = getParty(); 45 | 46 | if (party) { 47 | do { 48 | count += 1; 49 | } while (party.getNext()); 50 | } 51 | 52 | return count; 53 | }; 54 | 55 | this.getPartyAct = function () { 56 | var party = getParty(), 57 | minArea = 999; 58 | 59 | do { 60 | if (party.name !== me.name) { 61 | while (!party.area) { 62 | me.overhead("Waiting for party area info"); 63 | delay(500); 64 | } 65 | 66 | if (party.area < minArea) { 67 | minArea = party.area; 68 | } 69 | } 70 | } while (party.getNext()); 71 | 72 | if (minArea <= 39) { 73 | return 1; 74 | } 75 | 76 | if (minArea >= 40 && minArea <= 74) { 77 | return 2; 78 | } 79 | 80 | if (minArea >= 75 && minArea <= 102) { 81 | return 3; 82 | } 83 | 84 | if (minArea >= 103 && minArea <= 108) { 85 | return 4; 86 | } 87 | 88 | return 5; 89 | }; 90 | 91 | this.chatEvent = function (nick, msg) { 92 | if (nick !== me.name) { 93 | switch (msg) { 94 | case "master": 95 | if (!master) { 96 | say(nick + " is my master."); 97 | 98 | master = nick; 99 | } else { 100 | say("I already have a master."); 101 | } 102 | 103 | break; 104 | case "release": 105 | if (nick === master) { 106 | say("I have no master now."); 107 | 108 | master = false; 109 | } else { 110 | say("I'm only accepting commands from my master."); 111 | } 112 | 113 | break; 114 | case "quit": 115 | if (nick === master) { 116 | say("bye ~"); 117 | scriptBroadcast("quit"); 118 | } else { 119 | say("I'm only accepting commands from my master."); 120 | } 121 | 122 | break; 123 | default: 124 | if (msg && msg.match(/^do \w|^clear \d|^pause$|^resume$/gi)) { 125 | if (nick === master) { 126 | commands.push(msg); 127 | } else { 128 | say("I'm only accepting commands from my master."); 129 | } 130 | } 131 | 132 | break; 133 | } 134 | } 135 | }; 136 | 137 | addEventListener("chatmsg", this.chatEvent); 138 | 139 | while (this.getPlayerCount() < Math.min(8, Config.Rusher.WaitPlayerCount)) { 140 | me.overhead("Waiting for players to join"); 141 | delay(500); 142 | } 143 | 144 | // Skip to a higher act if all party members are there 145 | switch (this.getPartyAct()) { 146 | case 2: 147 | say("Party is in act 2, starting from act 2"); 148 | rushThread.send("skiptoact 2"); 149 | 150 | break; 151 | case 3: 152 | say("Party is in act 3, starting from act 3"); 153 | rushThread.send("skiptoact 3"); 154 | 155 | break; 156 | case 4: 157 | say("Party is in act 4, starting from act 4"); 158 | rushThread.send("skiptoact 4"); 159 | 160 | break; 161 | case 5: 162 | say("Party is in act 5, starting from act 5"); 163 | rushThread.send("skiptoact 5"); 164 | 165 | break; 166 | } 167 | 168 | delay(200); 169 | rushThread.send("go"); 170 | 171 | while (true) { 172 | if (commands.length > 0) { 173 | command = commands.shift(); 174 | 175 | switch (command) { 176 | case "pause": 177 | if (rushThread.running) { 178 | say("Pausing"); 179 | 180 | rushThread.pause(); 181 | } 182 | 183 | break; 184 | case "resume": 185 | if (!rushThread.running) { 186 | say("Resuming"); 187 | 188 | rushThread.resume(); 189 | } 190 | 191 | break; 192 | default: 193 | commandSplit0 = command.split(" ")[0]; 194 | 195 | if (commandSplit0 === undefined) { 196 | break; 197 | } 198 | 199 | if (commandSplit0.toLowerCase() === "do") { 200 | for (i = 0; i < sequence.length; i += 1) { 201 | if (command.split(" ")[1] && sequence[i].match(command.split(" ")[1], "gi")) { 202 | this.reloadThread(); 203 | rushThread.send(command.split(" ")[1]); 204 | 205 | break; 206 | } 207 | } 208 | 209 | if (i === sequence.length) { 210 | say("Invalid sequence"); 211 | } 212 | } else if (commandSplit0.toLowerCase() === "clear") { 213 | if (!isNaN(parseInt(command.split(" ")[1], 10)) && parseInt(command.split(" ")[1], 10) > 0 && parseInt(command.split(" ")[1], 10) <= 132) { 214 | this.reloadThread(); 215 | rushThread.send(command); 216 | } else { 217 | say("Invalid area"); 218 | } 219 | } 220 | 221 | break; 222 | } 223 | } 224 | 225 | delay(100); 226 | } 227 | 228 | return true; 229 | } 230 | -------------------------------------------------------------------------------- /kolbot/libs/bots/SealLeecher.js: -------------------------------------------------------------------------------- 1 | function SealLeecher() { 2 | var monster, 3 | commands = []; 4 | 5 | Town.goToTown(4); 6 | Town.doChores(); 7 | Town.move("portalspot"); 8 | 9 | if (!Config.Leader) { 10 | D2Bot.printToConsole("You have to set Config.Leader"); 11 | D2Bot.stop(); 12 | 13 | return false; 14 | } 15 | 16 | addEventListener("chatmsg", 17 | function (nick, msg) { 18 | if (nick === Config.Leader) { 19 | commands.push(msg); 20 | } 21 | }); 22 | 23 | // Wait until leader is partied 24 | while (!Misc.inMyParty(Config.Leader)) { 25 | delay(1000); 26 | } 27 | 28 | while (Misc.inMyParty(Config.Leader)) { 29 | if (commands.length > 0) { 30 | switch (commands[0]) { 31 | case "in": 32 | if (me.inTown) { 33 | Pather.usePortal(108, Config.Leader); 34 | delay(250); 35 | } 36 | 37 | if (getDistance(me, 7761, 5267) < 10) { 38 | Pather.walkTo(7761, 5267, 2); 39 | } 40 | 41 | commands.shift(); 42 | 43 | break; 44 | case "out": 45 | if (!me.inTown) { 46 | Pather.usePortal(103, Config.Leader); 47 | } 48 | 49 | commands.shift(); 50 | 51 | break; 52 | case "done": 53 | if (!me.inTown) { 54 | Pather.usePortal(103, Config.Leader); 55 | } 56 | 57 | return true; // End script 58 | } 59 | } 60 | 61 | while (me.mode === 40) { 62 | delay(40); 63 | } 64 | 65 | if (me.mode === 17) { 66 | me.revive(); 67 | 68 | while (!me.inTown) { 69 | delay(40); 70 | } 71 | } 72 | 73 | if (!me.inTown) { 74 | monster = getUnit(1); 75 | 76 | if (monster) { 77 | do { 78 | if (Attack.checkMonster(monster) && getDistance(me, monster) < 20) { 79 | me.overhead("HOT"); 80 | Pather.usePortal(103, Config.Leader); 81 | } 82 | } while (monster.getNext()); 83 | } 84 | } 85 | 86 | delay(100); 87 | } 88 | 89 | return true; 90 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/SharpTooth.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Sharptooth.js 3 | * @author loshmi 4 | * @desc kill Thresh Socket 5 | */ 6 | 7 | function SharpTooth() { 8 | Town.doChores(); 9 | Pather.useWaypoint(111); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToPreset(me.area, 1, 790)) { 13 | throw new Error("Failed to move to Sharptooth Slayer"); 14 | } 15 | 16 | Attack.kill(getLocaleString(22493)); // Sharptooth Slayer 17 | Pickit.pickItems(); 18 | 19 | return true; 20 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Smith.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Smith.js 3 | * @author kolton 4 | * @desc kill the Smith 5 | */ 6 | 7 | function Smith() { 8 | Town.doChores(); 9 | Pather.useWaypoint(27); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToPreset(28, 2, 108)) { 13 | throw new Error("Failed to move to the Smith"); 14 | } 15 | 16 | Attack.kill(getLocaleString(2889)); // The Smith 17 | Pickit.pickItems(); 18 | 19 | return true; 20 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Snapchip.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Snapchip.js 3 | * @author kolton 4 | * @desc kill Snapchip and optionally clear Icy Cellar 5 | */ 6 | 7 | function Snapchip() { 8 | Town.doChores(); 9 | Pather.useWaypoint(118); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit(119, true) || !Pather.moveToPreset(me.area, 2, 397)) { 13 | throw new Error("Failed to move to Snapchip Shatter"); 14 | } 15 | 16 | Attack.clear(15, 0, getLocaleString(22496)); // Snapchip Shatter 17 | 18 | if (Config.Snapchip.ClearIcyCellar) { 19 | Attack.clearLevel(Config.ClearType); 20 | } 21 | 22 | return true; 23 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/StonyTomb.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename StonyTomb.js 3 | * @author marketfresh 4 | * @desc Clear Stony Tombs 5 | */ 6 | 7 | function StonyTomb() { 8 | Town.doChores(); 9 | Pather.useWaypoint(40); // Lut Gholein 10 | Precast.doPrecast(true); 11 | 12 | if (!(Pather.moveToExit([41, 55], true))) { 13 | throw new Error("Failed to move to Stony Tombs 1"); 14 | } 15 | 16 | Attack.clearLevel(Config.StonyTomb.ClearType); 17 | 18 | if (!(Pather.moveToExit([59], true))) { 19 | throw new Error("Failed to Move to Stony Tombs 2"); 20 | } 21 | 22 | Attack.clearLevel(Config.StonyTomb.ClearType); 23 | 24 | return true; 25 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Stormtree.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Stormtree.js 3 | * @author kolton 4 | * @desc kill Stormtree 5 | */ 6 | 7 | function Stormtree() { 8 | Town.doChores(); 9 | Pather.useWaypoint(79); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit(78, true)) { 13 | throw new Error("Failed to move to Stormtree"); 14 | } 15 | 16 | Attack.clear(15, 0, getLocaleString(2866)); // Stormtree 17 | 18 | return true; 19 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Summoner.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Summoner.js 3 | * @author kolton 4 | * @desc kill the Summoner 5 | */ 6 | 7 | function Summoner () { 8 | Town.doChores(); 9 | Pather.useWaypoint(74); 10 | Precast.doPrecast(true); 11 | 12 | if (Config.Summoner.FireEye) { 13 | if (!Pather.usePortal(null)) { 14 | throw new Error("Failed to move to Fire Eye"); 15 | } 16 | 17 | Attack.clear(15, 0, getLocaleString(2885)); // Fire Eye 18 | 19 | if (!Pather.usePortal(null)) { 20 | throw new Error("Failed to move to Summoner"); 21 | } 22 | } 23 | 24 | if (!Pather.moveToPreset(me.area, 2, 357, -3, -3)) { 25 | throw new Error("Failed to move to Summoner"); 26 | } 27 | 28 | Attack.clear(15, 0, 250); // The Summoner 29 | 30 | if (Loader.scriptName(1) === "Duriel") { 31 | let journal = getUnit(2, 357); 32 | 33 | if (!journal) { 34 | return true; 35 | } 36 | 37 | Pather.moveToUnit(journal); 38 | journal.interact(); 39 | delay(500); 40 | me.cancel(); 41 | 42 | if (!Pather.usePortal(46)) { 43 | return true; 44 | } 45 | 46 | Loader.skipTown.push("Duriel"); 47 | } 48 | 49 | return true; 50 | } 51 | -------------------------------------------------------------------------------- /kolbot/libs/bots/Synch.js: -------------------------------------------------------------------------------- 1 | var Synched = false; 2 | 3 | var uRdyMsg = "I'm rdy, u?"; 4 | var rdyMsg = "rdy"; 5 | 6 | function messageHandler(nick, msg) { 7 | if (nick !== me.name) { 8 | if (msg === uRdyMsg) { 9 | say(rdyMsg); 10 | Synched = true; 11 | } else if (msg === rdyMsg) { 12 | Synched = true; 13 | } else if (msg === "Yo, I'm rdy, u?") { 14 | say("No"); 15 | quit(); 16 | } 17 | } 18 | } 19 | 20 | function Synch() { 21 | var i, party, j; 22 | 23 | addEventListener("chatmsg", messageHandler); 24 | 25 | delay(1000); 26 | say(uRdyMsg); 27 | 28 | for (i = 0; i < 720 && !Synched; i += 1) { 29 | delay(1000); 30 | 31 | for (j = 0; j < Config.Synch.WaitFor.length; j += 1) { 32 | party = getParty(Config.Synch.WaitFor[j]); 33 | if (!party) { 34 | D2Bot.printToConsole("WaitFor not in game: " + 35 | Config.Synch.WaitFor[j] + " so quitting."); 36 | 37 | removeEventListener("chatmsg", messageHandler); 38 | quit(); 39 | return false; 40 | } 41 | } 42 | } 43 | 44 | if (!Synched) { 45 | D2Bot.printToConsole("Failed to sync."); 46 | quit(); 47 | } 48 | 49 | removeEventListener("chatmsg", messageHandler); 50 | 51 | return true; 52 | } 53 | -------------------------------------------------------------------------------- /kolbot/libs/bots/Synch2.js: -------------------------------------------------------------------------------- 1 | var Synched2 = false; 2 | 3 | var uRdyMsg2 = "Yo, I'm rdy, u?"; 4 | var rdyMsg2 = "Let's go"; 5 | 6 | function messageHandler2(nick, msg) { 7 | if (nick !== me.name) { 8 | if (msg === uRdyMsg2) { 9 | say(rdyMsg2); 10 | Synched2 = true; 11 | } else if (msg === rdyMsg2) { 12 | Synched2 = true; 13 | } else if (msg === "I'm rdy, u?") { 14 | say("No"); 15 | quit(); 16 | } 17 | } 18 | } 19 | 20 | function Synch2() { 21 | var i, party, j; 22 | 23 | addEventListener("chatmsg", messageHandler2); 24 | 25 | delay(1000); 26 | say(uRdyMsg2); 27 | 28 | delay(1000); 29 | 30 | for (i = 0; i < 720 && !Synched2; i += 1) { 31 | for (j = 0; j < Config.Synch.WaitFor.length; j += 1) { 32 | party = getParty(Config.Synch.WaitFor[j]); 33 | if (!party) { 34 | D2Bot.printToConsole("WaitFor not in game: " + 35 | Config.Synch.WaitFor[j] + " so quitting."); 36 | 37 | removeEventListener("chatmsg", messageHandler2); 38 | quit(); 39 | return false; 40 | } 41 | } 42 | 43 | delay(1000); 44 | } 45 | 46 | if (!Synched) { 47 | D2Bot.printToConsole("Failed to sync."); 48 | quit(); 49 | } 50 | 51 | delay(1000); 52 | 53 | removeEventListener("chatmsg", messageHandler2); 54 | 55 | return true; 56 | } 57 | -------------------------------------------------------------------------------- /kolbot/libs/bots/Test.js: -------------------------------------------------------------------------------- 1 | function Test() { 2 | print("ÿc8TESTING"); 3 | 4 | var c; 5 | 6 | function KeyDown(key) { 7 | if (key === 45) { 8 | c = true; 9 | } 10 | } 11 | 12 | addEventListener("keydown", KeyDown); 13 | 14 | while (true) { 15 | if (c) { 16 | try { 17 | test(); 18 | } catch (qq) { 19 | print('faile'); 20 | print(qq + " " + qq.fileName + " " + qq.lineNumber); 21 | } 22 | 23 | c = false; 24 | } 25 | 26 | delay(10); 27 | } 28 | } 29 | 30 | function test() { 31 | print("test"); 32 | 33 | print("done"); 34 | } 35 | -------------------------------------------------------------------------------- /kolbot/libs/bots/ThreshSocket.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename ThreshSocket.js 3 | * @author kolton 4 | * @desc kill Thresh Socket 5 | */ 6 | 7 | function ThreshSocket() { 8 | Town.doChores(); 9 | Pather.useWaypoint(112); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit(113, false)) { 13 | throw new Error("Failed to move to Thresh Socket"); 14 | } 15 | 16 | Attack.kill(getLocaleString(22498)); // Thresh Socket 17 | Pickit.pickItems(); 18 | 19 | return true; 20 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Tombs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Tombs.js 3 | * @author kolton 4 | * @desc clear Tal Rasha's Tombs 5 | */ 6 | 7 | function Tombs() { 8 | var i; 9 | 10 | Town.doChores(); 11 | Pather.useWaypoint(46); 12 | Precast.doPrecast(true); 13 | 14 | for (i = 66; i <= 72; i += 1) { 15 | if (!Pather.moveToExit(i, true)) { 16 | throw new Error("Failed to move to tomb"); 17 | } 18 | 19 | Attack.clearLevel(Config.ClearType); 20 | 21 | if (i === 69) { 22 | Precast.doPrecast(true); 23 | } 24 | 25 | if (!Pather.moveToExit(46, true)) { 26 | throw new Error("Failed to move to Canyon"); 27 | } 28 | } 29 | 30 | return true; 31 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Travincal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Travincal.js 3 | * @author kolton 4 | * @desc kill Counncil members in Travincal 5 | */ 6 | 7 | function Travincal() { 8 | var i, orgX, orgY, coords; 9 | 10 | this.buildList = function (checkColl) { 11 | var monsterList = [], 12 | monster = getUnit(1); 13 | 14 | if (monster) { 15 | do { 16 | if ([345, 346, 347].indexOf(monster.classid) > -1 && Attack.checkMonster(monster) && (!checkColl || !checkCollision(me, monster, 0x1))) { 17 | monsterList.push(copyUnit(monster)); 18 | } 19 | } while (monster.getNext()); 20 | } 21 | 22 | return monsterList; 23 | }; 24 | 25 | Town.doChores(); 26 | Pather.useWaypoint(83); 27 | Precast.doPrecast(true); 28 | 29 | orgX = me.x; 30 | orgY = me.y; 31 | 32 | if (Config.Travincal.PortalLeech) { 33 | Pather.moveTo(orgX + 85, orgY - 139); 34 | Attack.securePosition(orgX + 70, orgY - 139, 25, 2000); 35 | Attack.securePosition(orgX + 100, orgY - 139, 25, 2000); 36 | Attack.securePosition(orgX + 85, orgY - 139, 25, 5000); 37 | Pather.moveTo(orgX + 85, orgY - 139); 38 | Pather.makePortal(); 39 | delay(1000); 40 | Precast.doPrecast(true); 41 | } 42 | 43 | if (me.getSkill(143, 0) && !me.getSkill(54, 0) && !me.getStat(97, 54)) { 44 | coords = [60, -53, 64, -72, 78, -72, 74, -88]; 45 | 46 | for (i = 0; i < coords.length; i += 2) { 47 | if (i % 4 === 0) { 48 | Pather.moveTo(orgX + coords[i], orgY + coords[i + 1]); 49 | } else { 50 | Skill.cast(143, 0, orgX + coords[i], orgY + coords[i + 1]); 51 | Attack.clearList(this.buildList(1)); 52 | } 53 | } 54 | 55 | Attack.clearList(this.buildList(0)); 56 | } else { 57 | Pather.moveTo(orgX + 101, orgY - 56); 58 | 59 | // Stack Merc 60 | if (me.classid === 4 && !me.getSkill(54, 1) && me.gametype === 1) { 61 | Pather.moveToExit([100, 83], true); 62 | } 63 | 64 | if (Config.MFLeader) { 65 | Pather.makePortal(); 66 | say("council " + me.area); 67 | } 68 | 69 | Attack.clearList(this.buildList(0)); 70 | } 71 | 72 | return true; 73 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/TravincalLeech.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename TravincalLeech.js 3 | * @author ToS/XxXGoD/YGM/azero 4 | * @desc Travincal Leech 5 | */ 6 | 7 | function TravincalLeech() { 8 | 9 | this.findLeader = function (name) { 10 | var party = getParty(name); 11 | 12 | if (party) { 13 | return party; 14 | } 15 | 16 | return false; 17 | }; 18 | 19 | Town.goToTown(3); 20 | Town.doChores(); 21 | Town.move("portalspot"); 22 | 23 | while (!Misc.inMyParty(Config.Leader)) { 24 | delay(500); 25 | } 26 | 27 | var leader = this.findLeader(Config.Leader); 28 | 29 | while (Misc.inMyParty(Config.Leader)) { 30 | if (me.inTown && Pather.getPortal(83, Config.Leader)) { 31 | Pather.usePortal(83, Config.Leader); 32 | Town.getCorpse(); 33 | } 34 | 35 | if(me.area === 83 && leader.area !== 83 && leader.area !== 75) { 36 | break; 37 | } 38 | 39 | if (me.mode === 17) { 40 | me.revive(); 41 | 42 | while (!me.inTown) { 43 | delay(100); 44 | } 45 | 46 | Town.move("portalspot"); 47 | } 48 | 49 | delay(100); 50 | } 51 | 52 | return true; 53 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Treehead.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Treehead.js 3 | * @author kolton 4 | * @desc kill Treehead 5 | */ 6 | 7 | function Treehead() { 8 | Town.doChores(); 9 | Pather.useWaypoint(5); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToPreset(me.area, 2, 30, 5, 5)) { 13 | throw new Error("Failed to move to Treehead"); 14 | } 15 | 16 | Attack.clear(15, 0, getLocaleString(2873)); // Treehead Woodfist 17 | 18 | return true; 19 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Tristram.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Tristram.js 3 | * @author kolton, cuss 4 | * @desc clear Tristram 5 | */ 6 | 7 | function Tristram() { 8 | var tree, scroll, akara, stones, gibbet; 9 | 10 | if (!me.getQuest(4, 4) && !me.getItem(525)) { 11 | if (!me.getItem(524)) { 12 | // print("We need Scroll of Inifuss"); 13 | Town.doChores(); 14 | Pather.useWaypoint(5); 15 | Precast.doPrecast(true); 16 | 17 | if (!Pather.moveToPreset(me.area, 2, 30, 5, 5)) { 18 | throw new Error("Failed to move to Tree of Inifuss"); 19 | } 20 | 21 | tree = getUnit(2, 30); 22 | 23 | Misc.openChest(tree); 24 | delay(300); 25 | 26 | scroll = getUnit(4, 524); 27 | 28 | Pickit.pickItem(scroll); 29 | Town.goToTown(); 30 | } 31 | 32 | // print("We need Key to the Cairn Stones"); 33 | Town.move(NPC.Akara); 34 | 35 | akara = getUnit(1, NPC.Akara); 36 | 37 | akara.openMenu(); 38 | me.cancel(); 39 | } 40 | 41 | Pather._teleport = Pather.teleport; 42 | 43 | Town.doChores(); 44 | Pather.useWaypoint(4); 45 | Precast.doPrecast(true); 46 | 47 | /* if (!Pather.moveToPreset(me.area, 1, 737, 0, 0, false, true)) { 48 | throw new Error("Failed to move to Rakanishu"); 49 | } */ 50 | 51 | if (!me.getQuest(4, 4)) { 52 | stones = [getUnit(2, 17), getUnit(2, 18), getUnit(2, 19), getUnit(2, 20), getUnit(2, 21)]; 53 | } 54 | 55 | Pather.moveToPreset(me.area, 1, 922, 10, 10, false, true); //(area, unitType, unitId, offX, offY, clearPath, pop) 56 | 57 | 58 | while (!me.getQuest(4, 4)) { 59 | stones.forEach(function (stone) { 60 | if (!stone.mode) { 61 | Attack.securePosition(stone.x, stone.y, 10, me.ping * 2); 62 | Misc.click(0, 0, stone); 63 | } 64 | }); 65 | } 66 | 67 | Pather.usePortal(38) 68 | /* while (!Pather.usePortal(38)) { 69 | Attack.securePosition(me.x, me.y, 5, 1000); 70 | } */ 71 | 72 | Pather.moveTo(me.x, me.y + 6); 73 | 74 | if (Config.Tristram.PortalLeech) { 75 | Pather.makePortal(); 76 | delay(1000); 77 | Pather.teleport = !Config.Tristram.WalkClear && Pather._teleport; 78 | } 79 | 80 | /* gibbet = getUnit(2, 26); 81 | 82 | if (!gibbet.mode) { 83 | if (!Pather.moveToPreset(me.area, 2, 26, 0, 0, true, true)) { 84 | throw new Error("Failed to move to Cain's Gibbet"); 85 | } 86 | 87 | Misc.openChest(gibbet); 88 | } */ 89 | 90 | if (Config.Tristram.PortalLeech) { 91 | Attack.clearLevel(0xF); 92 | } else { 93 | Attack.clearLevel(Config.ClearType); 94 | } 95 | 96 | Pather.teleport = Pather._teleport; 97 | 98 | return true; 99 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/TristramLeech.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename TristramLeech.js 3 | * @author ToS/XxXGoD/YGM 4 | * @desc Tristram Leech (Helper) 5 | */ 6 | 7 | function TristramLeech() { 8 | 9 | var leader, i; 10 | 11 | // Get leader's Unit 12 | this.getLeaderUnit = function (name) { 13 | var player = getUnit(0, name); 14 | 15 | if (player) { 16 | do { 17 | if (player.mode !== 0 && player.mode !== 17) { 18 | return player; 19 | } 20 | } while (player.getNext()); 21 | } 22 | 23 | return false; 24 | }; 25 | 26 | Town.doChores(); 27 | Pather.useWaypoint(1); // Back To Rouge 28 | Town.move("portalspot"); // Portal Spot 29 | 30 | leader = Config.Leader; 31 | 32 | // Check leader isn't in other zones, whilst waiting for portal. 33 | for (i = 0; i < Config.TristramLeech.Wait; i += 1) { 34 | 35 | var whereisleader = getParty(leader); 36 | 37 | if (whereisleader) { 38 | if (whereisleader.area === 83) { 39 | return false; 40 | } 41 | if (whereisleader.area === 108) { 42 | return false; 43 | } 44 | if (whereisleader.area === 131) { 45 | return false; 46 | } 47 | } 48 | 49 | if (Pather.usePortal(38, leader)) { 50 | break; 51 | } 52 | 53 | delay(1000); 54 | } 55 | 56 | if (i === Config.TristramLeech.Wait) { 57 | throw new Error("No portal found to Tristram."); 58 | } 59 | 60 | Precast.doPrecast(true); 61 | delay(3000); 62 | 63 | for (i = 0; i < 30; i += 1) { 64 | 65 | var whereisleader = getParty(leader); 66 | 67 | if (whereisleader) { 68 | if (whereisleader.area === 38) { 69 | break; 70 | } 71 | } 72 | 73 | delay(1000); 74 | } 75 | 76 | while (whereisleader.area === 38) { 77 | 78 | var whereisleader = getParty(leader); 79 | var leaderUnit = this.getLeaderUnit(leader); 80 | 81 | if (whereisleader.area === me.area){ 82 | try{ 83 | if (copyUnit(leaderUnit).x) { 84 | if (getDistance(me, leaderUnit) > 4) { 85 | Pather.moveToUnit(leaderUnit); 86 | Attack.clear(10); 87 | } 88 | } else { 89 | Pather.moveTo(copyUnit(leaderUnit).x, copyUnit(leaderUnit).y); 90 | Attack.clear(10); 91 | } 92 | } 93 | catch(err){ 94 | if (whereisleader.area === me.area){ 95 | Pather.moveTo(whereisleader.x, whereisleader.y); 96 | Attack.clear(10); 97 | } 98 | } 99 | } 100 | 101 | delay(100); 102 | } 103 | 104 | //if (partyleader.area === 38) { 105 | // Attack.clearLevel(0); 106 | //} 107 | 108 | return true; 109 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/UndergroundPassage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename UndergroundPassage.js 3 | * @author loshmi 4 | * @desc Move and clear Underground passage level 2 5 | */ 6 | 7 | function UndergroundPassage() { 8 | Town.doChores(); 9 | Pather.useWaypoint(4); 10 | Precast.doPrecast(true); 11 | 12 | if (!Pather.moveToExit([10, 14], true)) { 13 | throw new Error("Failed to move to Underground passage level 2"); 14 | } 15 | 16 | Attack.clearLevel(); 17 | 18 | return true; 19 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Vizier.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Vizier.js 3 | * @author kolton 4 | * @desc kill Grand Vizier of Chaos 5 | */ 6 | 7 | function Vizier() { 8 | var i, tick, seal; 9 | 10 | this.openSeal = function (id) { 11 | Pather.moveToPreset(108, 2, id, 4); 12 | 13 | seal = getUnit(2, id); 14 | 15 | if (seal) { 16 | for (i = 0; i < 3; i += 1) { 17 | seal.interact(); 18 | 19 | tick = getTickCount(); 20 | 21 | while (getTickCount() - tick < 500) { 22 | if (seal.mode) { 23 | return true; 24 | } 25 | 26 | delay(10); 27 | } 28 | } 29 | } 30 | 31 | return false; 32 | }; 33 | 34 | Town.doChores(); 35 | Pather.useWaypoint(107); 36 | Precast.doPrecast(true); 37 | 38 | if (!this.openSeal(396) || !this.openSeal(395)) { 39 | throw new Error("Failed to open seals"); 40 | } 41 | 42 | Pather.moveToPreset(108, 2, 396, 4); 43 | 44 | for (i = 0; i < 10; i += 1) { 45 | if (getUnit(1, getLocaleString(2851))) { 46 | break; 47 | } 48 | 49 | delay(250); 50 | } 51 | 52 | Attack.kill(getLocaleString(2851)); // Grand Vizier of Chaos 53 | Pickit.pickItems(); 54 | 55 | return true; 56 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/WPGetter.js: -------------------------------------------------------------------------------- 1 | function WPGetter() { 2 | Town.doChores(); 3 | Town.goToTown(1); 4 | Pather.getWP(me.area); 5 | 6 | var i, access; 7 | 8 | for (i = 0; i < Pather.wpAreas.length; i += 1) { 9 | if (Pather.wpAreas[i] < 40) { 10 | access = true; 11 | } else if (Pather.wpAreas[i] >= 40 && Pather.wpAreas[i] < 75) { 12 | access = Pather.accessToAct(2); 13 | } else if (Pather.wpAreas[i] >= 75 && Pather.wpAreas[i] < 103) { 14 | access = Pather.accessToAct(3); 15 | } else if (Pather.wpAreas[i] >= 103 && Pather.wpAreas[i] < 109) { 16 | access = Pather.accessToAct(4); 17 | } else if (Pather.wpAreas[i] >= 109) { 18 | access = Pather.accessToAct(5); 19 | } 20 | 21 | if (access && !getWaypoint(i) && Pather.wpAreas[i] !== 123) { 22 | Pather.getWP(Pather.wpAreas[i]); 23 | } 24 | } 25 | 26 | return true; 27 | } -------------------------------------------------------------------------------- /kolbot/libs/bots/Worldstone.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Worldstone.js 3 | * @author kolton 4 | * @desc Clear Worldstone levels 5 | */ 6 | 7 | function Worldstone() { 8 | Town.doChores(); 9 | Pather.useWaypoint(129); 10 | Precast.doPrecast(true); 11 | Attack.clearLevel(Config.ClearType); 12 | 13 | if (Pather.moveToExit(128, true)) { 14 | Attack.clearLevel(Config.ClearType); 15 | } 16 | 17 | if (Pather.moveToExit([129, 130], true)) { 18 | Attack.clearLevel(Config.ClearType); 19 | } 20 | 21 | return true; 22 | } -------------------------------------------------------------------------------- /kolbot/libs/common/Attacks/Wereform.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Wereform.js 3 | * @author kolton 4 | * @desc Wereform attack sequence 5 | */ 6 | 7 | var ClassAttack = { 8 | doAttack: function (unit, preattack) { 9 | if (Config.MercWatch && Town.needMerc()) { 10 | Town.visitTown(); 11 | } 12 | 13 | if (preattack && Config.AttackSkill[0] > 0 && Attack.checkResist(unit, Config.AttackSkill[0]) && (!me.getState(121) || !Skill.isTimed(Config.AttackSkill[0]))) { 14 | if (Math.round(getDistance(me, unit)) > Skill.getRange(Config.AttackSkill[0]) || checkCollision(me, unit, 0x4)) { 15 | if (!Attack.getIntoPosition(unit, Skill.getRange(Config.AttackSkill[0]), 0x4)) { 16 | return 0; 17 | } 18 | } 19 | 20 | Skill.cast(Config.AttackSkill[0], Skill.getHand(Config.AttackSkill[0]), unit); 21 | 22 | return 1; 23 | } 24 | 25 | var index, checkSkill, result, 26 | mercRevive = 0, 27 | timedSkill = -1, 28 | untimedSkill = -1; 29 | 30 | index = ((unit.spectype & 0x7) || unit.type === 0) ? 1 : 3; 31 | 32 | // Get timed skill 33 | if (Attack.getCustomAttack(unit)) { 34 | checkSkill = Attack.getCustomAttack(unit)[0]; 35 | } else { 36 | checkSkill = Config.AttackSkill[index]; 37 | } 38 | 39 | if (Attack.checkResist(unit, checkSkill)) { 40 | timedSkill = checkSkill; 41 | } else if (Config.AttackSkill[5] > -1 && Attack.checkResist(unit, Config.AttackSkill[5]) && ([56, 59].indexOf(Config.AttackSkill[5]) === -1 || Attack.validSpot(unit.x, unit.y))) { 42 | timedSkill = Config.AttackSkill[5]; 43 | } 44 | 45 | // Get untimed skill 46 | if (Attack.getCustomAttack(unit)) { 47 | checkSkill = Attack.getCustomAttack(unit)[1]; 48 | } else { 49 | checkSkill = Config.AttackSkill[index + 1]; 50 | } 51 | 52 | if (Attack.checkResist(unit, checkSkill)) { 53 | untimedSkill = checkSkill; 54 | } else if (Config.AttackSkill[6] > -1 && Attack.checkResist(unit, Config.AttackSkill[6]) && ([56, 59].indexOf(Config.AttackSkill[6]) === -1 || Attack.validSpot(unit.x, unit.y))) { 55 | untimedSkill = Config.AttackSkill[6]; 56 | } 57 | 58 | // Low mana timed skill 59 | if (Config.LowManaSkill[0] > -1 && Skill.getManaCost(timedSkill) > me.mp && Attack.checkResist(unit, Config.LowManaSkill[0])) { 60 | timedSkill = Config.LowManaSkill[0]; 61 | } 62 | 63 | // Low mana untimed skill 64 | if (Config.LowManaSkill[1] > -1 && Skill.getManaCost(untimedSkill) > me.mp && Attack.checkResist(unit, Config.LowManaSkill[1])) { 65 | untimedSkill = Config.LowManaSkill[1]; 66 | } 67 | 68 | result = this.doCast(unit, timedSkill, untimedSkill); 69 | 70 | if (result === 2 && Config.TeleStomp && Attack.checkResist(unit, "physical") && !!me.getMerc()) { 71 | while (Attack.checkMonster(unit)) { 72 | if (Town.needMerc()) { 73 | if (Config.MercWatch && mercRevive++ < 1) { 74 | Town.visitTown(); 75 | } else { 76 | return 2; 77 | } 78 | } 79 | 80 | if (getDistance(me, unit) > 3) { 81 | Pather.moveToUnit(unit); 82 | } 83 | 84 | this.doCast(unit, Config.AttackSkill[1], Config.AttackSkill[2]); 85 | } 86 | 87 | return 1; 88 | } 89 | 90 | return result; 91 | }, 92 | 93 | afterAttack: function () { 94 | Misc.unShift(); 95 | Precast.doPrecast(false); 96 | }, 97 | 98 | // Returns: 0 - fail, 1 - success, 2 - no valid attack skills 99 | doCast: function (unit, timedSkill, untimedSkill) { 100 | var i; 101 | 102 | // No valid skills can be found 103 | if (timedSkill < 0 && untimedSkill < 0) { 104 | return 2; 105 | } 106 | 107 | if (timedSkill > -1 && (!me.getState(121) || !Skill.isTimed(timedSkill))) { 108 | if (Skill.getRange(timedSkill) < 4 && !Attack.validSpot(unit.x, unit.y)) { 109 | return 0; 110 | } 111 | 112 | // Teleport closer 113 | if (Math.ceil(getDistance(me, unit)) > 10) { 114 | Misc.unShift(); 115 | 116 | if (!Attack.getIntoPosition(unit, 10, 0x4)) { 117 | return 0; 118 | } 119 | } 120 | 121 | Misc.shapeShift(Config.Wereform); 122 | 123 | if (Math.round(getDistance(me, unit)) > Skill.getRange(timedSkill) || checkCollision(me, unit, 0x4)) { 124 | if (!Attack.getIntoPosition(unit, Skill.getRange(timedSkill), 0x4, true)) { 125 | return 0; 126 | } 127 | } 128 | 129 | if (!unit.dead) { 130 | Skill.cast(timedSkill, Skill.getHand(timedSkill), unit); 131 | } 132 | 133 | return 1; 134 | } 135 | 136 | if (untimedSkill > -1) { 137 | if (Skill.getRange(untimedSkill) < 4 && !Attack.validSpot(unit.x, unit.y)) { 138 | return 0; 139 | } 140 | 141 | // Teleport closer 142 | if (Math.ceil(getDistance(me, unit)) > 10) { 143 | Misc.unShift(); 144 | 145 | if (!Attack.getIntoPosition(unit, 10, 0x4)) { 146 | return 0; 147 | } 148 | } 149 | 150 | Misc.shapeShift(Config.Wereform); 151 | 152 | if (Math.round(getDistance(me, unit)) > Skill.getRange(untimedSkill) || checkCollision(me, unit, 0x4)) { 153 | if (!Attack.getIntoPosition(unit, Skill.getRange(untimedSkill), 0x4, true)) { 154 | return 0; 155 | } 156 | } 157 | 158 | if (!unit.dead) { 159 | Skill.cast(untimedSkill, Skill.getHand(untimedSkill), unit); 160 | } 161 | 162 | return 1; 163 | } 164 | 165 | for (i = 0; i < 25; i += 1) { 166 | if (!me.getState(121)) { 167 | break; 168 | } 169 | 170 | delay(40); 171 | } 172 | 173 | return 1; 174 | } 175 | }; -------------------------------------------------------------------------------- /kolbot/libs/common/AutoBuild.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @title : AutoBuild.js 3 | * 4 | * @author : alogwe 5 | * 6 | * @desc : This script is included when any script includes libs/common/Config.js and calls Config.init(). 7 | * If enabled, loads a threaded helper script that will monitor changes in character level and 8 | * upon level up detection, it will spend skill and stat points based on a configurable 9 | * character build template file located in libs/config/Builds/*. 10 | * 11 | * Any skill and stat points obtained as quest rewards are currently 12 | * invisible to this script and must be spent manually. 13 | * 14 | * @todo : Make this file "libs/config/Builds/README.txt" 15 | */ 16 | js_strict(true); 17 | 18 | if (!isIncluded("common/Cubing.js")) { include("common/Cubing.js"); }; 19 | if (!isIncluded("common/Prototypes.js")) { include("common/Prototypes.js"); }; 20 | if (!isIncluded("common/Runewords.js")) { include("common/Runewords.js"); }; 21 | 22 | var AutoBuild = new function AutoBuild () { 23 | 24 | if (Config.AutoBuild.DebugMode) { Config.AutoBuild.Verbose = true; } 25 | 26 | var debug = !!Config.AutoBuild.DebugMode, 27 | verbose = !!Config.AutoBuild.Verbose, 28 | configUpdateLevel = 0; 29 | 30 | 31 | // Apply all Update functions from the build template in order from level 1 to me.charlvl. 32 | // By reapplying all of the changes to the Config object, we preserve 33 | // the state of the Config file without altering the saved char config. 34 | function applyConfigUpdates () { 35 | if (debug) { this.print("Updating Config from level "+configUpdateLevel+" to "+me.charlvl)} 36 | while (configUpdateLevel < me.charlvl) { 37 | configUpdateLevel += 1; 38 | AutoBuildTemplate[configUpdateLevel].Update.apply(Config); // TODO: Make sure this works 39 | } 40 | }; 41 | 42 | 43 | function getBuildType () { 44 | var build = Config.AutoBuild.Template; 45 | if (!build) { 46 | this.print("Config.AutoBuild.Template is either 'false', or invalid ("+build+")"); 47 | throw new Error("Invalid build template, read libs/config/Builds/README.txt for information"); 48 | } 49 | return build; 50 | }; 51 | 52 | 53 | function getCurrentScript () { 54 | return getScript(true).name.toLowerCase(); 55 | }; 56 | 57 | 58 | function getLogFilename () { 59 | var d = new Date(); 60 | var dateString = d.getMonth()+"_"+d.getDate()+"_"+d.getFullYear(); 61 | return "logs/AutoBuild."+me.realm+"."+me.charname+"."+dateString+".log"; 62 | }; 63 | 64 | 65 | function getTemplateFilename () { 66 | var classname = ["Amazon", "Sorceress", "Necromancer", "Paladin", "Barbarian", "Druid", "Assassin"][me.classid]; 67 | var build = getBuildType(); 68 | var template = "config/Builds/"+classname+"."+build+".js"; 69 | return template.toLowerCase(); 70 | }; 71 | 72 | 73 | function initialize () { 74 | var currentScript = getCurrentScript(); 75 | var template = getTemplateFilename(); 76 | this.print("Including build template "+template+" into "+currentScript); 77 | if (!include(template)) { 78 | throw new Error("Failed to include template: "+template); 79 | } 80 | 81 | // Only load() helper thread from default.dbj if it isn't loaded 82 | if (currentScript === "default.dbj" && !getScript("tools\\autobuildthread.js")) { 83 | load("tools/autobuildthread.js"); 84 | } 85 | 86 | // All threads except autobuildthread.js use this event listener 87 | // to update their thread-local Config object 88 | if (currentScript !== "tools\\autobuildthread.js") { 89 | addEventListener("scriptmsg", levelUpHandler); 90 | } 91 | 92 | // Resynchronize our Config object with all past changes 93 | // made to it by AutoBuild system 94 | applyConfigUpdates(); 95 | }; 96 | 97 | 98 | function levelUpHandler (obj) { 99 | if (typeof obj === "object" && obj.hasOwnProperty("event") && obj["event"] === "level up") { 100 | applyConfigUpdates(); 101 | } 102 | }; 103 | 104 | 105 | function log (message) { FileTools.appendText(getLogFilename(), message+"\n"); }; 106 | 107 | 108 | // Only print to console from autobuildthread.js, 109 | // but log from all scripts 110 | function myPrint () { 111 | var args = Array.prototype.slice.call(arguments); 112 | args.unshift("AutoBuild:"); 113 | var result = args.join(" "); 114 | if (verbose) { print.call(this, result); } 115 | if (debug) { log.call(this, result); } 116 | }; 117 | 118 | 119 | this.print = myPrint; 120 | this.initialize = initialize; 121 | this.applyConfigUpdates = applyConfigUpdates; 122 | 123 | }; 124 | -------------------------------------------------------------------------------- /kolbot/libs/common/AutoSkill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename AutoSkill.js 3 | * @author Original work by Nad42, edited by IMBA 4 | * @desc Automatically allocate skill points and its pre-requisites if necessary 5 | */ 6 | 7 | var AutoSkill = new function () { 8 | this.skillBuildOrder = []; 9 | this.save = 0; 10 | 11 | /* skillBuildOrder - array of skill points to spend in order 12 | save - number of skill points that will not be spent and saved 13 | 14 | skillBuildOrder Settings 15 | Set skillBuildOrder in the array form: [[skill, count, satisfy], [skill, count, satisfy], ... [skill, count, satisfy]] 16 | skill - skill id number (see /sdk/skills.txt) 17 | count - maximum number of skill points to allocate for that skill 18 | satisfy - boolean value to stop(true) or continue(false) further allocation until count is met. Defaults to true if not specified. 19 | 20 | skillBuildOrder = [ 21 | [37, 1, true], [42, 1, true], [54, 1, true], //warmth, static, teleport 22 | [59, 1, false], [55, 7, true], [45, 13, true], //blizzard, glacial spike, ice blast 23 | [59, 7, false], [65, 1, true], //blizzard, cold mastery 24 | [59, 20, false], [65, 20, true], //max blizzard, max cold mastery 25 | [55, 20, true], [45, 20, true], //max glacial spike, max ice blast 26 | ]; 27 | */ 28 | 29 | this.needPreReq = function (skillid) { //a function to return false if have all prereqs or a skill if not 30 | for (var t = 183; t >=181; t--) { //a loop to go through each reqskill 31 | var preReq = (getBaseStat('skills', skillid, t)); // Check ReqSkills 32 | 33 | if (preReq > 0 && preReq < 356 && !me.getSkill(preReq, 0)) { 34 | return preReq; 35 | } 36 | } 37 | 38 | return false; 39 | }; 40 | 41 | this.skillCheck = function (skillid, count){ 42 | if (me.getSkill(skillid, 0) <= me.charlvl - getBaseStat("skills", skillid, 176) && me.getSkill(skillid, 0) < count) { 43 | return true; 44 | } 45 | 46 | return false; 47 | }; 48 | 49 | this.skillToAdd = function (inputArray) { 50 | for (var i = 0; i < inputArray.length; i += 1) { 51 | // limit maximum allocation count to 20 52 | if (inputArray[i][1] > 20) { 53 | print("AutoSkill: Skill build index " + i + " has allocation count of " + inputArray[i][1] + " and it will be limited to 20"); 54 | inputArray[i][1] = 20; 55 | } 56 | 57 | // set satify condition as default if not specified 58 | if (inputArray[i][2] === undefined) 59 | inputArray[i][2] = true; 60 | 61 | // check to see if skill count in previous array is satisfied 62 | if (i > 0 && inputArray[i-1][2] && (!me.getSkill(inputArray[i-1][0], 0) ? 0 : me.getSkill(inputArray[i-1][0], 0)) < inputArray[i-1][1]) { 63 | return false; 64 | } 65 | 66 | if (me.getSkill(inputArray[i][0], 0) && this.skillCheck(inputArray[i][0], inputArray[i][1])) { 67 | return inputArray[i][0]; 68 | } 69 | 70 | var reqIn, 71 | reqOut = this.needPreReq(inputArray[i][0]); 72 | 73 | if (!reqOut && this.skillCheck(inputArray[i][0], inputArray[i][1])) { 74 | return inputArray[i][0]; 75 | } 76 | 77 | while (reqOut) { 78 | reqIn = reqOut; 79 | reqOut = this.needPreReq(reqIn); 80 | } 81 | 82 | if (this.skillCheck(reqIn, 1)) { 83 | return reqIn; 84 | } 85 | } 86 | 87 | return false; 88 | }; 89 | 90 | this.allocate = function () { 91 | var tick = getTickCount(); 92 | 93 | this.remaining = me.getStat(5); 94 | 95 | if (!getUIFlag(0x17)) { 96 | var addTo = this.skillToAdd(this.skillBuildOrder); 97 | 98 | if (addTo) { 99 | print("AutoSkill: Using skill point in Skill ID: " + addTo); 100 | delay(100); 101 | useSkillPoint(addTo, 1); 102 | } 103 | } 104 | 105 | while (getTickCount() - tick < 1500 + 2 * me.ping) { 106 | if (this.remaining > me.getStat(5)) { 107 | return true; 108 | } 109 | 110 | delay(100); 111 | } 112 | 113 | return false; 114 | }; 115 | 116 | this.remaining = 0; 117 | this.count = 0; 118 | 119 | this.init = function (skillBuildOrder, save = 0) { 120 | this.skillBuildOrder = skillBuildOrder; 121 | this.save = save; 122 | 123 | if (!this.skillBuildOrder || !this.skillBuildOrder.length) { 124 | print("AutoSkill: No build array specified"); 125 | 126 | return false; 127 | } 128 | 129 | while (me.getStat(5) > this.save) { 130 | this.allocate(); 131 | delay(200 + me.ping); // may need longer delay under high ping 132 | 133 | // break out of loop if we have skill points available but cannot allocate further due to unsatisfied skill 134 | if (me.getStat(5) === this.remaining) { 135 | this.count += 1; 136 | } 137 | 138 | if (this.count > 2) { 139 | break; 140 | } 141 | } 142 | 143 | print("AutoSkill: Finished allocating skill points"); 144 | 145 | return true; 146 | }; 147 | 148 | return true; 149 | }; -------------------------------------------------------------------------------- /kolbot/libs/common/CollMap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename CollMap.js 3 | * @author kolton 4 | * @desc manipulate map collision data 5 | */ 6 | 7 | var CollMap = new function () { 8 | this.rooms = []; 9 | this.maps = []; 10 | 11 | this.getNearbyRooms = function (x, y) { 12 | var i, room, rooms; 13 | 14 | room = getRoom(x, y); 15 | 16 | if (!room) { 17 | return false; 18 | } 19 | 20 | rooms = room.getNearby(); 21 | 22 | if (!rooms) { 23 | return false; 24 | } 25 | 26 | for (i = 0; i < rooms.length; i += 1) { 27 | if (this.getRoomIndex(rooms[i].x * 5 + rooms[i].xsize / 2, rooms[i].y * 5 + rooms[i].ysize / 2, true) === undefined) { 28 | this.addRoom(rooms[i]); 29 | } 30 | } 31 | 32 | return true; 33 | }; 34 | 35 | this.addRoom = function (x, y) { 36 | var room, coll; 37 | 38 | room = x instanceof Room ? x : getRoom(x, y); 39 | 40 | // Coords are not in the returned room. 41 | if (arguments.length === 2 && !this.coordsInRoom(x, y, room)) { 42 | return false; 43 | } 44 | 45 | if (room) { 46 | coll = room.getCollision(); 47 | } 48 | 49 | if (coll) { 50 | this.rooms.push({x: room.x, y: room.y, xsize: room.xsize, ysize: room.ysize}); 51 | this.maps.push(coll); 52 | 53 | return true; 54 | } 55 | 56 | return false; 57 | }; 58 | 59 | this.getColl = function (x, y, cacheOnly) { 60 | var i, j, 61 | index = this.getRoomIndex(x, y, cacheOnly); 62 | 63 | if (index === undefined) { 64 | return 5; 65 | } 66 | 67 | j = x - this.rooms[index].x * 5; 68 | i = y - this.rooms[index].y * 5; 69 | 70 | if (this.maps[index] !== undefined && this.maps[index][i] !== undefined && this.maps[index][i][j] !== undefined) { 71 | return this.maps[index][i][j]; 72 | } 73 | 74 | return 5; 75 | }; 76 | 77 | this.getRoomIndex = function (x, y, cacheOnly) { 78 | if (this.rooms.length > 25) { 79 | this.reset(); 80 | } 81 | 82 | var i; 83 | 84 | for (i = 0; i < this.rooms.length; i += 1) { 85 | if (this.coordsInRoom(x, y, this.rooms[i])) { 86 | return i; 87 | } 88 | } 89 | 90 | if (!cacheOnly && this.addRoom(x, y)) { 91 | return i; 92 | } 93 | 94 | return undefined; 95 | }; 96 | 97 | this.coordsInRoom = function (x, y, room) { 98 | if (room && x >= room.x * 5 && x < room.x * 5 + room.xsize && y >= room.y * 5 && y < room.y * 5 + room.ysize) { 99 | return true; 100 | } 101 | 102 | return false; 103 | }; 104 | 105 | this.reset = function () { 106 | this.rooms = []; 107 | this.maps = []; 108 | }; 109 | 110 | // Check collision between unitA and unitB. true = collision present, false = collision not present 111 | // If checking for blocking collisions (0x1, 0x4), true means blocked, false means not blocked 112 | this.checkColl = function (unitA, unitB, coll, thickness) { 113 | if (thickness === undefined) { 114 | thickness = 1; 115 | } 116 | 117 | var i, k, l, cx, cy, angle, distance; 118 | 119 | angle = Math.atan2(unitA.y - unitB.y, unitA.x - unitB.x); 120 | distance = Math.round(getDistance(unitA, unitB)); 121 | 122 | for (i = 1; i < distance; i += 1) { 123 | cx = Math.round((Math.cos(angle)) * i + unitB.x); 124 | cy = Math.round((Math.sin(angle)) * i + unitB.y); 125 | 126 | for (k = cx - thickness; k <= cx + thickness; k += 1) { // check thicker line 127 | for (l = cy - thickness; l <= cy + thickness; l += 1) { 128 | if (this.getColl(k, l, false) & coll) { 129 | return true; 130 | } 131 | } 132 | } 133 | } 134 | 135 | return false; 136 | }; 137 | 138 | this.getTelePoint = function (room) { 139 | // returns {x, y, distance} of a valid point with lowest distance from room center 140 | // distance is from room center, handy for keeping bot from trying to teleport on walls 141 | 142 | if (!room) { 143 | throw new Error("Invalid room passed to getTelePoint"); 144 | } 145 | 146 | let roomx = room.x * 5, roomy = room.y * 5; 147 | 148 | if (getCollision(room.area, roomx, roomy) & 1) { 149 | let collision = room.getCollision(), validTiles = []; 150 | let aMid = Math.round(collision.length / 2), bMid = Math.round(collision[0].length / 2); 151 | 152 | for (let a = 0; a < collision.length; a++) { 153 | for (let b = 0; b < collision[a].length; b++) { 154 | if (!(collision[a][b] & 1)) { 155 | validTiles.push({x: roomx + b - bMid, y: roomy + a - aMid, distance: getDistance(0, 0, a - aMid, b - bMid)}); 156 | } 157 | } 158 | } 159 | 160 | if (validTiles.length) { 161 | validTiles.sort((a, b) => { 162 | return a.distance - b.distance; 163 | }); 164 | 165 | return validTiles[0]; 166 | } 167 | 168 | return null; 169 | } 170 | 171 | return {x: roomx, y: roomy, distance: 0}; 172 | }; 173 | 174 | this.getRandCoordinate = function (cX, xmin, xmax, cY, ymin, ymax, factor = 1) { 175 | // returns randomized {x, y} object with valid coordinates 176 | var coordX, coordY, 177 | retry = 0; 178 | 179 | do { 180 | if (retry > 30) { 181 | print("failed to get valid coordinate"); 182 | coordX = cX; 183 | coordY = cY; 184 | 185 | break; 186 | } 187 | 188 | coordX = cX + factor * rand(xmin, xmax); 189 | coordY = cY + factor * rand(ymin, ymax); 190 | 191 | if (cX === coordX && cY === coordY) { // recalculate if same coordiante 192 | coordX = 0; 193 | continue; 194 | } 195 | 196 | retry++; 197 | } while (getCollision(me.area, coordX, coordY) & 1); 198 | 199 | // print("Move " + retry + " from (" + cX + ", " + cY + ") to (" + coordX + ", " + coordY + ")"); 200 | return {x:coordX, y:coordY}; 201 | }; 202 | }; 203 | -------------------------------------------------------------------------------- /kolbot/libs/common/Loader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Loader.js 3 | * @author kolton 4 | * @desc script loader, based on mBot's Sequencer.js 5 | */ 6 | 7 | var global = this; 8 | 9 | var Loader = { 10 | fileList: [], 11 | scriptList: [], 12 | scriptIndex: -1, 13 | skipTown: ["Test", "Follower"], 14 | 15 | init: function () { 16 | this.getScripts(); 17 | this.loadScripts(); 18 | }, 19 | 20 | getScripts: function () { 21 | var i, 22 | fileList = dopen("libs/bots/").getFiles(); 23 | 24 | for (i = 0; i < fileList.length; i += 1) { 25 | if (fileList[i].indexOf(".js") > -1) { 26 | this.fileList.push(fileList[i].substring(0, fileList[i].indexOf(".js"))); 27 | } 28 | } 29 | }, 30 | 31 | // see http://stackoverflow.com/questions/728360/copying-an-object-in-javascript#answer-728694 32 | clone: function (obj) { 33 | var i, copy, attr; 34 | 35 | // Handle the 3 simple types, and null or undefined 36 | if (null === obj || "object" !== typeof obj) { 37 | return obj; 38 | } 39 | 40 | // Handle Date 41 | if (obj instanceof Date) { 42 | copy = new Date(); 43 | 44 | copy.setTime(obj.getTime()); 45 | 46 | return copy; 47 | } 48 | 49 | // Handle Array 50 | if (obj instanceof Array) { 51 | copy = []; 52 | 53 | for (i = 0; i < obj.length; i += 1) { 54 | copy[i] = this.clone(obj[i]); 55 | } 56 | 57 | return copy; 58 | } 59 | 60 | // Handle Object 61 | if (obj instanceof Object) { 62 | copy = {}; 63 | 64 | for (attr in obj) { 65 | if (obj.hasOwnProperty(attr)) { 66 | copy[attr] = this.clone(obj[attr]); 67 | } 68 | } 69 | 70 | return copy; 71 | } 72 | 73 | throw new Error("Unable to copy obj! Its type isn't supported."); 74 | }, 75 | 76 | copy: function (from, to) { 77 | var i; 78 | 79 | for (i in from) { 80 | if (from.hasOwnProperty(i)) { 81 | to[i] = this.clone(from[i]); 82 | } 83 | } 84 | }, 85 | 86 | loadScripts: function () { 87 | var reconfiguration, s, script, 88 | unmodifiedConfig = {}; 89 | 90 | this.copy(Config, unmodifiedConfig); 91 | 92 | if (!this.fileList.length) { 93 | showConsole(); 94 | 95 | throw new Error("You don't have any valid scripts in bots folder."); 96 | } 97 | 98 | for (s in Scripts) { 99 | if (Scripts.hasOwnProperty(s) && Scripts[s]) { 100 | this.scriptList.push(s); 101 | } 102 | } 103 | 104 | for (this.scriptIndex = 0; this.scriptIndex < this.scriptList.length; this.scriptIndex++) { 105 | script = this.scriptList[this.scriptIndex]; 106 | 107 | if (this.fileList.indexOf(script) < 0) { 108 | Misc.errorReport("ÿc1Script " + script + " doesn't exist."); 109 | continue; 110 | } 111 | 112 | if (!include("bots/" + script + ".js")) { 113 | Misc.errorReport("Failed to include script: " + script); 114 | continue; 115 | } 116 | 117 | if (isIncluded("bots/" + script + ".js")) { 118 | try { 119 | if (typeof (global[script]) !== "function") { 120 | throw new Error("Invalid script function name"); 121 | } 122 | 123 | if (this.skipTown.indexOf(script) > -1 || Town.goToTown()) { 124 | print("ÿc2Starting script: ÿc9" + script); 125 | //scriptBroadcast(JSON.stringify({currScript: script})); 126 | Messaging.sendToScript("tools/toolsthread.js", JSON.stringify({currScript: script})); 127 | 128 | reconfiguration = typeof Scripts[script] === 'object'; 129 | 130 | if (reconfiguration) { 131 | print("ÿc2Copying Config properties from " + script + " object."); 132 | this.copy(Scripts[script], Config); 133 | } 134 | 135 | global[script](); 136 | 137 | if (reconfiguration) { 138 | print("ÿc2Reverting back unmodified config properties."); 139 | this.copy(unmodifiedConfig, Config); 140 | } 141 | } 142 | } catch (error) { 143 | Misc.errorReport(error, script); 144 | } 145 | } 146 | } 147 | }, 148 | 149 | scriptName: function (offset = 0) { 150 | let index = this.scriptIndex + offset; 151 | 152 | if (index >= 0 && index < this.scriptList.length) { 153 | return this.scriptList[index]; 154 | } 155 | 156 | return null; 157 | } 158 | }; 159 | -------------------------------------------------------------------------------- /kolbot/libs/common/Util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param args 3 | * @returns {Unit[]} 4 | */ 5 | function getUnits(...args) { 6 | let units = [], unit = getUnit.apply(null, args); 7 | 8 | if (!unit) { 9 | return []; 10 | } 11 | do { 12 | units.push(copyUnit(unit)); 13 | } while (unit.getNext()); 14 | return units; 15 | } 16 | 17 | const clickItemAndWait = (...args) => { 18 | let before, 19 | itemEvent = false, 20 | timeout = getTickCount(),timedOut; 21 | 22 | before = !me.itemoncursor; 23 | clickItem.apply(undefined, args); 24 | delay(Math.max(me.ping * 2, 250)); 25 | 26 | 27 | while (true) { // Wait until item is picked up. 28 | delay(3); 29 | 30 | if (before !== !!me.itemoncursor || (timedOut = getTickCount() - timeout > Math.min(1000, 100 + (me.ping * 4)))) { 31 | break; // quit the loop of item on cursor has changed 32 | } 33 | } 34 | 35 | delay(Math.max(me.ping, 50)); 36 | 37 | // return item if we didnt timeout 38 | return !timedOut; 39 | }; -------------------------------------------------------------------------------- /kolbot/libs/config/Builds/README.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Borega/pd2bs-scripts/fb578879d11c7726039f34325d727882e2e9ca31/kolbot/libs/config/Builds/README.txt -------------------------------------------------------------------------------- /kolbot/libs/config/Templates/AutoSkillExampleBuilds.txt: -------------------------------------------------------------------------------- 1 | Refer to sdk/skills.txt for skill id index 2 | 3 | Example: Blizzard Sorceress 4 | 5 | Config.AutoSkill.Build = [ 6 | [37, 1, true], [42, 1, true], [54, 1, true], // spend points in warmth, static, teleport (prerequisite to teleport: telekenesis will be learned automatically) 7 | [59, 1, false], [55, 7, true], [45, 13, true], // learn blizzard if possible, and move on to glacial spike, and ice blast 8 | // if satisfy boolean was defined for blizzard as [59, 1, true] and character was under level 24, AutoSkill will stop at this point 9 | [59, 7, false], [65, 1, true], // get blizzard skill level up to 7 and learn cold mastery 10 | [59, 20, false], [65, 20, true], // max blizzard, max cold mastery 11 | [55, 20, true], [45, 20, true], // max glacial spike, max ice blast 12 | ]; 13 | 14 | 15 | Example: Fire Sorceress 16 | 17 | Config.AutoSkill.Build = [ 18 | [36, 4, false], [40, 1, false], // learn fire bolt until skill level 4, learn frozen armor 19 | [36, 8, false], [37, 1, false], [42, 1, false], // learn fire bolt until skill level 7, learn warmth, learn static field 20 | [47, 6, false], [54, 1, true], // learn fire ball until skill level 7, learn teleport 21 | [61, 1, false], [47, 20, false], // learn fire mastery when available, max fire ball 22 | [36, 12, false], [61, 2, false], // leran fire bolt until 14 and skill extra point in fire mastery 23 | [36, 14, false], [61, 5, false], // continue leveling up fire bolt and fire mastery 24 | [36, 16, false], [61, 6, false], // continue leveling up fire bolt and fire mastery 25 | [36, 17, false], [61, 7, false], // continue leveling up fire bolt and fire mastery 26 | [36, 18, false], [61, 8, false], // continue leveling up fire bolt and fire mastery 27 | [36, 19, false], [61, 9, false], // continue leveling up fire bolt and fire mastery 28 | [36, 20, true], [61, 10, false], // max fire bolt and continue leveling fire mastery 29 | [56, 5, true], [61, 15, false], // learn up to 5 meteor first, and fire mastery 30 | [56, 7, false], [61, 16, false], // continue leveling up meteor and fire mastery 31 | [56, 8, false], [61, 17, false], // continue leveling up meteor and fire mastery 32 | [56, 9, false], [61, 18, false], // continue leveling up meteor and fire mastery 33 | [56, 10, false], [61, 20, false], // continue leveling up meteor and max fire mastery 34 | [56, 20, false], [41, 20, false] // max meteor, max inferno 35 | ]; 36 | -------------------------------------------------------------------------------- /kolbot/libs/config/Templates/AutoStatExampleBuilds.txt: -------------------------------------------------------------------------------- 1 | You may input stat types as an integer, or as string type defined as below. 2 | Make sure string types are defined in lowercase. 3 | 4 | 0, "strength", "str", "s" 5 | 1, "energy", "enr", "e" 6 | 2, "dexterity", "dex", "d" 7 | 3, "vitality", "vit", "v" 8 | 9 | 10 | Example: 11 | 12 | Config.AutoStat.Build = [ 13 | ["strength", 35], // spend points in strength until it reaches 35 strength (all +stats from items are ingnored!) 14 | ["vitality", 50], // spend points in vitality until it reaches 50. 15 | ["dexterity", "block"], // spend points in dexterity until it reaches desired block chance defined in Config.AutoStat.BlockChance (+dexterity items are taken into account for "block" option) 16 | // when more stat points are available after leveling, AutoStat will go through the array again and it will continue to stat dexterity as needed. 17 | // if paladin has holy shield skill available and if it's not active, it'll attemp to cast holy shield first 18 | ["strength", 55], // spend points on strength until it reaches 55 19 | ["vitality", "all"] // all remaining points will be spent in vitality. 20 | ]; 21 | 22 | 23 | If you are allocating stats points for high level character and you know your strength/dex requirements, 24 | you may simply specify strength and dexterity value to what you want and put rest into vitality 25 | 26 | Config.AutoStat.Build = [ 27 | ["strength", 55], // spend points in strength until it reaches 35 28 | ["dexterity", 150], // spend points in dexterity until it reaches 150 29 | ["vitality", "all"] // spend all remaining points in vitality 30 | ]; 31 | 32 | 33 | If you are building a character from scratch along with AutoBuild system, you want to be more specific about order of stat allocation. 34 | 35 | Config.AutoStat.Build = [ 36 | ["strength", 12], // stat strength for quilt armor 37 | ["vitality", 28], // spend in vitality until it reaches 28 (level 5) 38 | ["energy", 50], // spend in energy until 50 (level 8) 39 | ["vitality", 50], // spend more in vitality 40 | ["strength", 15], // get up to 15 strength (level 13) 41 | ["vitality", 65], // spend in vitality (level 18) 42 | ["strength", 35], // get up to 25 strength (level 20) 43 | ["energy", 75], // spend in energy (level 25) 44 | ["v", 75], // level 27 45 | ["s", 55], // level 31 46 | ["v", 100], // level 36 47 | ["s", 80], // level 41 48 | ["v", 125], // level 46 49 | ["s", 95], // level 49 (less if done stat quests) 50 | ["v", "all"], // put rest of the points in vitality 51 | ]; 52 | -------------------------------------------------------------------------------- /kolbot/libs/config/Templates/Cubing.txt: -------------------------------------------------------------------------------- 1 | Available cubing recipes: 2 | 3 | Recipe.Gem 4 | Recipe.HitPower.Helm 5 | Recipe.HitPower.Boots 6 | Recipe.HitPower.Gloves 7 | Recipe.HitPower.Belt 8 | Recipe.HitPower.Shield 9 | Recipe.HitPower.Body 10 | Recipe.HitPower.Amulet 11 | Recipe.HitPower.Ring 12 | Recipe.HitPower.Weapon 13 | Recipe.Blood.Helm 14 | Recipe.Blood.Boots 15 | Recipe.Blood.Gloves 16 | Recipe.Blood.Belt 17 | Recipe.Blood.Shield 18 | Recipe.Blood.Body 19 | Recipe.Blood.Amulet 20 | Recipe.Blood.Ring 21 | Recipe.Blood.Weapon 22 | Recipe.Caster.Helm 23 | Recipe.Caster.Boots 24 | Recipe.Caster.Gloves 25 | Recipe.Caster.Belt 26 | Recipe.Caster.Shield 27 | Recipe.Caster.Body 28 | Recipe.Caster.Amulet 29 | Recipe.Caster.Ring 30 | Recipe.Caster.Weapon 31 | Recipe.Safety.Helm 32 | Recipe.Safety.Boots 33 | Recipe.Safety.Gloves 34 | Recipe.Safety.Belt 35 | Recipe.Safety.Shield 36 | Recipe.Safety.Body 37 | Recipe.Safety.Amulet 38 | Recipe.Safety.Ring 39 | Recipe.Safety.Weapon 40 | Recipe.Unique.Weapon.ToExceptional 41 | Recipe.Unique.Weapon.ToElite 42 | Recipe.Unique.Armor.ToExceptional 43 | Recipe.Unique.Armor.ToElite 44 | Recipe.Rare.Weapon.ToExceptional 45 | Recipe.Rare.Weapon.ToElite 46 | Recipe.Rare.Armor.ToExceptional 47 | Recipe.Rare.Armor.ToElite 48 | Recipe.Socket.Shield 49 | Recipe.Socket.Weapon 50 | Recipe.Socket.Armor 51 | Recipe.Socket.Helm 52 | Recipe.Reroll.Magic 53 | Recipe.Reroll.Rare 54 | Recipe.Rune 55 | Recipe.Token -------------------------------------------------------------------------------- /kolbot/libs/config/Templates/Runewords.txt: -------------------------------------------------------------------------------- 1 | Available runewords: 2 | 3 | NOTE: enhanced damage, enhanced defense and +defense will NOT currently work due to core limitations. this might be fixed in the future 4 | 5 | 1.09: 6 | Runeword.AncientsPledge 7 | Runeword.Black 8 | Runeword.Fury 9 | Runeword.HolyThunder 10 | Runeword.Honor 11 | Runeword.KingsGrace 12 | Runeword.Leaf 13 | Runeword.Lionheart 14 | Runeword.Lore 15 | Runeword.Malice 16 | Runeword.Melody 17 | Runeword.Memory 18 | Runeword.Nadir 19 | Runeword.Radiance 20 | Runeword.Rhyme 21 | Runeword.Silence 22 | Runeword.Smoke 23 | Runeword.Stealth 24 | Runeword.Steel 25 | Runeword.Strength 26 | Runeword.Venom 27 | Runeword.Wealth 28 | Runeword.White 29 | Runeword.Zephyr 30 | 31 | 1.10: 32 | Runeword.Beast 33 | Runeword.Bramble 34 | Runeword.BreathoftheDying 35 | Runeword.CallToArms 36 | Runeword.ChainsofHonor 37 | Runeword.Chaos 38 | Runeword.CrescentMoon 39 | Runeword.Delirium 40 | Runeword.Doom 41 | Runeword.Duress 42 | Runeword.Enigma 43 | Runeword.Eternity 44 | Runeword.Exile 45 | Runeword.Famine 46 | Runeword.Gloom 47 | Runeword.HandofJustice 48 | Runeword.HeartoftheOak 49 | Runeword.Kingslayer 50 | Runeword.Passion 51 | Runeword.Prudence 52 | Runeword.Sanctuary 53 | Runeword.Splendor 54 | Runeword.Stone 55 | Runeword.Wind 56 | 57 | 1.10 ladder-only: 58 | Runeword.Brand 59 | Runeword.Death 60 | Runeword.Destruction 61 | Runeword.Dragon 62 | Runeword.Dream 63 | Runeword.Edge 64 | Runeword.Faith 65 | Runeword.Fortitude 66 | Runeword.Grief (use [normaldamage] modifier for grief pickit) 67 | Runeword.Harmony 68 | Runeword.Ice 69 | Runeword.Infinity 70 | Runeword.Insight 71 | Runeword.LastWish 72 | Runeword.Lawbringer 73 | Runeword.Oath 74 | Runeword.Obedience 75 | Runeword.Phoenix 76 | Runeword.Pride 77 | Runeword.Rift 78 | Runeword.Spirit 79 | Runeword.VoiceofReason 80 | Runeword.Wrath 81 | 82 | 1.11: 83 | Runeword.Bone 84 | Runeword.Enlightenment 85 | Runeword.Myth 86 | Runeword.Peace 87 | Runeword.Principle 88 | Runeword.Rain 89 | Runeword.Treachery -------------------------------------------------------------------------------- /kolbot/libs/config/Templates/ShopBot.txt: -------------------------------------------------------------------------------- 1 | Names can now be used instead of classids. If you want to use classids, check NTItemAlias.dbl 2 | To see which NPC sells which items, check this link: http://members.iinet.net.au/~dcarson/shopcalc.html -------------------------------------------------------------------------------- /kolbot/libs/config/Templates/chestlist.txt: -------------------------------------------------------------------------------- 1 | ID Act1 2 | 15 - Hole Level 2 3 | 13 - Cave Level 2 4 | 16 - Pit Level 2 5 | 14 - Passage Level 2 6 | 25 - Tower Level 5 7 | 18 - Crypta 8 | 19 - Mausoleum 9 | Act2 10 | 55 - stony Tomb 11 | 65 - Ancient Tunnels 12 | 66-72 - Tal Tombs 13 | Act3 14 | 84 - SpiderCave 15 | 85 - SpiderCavern 16 | 77 - Marsh 17 | 90 - Smapy Grave 18 | 79 - lower Kurast 19 | 80 - Kurast Basar 20 | 92 - Sewers Level 1 21 | 93 - Sewers Level 2 22 | Act5 23 | 115 - Glacial Trail 24 | 116 - Drifter Cavern 25 | 119 - FrozenCellar 26 | 125 - Abbadon 27 | 126 - Archeon 28 | 127 - Infernal -------------------------------------------------------------------------------- /kolbot/libs/config/_CustomConfig.js: -------------------------------------------------------------------------------- 1 | var CustomConfig = { 2 | /* Format: 3 | "Config_Filename_Without_Extension": ["array", "of", "profiles"] 4 | 5 | Multiple entries are separated by commas 6 | */ 7 | 8 | 9 | }; -------------------------------------------------------------------------------- /kolbot/libs/modules/Deltas.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Nishimura-Katsuo, Jaenster 3 | * @description a basic implementation of delta's 4 | * 5 | */ 6 | (function (module, require) { 7 | const Worker = require('Worker'); 8 | let instances = 0; 9 | 10 | /** @constructor 11 | * @class Delta */ 12 | module.exports = function (trackers) { 13 | let active = true; 14 | this.values = (Array.isArray(trackers) && (Array.isArray(trackers.first()) && trackers || [trackers])) || []; 15 | this.track = function (checkerFn, callback) { 16 | return this.values.push({fn: checkerFn, callback: callback, value: checkerFn()}); 17 | }; 18 | this.check = function () { 19 | this.values.some(delta => { 20 | let val = delta.fn(); 21 | 22 | if (delta.value !== val) { 23 | let ret = delta.callback(delta.value, val); 24 | delta.value = val; 25 | 26 | return ret; 27 | } 28 | 29 | return null; 30 | }); 31 | }; 32 | 33 | this.destroy = () => active = false; 34 | 35 | Worker.runInBackground['__delta' + (instances++)] = () => active && (this.check() || true); 36 | return this; 37 | }; 38 | 39 | }).call(null, typeof module === 'object' && module || {}, typeof require === 'undefined' && (include('require.js') && require) || require); -------------------------------------------------------------------------------- /kolbot/libs/modules/Events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Jaenster 3 | * @description A node like event system 4 | * 5 | */ 6 | 7 | (function (module, require) { 8 | const Events = module.exports = function () { 9 | const Worker = require('Worker'), self = this; 10 | 11 | this.hooks = []; 12 | 13 | function Hook(name, callback) { 14 | this.name = name; 15 | this.callback = callback; 16 | this.id = self.hooks.push(this); 17 | this.__callback = callback; // used for once 18 | } 19 | 20 | this.on = function (name, callback) { 21 | if (callback === undefined && typeof name === 'function') [callback,name] = [name,callback]; 22 | return new Hook(name, callback); 23 | }; 24 | 25 | this.trigger = function (name, ...args) { 26 | return self.hooks.forEach(hook => !hook.name || hook.name === name && Worker.push(function () { 27 | hook.callback.apply(hook, args); 28 | })); 29 | }; 30 | 31 | this.emit = this.trigger; // Alias for trigger 32 | 33 | this.once = function (name, callback) { 34 | if (callback === undefined && typeof name === 'function') [callback,name] = [name,callback]; 35 | const hook = new Hook(name, function (...args) { 36 | callback.apply(undefined, args); 37 | delete self.hooks[this.id]; 38 | }); 39 | hook.__callback = callback; 40 | }; 41 | 42 | this.off = function (name, callback) { 43 | self.hooks.filter(hook => hook.__callback === callback).forEach(hook => { 44 | delete self.hooks[hook.id]; 45 | }) 46 | }; 47 | 48 | this.removeListener = this.off; // Alias for remove 49 | }; 50 | })(module, require); -------------------------------------------------------------------------------- /kolbot/libs/modules/HTTP.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description Do a http request 3 | * @author jaenster 4 | */ 5 | 6 | (function (module, require) { 7 | 8 | const Socket = require('Socket'); 9 | const Promise = require('Promise'); 10 | 11 | const defaultOptions = { 12 | url: '', 13 | headers: { 14 | 'User-Agent': 'd2bs', 15 | 'Accept': '*/*', 16 | }, 17 | port: 80, 18 | method: 'GET', 19 | data: '', // Fill with content for post 20 | }; 21 | 22 | const HTTP = function (config = {}) { 23 | config = Object.assign(defaultOptions, config); 24 | if (!config.url) { 25 | throw new Error('Must give a url to connect to') 26 | } 27 | const [fullUrl, protocol, hostname, uri] = config.url.match(/^(.*:)\/\/([A-Za-z0-9\-\.]+)?(.*)/); 28 | const socket = new Socket(hostname, config.port); 29 | 30 | socket.connect(); 31 | if (!socket.connected) { 32 | throw new Error('failed to connect to ' + hostname); 33 | } 34 | 35 | if (config.data.length) { // in case we send data 36 | config.headers['Content-Length'] = config.data.length; 37 | } 38 | config.headers['Host'] = hostname; // required for HTTP/1.1 39 | 40 | const data = [config.method + ' ' + uri + ' ' + 'HTTP/1.1']; 41 | Object.keys(config.headers).forEach((key) => data.push(key + ': ' + config.headers[key])); 42 | 43 | socket.send(data.join('\r\n') + '\r\n\r\n' + config.data); 44 | 45 | let recvd = false; // where we store recv'd data 46 | socket.once('data', data => recvd = data); 47 | return new Promise((resolve) => recvd && resolve(recvd)); 48 | }; 49 | 50 | module.exports = HTTP; 51 | 52 | }).call(null, module, require); 53 | -------------------------------------------------------------------------------- /kolbot/libs/modules/Messaging.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description Easy communication between threads 3 | * @Author Jaenster 4 | */ 5 | 6 | 7 | (function (module, require) { 8 | const myEvents = new (require('Events')); 9 | const Worker = require('Worker'); 10 | 11 | 12 | Worker.runInBackground.messaging = (new function () { 13 | const workBench = []; 14 | addEventListener('scriptmsg', data => workBench.push(data)); 15 | 16 | this.update = function () { 17 | if (!workBench.length) return true; 18 | 19 | let work = workBench.splice(0, workBench.length); 20 | work.filter(data => typeof data === 'object' && data) 21 | .forEach(function (data) { 22 | Object.keys(data).forEach(function (item) { 23 | myEvents.emit(item, data[item]); // Trigger those events 24 | }) 25 | }); 26 | 27 | return true; // always, to keep looping; 28 | } 29 | }).update; 30 | 31 | module.exports = { 32 | on: myEvents.on, 33 | off: myEvents.off, 34 | once: myEvents.once, 35 | send: what => scriptBroadcast(what) 36 | } 37 | 38 | })(module, require); -------------------------------------------------------------------------------- /kolbot/libs/modules/Promise.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description Promise polyfill for d2bs. Try's to re-create the entire 3 | * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise 4 | * @author Jaenster 5 | */ 6 | 7 | (function (module, require) { 8 | const Worker = require('Worker'); 9 | /** 10 | * 11 | * @param {function({resolve},{reject}):boolean} callback 12 | * @constructor 13 | */ 14 | const Promise = module.exports = function (callback) { 15 | typeof Promise.__promiseCounter === 'undefined' && (Promise.__promiseCounter = 0); 16 | 17 | this._after = []; 18 | this._catchers = []; 19 | this._finally = []; 20 | this.stopped = false; 21 | this.value = this; 22 | const self = this; 23 | 24 | const final = function () { 25 | typeof self._finally !== 'undefined' && self._finally.forEach(function (callback) { 26 | return callback(self.value); 27 | }); 28 | }, resolve = function (result) { 29 | self.value = result; 30 | self.stopped = true; 31 | typeof self._after !== 'undefined' && self._after.forEach(callback => Worker.push(function () { 32 | return callback(result); 33 | })); 34 | Worker.push(final); 35 | }, 36 | reject = function (e) { 37 | self.stopped = true; 38 | typeof self._catchers !== 'undefined' && self._catchers.forEach(callback => Worker.push(function () { 39 | return callback(e); 40 | })); 41 | if (!Array.isArray(self._catchers) || !self._catchers.length) Misc.errorReport(e || (new Error)); 42 | Worker.push(final); 43 | }; 44 | 45 | 46 | if (this.__proto__.constructor !== Promise) { 47 | print((new Error).stack); 48 | throw new Error("Promise must be called with 'new' operator!"); 49 | } 50 | 51 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf 52 | // override the valueOf as primitive value function 53 | this.valueOf = () => self.stopped ? self.value : self; 54 | 55 | this.then = function (handler) { 56 | typeof self._after !== 'undefined' && (self._after = []); 57 | self._after.push(handler); 58 | 59 | return self; 60 | }; 61 | 62 | this.catch = function (handler) { 63 | typeof self._catchers !== 'undefined' && (self._catchers = []); 64 | self._catchers.push(handler); 65 | 66 | return self; 67 | }; 68 | 69 | this.finally = function (handler) { 70 | typeof self._finally !== 'undefined' && (self._finally = []); 71 | self._finally.push(handler); 72 | 73 | return self; 74 | }; 75 | 76 | Worker.runInBackground['promise__' + (++Promise.__promiseCounter)] = function () { 77 | try { 78 | callback(resolve, reject); 79 | } catch (e) { 80 | reject(e); 81 | } 82 | return !self.stopped; 83 | }; 84 | }; 85 | 86 | /** 87 | * @description wait for an array of promises to be ran. 88 | * @param promises Array 89 | */ 90 | Promise.all = function (promises) { 91 | while (promises.some(x => !x.stopped)) { 92 | delay(); 93 | } 94 | }; 95 | 96 | Promise.allSettled = (promises) => new Promise(resolve => promises.every(x => x.stopped) && resolve(promises)); 97 | 98 | })(module, require); 99 | 100 | -------------------------------------------------------------------------------- /kolbot/libs/modules/SimpleParty.js: -------------------------------------------------------------------------------- 1 | (function (module, require) { 2 | const Worker = require('Worker'); 3 | const NO_PARTY = 65535; 4 | const PARTY_MEMBER = 1; 5 | const ACCEPTABLE = 2; 6 | const INVITED = 4; 7 | const BUTTON_INVITE_ACCEPT_CANCEL = 2; 8 | const BUTTON_LEAVE_PARTY = 3; 9 | const BUTTON_HOSTILE = 4; 10 | 11 | print('ÿc2Kolbotÿc0 :: Simple party running'); 12 | 13 | const SimpleParty = {}; 14 | 15 | SimpleParty.biggestPartyId = function () { 16 | let uniqueParties = []; 17 | // Or add it and return the value 18 | for (let party = getParty(); party.getNext();) { 19 | ( 20 | // Find this party 21 | uniqueParties.find(u => u.partyid === party.partyid) 22 | // Or create an instance of it 23 | || ((uniqueParties.push({ 24 | partyid: party.partyid, 25 | used: 0 26 | }) && false) || uniqueParties[uniqueParties.length - 1]) 27 | // Once we have the party object, increase field used 28 | ).used++; 29 | } 30 | 31 | // Filter out no party, if another party is found 32 | uniqueParties.some(u => u.partyid !== NO_PARTY) && (uniqueParties = uniqueParties.filter(u => u.partyid !== NO_PARTY)); 33 | 34 | return (uniqueParties.sort((a, b) => b.used - a.used /*b-a = desc*/).first() || {partyid: -1}).partyid; 35 | }; 36 | 37 | SimpleParty.acceptFirst = function () { 38 | const toMd5Int = what => parseInt(md5(what).substr(0, 4), 16); //ToDo; do something with game number here 39 | const names = []; 40 | for (let party = getParty(); party.getNext();) { 41 | if (party.partyid === NO_PARTY) { 42 | names.push(party.name); 43 | } 44 | } 45 | return names.filter(n => n !== me.name /*cant accept yourself ;)*/).sort((a, b) => toMd5Int(a) - toMd5Int(b)).first(); 46 | }; 47 | 48 | SimpleParty.getFirstPartyMember = function () 49 | { 50 | let myPartyId = ((() => (getParty() || {partyid: 0}).partyid))(); 51 | for (let party = getParty(); party.getNext();) { 52 | if (party.partyid === myPartyId && party.name !== me.charname) { 53 | return party; 54 | } 55 | } 56 | return undefined; 57 | }; 58 | 59 | SimpleParty.invite = function (name) { 60 | 61 | for (let party = getParty(); party.getNext();) { 62 | // If party member is 63 | if (party.name === name && party.partyflag !== ACCEPTABLE && party.partyflag !== PARTY_MEMBER && party.partyid === NO_PARTY) { 64 | clickParty(party, BUTTON_INVITE_ACCEPT_CANCEL); // Press the invite button 65 | return true; 66 | } 67 | } 68 | return false; 69 | }; 70 | 71 | SimpleParty.timer = 0; 72 | 73 | if (getScript(true).name.toLowerCase() === 'default.dbj') { 74 | (Worker.runInBackground.party = (function () {// For now, we gonna do this in game with a single party 75 | SimpleParty.timer = getTickCount(); 76 | return function () { 77 | // Set timer back on 3 seconds, or reset it and continue 78 | if ((getTickCount() - SimpleParty.timer) < 3000 || (SimpleParty.timer = getTickCount()) && false) { 79 | return true; 80 | } 81 | 82 | if (Config.PublicMode !== true) { // Public mode 1/2/3 dont count. This is SimplyParty 83 | return true; 84 | } 85 | 86 | const myPartyId = ((() => (getParty() || {partyid: 0}).partyid))(); 87 | if (!myPartyId) { 88 | return true; // party ain't up yet 89 | } 90 | 91 | const biggestPartyId = SimpleParty.biggestPartyId(); 92 | 93 | for (let party = getParty(), acceptFirst; party && party.getNext();) { 94 | if (!(party && typeof party === 'object')) { 95 | continue; 96 | } 97 | 98 | if (!(party.hasOwnProperty('life'))) { 99 | continue; 100 | } // Somehow not a party member 101 | 102 | // Deal with inviting 103 | if ( // If no party is formed, or im member of the biggest party 104 | party.partyflag !== INVITED && // Already invited 105 | party.partyflag !== ACCEPTABLE && // Need to accept invite, so cant invite 106 | party.partyflag !== PARTY_MEMBER && // cant party again with soemone 107 | party.partyid === NO_PARTY // Can only invite someone that isnt in a party 108 | && ( // If im not in a party, only if there is no party 109 | myPartyId === NO_PARTY && biggestPartyId === NO_PARTY 110 | // OR, if im part of the biggest party 111 | || biggestPartyId === myPartyId 112 | ) 113 | ) { 114 | // if player isn't invited, invite 115 | clickParty(party, BUTTON_INVITE_ACCEPT_CANCEL); 116 | } 117 | 118 | // Deal with accepting 119 | if ( 120 | party.partyflag === ACCEPTABLE 121 | && myPartyId === NO_PARTY // Can only accept if we are not in a party 122 | && party.partyid === biggestPartyId // Only accept if it is an invite to the biggest party 123 | ) { 124 | // Try to make all bots accept the same char first, to avoid confusion with multiple parties 125 | if (biggestPartyId === NO_PARTY) { 126 | // if acceptFirst isnt set, create it (to cache it, yet generate on demand) 127 | if (!acceptFirst) { 128 | acceptFirst = SimpleParty.acceptFirst(); 129 | } 130 | 131 | if (acceptFirst !== party.name) { 132 | continue; // Ignore party acceptation 133 | } 134 | } 135 | 136 | clickParty(party, BUTTON_INVITE_ACCEPT_CANCEL); 137 | } 138 | 139 | // Deal with being in the wrong party. (we want to be in the biggest party) 140 | if ( 141 | party.partyflag === PARTY_MEMBER // We are in the same party 142 | && biggestPartyId !== party.partyid // yet this party isnt the biggest party available 143 | && biggestPartyId !== NO_PARTY // And the biggest party isnt no party 144 | ) { 145 | clickParty(party, BUTTON_LEAVE_PARTY); 146 | } 147 | 148 | } 149 | return true; 150 | }; 151 | })()); 152 | } 153 | 154 | module.exports = SimpleParty; 155 | 156 | })(module, require); 157 | -------------------------------------------------------------------------------- /kolbot/libs/modules/Socket.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description a wrapper around the socket object 3 | * @author Jaenster 4 | */ 5 | 6 | 7 | (function (module, require, buildinSock) { 8 | const Worker = require('Worker'); 9 | const Events = require('Events'); 10 | 11 | /** @constructor Socket*/ 12 | function Socket(hostname, port) { 13 | typeof Socket.__socketCounter === 'undefined' && (Socket.__socketCounter = 0); 14 | this.connected = false; 15 | const myEvents = new Events; 16 | this.connect = () => (this.socket = buildinSock.open(hostname, port)) && (this.connected = true) && this; 17 | 18 | this.on = myEvents.on; 19 | this.off = myEvents.off; 20 | this.once = myEvents.once; 21 | 22 | const close = () => { 23 | this.socket = null; 24 | this.connected = false; 25 | myEvents.emit('close', this); 26 | }; 27 | 28 | this.recv = () => { 29 | if (!this.connected || !this.socket || !this.socket.readable) return; 30 | 31 | const data = (() => { 32 | try { 33 | return this.socket.read() 34 | } catch (e) { 35 | close(); 36 | } 37 | return undefined; 38 | })(); 39 | 40 | data && myEvents.emit('data', data); 41 | }; 42 | 43 | this.send = (data) => { 44 | if (!data || !this.socket) return; 45 | 46 | try { 47 | this.socket.send(data); 48 | } catch (e) { 49 | close(); 50 | } 51 | }; 52 | 53 | Worker.runInBackground['__socket__' + (++Socket.__socketCounter)] = () => this.recv() || this.send() || true; 54 | } 55 | 56 | module.exports = Socket; 57 | }).call(null, module, require, Socket); 58 | -------------------------------------------------------------------------------- /kolbot/libs/modules/Team.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description Easy communication between clients 3 | * @Author Jaenster 4 | * 5 | */ 6 | !isIncluded('require.js') && include('require.js'); // load the require.js 7 | 8 | (function (threadType) { 9 | 10 | const others = []; 11 | 12 | const myEvents = new (require('Events')); 13 | const Worker = require('Worker'); 14 | const Messaging = require('Messaging'); 15 | const defaultCopyDataMode = 0xC0FFFEE; 16 | 17 | const Team = { 18 | on: myEvents.on, 19 | off: myEvents.off, 20 | once: myEvents.once, 21 | send: function (who, what, mode = defaultCopyDataMode) { 22 | what.profile = me.windowtitle; 23 | return sendCopyData(null, who, mode || defaultCopyDataMode, JSON.stringify(what)); 24 | }, 25 | broadcast: (what, mode) => { 26 | what.profile = me.windowtitle; 27 | return others.forEach(other => sendCopyData(null, other.profile, mode || defaultCopyDataMode, JSON.stringify(what))) 28 | }, 29 | broadcastInGame: (what, mode) => { 30 | what.profile = me.windowtitle; 31 | others.forEach(function (other) { 32 | for (const party = getParty(); party && party.getNext();) { 33 | typeof party === 'object' && party && party.hasOwnProperty('name') && party.name === other.name && sendCopyData(null, other.profile, mode || defaultCopyDataMode, JSON.stringify(what)); 34 | } 35 | }) 36 | } 37 | }; 38 | 39 | if (threadType === 'thread') { 40 | print('ÿc2Kolbotÿc0 :: Team thread started'); 41 | 42 | Messaging.on('Team', data => { 43 | return typeof data === 'object' && data && data.hasOwnProperty('call') && Team[data.call].apply(Team, data.hasOwnProperty('args') && data.args || []); 44 | }); 45 | 46 | Worker.runInBackground.copydata = (new function () { 47 | const workBench = []; 48 | const updateOtherProfiles = function () { 49 | const fileList = dopen("data/").getFiles(); 50 | fileList && fileList.forEach(function (filename) { 51 | let newContent, obj, profile = filename.split("").reverse().splice(5).reverse().join(''); // strip the last 5 chars (.json) = 5 chars 52 | 53 | 54 | if (profile === me.windowtitle || !filename.endsWith('.json')) return; 55 | try { 56 | newContent = FileTools.readText('data/' + filename); 57 | if (!newContent) return; // no content 58 | } catch (e) { 59 | print('Can\'t read: `' + 'data/' + filename + '`'); 60 | } 61 | 62 | 63 | try { // try to convert to an object 64 | obj = JSON.parse(newContent); 65 | } catch (e) { 66 | return; 67 | } 68 | 69 | let other; 70 | for (let i = 0, tmp; i < others.length; i++) { 71 | tmp = others[i]; 72 | if (tmp.hasOwnProperty('profile') && tmp.profile === profile) { 73 | other = tmp; 74 | break; 75 | } 76 | } 77 | 78 | if (!other) { 79 | others.push(obj); 80 | other = others[others.length - 1]; 81 | } 82 | 83 | other.profile = profile; 84 | Object.keys(obj).map(key => other[key] = obj[key]); 85 | }) 86 | }; 87 | addEventListener('copydata', (mode, data) => workBench.push({mode: mode, data: data})); 88 | 89 | let timer = getTickCount() - Math.round((Math.random() * 2500) + 1000); // start with 3 seconds off 90 | this.update = function () { 91 | if (!((getTickCount() - timer) < 3500)) { // only ever 3 seconds update the entire team 92 | timer = getTickCount(); 93 | updateOtherProfiles(); 94 | } 95 | 96 | // nothing to do? next 97 | if (!workBench.length) return true; 98 | const emit = workBench.splice(0, workBench.length).map( 99 | function (obj) { // Convert to object, if we can 100 | let data = obj.data; 101 | try { 102 | data = JSON.parse(data); 103 | } catch (e) { 104 | /* Dont care if we cant*/ 105 | return {}; 106 | } 107 | return {mode: obj.mode, data: data}; 108 | }) 109 | .filter(obj => typeof obj === 'object' && obj) 110 | .filter(obj => typeof obj.data === 'object' && obj.data) 111 | .filter(obj => typeof obj.mode === 'number' && obj.mode); 112 | emit.length && Messaging.send({ 113 | Team: { 114 | emit: emit 115 | } 116 | }); 117 | return true; // always, to keep looping; 118 | }; 119 | }).update; 120 | 121 | while (true) { 122 | delay(1000); 123 | } 124 | 125 | } else { 126 | (function (module, require) { 127 | const localTeam = module.exports = Team; // <-- some get overridden, but this still works for auto completion in your IDE 128 | 129 | // Filter out all Team functions that are linked to myEvent 130 | Object.keys(Team) 131 | .filter(key => !myEvents.hasOwnProperty(key) && typeof Team[key] === 'function') 132 | .forEach(key => { 133 | return module.exports[key] = (...args) => { 134 | return Messaging.send({ 135 | Team: { 136 | call: key, 137 | args: args 138 | } 139 | }); 140 | }; 141 | }); 142 | 143 | Messaging.on('Team', msg => 144 | typeof msg === 'object' 145 | && msg 146 | && msg.hasOwnProperty('emit') 147 | && Array.isArray(msg.emit) 148 | && msg.emit.forEach(function (obj) { 149 | 150 | // Registered events on the mode 151 | myEvents.emit(obj.mode, obj.data); 152 | 153 | // Only if data is set 154 | typeof obj.data === 'object' && obj.data && Object.keys(obj.data).forEach(function (item) { 155 | 156 | // For each item in the object, trigger an event 157 | obj.data[item].reply = (what, mode) => localTeam.send(obj.data.profile, what, mode); 158 | 159 | // Registered events on a data item 160 | myEvents.emit(item, obj.data[item]); 161 | }) 162 | }) 163 | ); 164 | })(module, require); 165 | } 166 | 167 | 168 | })(getScript.startAsThread()); -------------------------------------------------------------------------------- /kolbot/libs/modules/Worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description Simple worker class for async behavior 3 | * @author Jaenster 4 | */ 5 | 6 | (function(module,require) { 7 | const recursiveCheck = function (stackNumber) { 8 | let stack = new Error().stack.match(/[^\r\n]+/g), 9 | functionName = stack[stackNumber || 1].substr(0, stack[stackNumber || 1].indexOf('@')); 10 | 11 | for (let i = (stackNumber || 1) + 1; i < stack.length; i++) { 12 | let curFunc = stack[i].substr(0, stack[i].indexOf('@')); 13 | 14 | if (functionName === curFunc) { 15 | return true; 16 | } // recursion appeared 17 | } 18 | 19 | return false; 20 | }; 21 | 22 | let Worker = module.exports = new (function () { 23 | let work = [], workLowPrio = [], self = this; 24 | 25 | this.push = function (newWork) { 26 | return work.push(newWork); 27 | }; 28 | 29 | this.pushLowPrio = function (newWork) { 30 | return workLowPrio.push(newWork); 31 | }; 32 | 33 | const checker = function (val) { 34 | try { 35 | !self.workDisabled && val.length && val.splice(0, val.length).forEach(self.work); 36 | } catch (error) { 37 | if (!error.message.endsWith('too much recursion')) { 38 | throw error; 39 | } // keep on throwing 40 | 41 | print('[ÿc9Warningÿc0] Too much recursion'); 42 | } 43 | }; 44 | 45 | this.check = function () { 46 | return checker(work); 47 | }; 48 | 49 | this.checkLowPrio = function () { 50 | return checker(workLowPrio); 51 | }; 52 | 53 | this.work = function (what) { 54 | return typeof what === 'function' && what(self) || (Array.isArray(what) && what.forEach(self.work)); 55 | }; 56 | 57 | /** 58 | * 59 | * @param {function({Worker}):boolean} callback 60 | */ 61 | this.runInBackground = new Proxy({processes: {}}, { 62 | set: function (target, name, callback) { 63 | target.processes[name] = {callback: callback, running: true}; 64 | 65 | let proxyCallback = function () { 66 | target.processes.running = (callback() && self.pushLowPrio(proxyCallback) > -1); 67 | }; 68 | 69 | self.pushLowPrio(proxyCallback); 70 | }, 71 | }); 72 | 73 | global.await = function (promise) { 74 | while (delay() && !promise.stopped) {} 75 | 76 | return promise.value; 77 | }; 78 | 79 | this.workDisabled = 0; 80 | 81 | global._delay = delay; // The original delay function 82 | 83 | // Override the delay function, to check for background work while we wait anyway 84 | global.delay = function (amount) { 85 | 86 | let recursive = recursiveCheck(); 87 | let start = getTickCount(); 88 | amount = amount || 0; 89 | 90 | do { 91 | self.check(); 92 | global._delay(getTickCount() - start > 3 ? 3 : 1); 93 | !recursive && self.checkLowPrio(); 94 | } while (getTickCount() - start <= amount); 95 | 96 | return true; // always return true 97 | }; 98 | 99 | this.recursiveCheck = recursiveCheck; 100 | })(); 101 | })(module,require); -------------------------------------------------------------------------------- /kolbot/libs/require.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @description A node like require function. 3 | * @author Jaenster 4 | */ 5 | 6 | !isIncluded('polyfill.js') && include('polyfill.js'); 7 | 8 | // noinspection ThisExpressionReferencesGlobalObjectJS <-- definition of global here 9 | typeof global === 'undefined' && (this['global'] = this); 10 | 11 | global['module'] = {exports: undefined}; 12 | global['exports'] = {}; 13 | function removeRelativePath(test) { 14 | return test.replace(/\\/g, '/').split('/').reduce(function (acc, cur) { 15 | if (!cur || cur === '.') return acc; 16 | if (cur === '..') { 17 | acc.pop(); 18 | return acc; 19 | } 20 | acc.push(cur); 21 | return acc; 22 | 23 | }, []).join('/'); 24 | } 25 | global.require = (function (include, isIncluded, print, notify) { 26 | 27 | 28 | let depth = 0; 29 | const modules = {}; 30 | const obj = function require(field, path) { 31 | const stack = new Error().stack.match(/[^\r\n]+/g); 32 | let directory = stack[1].match(/.*?@.*?d2bs\\(kolbot\\?.*)\\.*(\.js|\.dbj):/)[1].replace('\\', '/') + '/'; 33 | let filename = stack[1].match(/.*?@.*?d2bs\\kolbot\\?(.*)(\.js|\.dbj):/)[1]; 34 | filename = filename.substr(filename.length - filename.split('').reverse().join('').indexOf('\\')); 35 | // remove the name kolbot of the file 36 | if (directory.startsWith('kolbot')) { 37 | directory = directory.substr('kolbot'.length); 38 | } 39 | 40 | // remove the / from it 41 | if (directory.startsWith('/')) { 42 | directory = directory.substr(1); 43 | } 44 | 45 | // strip off lib 46 | if (directory.startsWith('lib')) { 47 | directory = directory.substr(4); 48 | } else { 49 | directory = '../' + directory; // Add a extra recursive path, as we start out of the lib directory 50 | } 51 | 52 | 53 | path = path || directory; 54 | 55 | let fullpath = removeRelativePath((path + field).replace(/\\/, '/')).toLowerCase(); 56 | // remove lib again, if required in e.g. kolbot\tools but wants modules\whatever 57 | if (fullpath.startsWith('lib')) { 58 | fullpath = fullpath.substr(4); 59 | } 60 | const packageName = fullpath; 61 | 62 | const asNew = this.__proto__.constructor === require && ((...args) => new (Function.prototype.bind.apply(modules[packageName].exports, args))); 63 | 64 | if (field.hasOwnProperty('endsWith') && field.endsWith('.json')) { // Simply reads a json file 65 | return modules[packageName] = File.open('libs/' + path + field, 0).readAllLines(); 66 | } 67 | 68 | const moduleNameShort = (fullpath + '.js').match(/.*?\/(\w*).js$/)[1]; 69 | 70 | if (!isIncluded(fullpath + '.js') && !modules.hasOwnProperty(moduleNameShort)) { 71 | depth && notify && print('ÿc2Kolbotÿc0 :: - loading dependency of ' + filename + ': ' + moduleNameShort); 72 | !depth && notify && print('ÿc2Kolbotÿc0 :: Loading module: ' + moduleNameShort); 73 | 74 | let oldModule = Object.create(global['module']); 75 | let oldExports = Object.create(global['exports']); 76 | delete global['module']; 77 | delete global['exports']; 78 | global['module'] = {exports: null}; 79 | global['exports'] = {}; 80 | 81 | // Include the file; 82 | try { 83 | depth++; 84 | if (!include(fullpath + '.js')) { 85 | const err = new Error('module ' + fullpath + ' not found'); 86 | 87 | // Rewrite the location of the error, to be more clear for the developer/user _where_ it crashes 88 | const myStack = err.stack.match(/[^\r\n]+/g); 89 | err.fileName = directory + myStack[1].match(/.*?@.*?d2bs\\kolbot\\?(.*)(\.js|\.dbj):/)[1]; 90 | err.lineNumber = myStack[1].substr(stack[1].lastIndexOf(':') + 1); 91 | myStack.unshift(); 92 | err.stack = myStack.join('\r\n'); // rewrite stack 93 | 94 | throw err; 95 | } 96 | } finally { 97 | depth-- 98 | } 99 | 100 | if (!global['module']['exports'] && Object.keys(global['exports'])) { // Incase its transpiled typescript 101 | global['module']['exports'] = global['exports']; 102 | } 103 | 104 | modules[packageName] = Object.create(global['module']); 105 | delete global['module']; 106 | delete global['exports']; 107 | global['module'] = oldModule; 108 | global['exports'] = oldExports; 109 | } 110 | 111 | if (!modules.hasOwnProperty(packageName)) throw Error('unexpected module error -- ' + field); 112 | 113 | // If called as "new", fake an constructor 114 | return asNew || modules[packageName].exports; 115 | }; 116 | obj.modules = modules; 117 | return obj; 118 | })(include, isIncluded, print, getScript(true).name.toLowerCase().split('').reverse().splice(0, '.dbj'.length).reverse().join('') === '.dbj'); 119 | 120 | getScript.startAsThread = function () { 121 | let stack = new Error().stack.match(/[^\r\n]+/g), 122 | filename = stack[1].match(/.*?@.*?d2bs\\kolbot\\(.*):/)[1]; 123 | 124 | if (getScript(true).name.toLowerCase() === filename.toLowerCase()) { 125 | return 'thread'; 126 | } 127 | 128 | if (!getScript(filename)) { 129 | load(filename); 130 | return 'started'; 131 | } 132 | 133 | return 'loaded'; 134 | }; 135 | -------------------------------------------------------------------------------- /kolbot/mules/deleteme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Borega/pd2bs-scripts/fb578879d11c7726039f34325d727882e2e9ca31/kolbot/mules/deleteme -------------------------------------------------------------------------------- /kolbot/pickit/Autoequip/READ.txt: -------------------------------------------------------------------------------- 1 | This is an example autoequip pickit. 2 | The feature is experimental and there will be ZERO support for it. 3 | To use it, ADD these lines to your character config. 4 | 5 | Config.AutoEquip = true; 6 | Config.PickitFiles.push("autoequip/sorceress.xpac.nip"); -------------------------------------------------------------------------------- /kolbot/pickit/Autoequip/sorceress.xpac.nip: -------------------------------------------------------------------------------- 1 | // weapon 2 | //[type] == wand && [quality] <= rare # [fcr] > 0 && [maxmana] > 0 # [tier] == 1 3 | //[type] == wand && [quality] <= rare # [fcr] == 20 && [maxmana] >= 20 # [tier] == 2 4 | //[name] == blade && [quality] == unique # [fcr] > 0 # [tier] == 3 5 | //[name] == burntwand && [quality] == unique # [fcr] > 0 # [tier] == 4 6 | //[name] == swirlingcrystal && [quality] == set # # [tier] == 5 7 | [name] == swirlingcrystal && [quality] == set # [skillcoldmastery] == 2 # [tier] == 99 8 | [flag] == runeword # [plusskillbattleorders] > 0 # [tier] == 99 9 | 10 | // armor 11 | [type] == armor && [quality] <= rare # [maxhp] > 0 # [tier] == 1 12 | [name] == studdedleather && [quality] == unique # # [tier] == 2 13 | [name] == russetarmor && [quality] == unique && [flag] != ethereal # # [tier] == 3 14 | //[name] == hellforgeplate && [quality] == set # # [tier] == 4 15 | [name] == serpentskinarmor && [quality] == unique && [flag] != ethereal # [fireresist] < 35 # [tier] == 5 16 | [name] == lacqueredplate && [quality] == set # # [tier] == 101 17 | 18 | // boots 19 | [type] == boots && [quality] <= rare # [lightresist] > 0 # [tier] == 1 20 | [name] == battleboots && [quality] == set # # [tier] == 3 21 | [name] == heavyboots && [quality] == set # # [tier] == 4 22 | [name] == battleboots && [quality] == unique # [itemmagicbonus] < 40 # [tier] == 5 23 | [name] == battleboots && [quality] == unique # [itemmagicbonus] >= 40 # [tier] == 101 24 | 25 | // gloves 26 | [type] == gloves && [quality] <= rare # [maxhp] > 0 # [tier] == 1 27 | [name] == lightgauntlets && [quality] == unique # # [tier] == 2 28 | [name] == gauntlets && [quality] == unique # # [tier] == 3 29 | 30 | // amulet 31 | [type] == amulet && [quality] <= rare # [maxhp] > 0 && [maxmana] > 0 # [tier] == 1 32 | [type] == amulet && [quality] == unique # [itemallskills] == 1 # [tier] == 2 33 | [type] == amulet && [quality] == set # [sorceressskills] == 2 # [tier] == 101 34 | 35 | // ring 36 | [type] == ring && [quality] <= rare # [maxhp] > 0 # [tier] == 1 37 | [type] == ring && [quality] <= rare # [maxhp] > 0 && [fcr] == 10 # [tier] == 2 38 | [type] == ring && [quality] <= rare # [maxhp] > 0 && [maxmana] > 0 && [fcr] == 10 # [tier] == 3 39 | [type] == ring && [quality] == unique # [itemallskills] == 1 # [tier] == 100 40 | 41 | // belt 42 | [type] == belt && [quality] <= rare # [maxhp] > 0 # [tier] == 1 43 | [type] == belt && [quality] <= rare # [maxhp] > 0 && [fireresist]+[lightresist]+[coldresist] >= 30 # [tier] == 2 44 | [name] == meshbelt && [quality] == set # # [tier] == 3 45 | [name] == meshbelt && [quality] == set # [itemmagicbonus] == 15 # [tier] == 4 46 | 47 | // helm 48 | [type] == helm && [quality] == rare # [maxhp] > 0 # [tier] == 1 49 | [type] == helm && [quality] == rare # [maxhp] > 0 && [fireresist]+[lightresist]+[coldresist] >= 30 # [tier] == 2 50 | [name] == warhat && [quality] == unique # # [tier] == 3 51 | [name] == deathmask && [quality] == set # # [tier] == 4 52 | 53 | // shield 54 | [type] == shield && [quality] <= rare # [fireresist]+[lightresist]+[coldresist] >= 30 # [tier] == 1 55 | [type] == shield && [quality] <= rare # [fireresist]+[lightresist]+[coldresist] >= 50 # [tier] == 2 56 | [name] == grimshield && [quality] == unique # # [tier] == 3 57 | [name] == roundshield && [quality] == unique # # [tier] == 4 58 | -------------------------------------------------------------------------------- /kolbot/pickit/Jewelery.nip: -------------------------------------------------------------------------------- 1 | [Type] == Ring && [Quality] == Unique # [ItemMagicBonus] >= 40 //Nagel 2 | [Type] == Ring && [Quality] == Unique # [ItemMaxManaPercent] >= 15 //SOJ 3 | [Type] == Ring && [Quality] == Unique # [MaxHP] >= 50 && [MagicDamageReduction] == 15 && [ItemAbsorbFirePercent] >= 8 //Perf Dwarf 4 | [Type] == Ring && [Quality] == Unique # [MaxHP] >= 35 && [MagicDamageReduction] >= 12 && [ItemAbsorbFirePercent] >= 4 //Dwarf 5 | [Type] == Ring && [Quality] == Unique # [Dexterity] >= 20 && [ToHit] >= 250 //RAVEN FROST PERFECT 6 | [Type] == Ring && [Quality] == Unique # [Dexterity] >= 15 && [ToHit] >= 150 //RAVEN FROST 7 | [Type] == Ring && [Quality] == Unique # [NormalDamageReduction] >= 7 //Natures peace 8 | [Type] == Ring && [Quality] == Unique # [ItemAbsorbLightPercent] >= 4 // Wisp 9 | [Type] == Ring && [Quality] == Unique # [ItemAbsorbLightPercent] >= 6 && [ItemMagicBonus] >= 12 // Perf Wisp 10 | [Type] == Ring && [Quality] == Unique # [LifeLeech] >= 5 && [ItemAllSkills] == 1 //BUL-KATHOS' WEDDING BAND PERFECT 11 | [Type] == Ring && [Quality] == Unique # [LifeLeech] >= 3 && [ItemAllSkills] == 1 //BUL-KATHOS' WEDDING BAND 12 | 13 | [Type] == Amulet && [Quality] == Unique # [LightResist] >= 35 //Perf Highlords 14 | [Type] == Amulet && [Quality] == Unique # [LightResist] >= 25 //Highlords 15 | [Type] == Amulet && [Quality] == Unique # [DefensiveAurasSkillTab] >= 1 //SERAPH'S HYMN 16 | [Type] == Amulet && [Quality] == Unique # [ColdResist] >= 25 //METALGRID 17 | [Type] == Amulet && [Quality] == Unique # [ItemAllSkills] == 2 && [FireResist] >= 30 //MARA'S KALEIDOSCOPE PERFECT 18 | [Type] == Amulet && [Quality] == Unique # [ItemAllSkills] == 2 && [FireResist] >= 20 //MARA'S KALEIDOSCOPE -------------------------------------------------------------------------------- /kolbot/pickit/Misc.nip: -------------------------------------------------------------------------------- 1 | //UTILITY 2 | [Type] == Gold # [Gold] >= 1000 3 | //[Name] == ScrollofTownPortal 4 | //[Name] == ScrollofIdentify 5 | 6 | //UBERS 7 | [Name] == KeyOfTerror 8 | [Name] == KeyOfHate 9 | [Name] == KeyOfDestruction 10 | [Name] == KeyOfTerror 11 | [Name] == KeyOfHate 12 | [Name] == KeyOfDestruction 13 | [name] == diablo'shorn 14 | [name] == mephisto'sbrain 15 | [name] == baal'seye 16 | 17 | //TOKENS 18 | [Name] == TwistedEssenceOfSuffering 19 | [Name] == ChargedEssenceOfHatred 20 | [Name] == BurningEssenceOfTerror 21 | [Name] == FesteringEssenceOfDestruction 22 | [Name] == TokenOfAbsolution 23 | 24 | //RUNES Unstacked (Probably not used in PD2 25 | //but doesn't hurt to keep them in 26 | [Name] == ElRune 27 | [Name] == EldRune 28 | [Name] == TirRune 29 | [Name] == NefRune 30 | [Name] == EthRune 31 | [Name] == IthRune 32 | [Name] == TalRune 33 | [Name] == RalRune 34 | [Name] == OrtRune 35 | [Name] == ThulRune 36 | [Name] == AmnRune 37 | [Name] == SolRune 38 | [Name] == ShaelRune 39 | [Name] == DolRune 40 | [Name] == HelRune 41 | [Name] == IoRune 42 | [Name] == LumRune 43 | [Name] == KoRune 44 | [Name] == FalRune 45 | [Name] == LemRune 46 | [Name] == PulRune 47 | [Name] == UmRune 48 | [Name] == MalRune 49 | [Name] == IstRune 50 | [Name] == GulRune 51 | [Name] == VexRune 52 | [Name] == OhmRune 53 | [Name] == LoRune 54 | [Name] == SurRune 55 | [Name] == BerRune 56 | [Name] == JahRune 57 | [Name] == ChamRune 58 | [Name] == ZodRune 59 | 60 | //RUNESTACKS 61 | [Name] == Elstack 62 | [Name] == Eldstack 63 | [Name] == Tirstack 64 | [Name] == Nefstack 65 | [Name] == Ethstack 66 | [Name] == Ithstack 67 | [Name] == Talstack 68 | [Name] == Ralstack 69 | [Name] == Ortstack 70 | [Name] == Thulstack 71 | [Name] == Amnstack 72 | [Name] == Solstack 73 | [Name] == Shaelstack 74 | [Name] == Dolstack 75 | [Name] == Helstack 76 | [Name] == Iostack 77 | [Name] == Lumstack 78 | [Name] == Kostack 79 | [Name] == Falstack 80 | [Name] == Lemstack 81 | [Name] == Pulstack 82 | [Name] == Umstack 83 | [Name] == Malstack 84 | [Name] == Iststack 85 | [Name] == Gulstack 86 | [Name] == Vexstack 87 | [Name] == Ohmstack 88 | [Name] == Lostack 89 | [Name] == Surstack 90 | [Name] == Berstack 91 | [Name] == Jahstack 92 | [Name] == Chamstack 93 | [Name] == Zodstack 94 | 95 | //GEMS 96 | //[Name] == ChippedAmethyst # # [MaxQuantity] == 1 97 | //[Name] == ChippedDiamond # # [MaxQuantity] == 1 98 | //[Name] == ChippedEmerald # # [MaxQuantity] == 1 99 | //[Name] == ChippedRuby # # [MaxQuantity] == 1 100 | //[Name] == ChippedSapphire # # [MaxQuantity] == 1 101 | //[Name] == ChippedSkull # # [MaxQuantity] == 1 102 | //[Name] == ChippedTopaz # # [MaxQuantity] == 1 103 | //[Name] == FlawedAmethyst # # [MaxQuantity] == 1 104 | //[Name] == FlawedDiamond # # [MaxQuantity] == 1 105 | //[Name] == FlawedEmerald # # [MaxQuantity] == 1 106 | //[Name] == FlawedRuby # # [MaxQuantity] == 1 107 | //[Name] == FlawedSapphire # # [MaxQuantity] == 1 108 | //[Name] == FlawedSkull # # [MaxQuantity] == 1 109 | //[Name] == FlawedTopaz # # [MaxQuantity] == 1 110 | //[Name] == Amethyst # # [MaxQuantity] == 2 111 | //[Name] == Diamond # # [MaxQuantity] == 1 112 | //[Name] == Emerald # # [MaxQuantity] == 1 113 | //[Name] == Ruby # # [MaxQuantity] == 2 114 | //[Name] == Skull # # [MaxQuantity] == 1 115 | //[Name] == Sapphire # # [MaxQuantity] == 2 116 | //[Name] == Topaz # # [MaxQuantity] == 1 117 | //[Name] == FlawlessAmethyst 118 | //[Name] == FlawlessDiamond 119 | //[Name] == FlawlessEmerald 120 | //[Name] == FlawlessRuby 121 | //[Name] == FlawlessSapphire 122 | //[Name] == FlawlessSkull 123 | //[Name] == FlawlessTopaz 124 | [Name] == PerfectAmethyst 125 | [Name] == PerfectDiamond 126 | [Name] == PerfectEmerald 127 | [Name] == PerfectRuby 128 | [Name] == PerfectSapphire 129 | [Name] == PerfectSkull 130 | [Name] == PerfectTopaz 131 | 132 | //GEMSTACKS 133 | [Name] == FlawlessAmethyststack 134 | [Name] == FlawlessDiamondstack 135 | [Name] == FlawlessEmeraldstack 136 | [Name] == FlawlessRubystack 137 | [Name] == FlawlessSapphirestack 138 | [Name] == FlawlessSkullstack 139 | [Name] == FlawlessTopazstack 140 | [Name] == PerfectAmethyststack 141 | [Name] == PerfectDiamondstack 142 | [Name] == PerfectEmeraldstack 143 | [Name] == PerfectRubystack 144 | [Name] == PerfectSapphirestack 145 | [Name] == PerfectSkullstack 146 | [Name] == PerfectTopazstack 147 | 148 | //POTIONS 149 | [Name] == SuperHealingPotion 150 | [Name] == SuperManaPotion 151 | [Name] == RejuvenationPotion 152 | [Name] == FullRejuvenationPotion 153 | 154 | //PD2 ITEMS 155 | [Name] == worldstoneshard 156 | [Name] == larzuk'spuzzlebox 157 | [Name] == visionofterror 158 | [Name] == puredemonicessence 159 | [Name] == blacksoulstone 160 | [Name] == primeevilsoul 161 | 162 | //MAPS 163 | [type] >= t1map && [type] <= t3map -------------------------------------------------------------------------------- /kolbot/pickit/bs.nip: -------------------------------------------------------------------------------- 1 | [Name] == greaterhealingpotion 2 | [Name] == superhealingpotion 3 | 4 | [Name] == greatermanapotion 5 | [Name] == supermanapotion 6 | 7 | [Name] == rejuvenationpotion 8 | [Name] == fullrejuvenationpotion 9 | 10 | 11 | [quality] == unique && [class] == normal 12 | [quality] == set && [class] == normal 13 | [quality] == unique && [class] == exceptional 14 | [quality] == set && [class] == exceptional 15 | [quality] == unique && [class] == elite 16 | [quality] == set && [class] == elite 17 | 18 | [Type] == Jewel && [Quality] == Rare 19 | //[Type] == Jewel && [Quality] == magic 20 | [Type] == Ring && [Quality] == rare 21 | [Type] == Amulet && [Quality] == rare 22 | 23 | [Type] == Ring && [Quality] == set 24 | [Type] == Amulet && [Quality] == set 25 | [Type] == Shield && [Quality] == set 26 | [Type] == Gloves && [Quality] == set 27 | [Type] == Boots && [Quality] == set 28 | [Type] == Belt && [Quality] == set 29 | [Type] == Helm && [Quality] == set 30 | [Type] == Circlet && [Quality] == set 31 | [Type] == Armor && [Quality] == set 32 | 33 | [Type] == Sword && [Quality] == set 34 | [Type] == Mace && [Quality] == set 35 | [Type] == Scepter && [Quality] == set 36 | [Type] == Knife && [Quality] == set 37 | [Type] == Axe && [Quality] == set 38 | 39 | [Type] == Jewel && [Quality] == unique 40 | 41 | [Type] == Ring && [Quality] == unique 42 | [Type] == Amulet && [Quality] == unique 43 | [Type] == Shield && [Quality] == unique 44 | [Type] == Gloves && [Quality] == unique 45 | [Type] == Boots && [Quality] == unique 46 | [Type] == Belt && [Quality] == unique 47 | [Type] == Helm && [Quality] == unique 48 | [Type] == Circlet && [Quality] == unique 49 | [Type] == Armor && [Quality] == unique 50 | 51 | [Type] == Sword && [Quality] == unique 52 | [Type] == Mace && [Quality] == unique 53 | [Type] == Scepter && [Quality] == unique 54 | [Type] == Knife && [Quality] == unique 55 | [Type] == Axe && [Quality] == unique -------------------------------------------------------------------------------- /kolbot/pickit/follower.nip: -------------------------------------------------------------------------------- 1 | [name] == gold 2 | [Name] == minorhealingpotion 3 | [Name] == lighthealingpotion 4 | [Name] == healingpotion 5 | [Name] == greaterhealingpotion 6 | [Name] == superhealingpotion 7 | -------------------------------------------------------------------------------- /kolbot/pickit/gold.nip: -------------------------------------------------------------------------------- 1 | [name] == gold # [gold] >= 500 -------------------------------------------------------------------------------- /kolbot/pickit/keyorg.nip: -------------------------------------------------------------------------------- 1 | [name] == diablo'shorn || [name] == mephisto'sbrain || [name] == baal'seye 2 | [name] == keyofhate # # [maxquantity] == 5 3 | [name] == keyofterror # # [maxquantity] == 5 4 | [name] == keyofdestruction # # [maxquantity] == 5 5 | [name] == largecharm && [quality] == unique -------------------------------------------------------------------------------- /kolbot/pickit/pots.nip: -------------------------------------------------------------------------------- 1 | [name] == greaterhealingpotion 2 | [name] == superhealingpotion 3 | [name] == greatermanapotion 4 | [name] == supermanapotion 5 | [name] == rejuvenationpotion 6 | [name] == fullrejuvenationpotion 7 | [name] == gold # [gold] >= 500 -------------------------------------------------------------------------------- /kolbot/sdk/Shrines.txt: -------------------------------------------------------------------------------- 1 | 0 null 2 | 1 refilling 3 | 2 health 4 | 3 mana 5 | 4 health exchange 6 | 5 mana exchange 7 | 6 armor 8 | 7 combat 9 | 8 resist fire 10 | 9 resist cold 11 | 10 resist lightning 12 | 11 resist poison 13 | 12 skill 14 | 13 mana recharge 15 | 14 stamina 16 | 15 experience 17 | 16 enirhs 18 | 17 portal 19 | 18 gem 20 | 19 fire 21 | 20 monster 22 | 21 exploding 23 | 22 poison -------------------------------------------------------------------------------- /kolbot/sdk/SuperUniques.txt: -------------------------------------------------------------------------------- 1 | Name hcIdx 2 | Bishibosh 0 3 | Bonebreak 1 4 | Coldcrow 2 5 | Rakanishu 3 6 | Treehead WoodFist 4 7 | Griswold 5 8 | The Countess 6 9 | Pitspawn Fouldog 7 10 | Flamespike the Crawler 8 11 | Boneash 9 12 | Radament 10 13 | Bloodwitch the Wild 11 14 | Fangskin 12 15 | Beetleburst 13 16 | Leatherarm 14 17 | Coldworm the Burrower 15 18 | Fire Eye 16 19 | Dark Elder 17 20 | The Summoner 18 21 | Ancient Kaa the Soulless 19 22 | The Smith 20 23 | Web Mage the Burning 21 24 | Witch Doctor Endugu 22 25 | Stormtree 23 26 | Sarina the Battlemaid 24 27 | Icehawk Riftwing 25 28 | Ismail Vilehand 26 29 | Geleb Flamefinger 27 30 | Bremm Sparkfist 28 31 | Toorc Icefist 29 32 | Wyand Voidfinger 30 33 | Maffer Dragonhand 31 34 | Winged Death 32 35 | The Tormentor 33 36 | Taintbreeder 34 37 | Riftwraith the Cannibal 35 38 | Infector of Souls 36 39 | Lord De Seis 37 40 | Grand Vizier of Chaos 38 41 | The Cow King 39 42 | Corpsefire 40 43 | The Feature Creep 41 44 | 45 | Siege Boss 42 46 | Ancient Barbarian 1 43 47 | Ancient Barbarian 2 44 48 | Ancient Barbarian 3 45 49 | Axe Dweller 46 50 | Bonesaw Breaker 47 51 | Dac Farren 48 52 | Megaflow Rectifier 49 53 | Eyeback Unleashed 50 54 | Threash Socket 51 55 | Pindleskin 52 56 | Snapchip Shatter 53 57 | Anodized Elite 54 58 | Vinvear Molech 55 59 | Sharp Tooth Sayer 56 60 | Magma Torquer 57 61 | Blaze Ripper 58 62 | Frozenstein 59 63 | Nihlathak 60 64 | Baal Subject 1 61 65 | Baal Subject 2 62 66 | Baal Subject 3 63 67 | Baal Subject 4 64 68 | Baal Subject 5 65 69 | -------------------------------------------------------------------------------- /kolbot/sdk/Unit.d.ts: -------------------------------------------------------------------------------- 1 | /************************************* 2 | * Unit description * 3 | * Needs expansion * 4 | *************************************/ 5 | type ItemType = 4; 6 | declare class Item extends Unit { 7 | public type: ItemType; 8 | getFlags() :number; 9 | getFlag(flag: number) :boolean; 10 | shop():boolean; 11 | getItemCost() :number; 12 | } 13 | 14 | type UnitType = 0 | 1 | 2 | 3 | 4 | 5; 15 | type MonsterType = 1; 16 | 17 | declare class Monster extends Unit{ 18 | public type: MonsterType; 19 | getEnchant(type: number):boolean; 20 | } 21 | 22 | declare class Merc extends Monster{ 23 | 24 | } 25 | declare class Unit { 26 | type : UnitType; 27 | getNext() : Unit|false; 28 | cancel() : void; 29 | repair() : boolean; 30 | useMenu() : boolean; 31 | interact() : boolean; 32 | interact(area: number) : boolean; 33 | getItem(classId?: number,mode?: number, unitId?: number) : Unit|false; 34 | getItem(name?: string,mode?: number, unitId?: number) : Unit|false; 35 | getItems() : Item[]|false; 36 | getMerc() : Merc ; 37 | getMercHP() : number| false; 38 | 39 | // me.getSkill(0-4); // 40 | getSkill(type: 0|1|2|3|4) : number; 41 | getSkill(skillId: number,type: 0 | 1, item?: Item) : number; 42 | 43 | getParent() : Unit|false ; 44 | overhead(msg: string) : void ; 45 | 46 | getStat(index: number,subid?: number):number[]|number|false ; 47 | getState(index: number,subid?: number):number[]|number|false ; 48 | 49 | setSkill() ; 50 | move(x: number, y: number) ; 51 | getQuest(quest:number, subid: number) ; 52 | getMinionCount() : number ; 53 | } 54 | 55 | declare class me { 56 | revive() : void; 57 | getRepairCost() :number; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /kolbot/sdk/areas.txt: -------------------------------------------------------------------------------- 1 | 0 = None 2 | 1 = Rogue Encampment 3 | 2 = Blood Moor 4 | 3 = Cold Plains 5 | 4 = Stony Field 6 | 5 = Dark Wood 7 | 6 = Black Marsh 8 | 7 = Tamoe Highland 9 | 8 = Den Of Evil 10 | 9 = Cave Level 1 11 | 10 = Underground Passage Level 1 12 | 11 = Hole Level 1 13 | 12 = Pit Level 1 14 | 13 = Cave Level 2 15 | 14 = Underground Passage Level 2 16 | 15 = Hole Level 2 17 | 16 = Pit Level 2 18 | 17 = Burial Grounds 19 | 18 = Crypt 20 | 19 = Mausoleum 21 | 20 = Forgotten Tower 22 | 21 = Tower Cellar Level 1 23 | 22 = Tower Cellar Level 2 24 | 23 = Tower Cellar Level 3 25 | 24 = Tower Cellar Level 4 26 | 25 = Tower Cellar Level 5 27 | 26 = Monastery Gate 28 | 27 = Outer Cloister 29 | 28 = Barracks 30 | 29 = Jail Level 1 31 | 30 = Jail Level 2 32 | 31 = Jail Level 3 33 | 32 = Inner Cloister 34 | 33 = Cathedral 35 | 34 = Catacombs Level 1 36 | 35 = Catacombs Level 2 37 | 36 = Catacombs Level 3 38 | 37 = Catacombs Level 4 39 | 38 = Tristram 40 | 39 = Moo Moo Farm 41 | 40 = Lut Gholein 42 | 41 = Rocky Waste 43 | 42 = Dry Hills 44 | 43 = Far Oasis 45 | 44 = Lost City 46 | 45 = Valley Of Snakes 47 | 46 = Canyon Of The Magi 48 | 47 = A2 Sewers Level 1 49 | 48 = A2 Sewers Level 2 50 | 49 = A2 Sewers Level 3 51 | 50 = Harem Level 1 52 | 51 = Harem Level 2 53 | 52 = Palace Cellar Level 1 54 | 53 = Palace Cellar Level 2 55 | 54 = Palace Cellar Level 3 56 | 55 = Stony Tomb Level 1 57 | 56 = Halls Of The Dead Level 1 58 | 57 = Halls Of The Dead Level 2 59 | 58 = Claw Viper Temple Level 1 60 | 59 = Stony Tomb Level 2 61 | 60 = Halls Of The Dead Level 3 62 | 61 = Claw Viper Temple Level 2 63 | 62 = Maggot Lair Level 1 64 | 63 = Maggot Lair Level 2 65 | 64 = Maggot Lair Level 3 66 | 65 = Ancient Tunnels 67 | 66 = Tal Rashas Tomb #1 68 | 67 = Tal Rashas Tomb #2 69 | 68 = Tal Rashas Tomb #3 70 | 69 = Tal Rashas Tomb #4 71 | 70 = Tal Rashas Tomb #5 72 | 71 = Tal Rashas Tomb #6 73 | 72 = Tal Rashas Tomb #7 74 | 73 = Duriels Lair 75 | 74 = Arcane Sanctuary 76 | 75 = Kurast Docktown 77 | 76 = Spider Forest 78 | 77 = Great Marsh 79 | 78 = Flayer Jungle 80 | 79 = Lower Kurast 81 | 80 = Kurast Bazaar 82 | 81 = Upper Kurast 83 | 82 = Kurast Causeway 84 | 83 = Travincal 85 | 84 = Spider Cave 86 | 85 = Spider Cavern 87 | 86 = Swampy Pit Level 1 88 | 87 = Swampy Pit Level 2 89 | 88 = Flayer Dungeon Level 1 90 | 89 = Flayer Dungeon Level 2 91 | 90 = Swampy Pit Level 3 92 | 91 = Flayer Dungeon Level 3 93 | 92 = A3 Sewers Level 1 94 | 93 = A3 Sewers Level 2 95 | 94 = Ruined Temple 96 | 95 = Disused Fane 97 | 96 = Forgotten Reliquary 98 | 97 = Forgotten Temple 99 | 98 = Ruined Fane 100 | 99 = Disused Reliquary 101 | 100 = Durance Of Hate Level 1 102 | 101 = Durance Of Hate Level 2 103 | 102 = Durance Of Hate Level 3 104 | 103 = The Pandemonium Fortress 105 | 104 = Outer Steppes 106 | 105 = Plains Of Despair 107 | 106 = City Of The Damned 108 | 107 = River Of Flame 109 | 108 = Chaos Sanctuary 110 | 109 = Harrogath 111 | 110 = Bloody Foothills 112 | 111 = Frigid Highlands 113 | 112 = Arreat Plateau 114 | 113 = Crystalized Passage 115 | 114 = Frozen River 116 | 115 = Glacial Trail 117 | 116 = Drifter Cavern 118 | 117 = Frozen Tundra 119 | 118 = Ancient's Way 120 | 119 = Icy Cellar 121 | 120 = Arreat Summit 122 | 121 = Nihlathaks Temple 123 | 122 = Halls Of Anguish 124 | 123 = Halls Of Pain 125 | 124 = Halls Of Vaught 126 | 125 = Abaddon 127 | 126 = Pit Of Acheron 128 | 127 = Infernal Pit 129 | 128 = The Worldstone Keep Level 1 130 | 129 = The Worldstone Keep Level 2 131 | 130 = The Worldstone Keep Level 3 132 | 131 = Throne Of Destruction 133 | 132 = The Worldstone Chamber 134 | 133 = Matron's Den 135 | 134 = Fogotten Sands 136 | 135 = Furnace of Pain 137 | 136 = Tristram 138 | -------------------------------------------------------------------------------- /kolbot/sdk/basestats.txt: -------------------------------------------------------------------------------- 1 | 0 AlternateGfx (this is actually a 3-4 letter word) 2 | 1 WeaponClass (this is actually a 3-4 letter word) 3 | 2 TwoHandedWeaponClass (this is actually a 3-4 letter word) 4 | 3 5 | 4 MinAC 6 | 5 MaxAC 7 | 6 BaseGambleCost 8 | 7 BaseAttackSpeed 9 | 8 DurabilityWarning (ItemRarity in weapons?) 10 | 9 BaseCost 11 | 10 12 | 11 13 | 12 14 | 13 15 | 14 (always FFFFFFFF, probably just a terminator between the DWORDs and single BYTEs) 16 | 15 Version (64 for xpac, 0 for norm) 17 | 16 18 | 17 19 | 18 20 | 19 21 | 20 22 | 21 ItemRarity 23 | 22 BaseItemLevel 24 | 23 MinDmg (also applies to shields dmg) 25 | 24 MaxDmg (also applies to shields dmg) 26 | 25 27 | 26 28 | 27 MinTwoHandDmg 29 | 28 MaxTwoHandDmg 30 | 29 AttackRange 31 | 30 StrBonus 32 | 31 DexBonus 33 | 32 StrReq 34 | 33 DexReq 35 | 34 36 | 35 SizeX 37 | 36 SizeY 38 | 37 BaseBlock 39 | 38 BaseDurability 40 | 39 41 | 40 42 | 41 Component 43 | 42 44 | 43 45 | 44 46 | 45 47 | 46 48 | 47 49 | 48 TwoHanded 50 | 49 51 | 50 Type 52 | 51 (255 in weapons?) 53 | 52 54 | 53 SoundId 55 | 54 56 | 55 Quest 57 | 56 58 | 57 TransTable 59 | 58 60 | 59 LightRadius 61 | 60 62 | 61 63 | 62 64 | 63 65 | 64 66 | 65 DurationWarningWep 67 | 66 68 | 67 69 | 68 MaxSockets 70 | 69 71 | 70 72 | 71 73 | 72 74 | 73 75 | 74 76 | 75 BaseLevelReq 77 | 76 MagicLvl 78 | 77 Transform 79 | 78 InvTrans 80 | 79 81 | 82 | .. 83 | 84 | 167 Last few of these are probably the NPC sell values (all seem to be 255, which is what it is in the mpq) 85 | 86 | 87 | Initial compilation done by njaguar 88 | 89 | Feel free to update this as you discover (definitively) new values. Please post updates (just the new fields, or changes) 90 | to the forums. 91 | -------------------------------------------------------------------------------- /kolbot/sdk/bodylocations.txt: -------------------------------------------------------------------------------- 1 | #define BODYLOC_NONE 0 2 | #define BODYLOC_HEAD 1 3 | #define BODYLOC_NECK 2 4 | #define BODYLOC_TORSO 3 5 | #define BODYLOC_RIGHT_ARM 4 6 | #define BODYLOC_LEFT_ARM 5 7 | #define BODYLOC_RIGHT_RING 6 8 | #define BODYLOC_LEFT_RING 7 9 | #define BODYLOC_BELT 8 10 | #define BODYLOC_FEET 9 11 | #define BODYLOC_GLOVES 10 12 | #define BODYLOC_RIGHT_ARM_SECONDARY 11 13 | #define BODYLOC_LEFT_ARM_SECONDARY 12 14 | -------------------------------------------------------------------------------- /kolbot/sdk/commandRef.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Borega/pd2bs-scripts/fb578879d11c7726039f34325d727882e2e9ca31/kolbot/sdk/commandRef.htm -------------------------------------------------------------------------------- /kolbot/sdk/data/global/excel/states.txt: -------------------------------------------------------------------------------- 1 | state id 2 | none 0 3 | freeze 1 4 | poison 2 5 | resistfire 3 6 | resistcold 4 7 | resistlight 5 8 | resistmagic 6 9 | playerbody 7 10 | resistall 8 11 | amplifydamage 9 12 | frozenarmor 10 13 | cold 11 14 | inferno 12 15 | blaze 13 16 | bonearmor 14 17 | concentrate 15 18 | enchant 16 19 | innersight 17 20 | skill_move 18 21 | weaken 19 22 | chillingarmor 20 23 | stunned 21 24 | spiderlay 22 25 | dimvision 23 26 | slowed 24 27 | fetishaura 25 28 | shout 26 29 | taunt 27 30 | conviction 28 31 | convicted 29 32 | energyshield 30 33 | venomclaws 31 34 | battleorders 32 35 | might 33 36 | prayer 34 37 | holyfire 35 38 | thorns 36 39 | defiance 37 40 | thunderstorm 38 41 | lightningbolt 39 42 | blessedaim 40 43 | stamina 41 44 | concentration 42 45 | holywind 43 46 | holywindcold 44 47 | cleansing 45 48 | holyshock 46 49 | sanctuary 47 50 | meditation 48 51 | fanaticism 49 52 | redemption 50 53 | battlecommand 51 54 | preventheal 52 55 | conversion 53 56 | uninterruptable 54 57 | ironmaiden 55 58 | terror 56 59 | attract 57 60 | lifetap 58 61 | confuse 59 62 | decrepify 60 63 | lowerresist 61 64 | openwounds 62 65 | dopplezon 63 66 | criticalstrike 64 67 | dodge 65 68 | avoid 66 69 | penetrate 67 70 | evade 68 71 | pierce 69 72 | warmth 70 73 | firemastery 71 74 | lightningmastery 72 75 | coldmastery 73 76 | swordmastery 74 77 | axemastery 75 78 | macemastery 76 79 | polearmmastery 77 80 | throwingmastery 78 81 | spearmastery 79 82 | increasedstamina 80 83 | ironskin 81 84 | increasedspeed 82 85 | naturalresistance 83 86 | fingermagecurse 84 87 | nomanaregen 85 88 | justhit 86 89 | slowmissiles 87 90 | shiverarmor 88 91 | battlecry 89 92 | blue 90 93 | red 91 94 | death_delay 92 95 | valkyrie 93 96 | frenzy 94 97 | berserk 95 98 | revive 96 99 | skel_mastery 97 100 | sourceunit 98 101 | redeemed 99 102 | healthpot 100 103 | holyshield 101 104 | just_portaled 102 105 | monfrenzy 103 106 | corpse_nodraw 104 107 | alignment 105 108 | manapot 106 109 | shatter 107 110 | sync_warped 108 111 | conversion_save 109 112 | pregnant 110 113 | golem_mastery 111 114 | rabies 112 115 | defense_curse 113 116 | blood_mana 114 117 | burning 115 118 | dragonflight 116 119 | maul 117 120 | corpse_noselect 118 121 | shadowwarrior 119 122 | feralrage 120 123 | skilldelay 121 124 | progressive_damage 122 125 | progressive_steal 123 126 | progressive_other 124 127 | progressive_fire 125 128 | progressive_cold 126 129 | progressive_lightning 127 130 | shrine_armor 128 131 | shrine_combat 129 132 | shrine_resist_lightning 130 133 | shrine_resist_fire 131 134 | shrine_resist_cold 132 135 | shrine_resist_poison 133 136 | shrine_skill 134 137 | shrine_mana_regen 135 138 | shrine_stamina 136 139 | shrine_experience 137 140 | fenris_rage 138 141 | wolf 139 142 | bear 140 143 | bloodlust 141 144 | changeclass 142 145 | attached 143 146 | hurricane 144 147 | armageddon 145 148 | invis 146 149 | barbs 147 150 | wolverine 148 151 | oaksage 149 152 | vine_beast 150 153 | cyclonearmor 151 154 | clawmastery 152 155 | cloak_of_shadows 153 156 | recycled 154 157 | weaponblock 155 158 | cloaked 156 159 | quickness 157 160 | bladeshield 158 161 | fade 159 162 | summonresist 160 163 | oaksagecontrol 161 164 | wolverinecontrol 162 165 | barbscontrol 163 166 | debugcontrol 164 167 | itemset1 165 168 | itemset2 166 169 | itemset3 167 170 | itemset4 168 171 | itemset5 169 172 | itemset6 170 173 | runeword 171 174 | restinpeace 172 175 | corpseexp 173 176 | whirlwind 174 177 | fullsetgeneric 175 178 | monsterset 176 179 | delerium 177 180 | antidote 178 181 | thawing 179 182 | staminapot 180 183 | passive_resistfire 181 184 | passive_resistcold 182 185 | passive_resistltng 183 186 | -------------------------------------------------------------------------------- /kolbot/sdk/enchants.txt: -------------------------------------------------------------------------------- 1 | {"Extra Strong Desc", 0, &aszEnchantDescs[5], 0, 1}, 2 | {"Extra Fast Desc", 0, &aszEnchantDescs[6], 0, 1}, 3 | {"Cursed Desc", 0, &aszEnchantDescs[7], 0, 1}, 4 | {"Magic Resistant Desc", 0, &aszEnchantDescs[8], 0, 1}, 5 | {"Fire Enchanted Desc", 0, &aszEnchantDescs[9], 0, 1}, 6 | {"Champion Desc", 0, &aszEnchantDescs[16], 0, 1}, 7 | {"Lightning Enchanted Desc", 0, &aszEnchantDescs[17], 0, 1}, 8 | {"Cold Enchanted Desc", 0, &aszEnchantDescs[18], 0, 1}, 9 | {"Thief Desc", 0, &aszEnchantDescs[24], 0, 1}, 10 | {"Mana Burn Desc", 0, &aszEnchantDescs[25], 0, 1}, 11 | {"Teleportation Desc", 0, &aszEnchantDescs[26], 0, 1}, 12 | {"Spectral Hit Desc", 0, &aszEnchantDescs[27], 0, 1}, 13 | {"Stone Skin Desc", 0, &aszEnchantDescs[28], 0, 1}, 14 | {"Multiple Shots Desc", 0, &aszEnchantDescs[29], 0, 1}, 15 | {"Ghostly Desc", 0, &aszEnchantDescs[36], 0, 1}, 16 | {"Fanatic Desc", 0, &aszEnchantDescs[37], 0, 1}, 17 | {"Possessed Desc", 0, &aszEnchantDescs[38], 0, 1}, 18 | {"Berserker Desc", 0, &aszEnchantDescs[39], 0, 1}, 19 | -------------------------------------------------------------------------------- /kolbot/sdk/getskillinfo.txt: -------------------------------------------------------------------------------- 1 | Usage: 2 | returnvar = getSkillInfo([SkillID or SkillName], index); 3 | 4 | 0 Id 5 | 1 Name 6 | 2 ClassID 7 | 3 Monster 8 | 4 Enhanceable 9 | 5 CostMult 10 | 6 CostAdd 11 | 7 ClassReq 12 | 8 AttackRank 13 | 9 ItemClass1 String 14 | 10 ItemClass2 String 15 | 11 ItemClass3 String 16 | 12 ItemClass4 String 17 | 13 ItemClass5 String 18 | 14 ItemClass6 String 19 | 15 Anim String 20 | 16 MonAnim String 21 | 17 AnimID 22 | 18 MonAnimID 23 | 19 SeqNum 24 | 20 Durability 25 | 21 Shiver 26 | 22 unused 27 | 23 UseAttackRate 28 | 24 LineOfSight 29 | 25 ItemEffect 30 | 26 TargetableOnly 31 | 27 SearchEnemyXY 32 | 28 SearchMonsterNear 33 | 29 SelectDead 34 | 30 SearchOpenXY 35 | 31 TargetPet 36 | 32 TargetAlly 37 | 33 Range String 38 | 34 RangeID 39 | 35 AttackNoMana 40 | 36 ReqLevel 41 | 37 ReqStr 42 | 38 ReqDex 43 | 39 ReqInt 44 | 40 ReqVit 45 | 41 ReqSkillId1 46 | 42 ReqSkillId2 47 | 43 ReqSkillId3 48 | 44 CasterState 49 | 45 unknown, always -1 50 | 46 IsAura 51 | 47 pReqSkill1 ptr 52 | 48 pReqSkill2 ptr 53 | 49 pReqSkill3 ptr 54 | 50 State1 55 | 51 State2 56 | 52 State3 57 | 53 Delay 58 | 54 SkillPage 59 | 55 SkillRow 60 | 56 SkillColumn 61 | 57 IconCell 62 | 58 LeftSkill 63 | 59 ManaShift 64 | 60 Mana 65 | 61 LvlMana 66 | 62 Interrupt 67 | 63 InTown 68 | 64 Periodic 69 | 65 Finishing 70 | 66 Passive 71 | 67 Param1 72 | 68 Param2 73 | 69 Param3 74 | 70 Param4 75 | 71 Param5 76 | 72 Param6 77 | 73 InGame 78 | 74 Open 79 | 75 Beta 80 | 76 unknown 81 | 77 unknown 82 | 78 unused 83 | 79 ToHit 84 | 80 LevToHit 85 | 81 HitShift 86 | 82 SrcDam 87 | 83 unused 88 | 84 unused 89 | 85 MinDam 90 | 86 MaxDam 91 | 87 LevDam1 92 | 88 LevDam2 93 | 89 LevDam3 94 | 90 EType 95 | 91 EMin 96 | 92 EMax 97 | 93 ELev1 98 | 94 ELev2 99 | 95 ELev3 100 | 96 ELen 101 | 97 ELevLen1 102 | 98 ELevLen2 103 | 99 ELevLen3 104 | 100 Proper Skill Name (Locale based) 105 | 101 Item Description (Locale based) 106 | 107 | -------------------------------------------------------------------------------- /kolbot/sdk/itemflags.txt: -------------------------------------------------------------------------------- 1 | Item Flags, pass the 0x hex code to the getFlag(), eg; flag = getFlag(0x400000); 2 | 3 | 0x4000000 isRuneword set if it is a runeword (note that 'ith' qualifies ;) 4 | 0x1000000 isNamed has a custom name "Player's item" 5 | 0x800000 ? was set for all items tested (tested in inv, stash, store) 6 | 0x400000 isEthereal 0 if not ethereal 7 | 0x200000 isRuneOrPot rune or potion, also set for mephisto's soulstone 8 | 0x20000 isStartItem an item that a new character starts with (like javelin and buckler, and the minor healings at the start) 9 | 0x10000 isEar a player ear 10 | 0x4000 isNotInSocket 0 if in socket, 0 if in belt, 0 if equipped or equipped by merc, 0 for gems/charms/.. 11 | 0x2000 isInStore in trade or gamble screen 12 | 0x800 isSocketed the item has sockets (they can be full or empty) 13 | 0x400 isRejuv only seen set for full rejuvs for now 14 | 0x100 isBroken just a bet, but i'm pretty sure it's correct 15 | 0x80 isSwitchOut a weapon switch command was performed, and this item is no longer being used 16 | 0x40 isSwitchIn a weapon switch command was performed, and this item is now being used 17 | 0x10 isIdentified 0 if unid 18 | 0x8 isInSocket 8 if in socket, valid for rune and jewels, not gems 19 | 0x1 isEquipped player or merc is wearing the item (don't trust too much, especially when bit 9 is set) 20 | 21 | **thanks to bluemind for testing and creating this wonderful list! -------------------------------------------------------------------------------- /kolbot/sdk/miscscreenmodes.txt: -------------------------------------------------------------------------------- 1 | miscscreenmodes.txt: 2 | 3 | 1 npc trade open 4 | 2 buy cursor 5 | 3 sell cursor 6 | 4 repair cursor 7 | 5 sell/buy confirm 8 | 10 trade confirm 9 | 11 trade screen 10 | 12 Stash Open 11 | -------------------------------------------------------------------------------- /kolbot/sdk/modes.txt: -------------------------------------------------------------------------------- 1 | // ///////////////////////////////////////////////////////////////////////// 2 | // ///////////////////////////////////////////////////////////////////////// 3 | // Mode Flag To Mode List by TDW 4 | // ///////////////////////////////////////////////////////////////////////// 5 | Player Mode Flags: 6 | 0x00000001 = 0 = Player death = Player death 7 | 0x00000002 = 1 = Player standing outside town = Player standing outside town 8 | 0x00000004 = 2 = Player walking = Player walking 9 | 0x00000008 = 3 = Player running = Player running 10 | 0x00000010 = 4 = Player getting hit = Player getting hit 11 | 0x00000020 = 5 = Player standing in town = Player standing in town 12 | 0x00000040 = 6 = Player walking in town = Player walking in town 13 | 0x00000080 = 7 = Player attacking 1 = Player attacking 1 14 | 0x00000100 = 8 = Player attacking 2 = Player attacking 2 15 | 0x00000200 = 9 = Player blocking = Player blocking 16 | 0x00000400 = 10 = Player casting spell skill = Player casting spell skill 17 | 0x00000800 = 11 = Player throwing an item = Player throwing an item 18 | 0x00001000 = 12 = Player kicking = Player kicking 19 | 0x00002000 = 13 = Player using skill 1 = Player using skill 1 20 | 0x00004000 = 14 = Player using skill 2 = Player using skill 2 21 | 0x00008000 = 15 = Player using skill 3 = Player using skill 3 22 | 0x00010000 = 16 = Player using skill 4 = Player using skill 4 23 | 0x00020000 = 17 = Player dead = Player dead 24 | 0x00040000 = 18 = Player sequence = Player sequence 25 | 0x00080000 = 19 = Player being knocked back = Player being knocked back 26 | NPC Mode Flags: 27 | 0x00000001 = 0 = NPC death = NPC death 28 | 0x00000002 = 1 = NPC standing still = NPC standing still 29 | 0x00000004 = 2 = NPC walking = NPC walking 30 | 0x00000008 = 3 = NPC getting hit = NPC getting hit 31 | 0x00000010 = 4 = NPC attacking 1 = NPC attacking 1 32 | 0x00000020 = 5 = NPC attacking 2 = NPC attacking 2 33 | 0x00000040 = 6 = NPC blocking = NPC blocking 34 | 0x00000080 = 7 = NPC casting spell skill = NPC casting spell skill 35 | 0x00000100 = 8 = NPC using skill 1 = NPC using skill 1 36 | 0x00000200 = 9 = NPC using skill 2 = NPC using skill 2 37 | 0x00000400 = 10 = NPC using skill 3 = NPC using skill 3 38 | 0x00000800 = 11 = NPC using skill 4 = NPC using skill 4 39 | 0x00001000 = 12 = NPC dead = NPC dead 40 | 0x00002000 = 13 = NPC being knocked back = NPC being knocked back 41 | 0x00004000 = 14 = NPC sequence = NPC sequence 42 | 0x00008000 = 15 = NPC running = NPC running 43 | Object Mode Flags: 44 | 0x00000001 = 0 = Object idle = Object idle 45 | 0x00000002 = 1 = Object operating = Object operating 46 | 0x00000004 = 2 = Object opened = Object opened 47 | 0x00000008 = 3 = Object special 1 = Object special 1 48 | 0x00000010 = 4 = Object special 2 = Object special 2 49 | 0x00000020 = 5 = Object special 3 = Object special 3 50 | 0x00000040 = 6 = Object special 4 = Object special 4 51 | 0x00000080 = 7 = Object special 5 = Object special 5 52 | Item Mode Flags: 53 | 0x00000001 = 0 = Item inven stash cube store = Item inven stash cube store 54 | 0x00000002 = 1 = Item equipped self or merc = Item equipped self or merc 55 | 0x00000004 = 2 = Item in belt = Item in belt 56 | 0x00000008 = 3 = Item on ground = Item on ground 57 | 0x00000010 = 4 = Item on cursor = Item on cursor 58 | 0x00000020 = 5 = Item being dropped = Item being dropped 59 | 0x00000040 = 6 = Item socketed in item = Item socketed in item 60 | // ///////////////////////////////////////////////////////////////////////// 61 | -------------------------------------------------------------------------------- /kolbot/sdk/npcmenuid.txt: -------------------------------------------------------------------------------- 1 | NPC Menu List: 2 | 3 | 0x0D35 Talk 4 | 0x0D44 Trade 5 | 0x0D06 Trade/Repair 6 | 0x0FB1 Imbue 7 | 0x0D46 Gamble 8 | 0x0D45 Hire 9 | 0x0D36 Go East 10 | 0x0D37 Go West 11 | 0x0FB4 Identify Items 12 | 0x0D38 Sail East 13 | 0x0D39 Sail West 14 | 0x1507 Ressurect Merc 15 | 0x58DC Add Sockets 16 | 0x58DD Personalize 17 | 0x58D2 Travel to Harrogath 18 | 19 | -------------------------------------------------------------------------------- /kolbot/sdk/quests.txt: -------------------------------------------------------------------------------- 1 | Info from Mattir: 2 | 3 | int = me.getQuest( int QuestNumber , int QuestCompletion ); 4 | 5 | QuestNumber 6 | 0 = Spoke to Warriv 7 | 1 = Den of Evil 8 | 2 = Sisters' Burial Grounds 9 | 4 = The Search for Cain 10 | 5 = Forgotten Tower 11 | 3 = Tools of the Trade 12 | 6 = Sisters to the Slaughter 13 | 7 = Able to go to Act II 14 | 8 = Spoke to Jerhyn 15 | 9 = Radament's Lair 16 | 10 = The Horadric Staff 17 | 11 = The Tainted Sun 18 | 12 = The Arcane Sanctuary 19 | 13 = The Summoner 20 | 14 = The Seven Tombs 21 | 15 = Able to go to Act III 22 | 16 = Spoke to Hratli 23 | 20 = The Golden Bird 24 | 19 = Blade of the Old Religion 25 | 18 = Khalim's Will 26 | 17 = Lam Esen's Tome 27 | 21 = The Blackened Temple 28 | 22 = The Guardian 29 | 23 = Able to go to Act IV 30 | 24 = Spoke to Tyrael 31 | 25 = The Fallen Angel 32 | 27 = Hell's Forge 33 | 26 = Terror's End 34 | 28 = Able to go to Act V 35 | 35 = Seige on Haggorath 36 | 36 = Rescue on Mount Arreat 37 | 37 = Prison of Ice 38 | 38 = Betrayal of Haggorath 39 | 39 = Rite of Passage 40 | 40 = Eve of Destruction 41 | 42 | QuestCompletion 43 | 0 = Requirements Complete (Quest Complete) 44 | 2 = Quest Started 45 | 3-10 = Parts of Quest Complete Varies by Quest 46 | 12 = Quest Box Filled in 47 | -------------------------------------------------------------------------------- /kolbot/sdk/roomstats.txt: -------------------------------------------------------------------------------- 1 | roomstats.txt 2 | room.getStat(int); 3 | 4 | I don't know what all of this is, nor even very little. 5 | 6 | 7 | From dlrgroom1: 8 | 0 xStart 9 | 1 yStart 10 | 2 xSize1 11 | 3 ySize1 12 | 4 xPos 13 | 5 yPos 14 | 6 xSize2 15 | 7 ySize2 16 | 8 17 | 18 | From dlrgcoll: 19 | 9 nPosGameX 20 | 10 nPosGameY 21 | 11 nSizeGameX 22 | 12 nSizeGameY 23 | 13 nPosRoomX 24 | 14 nPosRoomY 25 | 15 nSizeRoomX 26 | 16 nSizeRoomY 27 | 28 | -------------------------------------------------------------------------------- /kolbot/sdk/stats_tabs.txt: -------------------------------------------------------------------------------- 1 | item.getStat( 188, tab ); // lookup table 2 | 3 | 0 Bow and Crossbow Skills 4 | 1 Passive and Magic Skills 5 | 2 Javelin and Spear Skills 6 | 8 Fire Skills 7 | 9 Lightning Skills 8 | 10 Cold Skills 9 | 16 Curses Skills 10 | 17 Poison and Bone Skills 11 | 18 Necromancer Summoning Skills 12 | 24 Paladin Combat Skills 13 | 25 Offensive Auras Skills 14 | 26 Defensive Auras Skills 15 | 32 Barbarian Combat Skills 16 | 33 Masteries Skills 17 | 34 Warcries Skills 18 | 40 Druid Summoning Skills 19 | 41 Shape Shifting Skills 20 | 42 Elemental Skills 21 | 48 Traps Skills 22 | 49 Shadow Disciplines Skills 23 | 50 Martial Arts Skills 24 | 25 | 26 | -- thanks to TheDesertWind for this list 27 | -------------------------------------------------------------------------------- /kolbot/sdk/superunique_presetunitids.txt: -------------------------------------------------------------------------------- 1 | Super Unique PresetUnit Ids: 2 | 3 | *this list is correct to the best of my knowledge 4 | 5 | Id Name 6 | 250 The Summoner 7 | 704 Bishibosh 8 | 705 Bonebreak 9 | 706 Coldcrow 10 | 707 Rakanishu 11 | 708 Treehead WoodFist 12 | 709 Griswold 13 | 710 The Countess 14 | 711 Pitspawn Fouldog 15 | 712 Flamespike the Crawler 16 | 713 Boneash 17 | 714 Radament 18 | 715 Bloodwitch the Wild 19 | 716 Fangskin 20 | 717 Beetleburst 21 | 718 Leatherarm 22 | 719 Coldworm the Burrower 23 | 720 Fire Eye 24 | 721 Dark Elder 25 | 723 Ancient Kaa the Soulless 26 | 724 The Smith 27 | 725 Web Mage the Burning 28 | 726 Witch Doctor Endugu 29 | 727 Stormtree 30 | 728 Sarina the Battlemaid 31 | 729 Icehawk Riftwing 32 | 730 Ismail Vilehand 33 | 731 Geleb Flamefinger 34 | 732 Bremm Sparkfist 35 | 733 Toorc Icefist 36 | 734 Wyand Voidfinger 37 | 735 Maffer Dragonhand 38 | 736 Winged Death 39 | 737 The Tormentor 40 | 738 Taintbreeder 41 | 739 Riftwraith the Cannibal 42 | 740 Infector of Souls 43 | 741 Lord De Seis 44 | 742 Grand Vizier of Chaos 45 | 743 The Cow King 46 | 744 Corpsefire 47 | 745 Hephasto (The Feature Creep) 48 | 746 Siege Boss 49 | 747 Ancient Barbarian 1 50 | 748 Ancient Barbarian 2 51 | 749 Ancient Barbarian 3 52 | 750 Axe Dweller 53 | 751 Bonesaw Breaker 54 | 752 Dac Farren 55 | 753 Eldritch (Megaflow Rectifier) 56 | 754 Eyeback Unleashed 57 | 755 Threash Socket 58 | 756 Pindleskin 59 | 757 Snapchip Shatter 60 | 758 Anodized Elite 61 | 759 Vinvear Molech 62 | 760 Sharp Tooth Sayer 63 | 761 Magma Torquer 64 | 762 Blaze Ripper 65 | 763 Frozenstein 66 | 764 Nihlathak Boss 67 | 765 Baal Subject 1 68 | 766 Baal Subject 2 69 | 767 Baal Subject 3 70 | 768 Baal Subject 4 71 | 769 Baal Subject 5 72 | 73 | 74 | 75 | --- not in super unique list, but still have a weird Ids: (thanks to mousepad for helping fill this in!) 76 | 77 | 772 random boss pack? 78 | 773 random champ pack? 79 | 774 Flavie 80 | 775 Blood Raven 81 | 778 maggot queen (broken?) 82 | 780,781 tenticles 83 | 787 flayers 84 | 788 flayer+shaman 85 | 792 ratmen 86 | 793 ratmen+shaman 87 | 794 demonimp pack 88 | 796 enslaved pack 89 | 795,797,798 ?? 90 | 799 dead enslaved 91 | 800 dead demonimp 92 | 801 dead barb 93 | 802 dead prowlingdead 94 | -------------------------------------------------------------------------------- /kolbot/sdk/uiflag.txt: -------------------------------------------------------------------------------- 1 | 0x01 Inventory open 2 | 0x02 Character Stat screen open 3 | 0x03 quick skill 4 | 0x04 skill 5 | 0x05 Chat box open (typing something) 6 | 0x06 7 | 0x07 8 | 0x08 npc menu 9 | 0x09 Esc menu? 10 | 0x0A Automap is on 11 | 0x0B config controls 12 | 0x0C Shop open at NPC 13 | 0x0D alt show items 14 | 0x0E cash 15 | 0x0F quest 16 | 0x10 17 | 0x11 questlog button 18 | 0x12 status area 19 | 0x13 ? 20 | 0x14 waypoint 21 | 0x15 mini panel 22 | 0x16 party 23 | 0x17 Trade Prompt up [ok/cancel] (player) or in Trade w/player 24 | 0x18 msgs 25 | 0x19 Stash is open 26 | 0x1A Cube is open 27 | 0x1B 28 | 0x1C 29 | 0x1D 30 | 0x1E 31 | 0x1F Belt show all is toggled 32 | 0x20 33 | 0x21 help 34 | 0x22 35 | 0x23 36 | 0x24 Merc screen 37 | 0x25 scroll of whatever 38 | -------------------------------------------------------------------------------- /kolbot/sdk/waypoints.txt: -------------------------------------------------------------------------------- 1 | var waypoints = [[0x01,0x03,0x04,0x05,0x06,0x1b,0x1d,0x20,0x23],[0x28,0x30,0x2a,0x39,0x2b,0x2c,0x34,0x4a,0x2e],[0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x53,0x65],[0x67,0x6a,0x6b],[0x6d,0x6f,0x70,0x71,0x73,0x7b,0x75,0x76,0x81]]; 2 | -------------------------------------------------------------------------------- /kolbot/test file - remove this.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Borega/pd2bs-scripts/fb578879d11c7726039f34325d727882e2e9ca31/kolbot/test file - remove this.txt -------------------------------------------------------------------------------- /kolbot/tools/CloneKilla.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename CloneKilla.js 3 | * @author kolton 4 | * @desc Kill Diablo Clone when he walks in game. Uses Fire Eye location. 5 | */ 6 | 7 | 8 | include("json2.js"); 9 | include("NTItemParser.dbl"); 10 | include("OOG.js"); 11 | include("AutoMule.js"); 12 | include("craftingsystem.js"); 13 | include("Gambling.js"); 14 | include("TorchSystem.js"); 15 | include("MuleLogger.js"); 16 | include("common/Attack.js"); 17 | include("common/Cubing.js"); 18 | include("common/CollMap.js"); 19 | include("common/Config.js"); 20 | include("common/Loader.js"); 21 | include("common/misc.js"); 22 | include("common/util.js"); 23 | include("common/Pickit.js"); 24 | include("common/Pather.js"); 25 | include("common/Precast.js"); 26 | include("common/Prototypes.js"); 27 | include("common/Runewords.js"); 28 | include("common/Storage.js"); 29 | include("common/Town.js"); 30 | 31 | function main() { 32 | D2Bot.init(); 33 | Config.init(); 34 | Pickit.init(); 35 | Attack.init(); 36 | Storage.Init(); 37 | CraftingSystem.buildLists(); 38 | Runewords.init(); 39 | Cubing.init(); 40 | include("bots/KillDclone.js"); 41 | 42 | if (typeof KillDclone === "function") { 43 | try { 44 | D2Bot.printToConsole("Trying to kill DClone.", 7); 45 | KillDclone.call(); 46 | } catch (e) { 47 | Misc.errorReport(e, "CloneKilla.js"); 48 | } 49 | } 50 | 51 | quit(); 52 | 53 | return true; 54 | } -------------------------------------------------------------------------------- /kolbot/tools/HeartBeat.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename HeartBeat.js 3 | * @author kolton 4 | * @desc Keep a link with d2bot#. If it's lost, the d2 window is killed 5 | */ 6 | 7 | function main() { 8 | include("oog.js"); 9 | include("json2.js"); 10 | include("common/misc.js"); 11 | include("common/util.js"); 12 | D2Bot.init(); 13 | print("Heartbeat loaded"); 14 | 15 | function togglePause() { 16 | var script = getScript(); 17 | 18 | if (script) { 19 | do { 20 | if (script.name.indexOf(".dbj") > -1) { 21 | if (script.running) { 22 | print("ÿc1Pausing ÿc0" + script.name); 23 | script.pause(); 24 | } else { 25 | print("ÿc2Resuming ÿc0" + script.name); 26 | script.resume(); 27 | } 28 | } 29 | } while (script.getNext()); 30 | } 31 | 32 | return true; 33 | } 34 | 35 | // Event functions 36 | function KeyEvent(key) { 37 | switch (key) { 38 | case 19: 39 | if (me.ingame) { 40 | break; 41 | } 42 | 43 | togglePause(); 44 | 45 | break; 46 | } 47 | } 48 | 49 | addEventListener("keyup", KeyEvent); 50 | 51 | while (true) { 52 | D2Bot.heartBeat(); 53 | delay(1000); 54 | } 55 | } -------------------------------------------------------------------------------- /kolbot/tools/MapHelper.js: -------------------------------------------------------------------------------- 1 | include("json2.js"); 2 | include("NTItemParser.dbl"); 3 | include("OOG.js"); 4 | include("AutoMule.js"); 5 | include("Gambling.js"); 6 | include("TorchSystem.js"); 7 | include("MuleLogger.js"); 8 | include("common/Attack.js"); 9 | include("common/Cubing.js"); 10 | include("common/CollMap.js"); 11 | include("common/Config.js"); 12 | include("common/Loader.js"); 13 | include("common/misc.js"); 14 | include("common/util.js"); 15 | include("common/Pickit.js"); 16 | include("common/Pather.js"); 17 | include("common/Precast.js"); 18 | include("common/Prototypes.js"); 19 | include("common/Runewords.js"); 20 | include("common/Storage.js"); 21 | include("common/Town.js"); 22 | 23 | function main() { 24 | include("json2.js"); 25 | 26 | var obj, action, 27 | mapThread = getScript("tools/mapthread.js"); 28 | 29 | Config.init(); 30 | Pickit.init(); 31 | Storage.Init(); 32 | addEventListener("scriptmsg", function (msg) { 33 | action = msg; 34 | }); 35 | 36 | while (true) { 37 | if (getUIFlag(0x09)) { 38 | delay(100); 39 | 40 | if (mapThread.running) { 41 | print("pause mapthread"); 42 | mapThread.pause(); 43 | } 44 | } else { 45 | if (!mapThread.running) { 46 | print("resume mapthread"); 47 | mapThread.resume(); 48 | } 49 | } 50 | 51 | if (action) { 52 | try { 53 | obj = JSON.parse(action); 54 | 55 | if (obj) { 56 | switch (obj.type) { 57 | case "area": 58 | Pather.moveToExit(obj.dest, true); 59 | 60 | break; 61 | case "unit": 62 | Pather.moveToUnit(obj.dest, true); 63 | 64 | break; 65 | case "wp": 66 | Pather.getWP(me.area); 67 | 68 | break; 69 | } 70 | } 71 | } catch (e) { 72 | 73 | } 74 | 75 | action = false; 76 | } 77 | 78 | delay(20); 79 | } 80 | } -------------------------------------------------------------------------------- /kolbot/tools/Party.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename Party.js 3 | * @author kolton 4 | * @desc handle party procedure ingame 5 | */ 6 | 7 | function main() { 8 | include("OOG.js"); 9 | include("json2.js"); 10 | include("common/Config.js"); 11 | include("common/Cubing.js"); 12 | include("common/Runewords.js"); 13 | include("common/misc.js"); 14 | include("common/util.js"); 15 | include("common/Prototypes.js"); 16 | include("common/Town.js"); 17 | 18 | Config.init(); 19 | 20 | var i, myPartyId, player, otherParty, shitList, currScript, scriptList, 21 | classes = ["Amazon", "Sorceress", "Necromancer", "Paladin", "Barbarian", "Druid", "Assassin"], 22 | playerLevels = {}, 23 | partyTick = getTickCount(); 24 | 25 | addEventListener("gameevent", 26 | function (mode, param1, param2, name1, name2) { 27 | var player; 28 | 29 | switch (mode) { 30 | case 0x02: // "%Name1(%Name2) joined our world. Diablo's minions grow stronger." 31 | if (Config.Greetings.length > 0) { 32 | try { 33 | player = getParty(name1); 34 | } catch (e1) { 35 | 36 | } 37 | 38 | if (player && player.name !== me.name) { 39 | say(Config.Greetings[rand(0, Config.Greetings.length - 1)].replace("$name", player.name).replace("$level", player.level).replace("$class", classes[player.classid])); 40 | } 41 | } 42 | 43 | break; 44 | case 0x06: // "%Name1 was Slain by %Name2" 45 | if (Config.DeathMessages.length > 0) { 46 | try { 47 | player = getParty(name1); 48 | } catch (e2) { 49 | 50 | } 51 | 52 | if (player && player.name !== me.name) { 53 | say(Config.DeathMessages[rand(0, Config.DeathMessages.length - 1)].replace("$name", player.name).replace("$level", player.level).replace("$class", classes[player.classid]).replace("$killer", name2)); 54 | } 55 | } 56 | 57 | break; 58 | } 59 | }); 60 | addEventListener("scriptmsg", 61 | function (msg) { 62 | var obj; 63 | 64 | try { 65 | obj = JSON.parse(msg); 66 | 67 | if (obj && obj.hasOwnProperty("currScript")) { 68 | currScript = obj.currScript; 69 | } 70 | } catch (e3) { 71 | 72 | } 73 | }); 74 | 75 | print("ÿc2Party thread loaded. Mode: " + (Config.PublicMode === 2 ? "Accept" : "Invite")); 76 | 77 | if (Config.ShitList || Config.UnpartyShitlisted) { 78 | shitList = ShitList.read(); 79 | 80 | print(shitList.length + " entries in shit list."); 81 | } 82 | 83 | if (Config.PartyAfterScript) { 84 | scriptList = []; 85 | 86 | for (i in Scripts) { 87 | if (Scripts.hasOwnProperty(i) && !!Scripts[i]) { 88 | scriptList.push(i); 89 | } 90 | } 91 | } 92 | 93 | // Main loop 94 | while (true) { 95 | if (me.gameReady && (!Config.PartyAfterScript || scriptList.indexOf(currScript) > scriptList.indexOf(Config.PartyAfterScript))) { 96 | player = getParty(); 97 | 98 | if (player) { 99 | myPartyId = player.partyid; 100 | 101 | while (player.getNext()) { 102 | switch (Config.PublicMode) { 103 | case 1: // Invite others 104 | case 3: // Invite others but never accept 105 | if (getPlayerFlag(me.gid, player.gid, 8)) { 106 | if (Config.ShitList && shitList.indexOf(player.name) === -1) { 107 | say(player.name + " has been shitlisted."); 108 | shitList.push(player.name); 109 | ShitList.add(player.name); 110 | } 111 | 112 | if (player.partyflag === 4) { 113 | clickParty(player, 2); // cancel invitation 114 | delay(100); 115 | } 116 | 117 | break; 118 | } 119 | 120 | if (Config.ShitList && shitList.indexOf(player.name) > -1) { 121 | break; 122 | } 123 | 124 | if (player.partyflag !== 4 && (Config.PublicMode === 1 || player.partyflag !== 2) && player.partyid === 65535) { 125 | clickParty(player, 2); 126 | delay(100); 127 | } 128 | 129 | if (Config.PublicMode === 3) { 130 | break; 131 | } 132 | case 2: // Accept invites 133 | if (Config.Leader && player.name !== Config.Leader) { 134 | break; 135 | } 136 | 137 | if (player.partyid !== 65535 && player.partyid !== myPartyId) { 138 | otherParty = player.partyid; 139 | } 140 | 141 | if (player.partyflag === 2 && (!otherParty || player.partyid === otherParty) && (getTickCount() - partyTick >= 2000 || Config.FastParty)) { 142 | clickParty(player, 2); 143 | delay(100); 144 | } 145 | 146 | break; 147 | } 148 | 149 | if (Config.UnpartyShitlisted) { 150 | // Add new hostile players to temp shitlist, leader should have Config.ShitList set to true to update the permanent list. 151 | if (getPlayerFlag(me.gid, player.gid, 8) && shitList.indexOf(player.name) === -1) { 152 | shitList.push(player.name); 153 | } 154 | 155 | if (shitList.indexOf(player.name) > -1 && myPartyId !== 65535 && player.partyid === myPartyId) { 156 | // Only the one sending invites should say this. 157 | if ([1, 3].indexOf(Config.PublicMode) > -1) { 158 | say(player.name + " is shitlisted. Do not invite them."); 159 | } 160 | 161 | clickParty(player, 3); 162 | delay(100); 163 | } 164 | } 165 | } 166 | } 167 | 168 | if (Config.Congratulations.length > 0) { 169 | player = getParty(); 170 | 171 | if (player) { 172 | do { 173 | if (player.name !== me.name) { 174 | if (!playerLevels[player.name]) { 175 | playerLevels[player.name] = player.level; 176 | } 177 | 178 | if (player.level > playerLevels[player.name]) { 179 | say(Config.Congratulations[rand(0, Config.Congratulations.length - 1)].replace("$name", player.name).replace("$level", player.level).replace("$class", classes[player.classid])); 180 | 181 | playerLevels[player.name] = player.level; 182 | } 183 | } 184 | } while (player.getNext()); 185 | } 186 | } 187 | } 188 | 189 | delay(500); 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /kolbot/tools/PickThread.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename PickThread.js 3 | * @author stffdtiger 4 | * @desc a loop that runs Pickit.FastPick() intended to be used with D2BotMap entry script 5 | */ 6 | 7 | js_strict(true); 8 | 9 | include("json2.js"); 10 | include("NTItemParser.dbl"); 11 | include("OOG.js"); 12 | include("CraftingSystem.js"); 13 | include("common/Cubing.js"); 14 | include("common/CollMap.js"); 15 | include("common/Config.js"); 16 | include("common/misc.js"); 17 | include("common/util.js"); 18 | include("common/Pickit.js"); 19 | include("common/Pather.js"); 20 | include("common/Prototypes.js"); 21 | include("common/Runewords.js"); 22 | include("common/Storage.js"); 23 | include("common/Town.js"); 24 | 25 | function main() { 26 | print("ÿc9Pick Thread Loaded."); 27 | Config.init(false); 28 | Pickit.init(false); 29 | Storage.Init(); 30 | CraftingSystem.buildLists(); 31 | Runewords.init(); 32 | Cubing.init(); 33 | 34 | var ii, noPick = false, 35 | UIFlagList = [0x01, 0x02, 0x03, 0x04, 0x05, 0x09, 0x0B, 0x0E, 0x0F, 0x14, 0x16, 0x1A, 0x24]; 36 | 37 | this.itemEvent = function (gid, mode, code, global) { 38 | if (gid > 0 && mode === 0) { 39 | Pickit.gidList.push(gid); 40 | } 41 | }; 42 | 43 | addEventListener("itemaction", this.itemEvent); 44 | 45 | while (true) { 46 | for (ii = 0 ; ii < UIFlagList.length ; ii++) { 47 | if (getUIFlag(UIFlagList[ii])) { 48 | noPick = true; 49 | break; 50 | } 51 | } 52 | if (!me.inTown && !noPick) { 53 | Pickit.fastPick(); 54 | } 55 | noPick = false; 56 | delay(50); 57 | } 58 | return true; 59 | } 60 | -------------------------------------------------------------------------------- /kolbot/tools/TownChicken.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @filename TownChicken.js 3 | * @author kolton 4 | * @desc handle town chicken 5 | */ 6 | 7 | js_strict(true); 8 | 9 | include("json2.js"); 10 | include("NTItemParser.dbl"); 11 | include("OOG.js"); 12 | include("Gambling.js"); 13 | include("CraftingSystem.js"); 14 | include("common/Attack.js"); 15 | include("common/Cubing.js"); 16 | include("common/Config.js"); 17 | include("common/CollMap.js"); 18 | include("common/Loader.js"); 19 | include("common/misc.js"); 20 | include("common/util.js"); 21 | include("common/Pickit.js"); 22 | include("common/Pather.js"); 23 | include("common/Precast.js"); 24 | include("common/Prototypes.js"); 25 | include("common/Runewords.js"); 26 | include("common/Storage.js"); 27 | include("common/Town.js"); 28 | 29 | function main() { 30 | var townCheck = false; 31 | 32 | this.togglePause = function () { 33 | var i, script, 34 | scripts = ["default.dbj", "tools/antihostile.js", "tools/rushthread.js", "tools/CloneKilla.js"]; 35 | 36 | for (i = 0; i < scripts.length; i += 1) { 37 | script = getScript(scripts[i]); 38 | 39 | if (script) { 40 | if (script.running) { 41 | if (i === 0) { // default.dbj 42 | print("ÿc1Pausing."); 43 | } 44 | 45 | script.pause(); 46 | } else { 47 | if (i === 0) { // default.dbj 48 | if (!getScript("tools/clonekilla.js")) { // resume only if clonekilla isn't running 49 | print("ÿc2Resuming."); 50 | script.resume(); 51 | } 52 | } else { 53 | script.resume(); 54 | } 55 | } 56 | } 57 | } 58 | 59 | return true; 60 | }; 61 | 62 | addEventListener("scriptmsg", 63 | function (msg) { 64 | if (msg === "townCheck") { 65 | if (me.area === 136) { 66 | print("Can't tp from uber trist."); 67 | } else { 68 | townCheck = true; 69 | } 70 | } 71 | }); 72 | 73 | // Init config and attacks 74 | D2Bot.init(); 75 | Config.init(); 76 | Pickit.init(); 77 | Attack.init(); 78 | Storage.Init(); 79 | CraftingSystem.buildLists(); 80 | Runewords.init(); 81 | Cubing.init(); 82 | 83 | while (true) { 84 | if (!me.inTown && (townCheck || 85 | (Config.TownHP > 0 && me.hp < Math.floor(me.hpmax * Config.TownHP / 100)) || 86 | (Config.TownMP > 0 && me.mp < Math.floor(me.mpmax * Config.TownMP / 100)))) { 87 | this.togglePause(); 88 | 89 | while (!me.gameReady) { 90 | delay(100); 91 | } 92 | 93 | try { 94 | me.overhead("Going to town"); 95 | Town.visitTown(); 96 | } catch (e) { 97 | Misc.errorReport(e, "TownChicken.js"); 98 | scriptBroadcast("quit"); 99 | 100 | return; 101 | } finally { 102 | this.togglePause(); 103 | 104 | townCheck = false; 105 | } 106 | } 107 | 108 | delay(50); 109 | } 110 | } --------------------------------------------------------------------------------