Jump to content

Xandy

Members
  • Content Count

    10
  • Joined

  • Last visited

Community Reputation

0 Neutral

About Xandy

  • Rank
    Bronze V

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. People fixed the memory. I had no part in this. http://www.ownedcore.com/forums/mmo/path-of-exile/poe-bots-programs/401805-release-autohotkey-script-poe-autoflasks-autoquit-28.html#post2911177
  2. The auto chicken worked before any of my changes. What I tried to do was use the still working chicken to throw the hotkeys for flasks. (If chicken still works then the memory for life must still be correct, eh?) I made an array for life flasks, granite flasks, and mana. The first index stores the amount of flask type, while the following indexes store the button to activate the flask in game. You can read how to configure the script (set the arrays) for your belt from my post above. You can also tell me your flasks in belt, and I'll send you a personalized script tailored for you belt. If it still dosen't work though then idk. I just started AutoHotkey like a week ago and partied for most of the week. I have been using this script everyday. Also the script doesn't seem to work well on my low level chars, that doesn't make sense to me. Try it with higher level chars and remember each char needs to have the script tailored to his belt.
  3. Modified my example above to (hopefully) work with reserved mana. I tested it once it seemed to work, so I posted my changes. I also changed some of the assignments to ':=" in the delay times, I didn't notice a difference, but maybe it will work MonsterHYS granite flasks idk. Good luck.
  4. Works fine for me. Not sure. I re-copied the script to my post above. To setup the config for your belt: Open the script for editing, Notepad or whatever you do. I'll be using this example belt: 1 HP pot, 2 HP, 3 GRANITE, 4 (run / walk unused), 5 (run / walk unused) ZERO MANAs Find this code area under Xandy near the top of script. ;config life potions life_pot[0]:= 2 ; <---<< I have 2 LIFE pots in my belt life_pot[1]:= 1 ; The button to fire is 1 and life_pot[2]:= 2 ; fire 2 after firing 1 then cycle back to 1 ;config granite potions granite_pot[0]:= 1 ; <---<< I have 1 GRANITE pot in my belt granite_pot[1]:= 3 ; the button to fire is 3 ;config mana potions mana_pot[0]:= 0 ; <---<< I have zero mana pots in my belt mana_pot[1]:= 1 ; this value should make no difference, but it is set to 1 and idc and left for example copy mana_pot[2]:= 2 ; the following shows how you could have a belt of 5 mana pots mana_pot[3]:= 3 ; .. mana_pot[4]:= 4 ; .. mana_pot[5]:= 5 ; but in the case of 5 mana pots index [0] would be 5 global life_potdelay= 2000 ; my pots are instant so this is only 200 for me global granite_potdelay= 4000 ; Duration before re-drink granite global mana_potdelay= 400 ; Duration before re-drink mana
  5. Here it is working very nice with delays. Sorry you'll need to re-config the script for your belt and make sure you use numeric hotkeys for flasks such as the default (1, 2, 3, 4, 5) See: life_potdelay, granite_potdelay, mana_potdelay and feed the values milliseconds yum ; - - - Modified by: Xandy global life_pot:= object() global granite_pot:= object() global mana_pot:= object() ;config life potions life_pot[0]:= 2 ;life potion max life_pot[1]:= 1 ;life potion 1 hotkey value life_pot[2]:= 2 ;life potion 2 hotkey value ;config granite potions granite_pot[0]:= 0 ;granite potion max granite_pot[1]:= 3 ;granite potion 1 hotkey value ;config mana potions mana_pot[0]:= 2 ;mana potion max mana_pot[1]:= 4 ;mana potion 1 hotkey value mana_pot[2]:= 5 ;mana potion 1 hotkey value global life_potdelay:= 200 global granite_potdelay:= 4000 global mana_potdelay:= 400 ; 99 cents, bag it global life_potcur:= 1 ; the potion to use cursor and index [0] holds the max global granite_potcur:= 1 ; the potion to use cursor and index [0] holds the max global mana_potcur:= 1 ; the potion to use cursor and index [0] holds the max global life_pottimer:= 0, granite_pottimer:= 0, mana_pottimer:= 0 ; - - - END modified SetBatchLines, -1 DetectHiddenWindows, On cliname=Path of Exile cliexe=PathOfExile.exe trayNotifications:=true ;display tray notifications about script actions : drinking potions, autoquitting autoPotionsWatchdogPeriod:=100 ;milliseconds, decrease this value to have script recheck life/mana/flasks availability more often/increase chances of getting saved from death in time lagCompensation:=50 autoQuitMode:=1 ; default autoQuit method : 0 =winKill, 1 = exit to login screen autoQuitPauseBeforeClick:=100 autoQuitSoftToleranceBeforeKill:=2000 ; try to quit to loginscreen at most milliseconds before killing game window(in case we can't quit by clicking menu option for some reason) PlayerConfig:={} PlayerConfig["Default"]:={minLifeRatioToDrink: 0.85, minManaRatioToDrink: 0.55, minManaToDrink: 40, minLifeRatioToPopGranite: 0.79, minLifeRatioToQuit: 0.45} ; disableAutoPotions:true, minLifeRatioToQuit:, minNShieldRatioToQuit: , HasZealotsOath: false, } ;PlayerConfig["Default"]:={minLifeRatioToDrink: 0.75, minManaRatioToDrink: 0.45, minManaToDrink: 0, minLifeRatioToPopGranite: 0.75, minLifeRatioToQuit: 0.10} ; disableAutoPotions:true, minLifeRatioToQuit:, minNShieldRatioToQuit: , HasZealotsOath: false, } PlayerConfig["Default"].FlaskConfig:=[] PlayerConfig["Default"].FlaskConfig[1]:={Hotkey:"{1 Down 1 UP}"} ; ,OverrideFlaskDuration:70, instantRecoveryOnLowLife:true, } ;specify override recovery time in deciseconds, e.g. 7 seconds = 70 PlayerConfig["Default"].FlaskConfig[2]:={Hotkey:"{2 Down 2 UP}"} PlayerConfig["Default"].FlaskConfig[3]:={Hotkey:"{3 Down 3 UP}"} PlayerConfig["Default"].FlaskConfig[4]:={Hotkey:"{4 Down 4 UP}"} PlayerConfig["Default"].FlaskConfig[5]:={Hotkey:"{5 Down 5 UP}"} PlayerConfig["YourHardcorePlayerName"]:={minLifeRatioToDrink: 0.7, minManaRatioToDrink: 0.35, minManaToDrink: 70, minLifeRatioToQuit: 0.4} PlayerConfig["YourHardcorePlayerName"].FlaskConfig:=[] PlayerConfig["YourHardcorePlayerName"].FlaskConfig[1]:={Hotkey:"{1 Down 1 UP}"} PlayerConfig["YourHardcorePlayerName"].FlaskConfig[2]:={Hotkey:"{2 Down 2 UP}"} PlayerConfig["YourHardcorePlayerName"].FlaskConfig[3]:={Hotkey:"{3 Down 3 UP}"} PlayerConfig["YourHardcorePlayerName"].FlaskConfig[4]:={Hotkey:"{4 Down 4 UP}"} PlayerConfig["YourHardcorePlayerName"].FlaskConfig[5]:={Hotkey:"{5 Down 5 UP}"} autoPotionsState:=true WindowQueuedFlaskEffects:=[] ;keyed by "%hwnd%%CurrPid%", hpQueueEndtime, manaQueueEndtime ;baseMgrPtr:=0x785BB4 ; 0.11.3b delete for script to try to auto-scan for it in newer versions, scan takes 4-5 seconds basePtrAoBArray:=[0x6A,0xFF,0x68,"?","?","?","?",0x50,0x64,"?","?","?","?","?","?",0xA1,"?","?","?","?",0x81,0xEC,"?","?","?","?",0x53,0x55,0x56,0x57,0x33,0xFF,0x3B,0xC7] basePtrAobOffset:=0x10 WindowBasicsCache:=[] ; keyed by "%hwnd%%CurrPid%", entries are objects with properties processHandle, moduleBase, moduleSize, baseFramePtr #Include AutoHotkeyMemoryLib.ahk Loop { AutoPotions() } GetWindowBasics(hwnd, byref mB="", byref pH="", byref mS="") { global WindowBasicsCache global cliexe WinGet, CurrPid, PID, ahk_id %hwnd% k="%hwnd%%CurrPid%" mB:=WindowBasicsCache[k].mBase mS:=WindowBasicsCache[k].mSize if mB= { WindowBasicsCache[k]:=Object() GetModuleInfo(cliexe, CurrPid, mB, mS) if (mB="" || mS="") { MsgBox, Failed to obtain moduleBase or moduleSize for PID %CurrPid%, script will now terminate ExitApp } WindowBasicsCache[k].mBase:=mB WindowBasicsCache[k].mSize:=mS } pH:=WindowBasicsCache[k].ProcessHandle if pH= { pH:=GetProcessHandle(CurrPid) if (pH="" || pH=-1) { MsgBox, Invalid process handle obtained for PID %CurrPid%, script will now terminate ExitApp } WindowBasicsCache[k].ProcessHandle:=pH } } ScanBaseMgrPtr(mBase,pH,moduleSize) { global basePtrAoBArray global basePtrAobOffset global baseMgrPtr aobResult:=AobScan(pH,mBase,moduleSize,basePtrAoBArray) if aobResult { SetFormat, IntegerFast, hex baseMgrPtr:=ReadMemUInt(pH,mBase+aobResult+basePtrAobOffset)-mBase MsgBox, PoE Base ptr found with AoB Scan baseMgrPtr = %baseMgrPtr%, save this value to script for quick startup SetFormat, IntegerFast, dec } else { MsgBox, baseMgrPtr not found with AoBScan, script will now terminate ExitApp } } GetFrameBase(hwnd) { global baseMgrPtr global WindowBasicsCache WinGet, CurrPid, PID, ahk_id %hwnd% k="%hwnd%%CurrPid%" fB:=WindowBasicsCache[k].fBase if fB= { GetWindowBasics(hwnd, mBase, pH, mSize) if baseMgrPtr= { ScanBaseMgrPtr(mBase, pH, mSize) } fB:=GetMultilevelPointer(pH,[mBase+baseMgrPtr,4,0x7C,0x94]) WindowBasicsCache[k].fBase:=fB } return fB } GetUiBase(hwnd) { global baseMgrPtr GetWindowBasics(hwnd, mBase, pH, mSize) if baseMgrPtr= { ScanBaseMgrPtr(mBase, pH, mSize) } FrameBase:=GetFrameBase(hwnd) if (FrameBase="" || FrameBase=0) return uiBase:=GetMultilevelPointer(pH,[FrameBase+0xBC,0xA4,0x50]) return uiBase } ReadClientResolution(hwnd, ByRef w, ByRef h) { GetWindowBasics(hwnd,mBase,pH) if (mBase!=0 && pH && pH!=-1) { FrameBase:=GetFrameBase(hwnd) w:=ReadMemUInt(pH,FrameBase+0x1340) h:=ReadMemUInt(pH,FrameBase+0x1344) return true } } ReadPlayerStats(hwnd, byRef PlayerStats) { GetWindowBasics(hwnd, mBase, pH) fBase:=GetFrameBase(hwnd) PlayerBase:=GetMultilevelPointer(pH,[fBase+0xBC,0x59C]) PlayerMain:=ReadMemUInt(pH,PlayerBase+4) PlayerStatsOffset:=ReadMemUInt(pH,PlayerMain+0xC) PlayerStats.MaxHP:=ReadMemUInt(pH,PlayerStatsOffset+0x50) PlayerStats.CurrHP:=ReadMemUInt(pH,PlayerStatsOffset+0x54) PlayerStats.ReservedHPFlat:=ReadMemUInt(pH,PlayerStatsOffset+0x5C) PlayerStats.ReservedHPPercent:=ReadMemUInt(pH,PlayerStatsOffset+0x60) PlayerStats.MaxMana:=ReadMemUInt(pH,PlayerStatsOffset+0x74) PlayerStats.ReservedManaFlat:=ReadMemUInt(pH,PlayerStatsOffset+0x80) PlayerStats.ReservedManaPercent:=ReadMemUInt(pH,PlayerStatsOffset+0x84) PlayerStats.CurrMana:=ReadMemUInt(pH,PlayerStatsOffset+0x78) PlayerStats.MaxNShield:=ReadMemUInt(pH,PlayerStatsOffset+0x98) PlayerStats.CurrNShield:=ReadMemUInt(pH,PlayerStatsOffset+0x9C) if (ReadMemUInt(pH, ReadMemUInt(pH,PlayerMain+0x14)+0x24)<8) ;names shorter than 7 chars are stored immediately in component PlayerStats.Name:=ReadMemStr(pH, ReadMemUint(pH,PlayerMain+0x14)+0x10,100,"UTF-16") ;immediate name in component else PlayerStats.Name:=ReadMemStr(pH, GetMultilevelPointer(pH,[PlayerMain+0x14,0x10]),100,"UTF-16") ; otherwise pointer to name is stored } ReadFlasksData(hwnd, byRef FlasksData) { GetWindowBasics(hwnd, mBase, pH) UiBase:=GetUiBase(hwnd) if (!UiBase) ;not InGame return FlaskInvBase:=GetMultilevelPointer(pH,[UiBase+0x8e8,0x900,0x20]) Loop, 5 { currFlaskPtr:=ReadMemUInt(pH,FlaskInvBase+(A_Index-1)*4) if (currFlaskPtr!=0) ; there's a flask in said slot { FlasksData[A_Index]:={} FlaskChargesPtr:=GetMultilevelPointer(ph,[currFlaskPtr,4,0x1C,4,4,0xC]) FlasksData[A_Index].ChargesCurrent:=ReadMemUInt(pH,FlaskChargesPtr+0xC) FlasksData[A_Index].ChargesPerUse:=ReadMemUInt(pH,ReadMemUInt(pH,FlaskChargesPtr+8)+0xC) if (FlasksData[A_Index].ChargesCurrent < FlasksData[A_Index].ChargesPerUse) ; not enough charges in this flask to use it, don't bother continue FlaskMetadataPtr:=GetMultilevelPointer(ph,[currFlaskPtr,0,8]) FlaskMetadataStr:=ReadMemStr(ph,FlaskMetadataPtr,70,"UTF-16") FlaskTypeStr:=SubStr(FlaskMetadataStr,23) FlasksData[A_Index].type:=FlaskTypeStr FlaskLocalstatsPtr:=GetMultilevelPointer(ph,[currFlaskPtr,4,0x18,0x20,0xC]) if InStr(FlaskTypeStr, "Life") { FlasksData[A_Index].HPRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+4) FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0xC) } if InStr(FlaskTypeStr, "Mana") { FlasksData[A_Index].ManaRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+4) FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0xC) } if InStr(FlaskTypeStr, "Hybrid") { FlasksData[A_Index].HPRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+4) FlasksData[A_Index].ManaRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+0xC) FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0x14) } if InStr(FlaskTypeStr, "FlaskUtility") { FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0x4) } } } } IsInGame(hwnd) { if (hwnd=0 || hwnd="") return false GetWindowBasics(hwnd,mBase,pH) if (mBase="" || mBase=0 || pH="" || pH=-1) return false fBase:=GetFrameBase(hwnd) if (fBase="" || fBase=0) return false localConnection:=ReadMemUInt(pH,fBase+0xc0) if (localConnection=0 || localConnection="") return false else return true } SetGameStateMenu(hwnd) { if (hwnd=0 || hwnd="") return false GetWindowBasics(hwnd,mBase,pH) if (mBase="" || mBase=0 || pH="" || pH=-1) return false fBase:=GetFrameBase(hwnd) if (fBase="" || fBase=0) return false localConnection:=ReadMemUInt(pH,fBase+0xc0) if (localConnection!="" && localConnection!=0) { WriteMemUInt(pH,localConnection+0x2578,1) } } ReadCursorScreenPosition(hwnd,ByRef cX, ByRef cY) { GetWindowBasics(hwnd,mBase,pH) if (mBase!=0 && pH && pH!=-1) { FrameBase:=GetFrameBase(hwnd) cX:=ReadMemSInt(pH,FrameBase+0x155c) cY:=ReadMemSInt(pH,FrameBase+0x1560) return true } } ScreenToClient(hwnd, ByRef x, ByRef y) { VarSetCapacity(pt, 8) NumPut(x, pt, 0) NumPut(y, pt, 4) DllCall("ScreenToClient", "uint", hwnd, "uint", &pt) x := NumGet(pt, 0, "int") y := NumGet(pt, 4, "int") VarSetCapacity(pt, 0) } GetClientCoords(byRef mx, byRef my) { hwnd:=WinActive("A") CoordMode, Mouse, Screen MouseGetPos, mx, my ScreenToClient(hwnd,mx,my) ;get mouse pos relative to window client rect } GetFractionalCoords(ByRef fX, ByRef fY) { hwnd:=WinActive("A") if (!IsInGame(hwnd)) GetClientCoords(mx,my) else ReadCursorScreenPosition(hwnd,mx,my) ReadClientResolution(hwnd,w,h) fX:=mx/w fY:=my/h } GetClientCoordsFromFractional(hwnd, fX,fY, ByRef cX, ByRef cY) { ReadClientResolution(hwnd,w,h) cX:=fX*w cY:=fY*h } QuitToLoginScreen(hwnd) { if (!IsInGame(hwnd)) { return } SetGameStateMenu(hwnd) } GetMaxChargesFlaskOfType(ByRef FlasksData,TypeStr) { currMaxCharges:=0 Loop, 5 if (InStr(FlasksData[A_Index].type,TypeStr)) { if FlasksData[A_Index].ChargesCurrent>currMaxCharges { currMaxI:=A_Index currMaxCharges:=FlasksData[A_Index].ChargesCurrent } } return currMaxI } AutoPotions() { global autoPotionsWatchdogPeriod global lagCompensation global PlayerConfig global WindowQueuedFlaskEffects global cliname global cliexe global trayNotifications global autoQuitMode if (autoPotionsState!=true) return WinGet, WinID, List, %cliname% Loop, %WinID% { WinGet, ProcModuleName, ProcessName, % "ahk_id" WinID%A_Index% If(ProcModuleName!=cliexe) ; got a window with title "Path of Exile" but exe is not Client.exe, perhaps we have browser window open with PoE site, ignore it continue if (!IsInGame(WinID%A_Index%)) ;not ingame continue if (WinID%A_Index%=WinActive("A")) ThisID:=WinActive("A") PlayerStats:={} ReadPlayerStats(WinID%A_Index%, PlayerStats) if (PlayerStats.MaxHP<1 || PlayerStats.CurrHP=0) ;dead, don't bother continue if (PlayerConfig.HasKey(PlayerStats.Name)) CurrentConfig:=PlayerConfig[PlayerStats.Name] else CurrentConfig:=PlayerConfig["Default"] if PlayerStats.MaxNShield>0 { currNShieldRatio:=PlayerStats.CurrNShield/PlayerStats.MaxNShield } if (PlayerStats.MaxHP>1) { currLifeRatio:=PlayerStats.CurrHP/(PlayerStats.MaxHP-PlayerStats.ReservedHPFlat-PlayerStats.MaxHP*PlayerStats.ReservedHPPercent/100) } if CurrentConfig.HasZealotsOath { currLifeRatio:=currNShieldRatio } if (PlayerStats.MaxMana>0) { currManaRatio:=PlayerStats.CurrMana/(PlayerStats.MaxMana-PlayerStats.ReservedManaFlat-PlayerStats.MaxMana*PlayerStats.ReservedManaPercent/100) } if (currLifeRatio<CurrentConfig.minLifeRatioToQuit || currNShieldRatio<CurrentConfig.minNShieldRatioToQuit) { if (autoQuitMode=0) { TrayTip, PoE autoPotions AutoQuit by closing window, specified min life reached, %A_Space% , 2 WinKill, % "ahk_id" WinID%A_Index% } else if (autoQuitMode=1) { QuitToLoginScreen(WinID%A_Index%) } autoQuit:=1 continue } if (CurrentConfig.disableAutoPotions) continue FlasksData:=[] ReadFlasksData(WinID%A_Index%,FlasksData) WinGet, CurrPID, PID, % "ahk_id" WinID%A_Index% hwnd:=WinID%A_Index% k="%hwnd%%CurrPid%" if (!WindowQueuedFlaskEffects.HasKey(k)) { WindowQueuedFlaskEffects[k]:={} } if (currLifeRatio<CurrentConfig.minLifeRatioToPopGranite || currNShieldRatio<CurrentConfig.minNShieldRatioToPopGranite) ;rem'd next line Xandy ;if ((!WindowQueuedFlaskEffects[k].HasKey("graniteQueueEndtime")) || (A_TickCount>=(WindowQueuedFlaskEffects[k].graniteQueueEndtime-lagCompensation))) { ; modified by: Xandy if(granite_pot[0]> 0) { if(granite_pottimer<= A_TickCount) { send % granite_pot[granite_potcur] granite_potcur+= 1 if(granite_potcur> granite_pot[0]) granite_potcur= 1 granite_pottimer:= A_TickCount+granite_potdelay } } ;end modified flaskNum:=GetMaxChargesFlaskOfType(FlasksData,"FlaskUtility5") ; granite flask ; rem'd next line, Xandy ;if (flaskNum!="") { if CurrentConfig.FlaskConfig[flaskNum].HasKey("OverrideFlaskDuration") EffectDuration:=CurrentConfig.FlaskConfig[flaskNum].OverrideFlaskDuration else EffectDuration:=FlasksData[flaskNum].EffectDuration WindowQueuedFlaskEffects[k].graniteQueueEndtime:=A_TickCount+EffectDuration*100 if (trayNotifications) { pname:=PlayerStats.Name TrayTip, PoE autoPotions popping Granite flask %flaskNum% on %pname%, %A_Space% , 2 } hKey:=CurrentConfig.FlaskConfig[flaskNum].Hotkey ControlSend,,%hkey%, % "ahk_id" hwnd break } } if (currLifeRatio=1) WindowQueuedFlaskEffects[k].hpQueueEndtime:=A_TickCount if (currManaRatio=1) WindowQueuedFlaskEffects[k].ManaQueueEndtime:=A_TickCount if (currLifeRatio<CurrentConfig.minLifeRatioToDrink || (PlayerStats.CurrHP<CurrentConfig.minLifeToDrink)) ; rem'd next line, Xandy ;if ((!WindowQueuedFlaskEffects[k].HasKey("hpQueueEndtime")) || (A_TickCount>=(WindowQueuedFlaskEffects[k].hpQueueEndtime-lagCompensation))) { ;modified by: Xandy if(life_pot[0]> 0) { if(life_pottimer<= A_TickCount) { send % life_pot[life_potcur] life_potcur+= 1 if(life_potcur> life_pot[0]) life_potcur= 1 life_pottimer:= A_TickCount+life_potdelay } } ; END modified tflaskNum1:=GetMaxChargesFlaskOfType(FlasksData,"FlaskLife") tflaskNum2:=GetMaxChargesFlaskOfType(FlasksData,"FlaskHybrid") if ((tflaskNum1!=) && (tflaskNum2!=)) flaskNum:=(FlasksData[tflaskNum1].ChargesCurrent>FlasksData[tflaskNum2].ChargesCurrent) ? tflaskNum1 : tflaskNum2 else { if (tflaskNum1!="") flaskNum:=tflaskNum1 if (tflaskNum2!="") flaskNum:=tflaskNum2 } ; rem'd next line, Xandy ;if (flaskNum!="") { if CurrentConfig.FlaskConfig[flaskNum].HasKey("OverrideFlaskDuration") EffectDuration:=CurrentConfig.FlaskConfig[flaskNum].OverrideFlaskDuration else EffectDuration:=FlasksData[flaskNum].EffectDuration if ((CurrentConfig.FlaskConfig[flaskNum].instantRecoveryOnLowLife) && ((PlayerStats.CurrHP/PlayerStats.MaxHP)<=0.35)) ; "Low life" can be caused by auras hp reservation from blood magic EffectDuration:=lagCompensation WindowQueuedFlaskEffects[k].hpQueueEndtime:=A_TickCount+EffectDuration*100 if (FlasksData[flaskNum].HasKey("ManaRegAmount")) ; hybrid flask WindowQueuedFlaskEffects[k].ManaQueueEndtime:=A_TickCount+EffectDuration*100 if (trayNotifications) { pname:=PlayerStats.Name TrayTip, PoE autoPotions sipping HP flask %flaskNum% on %pname%, %A_Space% , 2 } hKey:=CurrentConfig.FlaskConfig[flaskNum].Hotkey ControlSend,,%hkey%, % "ahk_id" hwnd break } } ; modified example inserted below remared line rem'd next line Xandy ;if (PlayerStats.MaxMana>0 && (currManaRatio<CurrentConfig.minManaRatioToDrink || PlayerStats.CurrMana<CurrentConfig.minManaToDrink)) if (PlayerStats.MaxMana>0 && (currManaRatio<CurrentConfig.minManaRatioToDrink)) ; rem'd next line, Xandy ;if ((!WindowQueuedFlaskEffects[k].HasKey("ManaQueueEndtime")) || (A_TickCount>=(WindowQueuedFlaskEffects[k].ManaQueueEndtime-lagCompensation))) { ; modified by: Xandy if(mana_pot[0]> 0) { if(mana_pottimer<= A_TickCount) { send % mana_pot[mana_potcur] mana_potcur+= 1 if(mana_potcur> mana_pot[0]) mana_potcur= 1 mana_pottimer:= A_TickCount+mana_potdelay } } ; END modified tflaskNum1:=GetMaxChargesFlaskOfType(FlasksData,"FlaskMana") tflaskNum2:=GetMaxChargesFlaskOfType(FlasksData,"FlaskHybrid") if ((tflaskNum1!=) && (tflaskNum2!=)) flaskNum:=(FlasksData[tflaskNum1].ChargesCurrent>FlasksData[tflaskNum2].ChargesCurrent) ? tflaskNum1 : tflaskNum2 else { if (tflaskNum1!="") flaskNum:=tflaskNum1 if (tflaskNum2!="") flaskNum:=tflaskNum2 } ; rem'd next line, Xandy ;if (flaskNum!="") { if CurrentConfig.FlaskConfig[flaskNum].HasKey("OverrideFlaskDuration") { EffectDuration:=CurrentConfig.FlaskConfig[flaskNum].OverrideFlaskDuration } else EffectDuration:=FlasksData[flaskNum].EffectDuration if ((CurrentConfig.FlaskConfig[flaskNum].instantRecoveryOnLowLife) && ((PlayerStats.CurrHP/PlayerStats.MaxHP)<=0.35)) EffectDuration:=lagCompensation WindowQueuedFlaskEffects[k].ManaQueueEndtime:=A_TickCount+EffectDuration*100 if (FlasksData[flaskNum].HasKey("HPRegAmount")) ; hybrid flask WindowQueuedFlaskEffects[k].hpQueueEndtime:=A_TickCount+EffectDuration*100 hKey:=CurrentConfig.FlaskConfig[flaskNum].Hotkey if (trayNotifications) { pname:=PlayerStats.Name TrayTip, PoE autoPotions sipping mana flask %flaskNum% on %pname%, %A_Space% , 2 } ControlSend,,%hkey%, % "ahk_id" hwnd break } } } if ((autoQuit=1) && (ThisID!="") && (ThisID!=WinActive("A"))) WinActivate, % "ahk_id" ThisID Sleep, %autoPotionsWatchdogPeriod% } F14:: global autoPotionsState global trayNotifications autoPotionsState:=not autoPotionsState if (trayNotifications) { if (autoPotionsState=true) TrayTip, PoE autoPotions is on, %A_Space% , 2 else TrayTip, PoE autoPotions is off, %A_Space% , 2 } return F15:: GetClientCoords(mx,my) GetFractionalCoords(fx,fy) msgbox, mx=%mx% my=%my% fx=%fx% fy=%fy% return F4:: QuitToLoginScreen(WinActive("A")) return EDITED: Edited to function with reserved manaEDITED: Edited back to low life, mana delays
  6. I just spliced some reasonable arrays and counters into somebody else's beautiful memory activated code. My implementation is helpful to me b/c the correct offsets regarding the flasks are not being used and I don't have the skillz to sniff them out. The timers are messed up and I'm working on releasing a better version. Thing is I'm doing a LAN party at my homies for the rest of the weekend, so this really isn't a good programming environment for me to learn AutoHotkey. My example above works pretty well for me, but my lifers are instant heals, so idk how it'll work out for everyone. EDIT: http://exiled-bot.net/forum/viewtopic.php?p=7504#p7504 I gave an example of granite flask config. It was wrong and has been corrected. Note: A friend of mine changes his belt hotkeys in game to Numpad0 and shit. If you changed your belt hotkeys to a key that cannot be represented by a single char string, then I'm not sure how to do that yet. If you use the default belt hotkeys (1, 2, 3, 4, 5) this should work fine.
  7. works with my granite flask set to belt hotkey 3 ;config granite granite_pot[0]:= 1 ;how many granite potions in belt granite_pot[1]:= 3 ; the key to send to trigger the granite flask from belt belt bel EDIT: was missing the ':=' and it is required for the correct assignment !!!
  8. This code will use pots. I didn't test the mana section or implement any delay. See the config section to preset the hotkey flask buttons to your flask type hotkeys My example is from a 1life, 2life, 3granite, 4r/w, 5r/w ; - - - Modified by: Xandy global life_pot:= object() global granite_pot:= object() global mana_pot:= object() ;config life potions life_pot[0]:= 2 ;life potion max life_pot[1]:= 1 ;life potion 1 hotkey value life_pot[2]:= 2 ;life potion 2 hotkey value ;config granite potions granite_pot[0]:= 1 ;granite potion max granite_pot[1]:= 3 ;granite potion 1 hotkey value ;config mana potions mana_pot[0]:= 0 ;mana potion max mana_pot[1]:= 3 ;mana potion 1 hotkey value global life_potcur= 1 ; the potion to use cursor and index [0] holds the max global granite_potcur= 1 ; the potion to use cursor and index [0] holds the max global mana_potcur= 1 ; the potion to use cursor and index [0] holds the max global life_potdelay= 200 global granite_potdelay= 200 global mana_potdelay= 200 ; 99 cents, bag it ; - - - END modified SetBatchLines, -1 DetectHiddenWindows, On cliname=Path of Exile cliexe=PathOfExile.exe trayNotifications:=true ;display tray notifications about script actions : drinking potions, autoquitting autoPotionsWatchdogPeriod:=100 ;milliseconds, decrease this value to have script recheck life/mana/flasks availability more often/increase chances of getting saved from death in time lagCompensation:=50 autoQuitMode:=1 ; default autoQuit method : 0 =winKill, 1 = exit to login screen autoQuitPauseBeforeClick:=100 autoQuitSoftToleranceBeforeKill:=2000 ; try to quit to loginscreen at most milliseconds before killing game window(in case we can't quit by clicking menu option for some reason) PlayerConfig:={} PlayerConfig["Default"]:={minLifeRatioToDrink: 0.85, minManaRatioToDrink: 0.55, minManaToDrink: 40, minLifeRatioToPopGranite: 0.79, minLifeRatioToQuit: 0.45} ; disableAutoPotions:true, minLifeRatioToQuit:, minNShieldRatioToQuit: , HasZealotsOath: false, } ;PlayerConfig["Default"]:={minLifeRatioToDrink: 0.75, minManaRatioToDrink: 0.45, minManaToDrink: 0, minLifeRatioToPopGranite: 0.75, minLifeRatioToQuit: 0.10} ; disableAutoPotions:true, minLifeRatioToQuit:, minNShieldRatioToQuit: , HasZealotsOath: false, } PlayerConfig["Default"].FlaskConfig:=[] PlayerConfig["Default"].FlaskConfig[1]:={Hotkey:"{1 Down 1 UP}"} ; ,OverrideFlaskDuration:70, instantRecoveryOnLowLife:true, } ;specify override recovery time in deciseconds, e.g. 7 seconds = 70 PlayerConfig["Default"].FlaskConfig[2]:={Hotkey:"{2 Down 2 UP}"} PlayerConfig["Default"].FlaskConfig[3]:={Hotkey:"{3 Down 3 UP}"} PlayerConfig["Default"].FlaskConfig[4]:={Hotkey:"{4 Down 4 UP}"} PlayerConfig["Default"].FlaskConfig[5]:={Hotkey:"{5 Down 5 UP}"} PlayerConfig["YourHardcorePlayerName"]:={minLifeRatioToDrink: 0.7, minManaRatioToDrink: 0.35, minManaToDrink: 70, minLifeRatioToQuit: 0.4} PlayerConfig["YourHardcorePlayerName"].FlaskConfig:=[] PlayerConfig["YourHardcorePlayerName"].FlaskConfig[1]:={Hotkey:"{1 Down 1 UP}"} PlayerConfig["YourHardcorePlayerName"].FlaskConfig[2]:={Hotkey:"{2 Down 2 UP}"} PlayerConfig["YourHardcorePlayerName"].FlaskConfig[3]:={Hotkey:"{3 Down 3 UP}"} PlayerConfig["YourHardcorePlayerName"].FlaskConfig[4]:={Hotkey:"{4 Down 4 UP}"} PlayerConfig["YourHardcorePlayerName"].FlaskConfig[5]:={Hotkey:"{5 Down 5 UP}"} autoPotionsState:=true WindowQueuedFlaskEffects:=[] ;keyed by "%hwnd%%CurrPid%", hpQueueEndtime, manaQueueEndtime ;baseMgrPtr:=0x785BB4 ; 0.11.3b delete for script to try to auto-scan for it in newer versions, scan takes 4-5 seconds basePtrAoBArray:=[0x6A,0xFF,0x68,"?","?","?","?",0x50,0x64,"?","?","?","?","?","?",0xA1,"?","?","?","?",0x81,0xEC,"?","?","?","?",0x53,0x55,0x56,0x57,0x33,0xFF,0x3B,0xC7] basePtrAobOffset:=0x10 WindowBasicsCache:=[] ; keyed by "%hwnd%%CurrPid%", entries are objects with properties processHandle, moduleBase, moduleSize, baseFramePtr #Include AutoHotkeyMemoryLib.ahk Loop { AutoPotions() } GetWindowBasics(hwnd, byref mB="", byref pH="", byref mS="") { global WindowBasicsCache global cliexe WinGet, CurrPid, PID, ahk_id %hwnd% k="%hwnd%%CurrPid%" mB:=WindowBasicsCache[k].mBase mS:=WindowBasicsCache[k].mSize if mB= { WindowBasicsCache[k]:=Object() GetModuleInfo(cliexe, CurrPid, mB, mS) if (mB="" || mS="") { MsgBox, Failed to obtain moduleBase or moduleSize for PID %CurrPid%, script will now terminate ExitApp } WindowBasicsCache[k].mBase:=mB WindowBasicsCache[k].mSize:=mS } pH:=WindowBasicsCache[k].ProcessHandle if pH= { pH:=GetProcessHandle(CurrPid) if (pH="" || pH=-1) { MsgBox, Invalid process handle obtained for PID %CurrPid%, script will now terminate ExitApp } WindowBasicsCache[k].ProcessHandle:=pH } } ScanBaseMgrPtr(mBase,pH,moduleSize) { global basePtrAoBArray global basePtrAobOffset global baseMgrPtr aobResult:=AobScan(pH,mBase,moduleSize,basePtrAoBArray) if aobResult { SetFormat, IntegerFast, hex baseMgrPtr:=ReadMemUInt(pH,mBase+aobResult+basePtrAobOffset)-mBase MsgBox, PoE Base ptr found with AoB Scan baseMgrPtr = %baseMgrPtr%, save this value to script for quick startup SetFormat, IntegerFast, dec } else { MsgBox, baseMgrPtr not found with AoBScan, script will now terminate ExitApp } } GetFrameBase(hwnd) { global baseMgrPtr global WindowBasicsCache WinGet, CurrPid, PID, ahk_id %hwnd% k="%hwnd%%CurrPid%" fB:=WindowBasicsCache[k].fBase if fB= { GetWindowBasics(hwnd, mBase, pH, mSize) if baseMgrPtr= { ScanBaseMgrPtr(mBase, pH, mSize) } fB:=GetMultilevelPointer(pH,[mBase+baseMgrPtr,4,0x7C,0x94]) WindowBasicsCache[k].fBase:=fB } return fB } GetUiBase(hwnd) { global baseMgrPtr GetWindowBasics(hwnd, mBase, pH, mSize) if baseMgrPtr= { ScanBaseMgrPtr(mBase, pH, mSize) } FrameBase:=GetFrameBase(hwnd) if (FrameBase="" || FrameBase=0) return uiBase:=GetMultilevelPointer(pH,[FrameBase+0xBC,0xA4,0x50]) return uiBase } ReadClientResolution(hwnd, ByRef w, ByRef h) { GetWindowBasics(hwnd,mBase,pH) if (mBase!=0 && pH && pH!=-1) { FrameBase:=GetFrameBase(hwnd) w:=ReadMemUInt(pH,FrameBase+0x1340) h:=ReadMemUInt(pH,FrameBase+0x1344) return true } } ReadPlayerStats(hwnd, byRef PlayerStats) { GetWindowBasics(hwnd, mBase, pH) fBase:=GetFrameBase(hwnd) PlayerBase:=GetMultilevelPointer(pH,[fBase+0xBC,0x59C]) PlayerMain:=ReadMemUInt(pH,PlayerBase+4) PlayerStatsOffset:=ReadMemUInt(pH,PlayerMain+0xC) PlayerStats.MaxHP:=ReadMemUInt(pH,PlayerStatsOffset+0x50) PlayerStats.CurrHP:=ReadMemUInt(pH,PlayerStatsOffset+0x54) PlayerStats.ReservedHPFlat:=ReadMemUInt(pH,PlayerStatsOffset+0x5C) PlayerStats.ReservedHPPercent:=ReadMemUInt(pH,PlayerStatsOffset+0x60) PlayerStats.MaxMana:=ReadMemUInt(pH,PlayerStatsOffset+0x74) PlayerStats.ReservedManaFlat:=ReadMemUInt(pH,PlayerStatsOffset+0x80) PlayerStats.ReservedManaPercent:=ReadMemUInt(pH,PlayerStatsOffset+0x84) PlayerStats.CurrMana:=ReadMemUInt(pH,PlayerStatsOffset+0x78) PlayerStats.MaxNShield:=ReadMemUInt(pH,PlayerStatsOffset+0x98) PlayerStats.CurrNShield:=ReadMemUInt(pH,PlayerStatsOffset+0x9C) if (ReadMemUInt(pH, ReadMemUInt(pH,PlayerMain+0x14)+0x24)<8) ;names shorter than 7 chars are stored immediately in component PlayerStats.Name:=ReadMemStr(pH, ReadMemUint(pH,PlayerMain+0x14)+0x10,100,"UTF-16") ;immediate name in component else PlayerStats.Name:=ReadMemStr(pH, GetMultilevelPointer(pH,[PlayerMain+0x14,0x10]),100,"UTF-16") ; otherwise pointer to name is stored } ReadFlasksData(hwnd, byRef FlasksData) { GetWindowBasics(hwnd, mBase, pH) UiBase:=GetUiBase(hwnd) if (!UiBase) ;not InGame return FlaskInvBase:=GetMultilevelPointer(pH,[UiBase+0x8e8,0x900,0x20]) Loop, 5 { currFlaskPtr:=ReadMemUInt(pH,FlaskInvBase+(A_Index-1)*4) if (currFlaskPtr!=0) ; there's a flask in said slot { FlasksData[A_Index]:={} FlaskChargesPtr:=GetMultilevelPointer(ph,[currFlaskPtr,4,0x1C,4,4,0xC]) FlasksData[A_Index].ChargesCurrent:=ReadMemUInt(pH,FlaskChargesPtr+0xC) FlasksData[A_Index].ChargesPerUse:=ReadMemUInt(pH,ReadMemUInt(pH,FlaskChargesPtr+8)+0xC) if (FlasksData[A_Index].ChargesCurrent < FlasksData[A_Index].ChargesPerUse) ; not enough charges in this flask to use it, don't bother continue FlaskMetadataPtr:=GetMultilevelPointer(ph,[currFlaskPtr,0,8]) FlaskMetadataStr:=ReadMemStr(ph,FlaskMetadataPtr,70,"UTF-16") FlaskTypeStr:=SubStr(FlaskMetadataStr,23) FlasksData[A_Index].type:=FlaskTypeStr FlaskLocalstatsPtr:=GetMultilevelPointer(ph,[currFlaskPtr,4,0x18,0x20,0xC]) if InStr(FlaskTypeStr, "Life") { FlasksData[A_Index].HPRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+4) FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0xC) } if InStr(FlaskTypeStr, "Mana") { FlasksData[A_Index].ManaRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+4) FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0xC) } if InStr(FlaskTypeStr, "Hybrid") { FlasksData[A_Index].HPRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+4) FlasksData[A_Index].ManaRegAmount:=ReadMemUInt(pH,FlaskLocalstatsPtr+0xC) FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0x14) } if InStr(FlaskTypeStr, "FlaskUtility") { FlasksData[A_Index].EffectDuration:=ReadMemUInt(pH,FlaskLocalstatsPtr+0x4) } } } } IsInGame(hwnd) { if (hwnd=0 || hwnd="") return false GetWindowBasics(hwnd,mBase,pH) if (mBase="" || mBase=0 || pH="" || pH=-1) return false fBase:=GetFrameBase(hwnd) if (fBase="" || fBase=0) return false localConnection:=ReadMemUInt(pH,fBase+0xc0) if (localConnection=0 || localConnection="") return false else return true } SetGameStateMenu(hwnd) { if (hwnd=0 || hwnd="") return false GetWindowBasics(hwnd,mBase,pH) if (mBase="" || mBase=0 || pH="" || pH=-1) return false fBase:=GetFrameBase(hwnd) if (fBase="" || fBase=0) return false localConnection:=ReadMemUInt(pH,fBase+0xc0) if (localConnection!="" && localConnection!=0) { WriteMemUInt(pH,localConnection+0x2578,1) } } ReadCursorScreenPosition(hwnd,ByRef cX, ByRef cY) { GetWindowBasics(hwnd,mBase,pH) if (mBase!=0 && pH && pH!=-1) { FrameBase:=GetFrameBase(hwnd) cX:=ReadMemSInt(pH,FrameBase+0x155c) cY:=ReadMemSInt(pH,FrameBase+0x1560) return true } } ScreenToClient(hwnd, ByRef x, ByRef y) { VarSetCapacity(pt, 8) NumPut(x, pt, 0) NumPut(y, pt, 4) DllCall("ScreenToClient", "uint", hwnd, "uint", &pt) x := NumGet(pt, 0, "int") y := NumGet(pt, 4, "int") VarSetCapacity(pt, 0) } GetClientCoords(byRef mx, byRef my) { hwnd:=WinActive("A") CoordMode, Mouse, Screen MouseGetPos, mx, my ScreenToClient(hwnd,mx,my) ;get mouse pos relative to window client rect } GetFractionalCoords(ByRef fX, ByRef fY) { hwnd:=WinActive("A") if (!IsInGame(hwnd)) GetClientCoords(mx,my) else ReadCursorScreenPosition(hwnd,mx,my) ReadClientResolution(hwnd,w,h) fX:=mx/w fY:=my/h } GetClientCoordsFromFractional(hwnd, fX,fY, ByRef cX, ByRef cY) { ReadClientResolution(hwnd,w,h) cX:=fX*w cY:=fY*h } QuitToLoginScreen(hwnd) { if (!IsInGame(hwnd)) { return } SetGameStateMenu(hwnd) } GetMaxChargesFlaskOfType(ByRef FlasksData,TypeStr) { currMaxCharges:=0 Loop, 5 if (InStr(FlasksData[A_Index].type,TypeStr)) { if FlasksData[A_Index].ChargesCurrent>currMaxCharges { currMaxI:=A_Index currMaxCharges:=FlasksData[A_Index].ChargesCurrent } } return currMaxI } AutoPotions() { global autoPotionsWatchdogPeriod global lagCompensation global PlayerConfig global WindowQueuedFlaskEffects global cliname global cliexe global trayNotifications global autoQuitMode if (autoPotionsState!=true) return WinGet, WinID, List, %cliname% Loop, %WinID% { WinGet, ProcModuleName, ProcessName, % "ahk_id" WinID%A_Index% If(ProcModuleName!=cliexe) ; got a window with title "Path of Exile" but exe is not Client.exe, perhaps we have browser window open with PoE site, ignore it continue if (!IsInGame(WinID%A_Index%)) ;not ingame continue if (WinID%A_Index%=WinActive("A")) ThisID:=WinActive("A") PlayerStats:={} ReadPlayerStats(WinID%A_Index%, PlayerStats) if (PlayerStats.MaxHP<1 || PlayerStats.CurrHP=0) ;dead, don't bother continue if (PlayerConfig.HasKey(PlayerStats.Name)) CurrentConfig:=PlayerConfig[PlayerStats.Name] else CurrentConfig:=PlayerConfig["Default"] if PlayerStats.MaxNShield>0 { currNShieldRatio:=PlayerStats.CurrNShield/PlayerStats.MaxNShield } if (PlayerStats.MaxHP>1) { currLifeRatio:=PlayerStats.CurrHP/(PlayerStats.MaxHP-PlayerStats.ReservedHPFlat-PlayerStats.MaxHP*PlayerStats.ReservedHPPercent/100) } if CurrentConfig.HasZealotsOath { currLifeRatio:=currNShieldRatio } if (PlayerStats.MaxMana>0) { currManaRatio:=PlayerStats.CurrMana/(PlayerStats.MaxMana-PlayerStats.ReservedManaFlat-PlayerStats.MaxMana*PlayerStats.ReservedManaPercent/100) } if (currLifeRatio<CurrentConfig.minLifeRatioToQuit || currNShieldRatio<CurrentConfig.minNShieldRatioToQuit) { if (autoQuitMode=0) { TrayTip, PoE autoPotions AutoQuit by closing window, specified min life reached, %A_Space% , 2 WinKill, % "ahk_id" WinID%A_Index% } else if (autoQuitMode=1) { QuitToLoginScreen(WinID%A_Index%) } autoQuit:=1 continue } if (CurrentConfig.disableAutoPotions) continue FlasksData:=[] ReadFlasksData(WinID%A_Index%,FlasksData) WinGet, CurrPID, PID, % "ahk_id" WinID%A_Index% hwnd:=WinID%A_Index% k="%hwnd%%CurrPid%" if (!WindowQueuedFlaskEffects.HasKey(k)) { WindowQueuedFlaskEffects[k]:={} } if (currLifeRatio<CurrentConfig.minLifeRatioToPopGranite || currNShieldRatio<CurrentConfig.minNShieldRatioToPopGranite) if ((!WindowQueuedFlaskEffects[k].HasKey("graniteQueueEndtime")) || (A_TickCount>=(WindowQueuedFlaskEffects[k].graniteQueueEndtime-lagCompensation))) { ; modified by: Xandy if(granite_pot[0]> 0) { send % granite_pot[granite_potcur] granite_potcur+= 1 if(granite_potcur> granite_pot[0]) granite_potcur= 1 } ;end modified flaskNum:=GetMaxChargesFlaskOfType(FlasksData,"FlaskUtility5") ; granite flask ; rem'd next line, Xandy ;if (flaskNum!="") { if CurrentConfig.FlaskConfig[flaskNum].HasKey("OverrideFlaskDuration") EffectDuration:=CurrentConfig.FlaskConfig[flaskNum].OverrideFlaskDuration else EffectDuration:=FlasksData[flaskNum].EffectDuration WindowQueuedFlaskEffects[k].graniteQueueEndtime:=A_TickCount+EffectDuration*100 if (trayNotifications) { pname:=PlayerStats.Name TrayTip, PoE autoPotions popping Granite flask %flaskNum% on %pname%, %A_Space% , 2 } hKey:=CurrentConfig.FlaskConfig[flaskNum].Hotkey ControlSend,,%hkey%, % "ahk_id" hwnd break } } if (currLifeRatio=1) WindowQueuedFlaskEffects[k].hpQueueEndtime:=A_TickCount if (currManaRatio=1) WindowQueuedFlaskEffects[k].ManaQueueEndtime:=A_TickCount if (currLifeRatio<CurrentConfig.minLifeRatioToDrink || (PlayerStats.CurrHP<CurrentConfig.minLifeToDrink)) if ((!WindowQueuedFlaskEffects[k].HasKey("hpQueueEndtime")) || (A_TickCount>=(WindowQueuedFlaskEffects[k].hpQueueEndtime-lagCompensation))) { ;modified by: Xandy if(life_pot[0]> 0) { send % life_pot[life_potcur] life_potcur+= 1 if(life_potcur> life_pot[0]) life_potcur= 1 } ; END modified tflaskNum1:=GetMaxChargesFlaskOfType(FlasksData,"FlaskLife") tflaskNum2:=GetMaxChargesFlaskOfType(FlasksData,"FlaskHybrid") if ((tflaskNum1!=) && (tflaskNum2!=)) flaskNum:=(FlasksData[tflaskNum1].ChargesCurrent>FlasksData[tflaskNum2].ChargesCurrent) ? tflaskNum1 : tflaskNum2 else { if (tflaskNum1!="") flaskNum:=tflaskNum1 if (tflaskNum2!="") flaskNum:=tflaskNum2 } ; rem'd next line, Xandy ;if (flaskNum!="") { if CurrentConfig.FlaskConfig[flaskNum].HasKey("OverrideFlaskDuration") EffectDuration:=CurrentConfig.FlaskConfig[flaskNum].OverrideFlaskDuration else EffectDuration:=FlasksData[flaskNum].EffectDuration if ((CurrentConfig.FlaskConfig[flaskNum].instantRecoveryOnLowLife) && ((PlayerStats.CurrHP/PlayerStats.MaxHP)<=0.35)) ; "Low life" can be caused by auras hp reservation from blood magic EffectDuration:=lagCompensation WindowQueuedFlaskEffects[k].hpQueueEndtime:=A_TickCount+EffectDuration*100 if (FlasksData[flaskNum].HasKey("ManaRegAmount")) ; hybrid flask WindowQueuedFlaskEffects[k].ManaQueueEndtime:=A_TickCount+EffectDuration*100 if (trayNotifications) { pname:=PlayerStats.Name TrayTip, PoE autoPotions sipping HP flask %flaskNum% on %pname%, %A_Space% , 2 } hKey:=CurrentConfig.FlaskConfig[flaskNum].Hotkey ControlSend,,%hkey%, % "ahk_id" hwnd break } } if (PlayerStats.MaxMana>0 && (currManaRatio<CurrentConfig.minManaRatioToDrink || PlayerStats.CurrMana<CurrentConfig.minManaToDrink)) if ((!WindowQueuedFlaskEffects[k].HasKey("ManaQueueEndtime")) || (A_TickCount>=(WindowQueuedFlaskEffects[k].ManaQueueEndtime-lagCompensation))) { ; modified by: Xandy if(mana_pot[0]> 0) { send % mana_pot[mana_potcur] mana_potcur+= 1 if(mana_potcur> mana_pot[0]) mana_potcur= 1 } ; END modified tflaskNum1:=GetMaxChargesFlaskOfType(FlasksData,"FlaskMana") tflaskNum2:=GetMaxChargesFlaskOfType(FlasksData,"FlaskHybrid") if ((tflaskNum1!=) && (tflaskNum2!=)) flaskNum:=(FlasksData[tflaskNum1].ChargesCurrent>FlasksData[tflaskNum2].ChargesCurrent) ? tflaskNum1 : tflaskNum2 else { if (tflaskNum1!="") flaskNum:=tflaskNum1 if (tflaskNum2!="") flaskNum:=tflaskNum2 } ; rem'd next line, Xandy ;if (flaskNum!="") { if CurrentConfig.FlaskConfig[flaskNum].HasKey("OverrideFlaskDuration") { EffectDuration:=CurrentConfig.FlaskConfig[flaskNum].OverrideFlaskDuration } else EffectDuration:=FlasksData[flaskNum].EffectDuration if ((CurrentConfig.FlaskConfig[flaskNum].instantRecoveryOnLowLife) && ((PlayerStats.CurrHP/PlayerStats.MaxHP)<=0.35)) EffectDuration:=lagCompensation WindowQueuedFlaskEffects[k].ManaQueueEndtime:=A_TickCount+EffectDuration*100 if (FlasksData[flaskNum].HasKey("HPRegAmount")) ; hybrid flask WindowQueuedFlaskEffects[k].hpQueueEndtime:=A_TickCount+EffectDuration*100 hKey:=CurrentConfig.FlaskConfig[flaskNum].Hotkey if (trayNotifications) { pname:=PlayerStats.Name TrayTip, PoE autoPotions sipping mana flask %flaskNum% on %pname%, %A_Space% , 2 } ControlSend,,%hkey%, % "ahk_id" hwnd break } } } if ((autoQuit=1) && (ThisID!="") && (ThisID!=WinActive("A"))) WinActivate, % "ahk_id" ThisID Sleep, %autoPotionsWatchdogPeriod% } F14:: global autoPotionsState global trayNotifications autoPotionsState:=not autoPotionsState if (trayNotifications) { if (autoPotionsState=true) TrayTip, PoE autoPotions is on, %A_Space% , 2 else TrayTip, PoE autoPotions is off, %A_Space% , 2 } return F15:: GetClientCoords(mx,my) GetFractionalCoords(fx,fy) msgbox, mx=%mx% my=%my% fx=%fx% fy=%fy% return F4:: QuitToLoginScreen(WinActive("A")) return Fixed my own updates a bit: 2
  9. You may need to select 'Fullscreen WINDOW mode', from the options, graphics menu in game in order for pixel chicken addon to function correctly. If you use 1920, 1080, resolution and this addon does not work for you, please let me know. IGNORE b/c, Xandy dropped the code: Pixel Chicken Addon Thank you Wrongusername, alkpone, and everyone else for your time.
  10. SORRY THIS LOGIC IS A WAIST and has been dropped If you use 1920, 1080 resolution then this addon could enable pixel chicken for you. Pots are not yet active, I'm considering how I want to write this to work on any resolution. I'm just starting autohotkey. Paist this code right after the AutoPotions() in the main loop located around line 47. ;Pixel Chicken addon ;roughly half life chicken, on 1920, 1080 if(WinActive("Path of Exile")) { PixelGetColor pixelcolor, 118, 979 red:= SubStr(pixelcolor, 7, 2) if (red< 141) { ;if life not extream red ;SoundBeep if(red<> 0) { ;if NOT zone hopping QuitToLoginScreen(WinActive("A")) ;SoundBeep } ;red NOT true black } ;red< 141 } ;pixel chicken winactive() Main Loop should now look like this: Loop { AutoPotions() ;Pixel Chicken addon ;roughly half life chicken, on 1920, 1080 if(WinActive("Path of Exile")) { PixelGetColor pixelcolor, 118, 979 red:= SubStr(pixelcolor, 7, 2) if (red< 141) { ;if life not extream red ;SoundBeep if(red<> 0) { ;if NOT zone hopping QuitToLoginScreen(WinActive("A")) ;SoundBeep } ;red NOT true black } ;red< 141 } ;pixel chicken winactive() } SORRY THIS LOGIC IS A WAIST This code should be dropped until we lose the HP, MP values in some future patch. Then I'll revive the pixel sections.
×
×
  • Create New...