Giter Club home page Giter Club logo

d2bot-with-kolbot's Introduction

This repo will remain for stable releases new development will continue at https://github.com/blizzhackers/

  • This repository will get periodic updates, security fixes, and accept critical pull requests only
  • All new kolbot development and feature requests can be made to: https://github.com/blizzhackers/kolbot

Rules

  1. D2BS, D2Bot and kolbot # are educational tools with an open source developer community. These tools are meant to be used offline or on private servers that explicitly allow them. These tools are not meant to be abused on battle.net (a Blizzard Entertainment entity).

  2. D2BS, D2Bot and kolbot # are FREE software. If you paid or are asked to pay for these, you have been scammed.

  3. do not discuss cheating, maliciously exploiting, or illegal use of software.

  4. selling or discussing illegal software or cheating tools are strictly prohibited in all repositories.

kolbot

  • this name is better known than others, even it is just a part of d2bs (diablo 2 botting system) which contain 3 distinct components:

    • D2BS - core
    • D2Bot# - manager (C#)
    • kolbot - script library (JS)
  • use the master(trunk) branch

If you want to contribute to kolbot code, make sure you use ESLint options for kolbot code or JSLint options for kolbot code for final polish. If you want to contribute to d2bs/d2bot#, come to irc.synirc.net/d2bs and ask around.

D2BS is NOT SAFE from DETECTION!

Join the Forums!

Join the Discord Channel!

Documentation Repo

Install dependencies - do this first!

Getting Started

Guides

LimeDrop web based item manager and dropper

limedrop-general

d2bot-with-kolbot's People

Contributors

5noop avatar alogwe avatar cuss avatar demkca avatar detectivesquirrel avatar doc-saintly avatar drdentist avatar fa-b avatar ikorolev93 avatar imbalanced avatar jaenster avatar kolton avatar mercoory avatar mf022 avatar mnikic avatar nishimura-katsuo avatar noah- avatar ownasaurus avatar ross-weir avatar ryancrunchi avatar ryansgit avatar semajtrip avatar stffdtiger avatar stoneofjordan avatar supericy avatar szymski avatar uscgmatthew avatar yharahuts avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

d2bot-with-kolbot's Issues

All windows crash with any script

I have tried everything I can to fix this issue, looked up all I know how. I downloaded the bot from scratch. Last ladder season I had no issues but I'm getting this one now. My thought was to simply find the file "mpqstats.cpp" and fix line 172. However, either I'm not nearly as intelligent as I thought, or that file is not in the bot directory.

I've tried running several different scripts (please keep in mind, I did a fresh re-download) and all scripts round back to this issue. It either crashes as it enters the game, when it goes to a merchant, and sometimes it just simply crashes.

Here's the log error:

[12/01/13 19:34:18] D2BS 193360: D2BS Engine startup complete.
[12/01/13 19:36:18] D2BS 193360: EXCEPTION!
*** 0xc0000005 at 0x05a18ec5 (FillBaseStat in mpqstats.cpp line 172)
D2BS loaded at: 0x059b0000
Registers:
EIP: 0x05a18ec5, ESP: 0x0ab8f484
CS: 0x0023, DS: 0x002b, ES: 0x002b, SS: 0x002b, FS: 0x0053, GS: 0x002b
EAX: 0x0f00712d, EBX: 0x05a8af90, ECX: 0x00000080, EDX: 0x05a8b0c0, ESI: 0x00000004, EDI: 0x00000005, EBP: 0x00000000, FLG: 0x00010246
Stack Trace:
FillBaseStat+0x00068f20, File: (null) line 59679535
my_getBaseStat+0x00071f70, File: (null) line 59679535
js_Invoke+0x6102ab70

End of stack trace.
D2Client.DLL loaded at: 0x6fab0000.
D2Common.DLL loaded at: 0x005f0000.
D2Gfx.DLL loaded at: 0x6fa80000.
D2Lang.DLL loaded at: 0x003b0000.
D2Win.DLL loaded at: 0x6f8e0000.
D2Net.DLL loaded at: 0x00860000.
D2Game.DLL loaded at: 0x02ca0000.
D2Launch.DLL loaded at: 0x6fa40000.
Fog.DLL loaded at: 0x6ff50000.
BNClient.DLL loaded at: 0x6ff20000.
Storm.DLL loaded at: 0x6fbf0000.
D2Cmp.DLL loaded at: 0x00420000.
D2Multi.DLL loaded at: 0x6f9d0000.

Lack of Tags

This project doesn't use some handy features of GitHub. Both developers and end-users could benefit from Tags (Releases). It could make it more structured and easy to deal with.

hi trying to make random game name

Hi, wanted to Know if a way to make random game name
i have see this line on script

function randomString(len) {
var i,
rval = "",
letters = "abcdefghijklmnopqrstuvwxyz";

for (i = 0; i < len; i += 1) {
    rval += letters[Math.floor(Math.random() * 26)];
}

return rval;

but look like not working
if u got a idea on how thx to reply
and great work ^^

Pick up small gems

Hey I'm not sure how to make the bot pick up small gems for cubing such as chipped diamonds and such. How does one go about that?

With the Ping + Time + Ip with mapthread

Not enough checks to see if it is visable

    while (getUIFlag(0x09) || getUIFlag(0x0C) || getUIFlag(0x01) || getUIFlag(0x04) || getUIFlag(0x0C) || getUIFlag(0x19) || getUIFlag(0x1A)) {
        Hooks.flush();
        delay(100);
    }

You missed a few :)

Bot Error

as soon as i start the bot it gives the error: libnspr4.dll failed to load
is there any particular reason for this to occur?
(i only just set this up and would appreciate newbie answers, including any steps i may have missed in order to start running this bot)
thanks in advance

holy bolt & poison heal wave 2

the holy bolt runs back and forth shooting 1 or 2 times instead of taking down one at a time and merc moves too instead of attacking. it takes a while like that.. Also with lower geared hdins heal wil be vital with how fast runs are and going to corner with wave 3 this bot will be untouchable!

Why does the new release do this...I hope I can get help this time...

I had no issues with the old version and was able to run 12 bots. I do really like a couple of the new features i this latest version,but the new one seems to make my whole computer lag only running 8 bots. Why is this new version so much harder on my CPU? I only have a Pentium Dual-Core 3.0 GHz w/ 10 GB ram. I wouldn't think this should be an issue...Other than replacing my CPU can I do anything to reduse the stress on the CPU?

unable to use svn update

Update
C:\Documents and Settings\Roy Dickens\Desktop\KolBot
Unexpected HTTP status 500 'Internal Server Error' on
'/kolton/d2bot-with-kolbot'
Additional errors:
PROPFIND request on '/kolton/d2bot-with-kolbot' failed: 500 Internal Server
Error

Random Death Messages

At the bottom of a script. (ie Baal.js)
(idea stolen from Project Etal forums.)

var Slain = [
"That's Gotta Hurt!",
"I bet you won't do that again",
"That wasn't supposed to happen!",
"You make a lovely corpse!",
"You won't get any XP just laying there."];

addEventListener('chatmsg',
function (nick, msg, type) {
if (type === 4 && msg.indexOf("slain") > -1) {
t = rand(0,(Slain.length - 1));
say(Slain[t]);
}
});

Minor changes & one script fix.

Just some minor changes and one script fix. Very low importance for most.

Config.js line 46, before:

print("ÿc1" + configFilename + ".js not found!");

Config.js line 46, before:

print("ÿc1" + configFilename + " not found!");

Cubing.js line 659, before:

string += (" " + items[0].name);

Cubing.js line 659, after:

string += (" + " + items[0].name);

Runewords.js line 392, before:

D2Bot.printToConsole("Rerolling runeword:" + base.fname.split("\n").reverse().join(" ").replace(/ÿc[0-9!"+<;.*]/, "") + ";5");

Runewords.js line 392, after:

D2Bot.printToConsole("Rerolling runeword: " + base.fname.split("\n").reverse().join(" ").replace(/ÿc[0-9!"+<;.*]/, "") + ";5");

Eyeback.js lines 12 to 14 before:

if (!Pather.moveToPreset(111, 1, 784, 0, 0, false, true)) {
    throw new Error("Failed to move to Eyeback the Unleashed");
}

Eyeback.js lines 12 to 14 after:

if (!Pather.moveToExit(111, true)) {
    throw new Error("Failed to move to Eyeback the Unleashed");
}

Add a check to DiabloHelper & Wakka so if a player is already in Throne of Destruction or Baal's Chamber that it automatically ends the DiabloHelper or Wakka script.

Below is my example, stick it in the waiting loops.

partybaal = getParty();
if (partybaal) {
    do {
        if (partybaal.area === 131) {
            return false;
        }
    } while (partybaal.getNext());
}

Won't release click on Login

Fresh install, basic configuration. Bot enters username/pass and clicks on Login but then doesn't release the mouse click. Tried run as admin, etc. Any ideas?

Gambling in same game as "gold finders"

Hi friends,

In my current setup, I have 7 characters using "Team MF" to complete long multi-act runs that take 10-15 minutes per game. I have an 8th character that I would like to use the gamble feature in the same game as the 7 runners, but I'm having a hard time making that happen.

With the default Gamble.js, when my gold finder enters the same game as the gambler (to begin the mf run) he will drop his gold and then leave the game, thinking that he is going to go back to finding gold in a separate game. After playing around with the Gamble.js functions, I've gotten my "MF Leader" (and also the gold finder) to drop the gold without leaving the game, but I can't get him to then start running the boss/area scripts. I'm thinking that this shouldn't be too bad of a fix since it looks like there's already a "current gold" check upon entering the game. I think I just need to find a way to reactivate the boss/area scripts following that check. Any ideas or code snippet to help fix this problem?

Any input is appreciated, many thanks!

-Relax

Having a problem

Not sure what the issue is but I setup kolbot for sorc and every time I go to run it, it goes to game but when it goes to say to do andy it always looses connections. How do I fix this.

Cubing/Runewording buffering

Medium low priority feature request.

Add a user selectable maximum buffer size (instead of 1) to the number of things picked up for cubing/runewording. As an example: pick up more than one of each essence so you waste less.

D2BS is not responding...starting profile

Ok, I do have a question…
Sometimes I run 2 teams one chaos (4man), and one baal (4 man)…but if I'm trying to lvl a character past lvl 90 I will run a full 8 man baal game…I will take however many leechers I have to put in game and will fill the rest with fighters. I do you custom join delay so they are not all joining game at the same time, 7 chars entering at one time isn't a good idea :). The problem I'm having is some profiles will get a lot of 'D2BS is not responding…starting profile' errors. I am sure this is a ping issue (FYI I average 70Mbps connection speed). It doesn't matter if I use my home IP, or if it is on one of my proxies, also my proxies are close…they are in Dallas and I'm in Houston.
Any suggestions?

Thank you for taking the time to read this, and thanks in advance if you have any advice…

Trying To Setup Advanced Attack Pattern For Sorc (Running 2 Sorcs)

Config.AttackSkill[4] = 47; // Primary untimed skill to others. (FIREBALL)
Config.AttackSkill[6] = 55; // Secondary untimed if immune to [4] - (GLACIAL SPIKE)
Config.AttackSkill[7] = 42; // Third untimed skill if immune to both [4] and [6]
Basically it would allow to help other sorc by spamming static instead of skipping cuz cold/fire immune
Hey people i am trying to configure this attack pattern so my 2 sorcs can stick together at all times (one is cold/light and other is cold/fire), and i don't want them to skip any monsters because if one sorc skips a mob and the other one doesnt, they will split up and lose killing power and efficiency

If i can get this attack config to work i can remove skip "Cold and fire" immunes and it will just start using static and my other sorc will kill her with her lightning spells

I have been messing with the Attack.js file in the section where it selects spell based on monster resistance, but unfortunately i have never scripted anything in my life so yeah it wasnt the greatest

PLS HELP
SORCERESS LOVERS NEED 7 ATTACK CONFIGS :)

Item Viewer

Hey i was wondering if there is a way to set the item viewer tab on the bot to view all the items that go into the itemlog file?is it the value i set Config.ItemInfoQuality = []; in the char config to see more items sold/crafted/picked up, and what values show what?

D2BotChannel.dbj Ftj

two or three a game ftj is giving error

after

Lost connetion and character screen

CORE15 D2Bot.exe

Contains Worm.Win32.Luder.ccwj.

Thank god auto deleted by my Kaspersky.

Last time I downloaded kolbot core (which was about 6-7 months ago) there were no problems.

Can you release a new core without trojans and worms in it?

Your great work is much appreciated

Necro Raise Army Needs help with V.1.4.1786

Hello, I was using a custom script to have my Necro raise an army before the baal run, it was working wonderfully in V1763 but now I've updated to V1.4.1786 and it doesn't work...All he does is take Anya's portal and goes to spot (where he is suppose to raise skeletons) but just makes a tp and goes back to town...I'm sure it a simple fix but I can seem to get it...HELP plz...not sure how to attach the script so I'm just going to past it here...

function RaiseArmy() {
var useWaypoint = false; // Keep false to use red portal

    Town.goToTown(5);      
    Town.doChores();

    if (useWaypoint) {
            if (!Pather.useWaypoint(123)) {
                    throw new Error ("You don't have the waypoint, set useWaypoint = false to use red portal.");
            }

            Precast.doPrecast(true);               

            if (!Pather.moveToExit([122, 121], true)) {
                    throw new Error("Failed to move to temple.");
            }

    } else {
            Town.move("anya");

            if (!Pather.usePortal(121)) {
                    throw new Error("Failed to use portal. If you have no portal, set useWaypoint = true");
            }

            Precast.doPrecast(true);

    }

    Pather.moveTo(10064, 13274);
    Attack.clear(25); // Skelies are raised in this function.      

    return true;

AutoBaal leech improvements for Paladins

line 229 in AutoBaal.js add:

        if (Config.UsePaliAura > 0){
            Skill.cast(Config.UsePaliAura, 0);
        }

in your Paladin's character config only add:
(only Paladin config)

Config.UsePaliAura = 0; // Use an aura of your choice while passively leeching

Hey Kolton this is a must

Tertiary skill to everything else in case monster is immune to both primary and secondary.
I am experimenting with a hybrid sorceress in hell for trav and I need to be able to cast nova upon getting fire / cold immunes

Cubing Rerolling Rings <----> Amulets

Hey I've been trying to do this and believe this would be useful, if you'd like a brief explanation as to why I think so I can provide that. Basically it'd be nice to be able to keep any junk magic rings/amulets and then reroll 3 rings --> amulet and 3 amulets --> ring. What's nice about this is that it will only ever take up a maximum of 4 spaces.

I tried to do this by using the gem recipe and pushing 3 rings into it. However, it does not keep the needed ingredients to cube them. Would a completely new recipe need to be made in the cubing.js? Or would code need to be added to make the "rings/ammys" "objects" like gems were in the code? Any input would be helpful!

Socketing quest feature

Very low priority feature request.

Create a system for max-socketing items. Char gets created, rushed to a5, quest done for it, sockets items. Overall, bot would pick item that needs to get socketed, hand off to special rusher char. Rusher char then rushes one or more new chars to socket however many items it has. Gets items socketed. Items then either go back to original bot or to a mule depending on whether they're used for runewords.

If I get time I might get around to this at some point. For now it's just my thought in case someone's looking for something to do now or in the future.

Trying to run 4+ bots?

I am having an issue with running more than 4+ bots.

My issue lies with the manager itself.

I have followed and read many guides that suggest using game1.exe after the 4th bot or should I just keep it game.exe?

Also, if possible, could someone enlighten me on a simple process for doing multiple cdkeys? I will also look on the repository for info as well!

looping in mgr

everytime i make a character it either loops back to log in screen from char select or it stays in char select unless i click on the character??

Level bot based on kolbot

I would like to make a level bot based on kolbot. It seems like most of the code already exists (clearing areas). The only code I need to add is something to handle pots. At low level running out of pots (and getting the money to buy them and tps) will be a problem. I was wondering if you had any suggestions of how to implement such features in a non-invasive way.

The basic idea I have at the moment is to have the tool thread send a script message to the main (default.dbj) script stating the need for pots when it can't find a pot to drink (a non-rejuv pot ofc). It would set a flag stating that such message has been sent to avoid pounding the main thread with messages. The main script would then send a message back when it has bought pots to reset the message sent flag.

The other issue is that I would need to find a way to stuff the inventory with junk that can be sold to make money for tp scrolls. I see this as some sort of flag for the pickit set by the level module.

Finally a quick overview of remaining operation. The level bot will have a list of zones and the level to start them in (possibly just a formula based on the level of the area). The level bot will clear said zone, it will then check the next zone to see if you meet the level requirements. It will grab wps as it goes. Furthermore, a config will be given to allow the user to specify how to spend stats/skills. Once it hits a certain level (or is in a certain level range) it will have the option of joining runs (e.g. chaos runs, baal runs) hosted by another bot.

XML parsing failed: (200 OK)

I have been using Kolbot with not issues or questions since I can remember. As of the LAST revision, I am unable to download per the above error.
"XML parsing failed: (200 OK)"

There is "2" incidents of documentation on this via inter-webs.

Both speculate to an error on the up-loader TO svn.

please advise.

D2Bot fail to start - requirments?

What I did:
...
I get the zip archive, made a second Diablo 2 copy on different HDD and setuped it to run in window (-w parameter), then copied ONE my gameprofile into it (surprisingly Diablo 2 find all the profiles?!) and created a D2Bot dir", inside Diablo 2 dir, as the readme insist it need to be done.
Then I unpacked the archive and then I started the D2Bot.exe file.

And error 0xc0000135 resulted. Perhaps my old machine with Windows XP SP3 did not meet some requirmets? Do this software need something else also...?

...

This is unclear a bit for me:

.../D2Bot dir/D2BS/scripts.../
in your initial scirpts folder you must have
Folder: data <--- THIS IS MANDATORY!
File: D2BotLead.dbj
File: D2BotFollow.dbj
File: Any other starters you want

  1. it is not possible to create a directory with name "scripts..." - the dots are omited
  2. even when I create the dirs "scripts" and under it the directory "data" and copy the D2BotLead.dbj and D2BotFollow.dbj files into both of these directories, the D2Bot fail on start.

Some of the files are .js ... does it mean that it require JavaScript installed to work?

Thanks for some help.

Windows 8 fps lag

Hello, so I downloaded this "https://github.com/kolton/d2bot-with-kolbot/tree/Temp" a few days ago.
I can't run several bots without the button "visible" on windows 8 i suppose.
And it seemed that this were the only version with the "visible" button.

But now when I run it, the fps is down at 1x.

Is there anyway I can fix that? lmk please...

Best regards Mikk

D2Bot Feature Request: "Stop After Current Run" & "Pause" Buttons

Kolton,

I strongly believe a "stop after current run" button in the D2Bot manager would be very valuable to users. When pressed, a flag is set for a selected profile (and perhaps unset on second press) that is checked by kolbot at the end of each run and, when encountered, signals that it should stop running. This would allow the bot to finish up what it is doing, as opposed to immediately killing the running profile via the standard "stop" button.

In a similar vein, I believe a "pause" button would be equally -- if not more -- valuable in the D2Bot Manager. I believe pausing a given profile should be fairly elementary given the script.pause() and script.resume() functions. This would enable users to take temporary control as is occasionally desired or necessary.

Window has unexpectedly exited... starting profile

Hi

I'm having this error in D2Bot console. Game window is closed immediately after bot tries to create the game.

D2BS log below:

[06/10/15 11:35:04] D2BS 356: D2BS Engine startup complete.
[06/10/15 11:35:04] D2BS 356: My
[06/10/15 11:35:22] D2BS 356: Warden activity detected! Terminating Diablo to ensure your safety:)

Any help much appreciated.

Leader only Muling

I was told there is a fix for this already, but neither I nor my source can locate it. The problem,when my leader joins a mule game all my followers join in also, filling the game most of the time. I did set it to stop on of my followers, but I don't always use it and forget to change to one that I am using...
Is there anyway to get the leader to mule solo, I'm not sure but is my followers join and drop items will the mule pick up their stuff also, or will it be left on the ground. The console says they pick back up their stuff,but I know there have been items that I have seen in item viewer, but never make it to mules, and not there when I manually load the char and check...
I hate to put this in issues, but I have yet to locate a forum...
Thanks,
Ax

Further stability patches

This is a patch (attached in next comment) to add a bit more stability. It fixes two problems that I have:

  1. Sometimes the profile json files get corrupted (I think my disk was temporarily full or something).
  2. Every once in a while an exception would get thrown and D2BotMule.dbj would hang. The script would die but the instance wouldn't get restarted because HeartBeat.js would still be running.

From Bad to Worse

ok, so I've been having a lag issue with the new temp version (that i got as a ZIP file from a friend) so i got GIT and get a GOOD copy from here, the lag wasn't as bad but started getting crash errors...i tried using the D2M.dll from the master and then i got another crash, so i changed it back, and continued to get a crash. So, I did a sync to make sure I was using the latest D2M.dll and I'm still getting a crash. i am attaching a screen shot of the error crash and a copy past of the info it gives. I run windows 7 dual core Pentium 3.0 GHz processor, 64 bit, 10 GiGs of memory, if you need other system specs just let me know...I typically don't have these kind of issues and reporting like this is new to me, so I'm not sure what info you need or don't need, and how to get the info to ya. I really like the way the new temp version handles multiple leechers (not having to make a char config for a temp char is awesome). can i use the new scripts with the old core? (7 hours later), so after I get this error I still have multiple Game.exe open, oh yea i run proxies so i can up to 8 in a game and more than 12 D2 windows open (12 is the most I've done 8 in 1 game, and 4 in another) back when i didn't have these issues. Anyway this crash leaves game.exe's open and the only way to close the processes is to restart my computer. Ater a reboot I retry the bot now I open a single profile and after getting to channel the bot manager just closes, not even an error any more. I'm going to get a copy of the current master and try running it and see what happens, man I hate having all those temp configs...
info from the error:
Problem signature:
Problem Event Name: CLR20r3
Problem Signature 01: d2bot.exe
Problem Signature 02: 1.0.0.0
Problem Signature 03: 520eb25c
Problem Signature 04: D2Bot
Problem Signature 05: 1.0.0.0
Problem Signature 06: 520eb25c
Problem Signature 07: 59
Problem Signature 08: 31d
Problem Signature 09: System.NullReferenceException
OS Version: 6.1.7601.2.1.0.768.3
Locale ID: 1033
Additional Information 1: 0a9e
Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
Additional Information 3: 0a9e
Additional Information 4: 0a9e372d3b4ad19135b953a78882e789

Read our privacy statement online:
http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409

If the online privacy statement is not available, please read our privacy statement offline:
C:\Windows\system32\en-US\erofflps.txt

http://imgur.com/gzxqxOI

No gold pickup / item selling

So my not keeps getting items, identifying them, and dropping them without selling them, and also doesn't pickup gold. So after a little time, my not has zero gold.

I'm going to try to redownload everything when I get home and see if that solves the issue.

DClone not running

I have the following configuration settings set in 8 of my bot config files:
Config.StopOnDClone = false;
Config.SoJWaitTime = 30;
Config.KillDclone = true;
Config.DCloneQuit = false;

I am using 2 different configs at the moment. One is for the Wakka / AutoBaal combo. The other is DiabloHelper / BaalHelper. My bots all run together. If my bots are using the wakka/autobaal configuration then the above config settings work and they'll actually go to act 2 palace cellar to try and kill the clone. If they are running scripts DiabloHelper/BaalHelper then the config settings above do not work and they wont try to kill the clone if he walks.

With the Wakka/AutoBaal combo, it gets reported out to the console that SOJ's are sold and also when Diablo walks the earth.

When configured for DiabloHelper/BaalHelper they report the SOJ messages out to the console but they do not report to the console when Diablo Walks the earth. Its like they ignore that message and so will never try to go after the dclone. They will sit in act five waiting out the time specified by Config.SoJWaitTime but never recognize when he actually walks the earth.

barb attack low mana bug/patch

Hi

I will sometimes see this getting put into d2bs.log file

[Strict Warning] Code(162) File(c:\d2bs\kolbot\libs\common\attacks\barbarian.js:114) reference to undefined property Config.AttackSkill[(index + 1)] Line: (null)

Looking over the code there is a minor bug with barb attack with low mana and when the unit is immune to the low mana attack skill.

        // Low mana skill
        if (Config.AttackSkill[index] > -1 && Config.AttackSkill[Config.AttackSkill.length - 1] > -1 && Skill.getManaCost(Config.AttackSkill[index]) > me.mp) {
            index = Config.AttackSkill.length - 1;
        }

        // Check Immunities
        if (!Attack.checkResist(unit, this.skillElement[index])) {
            if (Config.AttackSkill[index + 1] > -1 && Attack.checkResist(unit, this.skillElement[index + 1])) {
                index = index + 1;
            } else {
                return 1;
            }
        }

When in low mana situation 'index' will be set to the last element in the Config.AttackSkill array. In the event the unit is immune to this attack the code is doing a 'Config.AttackSkill[index + 1]', which is beyond the end of the array.

patch:

http://www.gotwalls.com/files/barb_low_mana_fix.diff

thanks
-ack

TristramLeech, TravincalLeech, modified Mephisto, Diablo, Andarial.

Two new scripts, support for the two new scripts in existing scripts.
Supporting the red portal at mephisto
Better chest control
Changes to how "experience" is sent to console (Thanks to a mix of MrSithSqirrel, Malik)

Config.js (Obviously they need to be all added to config files aswell)

    Tristram: {
        PortalLeech: false
    },
    TristramLeech: {
        Leader: "",
        Weakling: false
    },
    Travincal: {
        PortalLeech: false
    },
    TravincalLeech: {
        Leader: ""
    },
    Mephisto: {
        TakeRedPortal: false
    },

Andariel.js (Add for after Andariel is killed, you get some good drops from the bodies, chests...etc)

    if (Config.OpenChests) {
        Misc.openChestsInArea(37);
    }

Mephisto.js (Remove the old openchest setting for the two racks and change it so after they have killed mephisto the character will clear chests as old function was missing loads of chests especialy the special chest at back of room)

    if (Config.OpenChests) {
        Misc.openChestsInArea(102);
    }

Mephisto.js (Delete commented code and switch to the following

    if (Config.Mephisto.TakeRedPortal) {
        Pather.moveTo(17590, 8068);
        delay(1000);
        Pather.moveTo(17601, 8070);
        delay(500);
        Pather.usePortal(null);
    }

Diablo.js / DiabloHelper.js aswell? (Add just after the followpath cleared function, so after it moves onces, kills it checks for the chest/stashs withing a 5 block radius, high runes are common in Chaos)

            if (Config.OpenChests) {
                Attack.openChests(5);
            }

Travincal.js (Added portal support for leechers, compare to see changes)

/**
*   @filename   Travincal.js
*   @author     kolton
*   @desc       Kill Counncil members in Travincal
*/

function Travincal() {
    var i, orgX, orgY;

    this.buildList = function () {
        var monsterList = [],
            monster = getUnit(1);

        if (monster) {
            do {
                if ([345, 346, 347].indexOf(monster.classid) > -1 && Attack.checkMonster(monster)) {
                    monsterList.push(copyUnit(monster));
                }
            } while (monster.getNext());
        }

        return monsterList;
    }

    Town.doChores();
    Pather.useWaypoint(83);
    Precast.doPrecast(true);

    orgX = me.x;
    orgY = me.y;

    if (Config.Travincal.PortalLeech) {
        Pather.moveTo(orgX + 85, orgY - 139);
        Attack.clear(10); 
        Pather.moveTo(orgX + 85, orgY - 139);
        Pather.makePortal();
        delay(1000);
        Precast.doPrecast(true);
    }

    Pather.moveTo(orgX + 101, orgY - 56);

    if (me.classid === 4 && !me.getSkill(54, 1) && me.gametype === 1) {
        Pather.moveToExit([100, 83], true);
    }

    Attack.clearList(this.buildList());

    return true;
}

TravincalLeech.js (New Script)

/**
*   @filename   TravincalLeech.js
*   @author     ToS/XxXGoD/YGM
*   @desc       Travinical Leech
*/

function TravincalLeech() {

    var leader, i;

    Town.doChores();
    Pather.useWaypoint("random");
    Precast.doPrecast(true);
    Pather.useWaypoint(75);
    Town.move("portalspot"); 

    leader = Config.TravincalLeech.Leader

    for (i = 0; i < 100; i += 1) {
        if (Pather.usePortal(83, null)) { // leader fails so take first portal to location
            break;
        }
            delay(1000);
    }

    if (i === 100) {
        throw new Error("No portal found to Travincal.");
    }

    leader = getParty(leader);

    while (leader.area === 83) {
        delay(1000);
    }

    return true;
}

TristramLeech.js (New Script)

/**
*   @filename   TristramLeech.js
*   @author     ToS/XxXGoD/YGM
*   @desc       Tristram Leech (Helper)
*/

function TristramLeech() {

    var leader, i;

    Town.doChores();
    Pather.useWaypoint("random") // Random waypoint / antipk
    Precast.doPrecast(true); // precast
    Pather.useWaypoint(1); // Back To Rouge
    Town.move("portalspot"); // Portal Spot

    leader = Config.TristramLeech.Leader

    for (i = 0; i < 100; i += 1) {
        if (Pather.usePortal(38, leader)) {
            break;
        }
            delay(1000);
    }

    if (i === 100) {
        throw new Error("No portal found to Tristram.");
    }

    delay(3000);

    if (Config.TristramLeech.Weakling) {

        Pather.moveTo(25175, 5125);  //Down
        Attack.clear(20);   
        Pather.moveTo(25175, 5158);  //Down
        Attack.clear(20);   
        Pather.moveTo(25167, 5189);  //Corner
        Attack.clear(20);   
        Pather.moveTo(25139, 5187);  //left
        Attack.clear(20);   
        Pather.moveTo(25127, 5161);  //Doorway Avoid
        Pather.moveTo(25116, 5135);  //Mid
        Attack.clear(15);   
        Pather.moveTo(25083, 5135);  //Out Mid leftup
        Pather.moveTo(25084, 5185);  //Down Left 
        Attack.clear(20);   
        Pather.moveTo(25047, 5196);  //Left Corner
        Attack.clear(20);   
        Pather.moveTo(25046, 5150);  //Left Mid
        Attack.clear(20);   
        Pather.moveTo(25052, 5108);  //Left Mid Upper
        Attack.clear(20);   
        Pather.moveTo(25051, 5058);  //Top
        Attack.clear(15);   
        Pather.moveTo( 25096, 5053);  //Working down right
        Pather.moveTo( 25116, 5074);  //Right top
        Attack.clear(20);   
        Pather.moveTo(25119, 5094);  //Top of mid
        Attack.clear(20);   

    } else {

        Pather.moveTo(25096, 5053);  //Working down right
        Pather.moveTo(25116, 5074);  //Right top
        Attack.clear(20);   
        Pather.moveTo(25119, 5094);  //Top of mid
        Attack.clear(20);   
        Attack.clear(20);             // To clear start
        Pather.moveTo(25175, 5125);  //Down
        Attack.clear(20);   
        Pather.moveTo(25175, 5158);  //Down
        Attack.clear(20);   
        Pather.moveTo(25167, 5189);  //Corner
        Attack.clear(20);   
        Pather.moveTo(25139, 5187);  //left
        Attack.clear(20);   
        Pather.moveTo(25127, 5161);  //Doorway Avoid
        Pather.moveTo(25116, 5135);  //Mid
        Attack.clear(15);   
        Pather.moveTo(25083, 5135);  //Out Mid leftup
        Pather.moveTo(25084, 5185);  //Down Left 
        Attack.clear(20);   
        Pather.moveTo(25047, 5196);  //Left Corner
        Attack.clear(20);   
        Pather.moveTo(25046, 5150);  //Left Mid
        Attack.clear(20);   
        Pather.moveTo(25052, 5108);  //Left Mid Upper
        Attack.clear(20);   
        Pather.moveTo(25051, 5058);  //Top
        Attack.clear(15);   
        Pather.moveTo(25096, 5053);  //Working down right
        Pather.moveTo(25116, 5074);  //Right top
        Attack.clear(20);   
        Pather.moveTo(25119, 5094);  //Top of mid
        Attack.clear(20);   
    }

    return true;
}

Tristram.js (Added leech support, compare to see changes)

/**
*   @filename   Tristram.js
*   @author     kolton
*   @desc       Clear Tristram
*/

function Tristram() {
    if (!me.getQuest(4, 0)) {
        throw new Error("You don't have the Cain quest");
    }

    var i;

    Town.doChores();
    Pather.useWaypoint(4);
    Precast.doPrecast(true);

    if (!Pather.moveToPreset(me.area, 1, 737, 0, 0, false, true)) {
        throw new Error("Failed to move to Rakanishu");
    }

    Attack.clear(15, 0, getLocaleString(2872)); // Rakanishu

    for (i = 0; i < 5; i += 1) {
        if (Pather.usePortal(38)) {
            break;
        }
        delay(1000);
    }

    if (Config.Tristram.PortalLeech) {

        Pather.makePortal();
        delay(2000);
        Precast.doPrecast(true);

        Pather.moveTo(25096, 5053);  //Working down right
        Pather.moveTo(25116, 5074);  //Right top
        Attack.clear(20);   
        Pather.moveTo(25119, 5094);  //Top of mid
        Attack.clear(20);   
        Attack.clear(20);             // To clear start
        Pather.moveTo(25175, 5125);  //Down
        Attack.clear(20);   
        Pather.moveTo(25175, 5158);  //Down
        Attack.clear(20);   
        Pather.moveTo(25167, 5189);  //Corner
        Attack.clear(20);   
        Pather.moveTo(25139, 5187);  //left
        Attack.clear(20);   
        Pather.moveTo(25127, 5161);  //Doorway Avoid
        Pather.moveTo(25116, 5135);  //Mid
        Attack.clear(15);   
        Pather.moveTo(25083, 5135);  //Out Mid leftup
        Pather.moveTo(25084, 5185);  //Down Left 
        Attack.clear(20);   
        Pather.moveTo(25047, 5196);  //Left Corner
        Attack.clear(20);   
        Pather.moveTo(25046, 5150);  //Left Mid
        Attack.clear(20);   
        Pather.moveTo(25052, 5108);  //Left Mid Upper
        Attack.clear(20);   
        Pather.moveTo(25051, 5058);  //Top
        Attack.clear(15);   
        Pather.moveTo(25096, 5053);  //Working down right
        Pather.moveTo(25116, 5074);  //Right top
        Attack.clear(20);   
        Pather.moveTo(25119, 5094);  //Top of mid
        Attack.clear(20);   

    } else {

        Attack.clearLevel(Config.ClearType);

    }

    return true;
}

Misc.js, compare to default to look for changes.

/**
*   @filename   Misc.js
*   @author     kolton
*   @desc       misc library containing Skill, Misc and Sort classes
*/

// Raw Game Timer
function gameTimer(tick) {
    if (!tick) {
        return "";
    }

    var min, sec;

    min = Math.floor((getTickCount() - tick) / 60000).toString();

    if (min <= 9) {
        min = "0" + min;
    }

    sec = (Math.floor((getTickCount() - tick) / 1000) % 60).toString();

    if (sec <= 9) {
        sec = "0" + sec;
    }

    return min + "m " + sec + "s";
}

var gameTime = getTickCount();

// Raw Seconds Timer
function secondsTimer(tick) {
    if (!tick) {
        return "";
    }

    var sec;

    sec = (Math.floor((getTickCount() - tick) / 1000)).toString();

    if (sec <= 9) {
        sec = "0" + sec;
    }

    return sec;
}

var gameSeconds = getTickCount();

var Skill = {
    // Cast a skill on self, Unit or coords
    cast: function (skillId, hand, x, y) {
        if (me.inTown && !this.townSkill(skillId)) {
            return false;
        }

        if (!me.getSkill(skillId, 1)) {
            return false;
        }

        if (typeof skillId === "undefined") {
            throw new Error("Skill.cast: Must supply a skill ID");
        }

        var i, n, clickType, shift;

        if (typeof hand === "undefined") {
            hand = 0;
        }

        if (typeof x === "undefined") {
            x = me.x;
        }

        if (typeof y === "undefined") {
            y = me.y;
        }

        switch (hand) {
        case 0:
            clickType = 3;
            shift = 0;
            break;
        case 1:
            clickType = 0;
            shift = 1;
            break;
        case 2: // For melee skills that don't need shift
            clickType = 0;
            shift = 0;
            break;
        }

        if (!this.setSkill(skillId, hand)) {
            return false;
        }

MainLoop:
        for (n = 0; n < 3; n += 1) {
            if (typeof x === "object") {
                clickMap(clickType, shift, x);
            } else {
                clickMap(clickType, shift, x, y);
            }

            delay(30);

            if (typeof x === "object") {
                clickMap(clickType + 2, shift, x);
            } else {
                clickMap(clickType + 2, shift, x, y);
            }

            for (i = 0; i < 4; i += 1) {
                if (me.attacking) {
                    break MainLoop;
                }

                delay(40);
            }
        }

        while (me.attacking) {
            delay(10);
        }

        if (this.isTimed(skillId)) { // account for lag, state 121 doesn't kick in immediately
            for (i = 0; i < 10; i += 1) {
                if (me.getState(121)) {
                    break;
                }

                delay(10);
            }
        }

        return true;
    },

    // Put a skill on desired slot
    setSkill: function (skillId, hand) {
        if (!me.getSkill(skillId, 1)) {
            return false;
        }

        if (typeof hand === "undefined") {
            hand = 0;
        }

        // Check if the skill is already set
        if (me.getSkill(hand === 0 ? 2 : 3) === skillId) {
            return true;
        }

        if (me.setSkill(skillId, hand)) {
            return true;
        }

        return false;
    },

    // Timed skills
    isTimed: function (skillId) {
        return [15, 25, 27, 51, 56, 59, 62, 64, 121, 225, 223, 228, 229, 234, 244, 247, 249, 250, 256, 268, 275, 277, 279].indexOf(skillId) > -1;
    },

    // Skills that cn be cast in town
    townSkill: function (skillId) {
        return [32, 40, 43, 50, 52, 58, 60, 68, 75, 85, 94, 117, 221, 222, 226, 227, 235, 236, 237, 246, 247, 258, 267, 268, 277, 278, 279].indexOf(skillId) > -1;
    }
};

var Misc = {
    // Click something
    click: function (button, shift, x, y) {
        if (arguments.length < 2) {
            throw new Error("Misc.click: Needs at least 2 arguments.");
        }

        switch (arguments.length) {
        case 2:
            clickMap(button, shift, me.x, me.y);
            delay(20);
            clickMap(button + 2, shift, me.x, me.y);
            break;
        case 3:
            if (typeof (x) !== "object") {
                throw new Error("Misc.click: Third arg must be a Unit.");
            }

            clickMap(button, shift, x);
            delay(20);
            clickMap(button + 2, shift, x);
            break;
        case 4:
            clickMap(button, shift, x, y);
            delay(20);
            clickMap(button + 2, shift, x, y);
            break;
        }

        return true;
    },

    // Check if a player is in your party
    inMyParty: function (name) {
        var player, myPartyId;

        try {
            player = getParty();

            if (!player) {
                return false;
            }

            myPartyId = player.partyid;
            player = getParty(name); // May throw an error

            if (player && player.partyid !== 65535 && player.partyid === myPartyId) {
                return true;
            }
        } catch (e) {
            player = getParty();

            if (player) {
                myPartyId = player.partyid;

                while (player.getNext()) {
                    if (player.partyid !== 65535 && player.partyid === myPartyId) {
                        return true;
                    }
                }
            }
        }

        return false;
    },

    // Open a chest Unit
    openChest: function (unit) {
        if (!unit || unit.mode || unit.x === 12526 || unit.x === 12565) { // Skip invalid, opened and Countess chests
            return false;
        }

        if (me.classid !== 6 && unit.islocked && !me.findItem("key", 0, 3)) { // locked chest, no keys
            return false;
        }

        var i, tick;

        for (i = 0; i < 3; i += 1) {
            if (getDistance(me, unit) < 4 || Pather.moveToUnit(unit, 2, 0)) {
                unit.interact();
            }

            tick = getTickCount();

            while (getTickCount() - tick < 1000) {
                if (unit.mode) {
                    return true;
                }

                delay(10);
            }
        }

        return false;
    },

    // Open all chests that have preset units in an area
    openChestsInArea: function (area) {
        if (!area) {
            area = me.area;
        }

        var chest,
            presetUnits = getPresetUnits(area),
            chestIds = [5, 6, 87, 92, 104, 105, 106, 107, 143, 140, 141, 144, 146, 147, 148, 176, 177, 181, 183, 198, 240, 241, 242, 243, 329, 330, 331, 332, 333, 334, 335,
                        336, 354, 355, 356, 371, 387, 389, 390, 391, 397, 405, 406, 407, 413, 420, 424, 425, 430, 431, 432, 433, 454, 455, 501, 502, 504, 505, 580, 581];

        if (!presetUnits) {
            return false;
        }

        while (presetUnits.length > 0) {
            presetUnits.sort(Sort.presetUnits);

            if (chestIds.indexOf(presetUnits[0].id) > -1) {
                Pather.moveToUnit(presetUnits[0], 2, 0);

                chest = getUnit(2);

                if (chest) {
                    do {
                        if (chestIds.indexOf(chest.classid) > -1 && getDistance(me, chest) < 5 && this.openChest(chest)) {
                            Pickit.pickItems();
                        }
                    } while (chest.getNext());
                }
            }

            presetUnits.shift();
        }

        return true;
    },

    // Use a shrine Unit
    getShrine: function (unit) {
        var i, tick;

        for (i = 0; i < 3; i += 1) {
            if (getDistance(me, unit) < 4 || Pather.moveToUnit(unit, 2, 0)) {
                unit.interact();
            }

            tick = getTickCount();

            while (getTickCount() - tick < 1000) {
                if (unit.mode) {
                    return true;
                }

                delay(10);
            }
        }

        return false;
    },

    // Check all shrines in area and get the first one of specified type
    getShrinesInArea: function (area, type) {
        var i, coords, shrine,
            shrineLocs = [],
            shrineIds = [2, 81, 83],
            unit = getPresetUnits(area);

        if (unit) {
            for (i = 0; i < unit.length; i += 1) {
                if (shrineIds.indexOf(unit[i].id) > -1) {
                    shrineLocs.push([unit[i].roomx * 5 + unit[i].x, unit[i].roomy * 5 + unit[i].y]);
                }
            }
        }

        while (shrineLocs.length > 0) {
            shrineLocs.sort(Sort.points);

            coords = shrineLocs.shift();

            Pather.moveTo(coords[0], coords[1], 2, false, true);

            shrine = getUnit(2, "shrine");

            if (shrine) {
                do {
                    if (shrine.objtype === type) {
                        this.getShrine(shrine);

                        return true;
                    }
                } while (shrine.getNext());
            }
        }

        return false;
    },

    // Log kept item stats in the manager.
    logItem: function (action, unit, keptLine) {
        var i, val, code, desc,
            stringColor = "",
            color = -1,
            name = unit.fname.split("\n").reverse().join(" ").replace(/ÿc[0-9!"+<;.*]|^ /, "");

        desc = unit.description.split("\n");

        // Lines are normally in reverse. Add color tags if needed and reverse order.
        for (i = 0; i < desc.length; i += 1) {
            if (desc[i].match(/^ÿ/)) {
                stringColor = desc[i].substring(0, 3);
            } else {
                desc[i] = stringColor + desc[i];
            }
        }

        desc = desc.reverse().join("\n");
        color = unit.getColor();
        desc += ("\nÿc0Item Level: " + unit.ilvl);

        if (action === "Kept") {
            val = DataFile.getStats().lastArea;

            if (val) {
                desc += ("\nÿc0Area: " + val);
            }
        }

        // experimental
        /*switch (unit.quality) {
        case 5:
            // needs item by item handling :/
            break;
        case 7:
            for (i = 0; i < 401; i += 1) {
                if (unit.fname.split("\n").reverse()[0].indexOf(getLocaleString(getBaseStat(17, i, 2))) > -1) {
                    code = getBaseStat(17, i, "invfile");

                    break;
                }
            }

            break;
        }*/

        if (!code) {
            code = getBaseStat(0, unit.classid, 'normcode') || unit.code;
            code = code.replace(" ", "");

            if ([10, 12, 58, 82, 83, 84].indexOf(unit.itemType) > -1) {
                code += (unit.gfx + 1);
            }
        }

        if (keptLine) {
            desc += ("\nÿc0Line: " + keptLine);
        }

        D2Bot.printToItemLog(action + " " + name, desc, code, unit.quality, color);
    },

    // Change into werewolf or werebear
    shapeShift: function (mode) { // 0 = werewolf, 1 = werebear
        if (arguments.length === 0 || mode < 0 || mode > 2) {
            throw new Error("Misc.shapeShift: Invalid parameter");
        }

        var i, tick,
            state = mode === 0 ? 139 : 140,
            skill = mode === 0 ? 223 : 228;

        for (i = 0; i < 3; i += 1) {
            Skill.cast(skill, 0);

            tick = getTickCount();

            while (getTickCount() - tick < 2000) {
                if (me.getState(state)) {
                    return true;
                }

                delay(10);
            }
        }

        return false;
    },

    // Change back to human shape
    unShift: function () {
        var i, tick;

        if (me.getState(139) || me.getState(140)) {
            for (i = 0; i < 3; i += 1) {
                Skill.cast(me.getState(139) ? 223 : 228);

                tick = getTickCount();

                while (getTickCount() - tick < 2000) {
                    if (!me.getState(139) && !me.getState(140)) {
                        return true;
                    }

                    delay(10);
                }
            }
        } else {
            return true;
        }

        return false;
    },

    // Teleport with slot II
    teleSwitch: function () {
        this.oldSwitch = me.weaponswitch;

        Precast.weaponSwitch();

        return true;
    },

    // Go to town when low on hp/mp or when out of potions. can be upgraded to check for curses etc.
    townCheck: function () {
        var potion, check,
            needhp = true,
            needmp = true;

        if (Config.TownCheck && !me.inTown) {
            if (Config.BeltColumn.indexOf("hp") > -1) {
                potion = me.getItem(-1, 2); // belt item

                if (potion) {
                    do {
                        if (potion.code.indexOf("hp") > -1) {
                            needhp = false;

                            break;
                        }
                    } while (potion.getNext());
                }

                if (needhp) {
                    print("We need healing potions");

                    check = true;
                }
            }

            if (Config.BeltColumn.indexOf("mp") > -1) {
                potion = me.getItem(-1, 2); // belt item

                if (potion) {
                    do {
                        if (potion.code.indexOf("mp") > -1) {
                            needmp = false;

                            break;
                        }
                    } while (potion.getNext());
                }

                if (needmp) {
                    print("We need mana potions");

                    check = true;
                }
            }

            if (Config.OpenChests && Town.needKeys()) {
                check = true;
            }
        }

        if (check) {
            scriptBroadcast("townCheck");
        }

        return true;
    },

    // Log someone's gear
    spy: function (name) {
        if (!isIncluded("oog.js")) {
            include("oog.js");
        }

        if (!isIncluded("common/prototypes.js")) {
            include("common/prototypes.js");
        }

        var i, items,
            unit = getUnit(0, name);

        if (!unit) {
            print("player not found");

            return false;
        }

        items = unit.getItems();

        for (i = 0; i < items.length; i += 1) {
            this.logItem(name, items[i]);
        }

        return true;
    },

    // hopefully multi-thread and multi-profile friendly txt func
    fileAction: function (path, mode, msg) {
        var i, file,
            contents = "";

MainLoop:
        for (i = 0; i < 30; i += 1) {
            try {
                file = File.open(path, mode);

                switch (mode) {
                case 0: // read
                    contents = file.readLine();

                    break MainLoop;
                case 1: // write
                case 2: // append
                    file.write(msg);

                    break MainLoop;
                }
            } catch (e) {

            } finally {
                file.close();
            }

            delay(100);
        }

        return mode === 0 ? contents : true;
    },

    // Report script errors to logs/ScriptErrorLog.txt
    errorReport: function (msg) {
        var h, m, s, date;

        date = new Date();
        h = date.getHours();
        m = date.getMinutes();
        s = date.getSeconds();

        showConsole();
        print(msg);
        this.fileAction("logs/ScriptErrorLog.txt", 2, "[" + (h < 10 ? "0" + h : h) + ":" + (m < 10 ? "0" + m : m) + ":" + (s < 10 ? "0" + s : s) + "] <" + me.profile + "> " + msg.replace(/ÿc[0-9!"+<;.*]/gi, "") + "\n");
    }
};

var Sort = {
    // Sort units by comparing distance between the player
    units: function (a, b) {
        return getDistance(me, a) - getDistance(me, b);
    },

    // Sort preset units by comparing distance between the player (using preset x/y calculations)
    presetUnits: function (a, b) {
        return getDistance(me, a.roomx * 5 + a.x, a.roomy * 5 + a.y) - getDistance(me, b.roomx * 5 + b.x, b.roomy * 5 + b.y);
    },

    // Sort arrays of x,y coords by comparing distance between the player
    points: function (a, b) {
        return getDistance(me, a[0], a[1]) - getDistance(me, b[0], b[1]);
    }
};

var Experience = {
    totalExp: [0, 0, 500, 1500, 3750, 7875, 14175, 22680, 32886, 44396, 57715, 72144, 90180, 112725, 140906, 176132, 220165, 275207, 344008, 430010, 537513, 671891, 839864, 1049830, 1312287, 1640359, 2050449, 2563061, 3203826, 3902260, 4663553, 5493363, 6397855, 7383752, 8458379, 9629723, 10906488, 12298162, 13815086, 15468534, 17270791, 19235252, 21376515, 23710491, 26254525, 29027522, 32050088, 35344686, 38935798, 42850109, 47116709, 51767302, 56836449, 62361819, 68384473, 74949165, 82104680, 89904191, 98405658, 107672256, 117772849, 128782495, 140783010, 153863570, 168121381, 183662396, 200602101, 219066380, 239192444, 261129853, 285041630, 311105466, 339515048, 370481492, 404234916, 441026148, 481128591, 524840254, 572485967, 624419793, 681027665, 742730244, 809986056, 883294891, 963201521, 1050299747, 1145236814, 1248718217, 1361512946, 1484459201, 1618470619, 1764543065, 1923762030, 2097310703, 2286478756, 2492671933, 2717422497, 2962400612, 3229426756, 3520485254, 0, 0],
    nextExp: [0, 500, 1000, 2250, 4125, 6300, 8505, 10206, 11510, 13319, 14429, 18036, 22545, 28181, 35226, 44033, 55042, 68801, 86002, 107503, 134378, 167973, 209966, 262457, 328072, 410090, 512612, 640765, 698434, 761293, 829810, 904492, 985897, 1074627, 1171344, 1276765, 1391674, 1516924, 1653448, 1802257, 1964461, 2141263, 2333976, 2544034, 2772997, 3022566, 3294598, 3591112, 3914311, 4266600, 4650593, 5069147, 5525370, 6022654, 6564692, 7155515, 7799511, 8501467, 9266598, 10100593, 11009646, 12000515, 13080560, 14257811, 15541015, 16939705, 18464279, 20126064, 21937409, 23911777, 26063836, 28409582, 30966444, 33753424, 36791232, 40102443, 43711663, 47645713, 51933826, 56607872, 61702579, 67255812, 73308835, 79906630, 87098226, 94937067, 103481403, 112794729, 122946255, 134011418, 146072446, 159218965, 173548673, 189168053, 206193177, 224750564, 244978115, 267026144, 291058498, 0, 0],

    // Percent progress into the current level. Format: xx.xx%
    progress: function () {
        return me.getStat(12) === 99 ? 0 : (((me.getStat(13) - this.totalExp[me.getStat(12)]) / this.nextExp[me.getStat(12)]) * 100).toFixed(2);
    },

    // Total experience gained in current run
    gain: function () {
        return (me.getStat(13) - DataFile.getStats().experience);
    },

    // Percent experience gained in current run
    gainPercent: function () {
        return me.getStat(12) === 99 ? 0 : (this.gain() * 100 / this.nextExp[me.getStat(12)]).toFixed(6);
    },

    // Runs until next level
    runsToLevel: function () {
        return Math.round(((100 - this.progress()) / 100) * this.nextExp[me.getStat(12)] / this.gain());
    },

    // Total runs needed for next level (not counting current progress)
    totalRunsToLevel: function () {
        return Math.round(this.nextExp[me.getStat(12)] / this.gain());
    },

    //Time left till next level
    hoursLeft: function () {
        return (((this.runsToLevel() * secondsTimer(gameSeconds)) / 3600).toFixed(2));
    },

    //Time left till next level.
    timeToLevel: function () {
    var totalTime = this.runsToLevel() * secondsTimer(gameSeconds);
    var tDays = Math.floor(totalTime / 86400),
        tHours = Math.floor((totalTime % 86400) / 3600),
        tMinutes = Math.floor(((totalTime % 86400) % 3600) / 60),
        tSeconds = ((totalTime % 86400) % 3600) % 60;

    //return tDays + "d " + tHours + "h " + tMinutes + "m " + tSeconds + "s";
    //return tDays + "d " + tHours + "h " + tMinutes + "m";
    return tDays + " days " + tHours + " hours " + tMinutes + " minutes";
    },

    // Log to manager
    log: function () {
        var string,
            gain = this.gain(),
            progress = this.progress(),
            runsToLevel = this.runsToLevel(),
            totalRunsToLevel = this.totalRunsToLevel(),
            hoursLeft = this.hoursLeft(),
            timeToLevel = this.timeToLevel();

        //string = "Game: " + me.gamename + ", XP Gain: " + gain + ", Level: " + me.getStat(12) + " (" + progress + "%), Next: " + runsToLevel + "/" + totalRunsToLevel;
        //string = "[Game: " + me.gamename + "//" + me.gamepassword + "] [Game Time: " + gameTimer(gameTime) + "] [Level: " + me.getStat(12) + " (" + progress + "%)] [XP Gained: " + gain + "] [Games to Level eta: " + runsToLevel + "] [Time to Level eta: " + hoursLeft + "]";
        string = "[Game: " + me.gamename + "//" + me.gamepassword + "] [Game Time: " + gameTimer(gameTime) + "] [Level: " + me.getStat(12) + " (" + progress + "%)] [XP Gained: " + gain + "] [Games to Level eta: " + runsToLevel + "] [Time to Level eta: " + timeToLevel + "]";

        if (gain) {
            D2Bot.printToConsole(string + ";4");

            if (me.getStat(12) > DataFile.getStats().level) {
                D2Bot.printToConsole("Congrats! You gained a level. Current level:" + me.getStat(12) + ";5");
            }
        }
    }
};

var Packet = {
    buyItem: function (item, shiftBuy) {
        var i, tick, container,
            itemCount = me.itemcount,
            npc = getInteractedNPC();

        if (!npc) {
            throw new Error("buyItem: No NPC menu open.");
        }

        if (me.getStat(14) + me.getStat(15) < item.getItemCost(0)) { // Can we afford the item?
            return false;
        }

        for (i = 0; i < 3; i += 1) {
            sendPacket(1, 0x32, 4, npc.gid, 4, item.gid, 4, shiftBuy ? 0x80000000 : 0, 4, 0);

            tick = getTickCount();

            while (getTickCount() - tick < 2000) {
                if (shiftBuy) {
                    switch (item.classid) {
                    case 529: // tp scroll
                        container = me.getItem(518);

                        if (container && container.getStat(70) === 20) {
                            return true;
                        }

                        break;
                    case 530: // id scroll
                        container = me.getItem(519);

                        if (container && container.getStat(70) === 20) {
                            return true;
                        }

                        break;
                    case 543: // key
                        container = me.getItem(543);

                        if (container && container.getStat(70) === 12) {
                            return true;
                        }

                        break;
                    }
                }

                if (itemCount !== me.itemcount) {
                    return true;
                }

                delay(10);
            }
        }

        return false;
    },
    castSkill: function (hand, wX, wY) {
        hand = (hand === 0) ? 0x0c : 0x05;
        sendPacket(1, hand, 2, wX, 2, wY);
    },
    unitCast: function (hand, who) {
        hand = (hand === 0) ? 0x11 : 0x0a;
        sendPacket(1, hand, 4, who.type, 4, who.gid);
    },
    moveNPC: function (npc, dwX, dwY) {
        sendPacket(1, 0x59, 4, npc.type, 4, npc.gid, 4, dwX, 4, dwY);
    },
    teleWalk: function (wX, wY) {
        sendPacket(1, 0x5f, 2, wX, 2, wY);
        delay(me.ping + 5);
        sendPacket(1, 0x4b, 4, me.type, 4, me.gid);
    },
    flash: function (gid) {
        sendPacket(1, 0x4b, 4, 0, 4, gid);
    },
    changeStat: function (stat, value) {
        if (value > 0) {
            getPacket(1, 0x1d, 1, stat, 1, value);
        }
    }
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.