AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Diablo 2 Expansion Auto-Leveling Script

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
aobrien



Joined: 14 Feb 2008
Posts: 27

PostPosted: Tue May 13, 2008 8:04 am    Post subject: Diablo 2 Expansion Auto-Leveling Script Reply with quote

First, I would like to state the following:
1) If you copy/use this script please post a reply stating as such and if you like it or not and how much experience/hour you are getting. I just want to know how much interest there is in the script and how other characters compare to mine.
2) As crazy as it may seem - I wrote this script for my own enjoyment. I don't play Diablo on line, so I don't care if Blizzard pulls my account because I don't have one.
3) The fact that AHK could automate Diablo gave me new renewed interest in playing the game - or Auto-Leveling my characters until they were L99. There are several routines in the script which are quite powerfull and could be adapted to other games. Pixel_Search() and Pixel_Area() in particular.
4) Read all of the instructions before going any further, then read them again step-by-step as you attempt your first Auto-Leveling run.
5) There are around 1000 lines of code and it took me several months to get the script to this level of maturity.

Script Useage:
1) This script was written for DiabloII Expansion:Harrogath:Frigid Highlands.
2) Change the "User Variables" in the script to match your situation. The only variable that really needs to be changed is "Character_Name" and "Run_Speed" and the "Run_Speed "If" statement.
3) Search for "If Character_Name" (8 occurrences) - understand what is trying to be accomplished with the statement - make any necessary changes.
4) Print a hard copy of the script.
5) Start the game
6) Manually, launch the character that you want to Auto-Level
7) Manually, use the Waypoint to transport to Harrogath.
8 ) Set the video resolution to 800x600 ({ESC}/Options/Video Options)
9) Exit and Save
10) Double Click on the AHK script file.
11) CTRL-ALT-p (to begin the Auto-Leveling automation)
12) Follow the script on the paper hard copy to help understand what is actually happening.
13) CTRL-{F1} to exit the script automation.

Script Description (this is a short description of what the script does from start to finish):
1) Start the game - select single player, select the first player in the list...
2) Check hireling status. This is how the script will know if you died or not. If your hireling is dead then the script will assume that you died as well. If you died then it will restore the last saved game (where you were still alive). If your hireling is still alive then it will save the game.
3) Check your vital stats (health/mana) if they are too low then it will just wait and allow them to increase.
4) If you are playing an archer, then the script will re-supply your arrows if a certian amount of time has elapsed.
5) Move to where the action is
6) Attack and check health status. If health is below the set limit then the script will jump straight to step 7.
7) Quit and Save - also takes a printscreen image every 1800 seconds (30 minutes) and saves it for later analysis.
8 ) Repeat steps 2-8

Script Performance:
Casandra, my Amazon, was getting 15,831,092 experience per hour from level 73 to level 78 on Hell Mode - took 12.63 hours to get from L73 to L78.
Casandra, my Amazon, was getting 7,123,424 experience per hour on L94 on Hell Mode - spent 11.88 hours and didn't even make L95.
As you increase in experience level above L80 Diablo DECREASES the amount of experience received for each kill. I was a little surprised when I realized this and found supporting evidence/claims on the internet.
I calculated that it would take Casandra 470.9 hours (19.6 days) to get from L70 to L99.

Have fun and good luck
aobrien

Code:


;#######################################################
;# Exit script
;#######################################################
^F1::
Reload
;ExitApp
return

;#######################################################
;# Save and Reload script
;#######################################################
^!w::
Sleep, 300
Send, ^s
Sleep, 200
Reload
Sleep, 1000
return


;#######################################################
;# Play - Starting from Single Player Menu
;#
;# Initialization Instructions:
;#   This script is written for Diablo II Expansion
;#   Harrogath:Frigid Highlands - Start the game, select
;#   the character that you want to play and use the
;#   Waypoint to transport to Harrogath. Set the video
;#   resolution to 800 x 600 ({ESC}/Options/Video Options)
;#   Exit and Save.
;#   
;#   In the script below, select which mode (Normal, Nightmare...)
;#   you will be playing.
;#
;#   The following routines are customized for my character:
;#     Initialize_Bif_Party() - Highly customized
;#     Attack() - Somewhat customized. Might work as is.
;#######################################################
^!p::

;########################
;### User Variables

Use_Debug = ON  ;Uncomment this to log debug information into diablo_log.txt

AHK_Diablo_Save_Dir =  C:\Program Files\Diablo II\save\AHK_Save ;This is the directory that the character files will be saved to.
                                                                ;  If the directory doesn't exist then AHK will create it.

;Bif is a Druid, Casandra is an amazon archer.
;Character_Name = Bif      ;This is used to copy your character files to a
Character_Name = Casandra ;  backup directory and make different decisions based upon the character.

Pct_Mana_to_Recharge = 10 ;Upon entering the game, if your Mana is less than
                          ;  this then you will seek Malta.

Pct_Health_to_Exit = 65 ;If your character health is lower than this then
                        ;  the script will imediately quit and save the game.
                        ;  I don't know how or why, but when you return you
                        ;  will have full health.

;Run_Speed is your character's running speed.
;  The higher the number the faster your character. It is
;  used by the Character_Move() routine to determine how
;  long to delay between moves. The higher the number the
;  smaller the delay. It is better to start off with a low
;  number and work your way up.
If Character_Name = Bif
  Run_Speed = 195
If Character_Name = Casandra
  Run_Speed = 185

;########################
;### Beginning of Auto-Leveling Script
ALT_TAB_Time := A_Now
ALT_TAB_Wait_Time = 1800 ;Time to wait before doing ALT_TAB. This is necessary because sometimes the windows message balloons pop-up and push Diablo into the background.

Arrow_Resupply_Time := A_Now
Arrow_Resupply_Wait_Time = 800 ;Time to wait before refilling arrows

Snapshot_Time := A_Now
Snapshot_Wait_Time = 1800 ;Time to wait before taking a screen shot of EXP.

Diablo_Play_Loop_Beginning:
Loop
{
  ;MouseClick, left,  507,  784 ;This doesn't work...Click on Diablo in the Task Bar (1280x800 resolution last of two icons). For some reason the below doesn't actually activate diablo. Sometimes the windows message balloons pop-up and push Diablo into the background.

  WinActivate, Diablo II
  WinWait, Diablo II, , 5
  if ErrorLevel
     MsgBox, Can't Find Diablo II Window
/*
  ALT_TAB_Elapsed_Time := %A_Now%
  EnvSub, ALT_TAB_Elapsed_Time, %ALT_TAB_Time%, Seconds ;Same as ET := ET - ST results given in seconds.
  If ALT_TAB_Elapsed_Time > %ALT_TAB_Wait_Time%
  {
    Send, !{TAB}
    Sleep, 300
    Send, !{TAB}
    Sleep, 5000
    ALT_TAB_Time := A_Now ;Reset the clock
  }
*/
  MouseClick, Left, 393, 307, 1  ;Single Player
  Sleep, 1000

  MouseClick, Left, 173, 133, 2  ;Select 1st Player
  Sleep, 1000

  ;MouseClick, Left, 393, 300, 1  ;Select Normal Mode
  ;MouseClick, Left, 400, 325, 1  ;Select Nightmare Mode
  ;MouseClick, Left, 393, 370, 1  ;Select Hell Mode

  If Character_Name = Casandra
    MouseClick, Left, 393, 370, 1  ;Select Hell Mode

  If Character_Name = Bif
    MouseClick, Left, 393, 370, 1  ;Select Hell Mode

  Sleep, 6000

  ;Check if Hireling is Still Alive
  Hireling_Alive := Check_Hireling_Alive()
  If Hireling_Alive = False ;Then Hireling is dead. They always return with full health.
  {
   ;Quit Game then Restore Old Game files.
   Quit_and_Save() ;Only saves
   Restore_Game_Files()
   Goto, Diablo_Play_Loop_Beginning
  }
  Else
    Save_Game_Files()

  ;Check Vitals
  Pct_Mana   := Get_Vitals_Pct_Checked("Mana", "3")
  Pct_Health := Get_Vitals_Pct_Checked("Health", "3")

  If (Pct_Mana < Pct_Mana_to_Recharge or Pct_Health < Pct_Health_to_Exit)
  {
    ;Recharge
    ;Find_Malta()
    Sleep, 30000
  }

  Arrow_Resupply_Elapsed_Time := %A_Now%
  EnvSub, Arrow_Resupply_Elapsed_Time, %Arrow_Resupply_Time%, Seconds ;Same as ET := ET - ST results given in seconds.
  If Arrow_Resupply_Elapsed_Time > %Arrow_Resupply_Wait_Time%
  {
    Arrow_Resupply_Time := A_Now ;Reset the clock

    ;Re-Supply Arrows & repair equipment
    If Character_Name = Casandra
    {
      Arrow_Resupply() ;This is the subroutine that actually moves the archer to Larzuk and buys the arrows.
      Goto, Quit_And_Save
    }
  }

  If Character_Name = Bif
    Initialize_Bif_Party()

/*
  Character_Move(120, 523)  ;Move Toward Waypoint

  ;Move Toward Waypoint - when you click on the Waypoint your
  ;  character will walk instead of run, so Character_Move
  ;  won't work.
  MouseClick, Left, 130, 523, 1
  Sleep, 3000
*/

  Character_Move(180, 516) ;Move Toward Waypoint
  Character_Move(172, 448) ;Move Toward Waypoint
  Character_Move(321, 381) ;Click on Waypoint

  MouseClick, Left, 113, 174, 1  ;Select Frigid Highlands
  Sleep, 1000

  Character_Move(771, 480)  ;Walk toward Bridge
  Character_Move(681, 274)  ;Walk Toward Bridge
  Character_Move(627, 524)  ;Walk Toward Bridge
  Character_Move(476, 526)  ;Walk Toward Fight
  Character_Move(569, 404)  ;Walk Toward Fight

  If Character_Name = Casandra
  {
    Character_Move(569, 404)  ;Touch the Shrine
    Character_Move(569, 404)  ;Walk Toward Fight
    Character_Move(500, 375)  ;Deeper into the fight

;    Sleep, 2000

    Danger := Attack(25)
    If Danger = True
      Goto, Quit_And_Save

/*
    Character_Move(500, 375)  ;Deeper into the fight
    Danger := Sleep_Check_Status(2)
    If Danger = True
      Goto, Quit_And_Save
*/
  }

  If Character_Name = Bif
  {
    Character_Move(569, 404)  ;Touch the Shrine
    Character_Move(506, 210)  ;Walk Toward the Rock and Wait
    ;Sleep, 5000

    /*
    Danger := Attack(10)
    If Danger = True
      Goto, Quit_And_Save
    Danger := Sleep_Check_Status(2)
    If Danger = True
      Goto, Quit_And_Save
    */

    Character_Move(500, 375)  ;Deeper into the fight

    Danger := Attack(15)
    If Danger = True
      Goto, Quit_And_Save
    Danger := Sleep_Check_Status(1)
    If Danger = True
      Goto, Quit_And_Save

    Character_Move(500, 375)  ;Deeper into the fight
/*
    Danger := Attack(24)
    If Danger = True
      Goto, Quit_And_Save
    Danger := Sleep_Check_Status(2)
    If Danger = True
      Goto, Quit_And_Save
*/
    Character_Move(500, 375)  ;Deeper into the fight

    Danger := Attack(25)
    If Danger = True
      Goto, Quit_And_Save
  }

Quit_And_Save:
  ;Screen capture of experience
  If Danger = False
  {
    Snapshot_Elapsed_Time := %A_Now%
    EnvSub, Snapshot_Elapsed_Time, %Snapshot_Time%, Seconds ;Same as ET := ET - ST results given in seconds.
    If Snapshot_Elapsed_Time > %Snapshot_Wait_Time%
    {
      Snapshot_Time := A_Now ;Reset the clock
      Snapshot()
    }

  }



  Quit_and_Save()

  WinActivate, Diablo II
  Sleep, 1000
  Debug("=============== Main Loop " A_Now " ===============`r`n", "diablo_log.txt")
} ;Main Play Loop
return

;#######################################################
;# Debug - Send debug information to text file.
;#######################################################
Debug(Text, File)
{
  ;# The following:
  ;#     test = Hi there
  ;#     Debug(test " debug text`r`n", "diablo_log.txt")
  ;# will produce:
  ;#     Hi there debug text

  Global Use_Debug
  If Use_Debug = ON
  {
    FileAppend, %Text%, %File%
  }
} ;Debug

;#######################################################
;# Find Malta to Recharge Vitals
;#######################################################
Find_Malta()
{
  X_TL = 316
  Y_TL = 27
  X_BR = 417
  Y_BR = 64

  Sleep, 5000 ;Wait for her to get out of the way

  Character_Move(0, 233)  ;Walk toward Malta
  MouseMove, 387, 126     ;Place mouse in Malta's doorway

  ;Search for Malta and click on her when you find her.
  ;294, 7    ;TL search for Malta's name
  ;444, 203  ;BR search for Malta's name
  Pixel_Color_White = 0xD6D3D6

  Wait_Time = 30
  Start_Time := A_Now
  Elapsed_Time = %Start_Time%

  Loop
  {
    Num_White  := Pixel_Search(X_TL, Y_TL, X_BR, Y_BR, Pixel_Color_White)
    If (Num_White > 10)
    {
      MouseClick, Left, , , 1
      Sleep, 3000
      Break
    }

    Elapsed_Time := %A_Now%
    EnvSub, Elapsed_Time, %Start_Time%, Seconds ;Same as ET := ET - ST results given in seconds.
    If Elapsed_Time > %Wait_Time%
      Break

  }

  ;Go back to starting point.
  Character_Move(336, 530)
  Character_Move(773, 239)
  Character_Move(456, 350)

  Return
}

;#######################################################
;# Initialize Party
;#######################################################
MButton::
Initialize_Bif_Party()
Return

Initialize_Bif_Party()
{
  Delay = 600
  Delay2 = 700

  ;Werewolf
  Send, 6
  Sleep, %Delay%
  MouseClick, Right
  Sleep, %Delay%

  ;Armor
  ;Send, {F1}
  ;Sleep, %Delay%
  ;MouseClick, Right
  ;Sleep, %Delay%

  ;Birds
  Send, {F2}
  Sleep, %Delay2%
  MouseClick, Right
  Sleep, %Delay2%
  MouseClick, Right
  Sleep, %Delay2%
  MouseClick, Right
  Sleep, %Delay2%

  ;Corpse eating Vine
  Send, {F5}
  Sleep, %Delay%
  MouseClick, Right
  Sleep, %Delay%

  ;Spirit of thorns
  ;Send, {F6}
  ;Sleep, %Delay%
  ;MouseClick, Right
  ;Sleep, %Delay%

  ;Summon Grizzly Bear
  ;Send, {F7}
  ;Sleep, %Delay%
  ;MouseClick, Right
  ;Sleep, %Delay%

  Send, 8
  Return
} ;Initialize_Bif_Party

;#######################################################
;# Re-supply Arrows
;#######################################################
Arrow_Resupply()
{
  ;Walk toward Larzuk
  Character_Move(171, 526)
  Character_Move(761, 367)
  Sleep, 1000

  ;Hover mouse over where Larzuk likes to stand
  MouseMove, 681, 485

  ;Search for Larzuk's signature
  Loop
  {
    X_TL = 680
    Y_TL = 479
    X_BR = 682
    Y_BR = 481
    Larzuk_Shoulder = 0xB5F3FF

    Num_Pixel_Found  := Pixel_Search(X_TL, Y_TL, X_BR, Y_BR, Larzuk_Shoulder)
    If (Num_Pixel_Found > 0)
      Break
  }

  ;Click on Larzuk
  Character_Move(667, 478)

  ;Select Trade/Repair
  Send, {DOWN}
  Sleep, 200
  Send, {ENTER}
  Sleep, 1000

  ;Click "Repair All" Icon.
  MouseClick, Left, 368, 463
  Sleep, 500

  ;Click "Misc" tab
  MouseClick, Left, 360, 76
  Sleep, 500

  ;Refill Arrows
  Send, {Shift down}
  MouseClick, Right, 112, 162
  Send, {Shift up}
  Sleep, 500

  Send, {ESC}
  Sleep, 500

}

;#######################################################
;# Character Move - Move the character and calculate the
;#   time to reach the destination.
;#######################################################
Character_Move(X_Move, Y_Move)
{
  Global Run_Speed

  ;Character Position - where the feet touch the ground
  X_Character = 400
  Y_Character = 275

  Delta_X := X_Character - X_Move
  Delta_Y := Y_Character - Y_Move
  Sum_Squares := Delta_X**2 + Delta_Y**2
  Dist := Sqrt(Sum_Squares)

  Delay := Dist / Run_Speed
  Delay := Delay * 1000
  Delay := Floor(Delay)
  debug("Char_Move:dX = " Delta_X "; dY = " Delta_Y "; Sum_Squares = " Sum_Squares "; Dist = " Dist "; Delay = " Delay "`r`n", "diablo_log.txt")

  MouseClick, Left, %X_Move%, %Y_Move%, 1
  Sleep, %Delay%

}

;#######################################################
;# Attack
;#######################################################
Attack(Seconds)
{
  ;Kill time while checking health status - if it is low then exit immediately
  ;danger := check_hireling_health()
  Debug("Attack:Danger = " Danger "`r`n", "diablo_log.txt")

  MouseMove, 682, 546 ;Place to move mouse when attacking. If you are touching a monster then you will just stand there.

  ;Attack With Left Button
  Send, {SHIFT DOWN}

  ;mouseclick [, whichbutton , x, y, clickcount, speed, d|u, r]
  Mouseclick   , Left        ,  ,  ,           ,      , D

  ;Kill Time While Checking Health Status
  Time := Seconds / 5
  Danger := Sleep_Check_Status(Time)
  If Danger = True
    Return %Danger%

  ;Attack With Right Button
  MouseClick   , Left        ,  ,  , 3
  MouseClick   , Right       ,  ,  ,           ,      , D

  ;Kill Time While Checking Health Status
  Time := 4 * Seconds / 5
  Danger := Sleep_Check_Status(Time)
  If Danger = True
    Return %Danger%

  ;Unstick Right Mouse Button
  MouseClick   , Right       ,  ,  , 3

  ;Unstick Shift
  send, {SHIFT UP}

  Return %Danger%
} ;Attack

;#######################################################
;# Check Health Status While Killing Time
;#######################################################
Sleep_Check_Status(Seconds)
{
  Global Pct_Health_to_Exit
  Start_Time := A_Now
  Elapsed_Time = %Start_Time%

  Debug("Sleep_Check_Status:Start_Time = " Start_Time " Elapsed_Time = " Elapsed_Time "`r`n", "diablo_log.txt")
  Danger = False
  Loop
  {
    ;Check Hireling Health
    Danger := Check_Hireling_Health()
    If Danger = True
      Return %Danger%
     

    ;Check Player Health
    Pct_Health := Get_Vitals_Pct_Checked("Health", "3")
    Debug("Check_Player_Health:Pct_Health = " Pct_Health "`r`n", "diablo_log.txt")
    If Pct_Health < %Pct_Health_to_Exit%
    {
      Danger = True
      Return %Danger%
    }

    ;Check Time in Loop
    Elapsed_Time := %A_Now%
    EnvSub, Elapsed_Time, %Start_Time%, Seconds
    Debug("Sleep_Check_Status:Elapsed_Time = " Elapsed_Time "`r`n", "diablo_log.txt")
    If Elapsed_Time > %Seconds%
      Break
  }
  Return %Danger%
} ;Sleep_Check_Status

;#######################################################
;# Check Hireling Health
;#######################################################
Check_Hireling_Health()
{
  Danger = False

  ;Hireling Health-bar Co-ordinates
  X_TL = 15
  Y_TL = 15
  X_BR = 60
  Y_BR = 21

  Pixel_Color_Green  = 0x008600
  Pixel_Color_Yellow = 0x2186d6
  Pixel_Color_Red    = 0x2104f7

  ;Count Number of Pixel Values in a Range
  Num_Green  := Pixel_Search(X_TL, Y_TL, X_BR, Y_BR, Pixel_Color_Green)
  Num_Yellow := Pixel_Search(X_TL, Y_TL, X_BR, Y_BR, Pixel_Color_Yellow)
  Num_Red    := Pixel_Search(X_TL, Y_TL, X_BR, Y_BR, Pixel_Color_Red)

  Debug("Check_Hireling_Health:" "Num_Green = " Num_Green " Num_Yellow = " Num_Yellow " Num_Red = " Num_Red "`r`n", "diablo_log.txt")

  ;If there are no green pixels then check for yellow and red
  ;  If all 3 colors are not present then it is in a transition phase - do nothing
  If (Num_Green = 0)
  {
    Debug("Check_Hireling_Health:Num_Green = 0 `r`n", "diablo_log.txt")
    If (num_yellow > 0)
    {
      Debug("Check_Hireling_Health:Num_Yellow > 0 `r`n", "diablo_log.txt")
      Danger = True
    }
    If (num_red > 0)
    {
      Debug("Check_Hireling_Health:Num_Red > 0 `r`n", "diablo_log.txt")
      Danger = True
    }
  }
 
  Return %Danger%
} ;Check_Hireling_Health

;#######################################################
;# Check if Hireling is Alive
;#######################################################
Check_Hireling_Alive()
{
  Num_Checks = 10

  ;Hireling Health-bar Co-ordinates
  X_TL = 15
  Y_TL = 15
  X_BR = 60
  Y_BR = 21

  Pixel_Color_Green  = 0x008600

  ;Count Number of Pixel Values in a Range
  Num_Green  := Pixel_Search(X_TL, Y_TL, X_BR, Y_BR, Pixel_Color_Green)

  Loop %Num_Checks%
  {
    If (Num_Green = 0)
    {
      Alive = False
      Debug("Check_Hireling_Alive:Alive = " %Alive% " `r`n", "diablo_log.txt")
    }

    If (Num_Green > 10)
    {
      Alive = True
      Debug("Check_Hireling_Alive:Alive = " %Alive% " `r`n", "diablo_log.txt")
      Break
    }

    Sleep, 50
  }

  Return %Alive%
}

/*
;#######################################################
;# Check Player Health
;#######################################################
Check_Player_Health()
{
  Global Pct_Health_to_Exit
  Pct_Health := Get_Vitals_Pct_Checked(Health)
  Debug("Check_Player_Health:Pct_Health = " Pct_Health "`r`n", "diablo_log.txt")
  If Pct_Health < %Pct_Health_to_Exit%
    Danger = True

  Return %Danger%
}
*/

;#######################################################
;# Diablo Find the Percentage of Health/Mana Left - Unchecked
;#######################################################
Get_Vitals_Pct(Type)
{
  ;Debug("Get_Vitals_Pct:Type =" Type "`r`n", "diablo_log.txt")

  ;# 71,507 - health orb max y-value (full)
  ;# 71,585 - health orb min y-value (dead)
  Vital_Max = 507
  Vital_Min = 585

  If Type = Health
  {
    ;# Range of pixel values (BGR) in Helath orb
    Val1 = 0x080808 ;# very very top
    Val2 = 0x080839
    Val3 = 0x08104a
    Val4 = 0x000063
    Val5 = 0x00006b
    Val6 = 0x081052
    Val7 = 0x08104a
    Val8 = 0x081052
    Val9 = 0x080839
    Val10 = 0x000029
    Val11 = 0x000810
    Val12 = 0x080808
    Num_Vals = 12
    X = 71
    Y = 585
  }
  If Type = Mana
  {
    ;# Range of pixel values (BGR) in Mana orb
    Val1 = 0x630000
    Val2 = 0x5A0000
    Val3 = 0x291010
    Val4 = 0x311010
    Val5 = 0x080808
    Num_Vals = 5
    X = 730
    Y = 585
  }

  Loop 78
  {
     i = 1
     PixelGetColor, Pixel_Color, X, Y
     ;Debug("Get_Vitals_Pct: i = " i " pix Pixel_Color = " Pixel_Color "`r`n", "diablo_log.txt")

Check_Next_Vital_Pixel_Val:
     ;Debug("Get_Vitals_Pct: Valx = " Val%i% "`r`n", "diablo_log.txt")
     If % Pixel_Color = Val%i%
     {
       Y--
       ;Debug("Get_Vitals_Pct: Found health at y = " y "`r`n", "diablo_log.txt")
     }
     Else
     {
       ;Debug("Get_Vitals_Pct: Didn't find match trying another known value. i = " i "`r`n", "diablo_log.txt")
       If i = %Num_Vals%
       {
         Break
       }
       i++
       Goto, Check_Next_Vital_Pixel_Val
     }
     
  }

  Pct_Vital := (Vital_Min - Y) * 100 / (Vital_Min - Vital_Max)
  ;Debug("Get_Vitals_Pct: Pct_Vital = " Pct_Vital "`r`n", "diablo_log.txt")
  Return Pct_Vital
} ;Get_Vitals_Pct

;#######################################################
;# Diablo Find the Percentage of Health Left With ECC
;#######################################################
Get_Vitals_Pct_Checked(Type, Num_Checks)
{

  ;Debug("Get_Vitals_Pct_Checked:Type = " Type "`, Num_Checks = " Num_Checks "`r`n", "diablo_log.txt")
  Pct_Health_Keep = 0
  ;Num_Checks = 3
  Delay_Between_Checks = 50

  Loop %Num_Checks%
  {

Try_Again:

    Pct_Vital := Get_Vitals_Pct(Type)

    If Pct_Vital = 0
       Goto, Try_Again

    If Pct_Vital > %Pct_Health_Keep%
      Pct_Vital_Keep := Pct_Vital

    Sleep, %Delay_Between_Checks%
  }
  Return Pct_Vital_Keep
} ;Get_Vitals_Pct_Checked

;#######################################################
;# Quit and Save Game
;#######################################################
Quit_and_Save()
{
/*
  ;Old Method

  ;Experience Bar - No Click
  MouseMove, 312, 564
  Sleep, 20

  ;Printscreen
  Send, {PRINTSCREEN}
  Sleep, 250
*/
  ;quit menu
  Send, {ESC}
  Sleep, 500

  ;Save and Exit - Single Click
  MouseClick, left, 351, 262, 1
  Sleep, 5000

  ;Unstick the mouse and shift buttons
  ;mouseclick [, whichbutton , x, y, clickcount, speed, d|u, r]
  MouseClick   , Left        , 0, 0,          3
  MouseClick   , Right       , 0, 0,          3
  Send, {SHIFT 3}
  Send, {SHIFT UP}

/*
  ;Old Method

  ;Save the Files and Switch Back to Windows
  Save_Game_Files()
  Send, !{TAB}
  Sleep, 3300
 
  ;Paste and Save the Picture into MSPaint for Easy Status Viewing
  Run, %systemroot%\system32\mspaint.exe
  WinWait, untitled - Paint
  Sleep, 300
  Send, ^v
  Sleep, 300
  Send, ^s
  WinWait, Save As
  Send, C:\Program Files\Diablo II\save\AHK_Save\%A_Now%{ENTER}

  ;Close MSpaint
  Send, !{F4}

  Sleep, 1000
*/

  Return
} ;Quit_and_Save

;#######################################################
;# Take a snapshot of your experience
;#######################################################
Snapshot()
{
  Send, {ESC}

  ;Experience Bar - No Click
  MouseMove, 312, 564
  Sleep, 100

  ;Printscreen
  Send, {PRINTSCREEN}
  Sleep, 250

  ;Switch to Windows
  Send, !{TAB}
  Sleep, 3300
 
  ;Paste and Save the Picture into MSPaint for Easy Status Viewing
  Run, %systemroot%\system32\mspaint.exe
  WinWait, untitled - Paint
  Sleep, 300
  Send, ^v
  Sleep, 300
  Send, ^s
  WinWait, Save As
  Send, C:\Program Files\Diablo II\save\AHK_Save\%A_Now%{ENTER}

  ;Close MSpaint
  Send, !{F4}
  Sleep, 1000

  ;Switch to Diablo
  Send, !{TAB}
  Sleep, 3300

  Send, {ESC}
  Sleep, 200
}


;#######################################################
;# save game files
;#######################################################
Save_Game_Files()
{
  Global Character_Name
  Global AHK_Diablo_Save_Dir
  IfNotExist, %AHK_Diablo_Save_Dir%
    FileCreateDir, %AHK_Diablo_Save_Dir%
  FileCopy, C:\Program Files\Diablo II\save\%Character_Name%.*, %AHK_Diablo_Save_Dir%\*.*, 1
  Sleep, 500
  Return
} ;Save_Game_Files

;#######################################################
;# Restore Game
;#######################################################
Restore_Game_Files()
{
  Global Character_Name
  Global AHK_Diablo_Save_Dir
;  FileCopy, %AHK_Diablo_Save_Dir%\*.*, C:\Program Files\Diablo II\save\*.*, 1
  FileCopy, %AHK_Diablo_Save_Dir%\%Character_Name%.*, C:\Program Files\Diablo II\save\*.*, 1
  Sleep, 500
  FileAppend, Game Restored on %A_Now%`r`n, diablo_death_log.txt
  Return
} ;Restore_Game_Files

;#######################################################
;# Dump the Pixel Values of a Given Area to a File
;#######################################################
Pixel_Area(X_TL, Y_TL, X_BR, Y_BR, File_Name)
{
  ;Pixel_Area(70, 505, 72, 590, "diablo_Player_Helath.txt")
 
  X_Current = %X_TL%
  Y_Current = %Y_TL%

  Loop   
  {
    Loop
    {
      PixelGetColor, OutPutVar, X_Current, Y_Current
      FileAppend, %X_Current%`,%Y_Current% - (BGR) %OutPutVar%`r`n, %File_Name%
      X_Current++
      If X_Current > %X_BR%
        Break
    }
    X_Current = %X_TL%
    Y_Current++
    If Y_Current > %Y_BR%
      Break

    FileAppend, `r`n, %File_Name%
  }
} ;Pixel_Area

;#######################################################
;# Return Number of Pixel Values in a Range
;#######################################################
Pixel_Search(X_TL, Y_TL, X_BR, Y_BR, Pixel_Color_BGR)
{
  X_Current = %X_TL%
  Y_Current = %Y_TL%
  Num_Found = 0

  Loop   
  {
    Loop
    {
      PixelGetColor, OutPutVar, X_Current, Y_Current
      X_Current++
      If OutPutVar = %Pixel_Color_BGR%
        Num_Found++
      If X_Current > %X_BR%
        Break
    }
    X_Current = %X_TL%
    Y_Current++
    If Y_Current > %Y_BR%
      Break
  }
  Return %Num_Found%
} ;Pixel_Search

;===============================================================
;====== currently unused, but posibly useful, routines =========
;===============================================================

;#######################################################
;#  diablo discover belt contents
;#######################################################
belt_discover(byref slot)
{
  debug("belt_discover: slot=" slot "`r`n", "diablo_log.txt")
  number_found = 0

  color_red    = 0x080839
  color_blue   = 0x5a0000
  color_purple = 0x6b2073

  ;# y1 and y2 are the same for all 4 belt slots
  slot_y1 = 573
  slot_y2 = 587
  1_x1 = 432
  1_x2 = 448

  2_x1 = 459
  2_x2 = 477

  3_x1 = 491
  3_x2 = 508

  4_x1 = 521
  4_x2 = 541

  pixelsearch, x_red,    y_red,    %slot%_x1, slot_y1, %slot%_x2, slot_y2, color_red,    10
  pixelsearch, x_blue,   y_blue,   %slot%_x1, slot_y1, %slot%_x2, slot_y2, color_blue,   10
  pixelsearch, x_purple, y_purple, %slot%_x1, slot_y1, %slot%_x2, slot_y2, color_purple, 10

  if (x_red <> "")
  {
    number_found++
    slot%slot% = health
    bottle := slot%slot%
    debug("belt_discover: " bottle " in slot" slot "`r`n", "diablo_log.txt")
  }
  if (x_blue <> "")
  {
    number_found++
    slot%slot% = mana
    bottle := slot%slot%
    debug("belt_discover: " bottle " in slot" slot "`r`n", "diablo_log.txt")
  }
  if (x_purple <> "")
  {
    number_found++
    slot%slot% = rejuv
    bottle := slot%slot%
    debug("belt_discover: " bottle " in slot" slot "`r`n", "diablo_log.txt")
  }
  if (number_found > 1)
    msgbox, error - found more than one potion in belt slot%slot%

  i++
  return %bottle%
}


Back to top
View user's profile Send private message
aobrien



Joined: 14 Feb 2008
Posts: 27

PostPosted: Tue May 13, 2008 8:05 am    Post subject: Reply with quote

reserved for bug fixes/notes
Back to top
View user's profile Send private message
Icester
Guest





PostPosted: Wed Jun 25, 2008 8:12 pm    Post subject: Reply with quote

Wow! That is one awesome script. I haven't tried it yet, but I applaud your work! I know from experience how hard it can be to get ahk to act as a semi-intelligent game 'bot.

Good job!
Back to top
andrei901



Joined: 20 Jan 2008
Posts: 20

PostPosted: Sun Jun 29, 2008 5:30 am    Post subject: Reply with quote

Dude: you are good.

I'm gonna try this script out, and ill post some data, but I have one question: can you tell us how to edit the location? I don't want to use my main character, so could you tell me how I can edit it to use the second or third character in the list, and change the location to something like Act I:Stony Field or something like that?
_________________
-andrei901, your local wannabe AHK expert
Back to top
View user's profile Send private message AIM Address
TheLeO



Joined: 11 Jun 2005
Posts: 160
Location: England ish

PostPosted: Sun Jun 29, 2008 12:59 pm    Post subject: Reply with quote

mmmm it's a very interesting concept...

but if you're cheating in single player, you might as well use character editors. If you wanna go for battlenet, there's the pindle bot which does the job..

and if you are to level up to lvl 99 you must kill baal, otherwise you'd be running the script for a life time.

I admire your efforts, but i'm not too sure whether there'll be any one actually using this.
_________________
And i say: where there is a problem , there is a solution.(well some where that is.)
::
I Have Spoken
::
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group