Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Pixelsearch in an area



  • Please log in to reply
19 replies to this topic
hollow
  • Members
  • 125 posts
  • Last active: Dec 21 2014 09:12 AM
  • Joined: 19 May 2011

Hi,

 

I don't know if it's wrong to use Pixelsearch command or what. But can anyone help me with this ? 

 

m8z7te.png

 

Explain: I want when the mana (the blue bar) left a little, I want my script send key " 2 " (to drink mana potion automatically)

 

According to the screenshot above, I made the code as below but it's not working.

#SingleInstance, force

!a::
PixelSearch, OutX, OutY, 161, 49, 246, 58, 0x60300, 10, Fast
If Errorlevel = 0
	sleep, 500
	Send, 2
return


JadeDragon
  • Members
  • 935 posts
  • Last active: Jun 07 2014 07:40 AM
  • Joined: 18 Jan 2013

for situations like this it's more efficient to use the PixelGetColor command for separate pixel detection routines for each of the bars you want to check. Once you have the base color of the bar you want to check at that pixel location, it's a relatively simple matter to check to see if it is that color or not at that pixel location instead of doing a repeating scan of pixels just to find out. If the color you are searching for and it's location are known ...

!a::
PixelGetColor, somecolor, %locx%, %locy%, RGB
if (somecolor != PutYourBaseColorHere)
{   ; do colors not equal stuff here
}
else
{   ;do colors are equal stuff here
}
Return

it's important to realize that your base color detection routine and your color check routine use the same method for color detection -- either both RGB or both BGR or the test will fail. The above snippet of code uses the RGB switch to grab the color in Red-Green-Blue format. The default for PixelGetColor is BGR (Blue-Green-Red).


Never assume evil intent when simple ignorance will suffice. Ignorance is an eventually curable condition with the right education. Evil intent, however, is another matter entirely. Scripts are much like children. Simple to conceive. Difficult, expensive, and time-consuming to raise. Often do the opposite of what you expect them to. Require frequent  "correction". And once they leave home you can't control them anymore. But you love them anyway.


hollow
  • Members
  • 125 posts
  • Last active: Dec 21 2014 09:12 AM
  • Joined: 19 May 2011

Look like it's not working..., anything I did wrong ?

#SingleInstance, force

!a::
PixelGetColor, color, 170, 55, RGB
if (color != 0x060300)
{   ; do colors not equal stuff here
	Sleep, 500
	MsgBox not detect
}
else
{   ;do colors are equal stuff here
	Send, 2
}
Return


JadeDragon
  • Members
  • 935 posts
  • Last active: Jun 07 2014 07:40 AM
  • Joined: 18 Jan 2013

did you capture the color 0x060300 using the RGB switch at the time you grabbed the color at 170,55? That color appears to be a very dark gray bordering on black (0x000000). What is the color when the bar is full it appears it should have a High Blue content probably over 0x????80 from the pic you posted. Just from the snip you posted above the color of the blue portion of the bar appears to be 0x0066BB. I would recommend you do this. 1) wait til the bar you want to check is full. 2) grab the color of the bar at a point where you wish to check to see if you need to take a pot. 3) when you need to, periodically check to see if the bar at that position IS NOT the normal blue color it needs to be as found in step 2 above. Here is a little utility that may help you determine exactly which colors you're looking for.

;--------------------------------------------------------------------
; JD's Color Scanner and verifier system
;--------------------------------------------------------------------
#NoEnv
#singleInstance, Force
#MaxThreadsPerHotkey, 3
SetBatchLines, -1
DetectHiddenWindows, On
CoordMode, Mouse, Screen
CoordMode, Pixel, Screen
CoordMode, Tooltip, Screen
SetTitleMatchMode, 2
SetKeyDelay, 30,50
SetMouseDelay 10
SendMode Event

;.................................
; Common to all modules
SplitPath, A_ScriptFullPath, ofname, ofdir, ofext, ofnamene, odrv
SetWorkingDir, %ofdir%
IniFile = %ofnamene%.ini
passback = Passback.ini ;<-- interprocess communication file

Blank =
centerx := (A_ScreenWidth // 2)
centery := (A_ScreenHeight // 2)

;------------------------------------------------
; loc/color grabber with timer display and preview window
; Use the middle mouse button to exit the routine
; Because some applications change the color of
; or highlight the the item the mouse is hovering
; over this this routine grabs two colors from 
; the selected location -- the color displayed 
; when the mouse is on the location and the color 
; that is displayed when the mouse is not on the 
; location. This method allows you to choose which
; color choice best works for you. The location and
; colors are copied to the clipboard as a comma-
; separated value so it can be pasted into a text
; file or directly into a variable in a script.
; -----------------------------------------------
+!g:: ;<-- tkGrabIt
tkGrabIt:
	KeyWait, b
	IniRead, GButton, %inifile%, Setup, GButton, MButton
	MouseGetPos, oposx, oposy ;<-- the off color position
	Sleep 200
	tkGrabItTimerFlag = 1
	gosub tkGrabItTimer
	Return
;................................................
tkGrabItTimer:
	Suspend, On
	MouseGetPos, mx, my ;<-- the on color position
	sleep 200
	pixelgetcolor, mouseoncolor, %mx%,%my%, Alt RGB ;<-- get the on color
	Sleep 200
	str = %mx%`,%my%`,%mouseoncolor%
	Tooltip, %str%`nUse the Mouse %GButton% to grab the loc and colors...,,,3

	; support for the color box
	gx := (mx + 20)
	If (gx > (A_Screenwidth - 50))
		gx := (mx - 100)
	gy := (my + 50)
	If (gy > (A_ScreenHeight - 50))
		gy := (my - 100)
	gmcolor := MouseOnColor
	gosub tkCreateColorGui

	If (GetKeyState(GButton, "P"))
	{	SoundBeep
		Tooltip, Release Mouse %GButton% to continue...,,,3	
		KeyWait, %GButton%	
		If (tkGrabItTimerFlag)	
		{	tkGrabItTimerFlag = 0
			MouseMove, %oposx%, %oposy%
			PixelGetColor, mouseoffcolor, %mx%,%my%, RGB ;<-- get the off color
			str = %str%`,%mouseoffcolor%`,`;OnPos-Color`, OffPos-Color in RGB Format
			Gui,9: Destroy
		}
		clipboard = %str%
		ClipWait
		tooltip,,,,3
		Suspend Off
		Return
	}
	suspend, off
	SetTimer, tkGrabItTimer, -100
	Return
;................................................
;gui for color picker
tkCreateColorGUI:
	;vgColor = 0xFFC0C0 ;<-- pale red
	;vgColor = 0xC0FFC0 ;<-- pale green
	;vgColor = 0xC0C0FF ;<-- pale blue
	;vgcolor = 0xFFFFC0 ;<-- pale yellow
	;vgcolor = 0xFFC0FF ;<-- pale violet
	;vgColor = 0xC0FFFF ;<-- pale teal
	vgColor = 0xFFC090 ;<-- flesh

	Gui,9: Destroy
	Gui,9: color, %vgColor%
	Gui,9: -Border
	Gui,9: Add, text, x8 y8 vcolor1txt, %gmcolor% RGB
	Gui,9: Add, Progress, E0x1 x7 y22 w76 h18 background0x000000 c%gmcolor% vcolor1Box, 100
	Gui,9: Show, x%gx% y%gy%
	Winset, AlwaysOnTop, On 
	Return

;------------------------------------------------
; pixel check routine based on the values returned
; by the tkGrabIt routine. Routine returns a 1 if match
; or 0 if no match on the color at the designated
; location. No checks are made for input validity.
; make sure the input is correct in all respects 
; before calling this routine.
; parameter tkGrabItStr format is x,y,oncolor,offcolor,[comment]
;------------------------------------------------

tkfnPixelCheck(tkGrabItstr)
{	If (tkGrabItstr = "None")
		Return 0
		
	; split the tkGrabIt string up into it's component parts
	stringsplit, tkGrabItary, tkGrabItstr, `,
	
	; grab the value of the current pixel color at the location
	; in question the same way the grab was made.
	; Best 2 out of 3 tries because the color could be varying
	sum = 0
	loop, 3
	{	pixelGetColor, thiscolor, %tkGrabItAry1%, %tkGrabItAry2%, alt, RGB
		sleep 200 ;<-- allow the color to stabilize
		; check the color in both forms because we don't always know
		; where the mouse is and if the color at that point is
		; highlighted or not.
		if ((thiscolor = %tkGrabItAry3%) || (thiscolor = %tkGrabItAry4%))
			sum += 1
	}
	Return, (sum > 1)
}

Esc::ExitApp

Note that some locations on the screen change color when you mouse over them, This routine can help you compensate for that by grabbing the color at the location when the mouse is both at that location and when it's not.


Never assume evil intent when simple ignorance will suffice. Ignorance is an eventually curable condition with the right education. Evil intent, however, is another matter entirely. Scripts are much like children. Simple to conceive. Difficult, expensive, and time-consuming to raise. Often do the opposite of what you expect them to. Require frequent  "correction". And once they leave home you can't control them anymore. But you love them anyway.


hollow
  • Members
  • 125 posts
  • Last active: Dec 21 2014 09:12 AM
  • Joined: 19 May 2011

I made a new image, included your utility. (Your utility is very useful & important for me so much thank you)

 

2i7ofbl.png

 

And my modified code:

#SingleInstance, force

!a::
WinWaitActive, gameID number 1
PixelGetColor, color, 179, 53, RGB
if (color != 0x3388CC)
{   ; do colors not equal stuff here
	Sleep, 500
	Send, 2
}
else
{   ;do colors are equal stuff here
	Sleep, 500
	MsgBox not detect
}
Return

It works only when the blue bar is fill at my location, and it give at the, else > sleep 500 & msgbox. But when I spend the blue bar more than the 179, 53...it does nothing, it doesn't send the Key number 2. Should you give some more advice ?



JadeDragon
  • Members
  • 935 posts
  • Last active: Jun 07 2014 07:40 AM
  • Joined: 18 Jan 2013

Normally you would select a point on the bar that is 1/3 to 1/2 of it's normal length. the color at that point on the bar should be its normal blue until your mana drops below that point. You would, while fighting for instance, check to see if it's still blue there and if it's not then you would take a mana potion and wait a brief time for the potion to work. This method uses something called bit masking to check to see if the blue part of the color is less than a limit value. if so it indicates the blue color is not "on" at that point on the mana bar. I added a label so you can call the routing by name if you should need to from another routine rather than just using a hotkey to check.

!a::
CheckManaBar:
PixelGetColor, color, 179, 53, RGB ;<-- get the color of the bar at 179,53
Sleep 200 ;<-- let the color stabilize
result := ((color & 0xFF) < 0x80) ;<-- strip everything but the blue and check to see if blue is off
If (result) ;<-- if blue is off (not high blue)
{   Send, 2 ;<-- take mana pot
    Sleep, 200 ;<-- and sleep for a bit to let the game handle the send
}
Return

Never assume evil intent when simple ignorance will suffice. Ignorance is an eventually curable condition with the right education. Evil intent, however, is another matter entirely. Scripts are much like children. Simple to conceive. Difficult, expensive, and time-consuming to raise. Often do the opposite of what you expect them to. Require frequent  "correction". And once they leave home you can't control them anymore. But you love them anyway.


hollow
  • Members
  • 125 posts
  • Last active: Dec 21 2014 09:12 AM
  • Joined: 19 May 2011

Hmm, this is not working. I've tried your whole code above.., it does nothing. I'm wondering if the problem can be the game itself. confused.png  I don't know. Do you think so ?



JadeDragon
  • Members
  • 935 posts
  • Last active: Jun 07 2014 07:40 AM
  • Joined: 18 Jan 2013

are you using

Coordmode Pixel, Screen for both the original read like in the color grabber i gave you earlier AND in your normal script? if not maybe that's the problem. You could be reading from the wrong location

!a::
CheckManaBar:
CoordMode, Pixel, Screen ;<-- line added
PixelGetColor, color, 179, 53, RGB ;<-- get the color of the bar at 179,53
Sleep 200 ;<-- let the color stabilize
result := ((color & 0xFF) < 0x80) ;<-- strip everything but the blue and check to see if blue is off
If (result) ;<-- if blue is off (not high blue)
{   Send, 2 ;<-- take mana pot
    Sleep, 200 ;<-- and sleep for a bit to let the game handle the send
}
Return

Never assume evil intent when simple ignorance will suffice. Ignorance is an eventually curable condition with the right education. Evil intent, however, is another matter entirely. Scripts are much like children. Simple to conceive. Difficult, expensive, and time-consuming to raise. Often do the opposite of what you expect them to. Require frequent  "correction". And once they leave home you can't control them anymore. But you love them anyway.


hollow
  • Members
  • 125 posts
  • Last active: Dec 21 2014 09:12 AM
  • Joined: 19 May 2011

Nope it's not working. I just copy everything from yours & add only Ifwinactive. This is the script:

#SingleInstance, force


!a::
CheckManaBar:
IfWinActive, gameid number 1
CoordMode, Pixel, Screen
PixelGetColor, color, 179, 53, RGB
Sleep 200
result := ((color & 0xFF) < 0x80)
If (result)
{   Send, 2
    Sleep, 200
}
Return


JadeDragon
  • Members
  • 935 posts
  • Last active: Jun 07 2014 07:40 AM
  • Joined: 18 Jan 2013

I don't know what to tell you. It worked when you used my utility to read the color 0x3388CC from the screen. yet now you say it doesn't work when you use the same code to read the color the second time to compare it. If you can read it once you should be able to read it again. something else is interfering with the read then.


Never assume evil intent when simple ignorance will suffice. Ignorance is an eventually curable condition with the right education. Evil intent, however, is another matter entirely. Scripts are much like children. Simple to conceive. Difficult, expensive, and time-consuming to raise. Often do the opposite of what you expect them to. Require frequent  "correction". And once they leave home you can't control them anymore. But you love them anyway.


hollow
  • Members
  • 125 posts
  • Last active: Dec 21 2014 09:12 AM
  • Joined: 19 May 2011

Sorry, the thing is that it worked only with this part:

}
else
{   ;do colors are equal stuff here
	Sleep, 500
	MsgBox not detect
}
Return

If I changed to:

}
else
{   ;do colors are equal stuff here
	Sleep, 500
	Send, 2
}
Return

It doesn't send the "2" ...no matter I tell it if the blue bar is not at the location I want or not. That's why...I said your help does helpful, but it maybe that crazy game which causes the issue with the send command.



hollow
  • Members
  • 125 posts
  • Last active: Dec 21 2014 09:12 AM
  • Joined: 19 May 2011

I don't know what to tell you. It worked when you used my utility to read the color 0x3388CC from the screen. yet now you say it doesn't work when you use the same code to read the color the second time to compare it. If you can read it once you should be able to read it again. something else is interfering with the read then.

 

JadeDragon, you have helped me with this. Since I was busy with my job and I test again with the script, it's working completely. The reason is that, I must run the script as Administrator and It works ! As always I run the script from Scite4 that's why it doesn't respond.

#SingleInstance, force

!a::
WinWaitActive, game id 1
PixelGetColor, color, 179, 53, RGB
if (color != 0x3388CC)
{   ; do colors not equal stuff here
	Sleep, 500
	Send, 2
}
else
{   ;do colors are equal stuff here
	Sleep, 1000
}
Return

One more question, now that it's working, I want to make it automatic. If at Location 179, 53 doesn't have this color 0x3388CC, I want it keep detecting, then take 2 or 3 potion, but if the bar reach 179, 53 (and it will goes over because we take potion) then I want the script stop take the potion. I cannot figure out where to add the argument.



JadeDragon
  • Members
  • 935 posts
  • Last active: Jun 07 2014 07:40 AM
  • Joined: 18 Jan 2013

Typically you only need to take a mana pot when your characters are casting spells and their mana falls below a certain point. If you have a standard fight routine you could add a timer that checks mana and uses a pot when it falls below a specific value on the mana bar.. That could be done with a simple gosub within the fight handler itself. Another way to handle this would be to set up a timer to check the mana or health bars regularly while your script is running and use a pot whenever the bar gets low.

 

Some pseudocode that could do this is shown here

; begin timer subroutine
; is timer running?
; if not
{  return
}
; check mana bar
; is color good?
; if not
{  ;use mana pot
}
; check health bar
; is color good?
; if not
{  ; use health pot
}
;reset the timer
return


Never assume evil intent when simple ignorance will suffice. Ignorance is an eventually curable condition with the right education. Evil intent, however, is another matter entirely. Scripts are much like children. Simple to conceive. Difficult, expensive, and time-consuming to raise. Often do the opposite of what you expect them to. Require frequent  "correction". And once they leave home you can't control them anymore. But you love them anyway.


hollow
  • Members
  • 125 posts
  • Last active: Dec 21 2014 09:12 AM
  • Joined: 19 May 2011

I really cannot analyze your assignment you gave to me to put into code. I understand your saying, but it's seem I don't know where to integrate into my code above. Can you help make it straight to me ?



hollow
  • Members
  • 125 posts
  • Last active: Dec 21 2014 09:12 AM
  • Joined: 19 May 2011

Sorry to double post. I come with this one also working..but if the code can be improved better then?.,example to toggle it on off..

!a::
WinWaitActive, game id 1
Loop,
{
	PixelGetColor, color, 206, 53, RGB
	if (color != 0x3388CC)
	{
		Sleep, 500
		Send, 2
	}		
	else
	{
		Sleep, 500
		break
	}
}
Return