Smorg Posted August 12, 2006 Share Posted August 12, 2006 What is the most correct way to modify a variable through a function under various conditions? Usually when i am feeding a function some paramaters i will use a regular return to give the function's result back to the variable I want. However, what if i want to return multiple parts to multiple variables? its not very efficient to run the whole function twice just to give say, an x & y to two variables for instance. In this case i will sometimes return an array, but then after the array is returned i still need a few extra lines to convert that array back into two separate variables. Is it generally considered okay to just assign a global variable within a function rather than using a return at all? This is particularly easy to do when the returned variable is never used as a function paramater but is simply the result of the function. I am also confused as to the usage of ByRef... What is it exactly? After re-reading this sentance several times my head was spinning... "The ByRef keyword is optional and means: (1) the parameter must a variable, and (2) the variable could be changed by the function. By default, a parameter is passed by value which means that a copy of the parameter's value is manipulated by the function." (seems to be the only reference to byref in the manual) This is my specific application... This is a script for tracking life for the game diablo II. d2 uses vertical bars as life indicators. The bars are actually textured and shaded so i read each base pixel of the full bar to a reference file which is then read to arrays and matched up with the current bar status. The script tracks the movments of the top edge of the bar to determine a percent life remaining. It can then use this info to automatically heal itself and can exit the game as a last ditch if it gets too low. Take a look at the Func GetLife($Direction). Since it seems you can't conditionally declare loops since i get a bunch of 'next without corresponding for' blah, the whole thing had to be copied for one to step forwards, and the other step backwards. As you can see since several variables are conditionally modified, I can't very well return the result to a var. And the paramater is already used up by the $direction, so it wouldn't make much sense to add more paramaters to return from... Whole script:expandcollapse popup;------------------------------------------------ ;----------------PotThread by Smorg-------------- ;------------------------------------------------ ;Version 3.0 ;#NoTrayIcon #Include <Array.au3> opt("PixelCoordMode", 2) opt("MouseCoordMode", 2) opt("ColorMode", 1) WinActivate("Diablo II") WinMove("Diablo II", "", 0, 0) ;------------------------------------------------ ;User Vars $ExtraDebug = "No" ;Show Extra pixel info, for debugging purposes only $File = "OrbReference.ini" ;Pixel Reference file to read from $Top = IniRead($File, "Stats", "Top", "") ;Top of the health/mana orbs $Bottom = IniRead($File, "Stats", "Bottom", "") ;Bottom of the health/mana orbs $HealthX = IniRead($File, "Stats", "Health", "") ;Xcoord to scan the health orb $ManaX = IniRead($File, "Stats", "Mana", "") ;Xcoord to scan the mana orb $BeltX = 437 ;Left Belt Slot pixel reference $BeltY = 582 ;Left Belt Slot pixel reference $MercBarLeft = 15 ;Left side of the merc bar $MercBarRight = 60 ;Right side of the merc bar $MercBarY = 18 ;Merc bar Y coord $beltfrjchecksum = 713163619 ;belt checksum for full rejuvs $beltrjchecksum = 1805125736 ;belt checksum for regular rejuvs $ChickenTimeout = 1000 ;Time to wait for sucessful chicken before retrying $ChickenRetries = 3 ;Times to retry chicken Global $HealthRef[ ($Bottom - $Top) + 1] ;Array to conatin health color data read from the ini file Global $ManaRef[ ($Bottom - $Top) + 1] ;Array to contain mana color data read from the ini file Global $PsnRef[ ($Bottom - $Top) + 1] ;Poisoned Health Color data Global $BeltData[4] ;Potions info. 0 = no pot, 1 = full rejuv pot, 2 = regular rejuv pot Dim $DrinkType ;Type of drink. 0 = Regular rejuv, 1 = Full rejuv, 2 = Merc Dim $LifePercent ;The returned percent from the health orb Dim $ManaPercent ;The returned percent from the mana orb Dim $HealthPixel ;Current Health Pixel y coord Dim $HealthColor ;Health pixelcolor result to check against healthref and psnref Dim $ManaPixel ;Current Mana Pixel y coord Dim $MercPercent ;Percent health remaining calculated from the merc bar Dim $MercPixel ;Current merc bar pixel Dim $MercColor ;Current merc bar color Dim $Check ;Belt checksum result Dim $Char_Key_PotionsRow[5] ;Potion drink keys Dim $Timer = 0 ;Timer flag, weather or not the drink timer is active Dim $Sleep ;Drink Delay Timestamp ;------------------------------------------------ ;Importing Vars $CurrentDir = StringSplit(@ScriptDir, "\") _ArrayPop($CurrentDir) $BotDir = $CurrentDir[1] For $Rebuild = 2 to ($CurrentDir[0] - 1) $BotDir = $BotDir & "\" & $CurrentDir[$Rebuild] Next $Char_Key_PotionsRow[1] = IniRead($BotDir & "\Config\mm.BOT.ini", "Character", "Char_Key_PotionsRow1", "") $Char_Key_PotionsRow[2] = IniRead($BotDir & "\Config\mm.BOT.ini", "Character", "Char_Key_PotionsRow2", "") $Char_Key_PotionsRow[3] = IniRead($BotDir & "\Config\mm.BOT.ini", "Character", "Char_Key_PotionsRow3", "") $Char_Key_PotionsRow[4] = IniRead($BotDir & "\Config\mm.BOT.ini", "Character", "Char_Key_PotionsRow4", "") $PauseBot = IniRead($BotDir & "\Config\mm.BOT.ini", "Advanced Settings", "Bot_PAUSE_HotKey", "") $PauseBot = "{" & $PauseBot & "}" $ClearScreen = IniRead($BotDir & "\Config\mm.BOT.ini", "Character", "Char_Key_ClearScreen", "") $ClearScreen = "{" & $ClearScreen & "}" $D2WinTitle = IniRead($BotDir & "\Config\mm.BOT.ini", "Advanced Settings", "D2_WName", "") $LifeRpotDrinkPercent = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Settings", "Rpot_Life_Percent", "") $LifeFpotDrinkPercent = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Settings", "FRJ_Life_Percent", "") $ManaRpotDrinkPercent = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Settings", "Rpot_Mana_Percent", "") $ManaFpotDrinkPercent = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Settings", "FRJ_Mana_Percent", "") $ChickenPercent = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Settings", "Chicken_Percent", "") $ScanDelay = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Settings", "Scan_Delay", "") $DrinkDelay = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Settings", "Drink_Delay", "") $MaxLife = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Settings", "Max_Life", "") $MaxMana = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Settings", "Max_Mana", "") $UseMerc = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Merc", "Use_Merc", "") $MercChicken = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Merc", "Merc_Chicken", "") $MercHealPercent = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Merc", "Merc_Heal_Percent", "") $MercChickenPercent = IniRead($BotDir & "\Config\mm.LifeCheck.ini", "Merc", "Merc_Chicken_Percent", "") ;Build arrays from OrbReference.ini For $Health = 0 To $Bottom - $Top $HealthRef[$Health] = IniRead($File, "Health", $Health, "") Next For $Mana = 0 To $Bottom - $Top $ManaRef[$Mana] = IniRead($File, "Mana", $Mana, "") Next For $Psn = 0 To $Bottom - $Top $PsnRef[$Psn] = IniRead($File, "Psn", $Psn, "") Next ;------------------------------------------------ GetBaseStats() If $UseMerc = "No" Then $MercPercent = "None" While 1 Sleep($ScanDelay) If PixelGetColor(481, 535) <> 5406092 Then If (PixelGetColor(320, 537) <> 6521492) OR (WinActive($D2WinTitle) = 0) Then SuspendCheck() EndIf ;Check if life has moved either up or down $HealthColor = PixelGetColor($HealthX, $HealthPixel) If ($HealthColor <> $HealthRef[$HealthPixel - $Top]) And ($HealthColor <> $PsnRef[$HealthPixel - $Top]) Then GetLife("down") ElseIf $LifePercent <> 100 Then $HealthColor = PixelGetColor($HealthX, $HealthPixel - 1) If ($HealthColor = $HealthRef[ ($HealthPixel - $Top) - 1]) Or ($HealthColor = $PsnRef[ ($HealthPixel - $Top) - 1]) Then GetLife("up") EndIf ;Check if mana has moved either up or down If PixelGetColor($ManaX, $ManaPixel) <> $ManaRef[$ManaPixel - $Top] Then GetMana("down") ElseIf $ManaPercent <> 100 Then If PixelGetColor($ManaX, $ManaPixel - 1) = $ManaRef[ ($ManaPixel - $Top) - 1] Then GetMana("up") EndIf ;Check if merc's life has changed & merc chicken check If $UseMerc = "Yes" Then If PixelGetColor($MercPixel, $MercBarY) = 0 Then GetMerc("down") ElseIf $MercPercent <> 100 Then If PixelGetColor($MercPixel + 1, $MercBarY) <> 0 Then GetMerc("up") EndIf If ($MercPercent < $MercChickenPercent) And $MercChicken = "Yes" Then Chicken() EndIf ;Drink pots, Chicken, and tooltip If $LifePercent < $ChickenPercent Then Chicken() If $Timer = 1 And TimerDiff($Sleep) > $DrinkDelay Then $Timer = 0 If $Timer = 0 Then Select Case $LifePercent < $LifeRpotDrinkPercent And $LifePercent > $LifeFpotDrinkPercent Drink(1) Case $LifePercent < $LifeFpotDrinkPercent Drink(0) Case $ManaPercent < $ManaRpotDrinkPercent And $ManaPercent > $ManaFpotDrinkPercent Drink(1) Case $ManaPercent < $ManaFpotDrinkPercent Drink(0) Case ($MercPercent < $MercHealPercent) And $UseMerc = "Yes" Drink(2) EndSelect EndIf WEnd Exit (1) Func GetLife($Direction) Select Case $Direction = "up" For $Search = $HealthPixel - $Top To 0 Step - 1 $HealthColor = PixelGetColor($HealthX, $Search + $Top) If ($HealthColor <> $HealthRef[$Search]) And ($HealthColor <> $PsnRef[$Search]) Or $Search = 0 Then Global $LifePercent = Round(100 * (($Bottom - ($Search + $Top)) / ($Bottom - $Top))) If $Search = 0 Then Global $HealthPixel = $Top Else Global $HealthPixel = $Search + $Top + 1 EndIf ExitLoop EndIf Next Case $Direction = "down" For $Search = $HealthPixel - $Top To $Bottom - $Top $HealthColor = PixelGetColor($HealthX, $Search + $Top) If ($HealthColor = $HealthRef[$Search]) Or ($HealthColor = $PsnRef[$Search]) Or $Search = $Bottom - $Top Then Global $LifePercent = Round(100 * (($Bottom - ($Search + $Top)) / ($Bottom - $Top))) Global $HealthPixel = $Search + $Top ExitLoop EndIf Next EndSelect ShowTip() EndFunc ;==>GetLife Func GetMana($Direction) Select Case $Direction = "up" For $Search = $ManaPixel - $Top To 0 Step - 1 If (PixelGetColor($ManaX, $Search + $Top) <> $ManaRef[$Search]) Or $Search = 0 Then Global $ManaPercent = Round(100 * (($Bottom - ($Search + $Top)) / ($Bottom - $Top))) If $Search = 0 Then Global $ManaPixel = $Top Else Global $ManaPixel = $Search + $Top + 1 EndIf ExitLoop EndIf Next Case $Direction = "down" For $Search = $ManaPixel - $Top To $Bottom - $Top If (PixelGetColor($ManaX, $Search + $Top) = $ManaRef[$Search]) Or $Search = $Bottom - $Top Then Global $ManaPercent = Round(100 * (($Bottom - ($Search + $Top)) / ($Bottom - $Top))) Global $ManaPixel = $Search + $Top ExitLoop EndIf Next EndSelect ShowTip() EndFunc ;==>GetMana Func GetMerc($Direction) Select Case $Direction = "up" For $Search = $MercPixel To $MercBarRight If (PixelGetColor($Search, $MercBarY) = 0) Or $Search = $MercBarRight Then Global $MercPercent = Round(100 * (($Search - $MercBarLeft) / ($MercBarRight - $MercBarLeft))) If $Search = $MercBarRight Then Global $MercPixel = $MercBarRight Else Global $MercPixel = $Search - 1 EndIf ExitLoop EndIf Next Case $Direction = "down" For $Search = $MercPixel To $MercBarLeft Step - 1 If (PixelGetColor($Search, $MercBarY) <> 0) Or $Search = $MercBarLeft Then Global $MercPercent = Round(100 * (($Search - $MercBarLeft) / ($MercBarRight - $MercBarLeft))) Global $MercPixel = $Search ExitLoop EndIf Next EndSelect ShowTip() EndFunc ;==>GetMerc Func GetBaseStats() Global $HealthPixel = $Top Global $ManaPixel = $Top Global $MercPixel = $MercBarRight GetLife("down") GetMana("down") If $UseMerc = "Yes" Then GetMerc("down") EndFunc ;==>GetBaseStats Func ShowTip() If $ExtraDebug = "No" Then ToolTip("Life: " & Round($MaxLife * ($LifePercent / 100)) & " / " & $MaxLife & " - " & Round($LifePercent) & "%" & @CRLF _ & "Mana: " & Round($MaxMana * ($ManaPercent / 100)) & " / " & $MaxMana & " - " & Round($ManaPercent) & "%" & @CRLF _ & "Merc: " & Round($MercPercent) & "%", 252, 578) ElseIf $ExtraDebug = "Yes" Then ToolTip("Life: " & $MaxLife * ($LifePercent / 100) & " / " & $MaxLife & " - " & $LifePercent & "%" & @CRLF _ & "Mana: " & $MaxMana * ($ManaPercent / 100) & " / " & $MaxMana & " - " & $ManaPercent & "%" & @CRLF _ & "Merc: " & $MercPercent & "%" & @CRLF _ & "HealthPix: " & $HealthPixel - $Top & " ManaPix: " & $ManaPixel - $Top & @CRLF _ & "MercPix: " & $MercPixel, 252, 578) EndIf EndFunc ;==>ShowTip Func Drink($DrinkType) For $N = 0 To 3 $Check = PixelChecksum(($BeltX + ($N * 31)) - 1, $BeltY - 1, ($BeltX + ($N * 31)) + 1, $BeltY + 1, 1) If $Check = $beltfrjchecksum Then $BeltData[$N] = 1 ElseIf $Check = $beltrjchecksum Then $BeltData[$N] = 2 Else $BeltData[$N] = 0 EndIf Next $A = 0 Select Case $DrinkType = 0 ;Prioritize regular rejuves For $N = 0 To 3 If $BeltData[$N] = 1 Then Send($Char_Key_PotionsRow[$N + 1]) $A = 1 ExitLoop EndIf Next If $A = 0 Then For $N = 0 To 3 If $BeltData[$N] = 2 Then Send($Char_Key_PotionsRow[$N + 1]) $A = 1 ExitLoop EndIf Next EndIf If $A = 0 Then Chicken() Case $DrinkType = 1 ;Prioritize Full rejuves For $N = 0 To 3 If $BeltData[$N] = 2 Then Send($Char_Key_PotionsRow[$N + 1]) $A = 1 ExitLoop EndIf Next If $A = 0 Then For $N = 0 To 3 If $BeltData[$N] = 1 Then Send($Char_Key_PotionsRow[$N + 1]) $A = 1 ExitLoop EndIf Next EndIf If $A = 0 Then Chicken() Case $DrinkType = 2 ;Send a pot to the merc, Prioritize regular rejuves Send("{SHIFTDOWN}") For $N = 0 To 3 If $BeltData[$N] = 2 Then Send($Char_Key_PotionsRow[$N + 1]) $A = 1 ExitLoop EndIf Next If $A = 0 Then For $N = 0 To 3 If $BeltData[$N] = 1 Then Send($Char_Key_PotionsRow[$N + 1]) $A = 1 ExitLoop EndIf Next EndIf Send("{SHIFTUP}") If $A = 0 Then Chicken() EndSelect Global $Sleep = TimerInit() Global $Timer = 1 GetBaseStats() EndFunc ;==>Drink Func Chicken() ToolTip("") Send($PauseBot) For $Retries = 1 To $ChickenRetries Send($ClearScreen) MouseUp("Right") MouseUp("Left") Send("{ESC}") $Timeout = TimerInit() While 1 If (PixelGetColor(481, 535) <> 5406092) AND (PixelGetColor(320, 537) <> 6521492) Then ExitLoop ElseIf TimerDiff($Timeout) > 500 Then ContinueLoop 2 EndIf Sleep(100) WEnd MouseClick("Left", 400, 280, 1, 0) $Timeout = TimerInit() While TimerDiff($Timeout) < $ChickenTimeout If (PixelGetColor(600, 575) <> 6512995) AND (PixelGetColor(5, 575) <> 2697257) Then ExitLoop 2 Sleep(100) WEnd Next Send($PauseBot) SuspendCheck() EndFunc ;==>Chicken Func SuspendCheck() ToolTip("") Do Sleep(100) If WinExists($D2WinTitle) = 0 Then Exit Until ((PixelGetColor(481, 535) = 5406092) OR (PixelGetColor(320, 537) = 6521492)) AND (WinActive($D2WinTitle) = 1) ShowTip() EndFunc ;==>SuspendCheck Also it seems Select-Case is buggy. A lot of times boolean conditions mess up and don't work with select case, but the same identical thing works with If statements... Link to comment Share on other sites More sharing options...
jefhal Posted August 12, 2006 Share Posted August 12, 2006 Personally I don't know why you need to use Return. In every case where I've created a function I just assign the variable(s) within the function and than use them after the function is done. Am I missing something? As to the issues with Select-Case v. If, I haven't run into the issue you describe, but I've only used Case-Select a few times... ...by the way, it's pronounced: "JIF"... Bob Berry --- inventor of the GIF format Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 12, 2006 Moderators Share Posted August 12, 2006 Personally I don't know why you need to use Return. In every case where I've created a function I just assign the variable(s) within the function and than use them after the function is done. Am I missing something?As to the issues with Select-Case v. If, I haven't run into the issue you describe, but I've only used Case-Select a few times...If you do that, you force your variables to be global...I try to keep my Function Variables Unique and Local as much as possible. This a good reason to use Return. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Smorg Posted August 12, 2006 Author Share Posted August 12, 2006 Right thats the problem. Vars within functions are isolated unless global, which can normally be a good thing unless you run into a situation like this. Link to comment Share on other sites More sharing options...
flyingboz Posted August 12, 2006 Share Posted August 12, 2006 (edited) If you desire to modify multiple variables from within a function, the preferred method is usually by using the ByRef keyword for the variables in question. This allows the original variable(s) to be modified, without forcing said variable(s) to be global in scope. While global variables are very useful - for assigning constants and other items that are truly Global in nature, in professional code development they are "bad things" in practice -- unexpected (and hard to debug) things happen when you call a function in a loop incrementing $i ; and the called function or a called function of the called function has another loop in it; incrementing or decrementing $i . While this is a manageable problem if you're the only developer on a one or two file project; it becomes very difficult to control and debug with a multiplicity of developers and hundreds or thousands of files, and thousands or tens of thousands of lines of code. Edited August 12, 2006 by flyingboz Reading the help file before you post... Not only will it make you look smarter, it will make you smarter. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now