Jump to content

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

InGame Scripts HowTo


  • Please log in to reply
56 replies to this topic
_3D_
  • Members
  • 79 posts
  • Last active: Mar 14 2014 07:49 PM
  • Joined: 28 Feb 2013

In my DD library I use some global variables. And what mess if some variable i forget to init. What I mean?

DD_PixelGetColor(X, Y, Mask= 0x00FFFFFF) 
{ global DD_PIXELINDIRECTCOLOR
  if DD_PIXELINDIRECTCOLOR
  { chdc:= CreateCompatibleDC(), hbm := CreateDIBSection(1, 1, chdc), obm := SelectObject(chdc, hbm), hhdc:= hhdc ? hhdc : GetDC()
    BitBlt(chdc, 0, 0, 1, 1, hhdc, X, Y, 0x40000000 | 0x00CC0020)

    ;return value ARGB format
    DllCall("GetBitmapBits", UInt, hbm, UInt, VarSetCapacity(bits,4,0), UInt,&bits)
    SetFormat, Integer, H
    RGB:= NumGet(bits,0, 4) & Mask
	
    ReleaseDC(hhdc), SelectObject(chdc, obm), DeleteObject(hbm), DeleteDC(hhdc), DeleteDC(chdc)
  } else PixelGetColor, RGB, X, Y, RGB  
	return RGB
}

Function not init DD_PIXELINDIRECTCOLOR just used it value (that is wrong).

I read some posts about HowTo check if variableExist and found this: http://www.autohotke...ge-3#entry78387 and rearange it a little

varExist(ByRef v) ;small functions lib
{ return !(&v = &_) 
}

I like this reference trick. Function compare pointer of "given" variable v to pointer to an inexistant variable _ (probably it is comparing no NULL pointer).



chaidy
  • Members
  • 57 posts
  • Last active: Oct 21 2015 05:53 PM
  • Joined: 20 Apr 2010
good tip

BeepBoop
  • Members
  • 1 posts
  • Last active: Nov 28 2013 03:21 PM
  • Joined: 28 Nov 2013

I think I understand.

If I have a script and i want to hold down a single key to trigger a combo key. Like

Control::
Send {Contro}{shift}

 When I hold down ctrl keep following the combo. Till i let the ctrl key go?


_3D_
  • Members
  • 79 posts
  • Last active: Mar 14 2014 07:49 PM
  • Joined: 28 Feb 2013

I think I understand.

If I have a script and i want to hold down a single key to trigger a combo key. Like

Control:: Send {Control}{shift}
When I hold down ctrl keep following the combo. Till i let the ctrl key go?

Theoretically yes.

But there must think that keyboard will start autorepeat Control button sending after a while and if not disable (I dont shure if {Control}, {Shift}, {Alt} reproduced autorepeat from keyboard controler).

The best result you will got if check button state at hold down:

; !!! NEXT EXAMPLE IS WRONG !!!
Control::
                               ; here Control is unknown because AHK catch it
  while GetKeyState("Control") ;http://www.autohotkey.com/docs/Functions.htm#GetKeyState 
  { Send {Control}{Shift} 
    Sleep 50                   ;This parameter must be fine tuned depend of given needs. 
  }
return

The code above must reproduce immediately repeating send Control and Shift while the Control is held down but acctualy cant.

Don`t forget that in any case you will lose Control if it set like hotkey. <<< thats a reason.

 

SORRY it is my BIG MISTAKE.

;SOLUTION (this example Send ab if a held down) 
a::
                   ; here a is unknown because AHK catch it for hotkey
  HotKey, a, Off
                   ; here a is known <<< need for GetKeyState
  BlockInput, Send ; <<< disable user input to prevent aabaabaab
  Send ab          ; autorepeat 
  HotKey, a, On    ;enable hotkey again
return
;the example is written by a and b for easy debug

Now what the problem with special key {Control} and other keys

1. When user press and hold a - keyboard controller generate {a down} wait given ms and autorepeat {a down} while user release a.

2. When user press and hold {Control} - keyboard controller wait for non modifier button - and nothing happened.

 

The SOLLUTION {Control}

~Control::              ; transparent Control
  HotKey, Control, Off
  BlockInput, Send
  Send {Control}{Shift}
  HotKey, Control, On
return

Why transparent {Control} needed?

1.When user press and hold {Control} - keyboard wait till user press other non modifier key - and AHK do nothing

2.When user release {Control} - AHK cathed the event and start 

But we need to start working when {Control} is pressed -> we need transparent {Control}

3.BlockInput - prevent user pressed {Control} to be used from other application {Control}{Control}{Shift}

4.HotKey, Control, Off - prevent AHK to catch sended {Control} 

 

I don`t do experiments with {Alt}, {Shift}, {Win} but mechanism must be the same. 


Edited by _3D_, 19 December 2013 - 12:33 PM.


_3D_
  • Members
  • 79 posts
  • Last active: Mar 14 2014 07:49 PM
  • Joined: 28 Feb 2013

 Next example represent trader helper - put 000000{Enter} (6 zeroes = Million)

#0::
#Numpad0::
  while GetKeyState("LWin") ;waiting release Left Win button
    Sleep 1
  DD_BtnSend("000000{Enter}", 60, 20) ;send 000000{Enter} with SetKeyDelay 60, 20
return  

Why waiting till Left Win button release ?

Player must release LWin first then AHK start sending zeroes. If LWin held down and AHK send 0 then hotkey #0:: (Win+0) will be called again in recursive order.

Using of sleep no so usable because different players pressed / released buttons different.

It is opposite to repeat using.



_3D_
  • Members
  • 79 posts
  • Last active: Mar 14 2014 07:49 PM
  • Joined: 28 Feb 2013

CONCLUSIONS from post #49 http://www.autohotke...e-4#entry623745

1.Inside hotkey body hotkey not known

<Button>:: 
  ;HERE <Button> cant be checked easy because AHK catch it for hotkey 
  ;and disabled to any other use 
return

2.If you need to send the same like hotkey you must disable hotkey and disable UserInput

<Button>::
  Hotkey, <Button>, Off         ; <<< (1)enable Button to other use and disable hotkey use
  BlockInput, Send              ; <<< (2)disable user input while send
    Send <Button>               ; <<< send can send <Button> and AHK cant catch it 
  Hotkey, <Button>, On          ; <<< disable Button to other use and enable hotkey use
return

3.This complicated mechanism must be used only if script send the same like hotkey if hotkey is single [button].

4.If <Button> is modifier ({Control},{Shift},{Alt},{Win} ...) must use ~ (transparent <Button>)

 

<Button> must be known to script and in the same time must be disable to other use and to AHK like hotkey.

Repeating came natively.


Edited by _3D_, 19 December 2013 - 12:43 PM.


RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

 

I think I understand.

If I have a script and i want to hold down a single key to trigger a combo key. Like

Control::
Send {Contro}{shift}

 When I hold down ctrl keep following the combo. Till i let the ctrl key go?

 

 

While the control key is physically held down, you want the the program to think that the Control and Shift keys are down? So any subsequent key press is modified by the control and shift keys?

If so, then this should also work.

#SingleInstance force
#InstallKeybdHook
#UseHook On
sendmode, Input


~ctrl::
Send {shift down}
keywait, ctrl
Send {shift up}
;SoundPlay, *-1 ; Can use this to verify its not repeating
Return



_3D_
  • Members
  • 79 posts
  • Last active: Mar 14 2014 07:49 PM
  • Joined: 28 Feb 2013

 

While the control key is physically held down, you want the the program to think that the Control and Shift keys are down? So any subsequent key press is modified by the control and shift keys?

If so, then this should also work.

BeepBoop wrote next:

BeepBoop, on 28 Nov 2013 - 4:50 PM, said:
Control:: Send {Control}{shift}
When I hold down ctrl keep following the combo. Till i let the ctrl key go?

I understand next:

while control button held down 

  Send {Control}

  Send {Shift}

}

It is interesting problem due to Send contain the same like Hotkey. http://www.autohotke...PerInterval.htm and about $ prefix.

$~Control::
while GetKeyState("Control","P")
  Send {Control}{Shift} 
return


_3D_
  • Members
  • 79 posts
  • Last active: Mar 14 2014 07:49 PM
  • Joined: 28 Feb 2013

Answer to CJJames question or just another rapid fire.

It is simple script based over my timedFunction http://www.autohotke...me/#entry613256 without any real functionality but represent quiet mechanism running "rapide fire".

#Persistent
#SingleInstance force
SetBatchLines, 10ms
;Copyright (c) D.Donchev

DD_Throttle()         ;timedFunction
{ static throttle
  static counter:=0   ;just for debug
  if !(throttle:=!throttle)
  {      SetTimer, LABEL_DD_Throtthle, Off
    counter:= 0       ;just for debug
    ToolTip           ;just for debug
    return
  } else SetTimer, LABEL_DD_Throtthle, 0
LABEL_DD_Throtthle:
  ToolTip,% counter++ ;just for debug
  ;Send               ;rapid sending
RETURN
}

x::DD_Throttle()      ;hotkey trigger 
#!q::ExitApp    

There no any Sending just little tooltip conter near mouse pointer.



_3D_
  • Members
  • 79 posts
  • Last active: Mar 14 2014 07:49 PM
  • Joined: 28 Feb 2013

This days I made some total optimizations of all my scripts and got next problem:

There many processes that keep on allot of time and me need to break current process while script still active.

In most parts of game scripts we use nest model:

 

action

sleep

action

sleep

action

 

now actions is quietly fast and script in most time stay over sleep. I go research about conditional execution but actually script languages haven`t debug mode :(((

 

breakable Sleep model:

;BREAKABLE MODEL
runContunue:= 1

!Space::runContinue:=!runContinue

Sleep(tm=0)
{ global 
  if tm
    Sleep tm
  return runContinue  
}

HowTo use this model?

1.IF

if !Sleep(2000)
return
;this part break current execution if runContinue going 0 by the way and return to caller

2.WHILE

while Sleep(200)
{ ;action
  if !Sleep(200) ;from IF ussage
  return
  ;action
  if !Sleep(200) ;from IF ussage
  return
  ;action
}

This way we got breakable by external condition algorithm. 



_3D_
  • Members
  • 79 posts
  • Last active: Mar 14 2014 07:49 PM
  • Joined: 28 Feb 2013

Next post is inspired from MirageGuardian post.

I think if I have enough time it will be good tutorial for programing and understanding why this way and not that way, but let try with only one post.

The beginning [original code]

Labelbattle:
Sleep, 7000
Color1 = 
PixelGetColor, Color1, 1334, 617
IfEqual, Color1, 0x0003f1
{
goto, labelbattle
}
else
goto, labelfinish

YES it work. YES it correct.

Let to optimize a little given code and explain why.

Labelbattle:
Sleep, 7000
Color1 =   ;very good line it is basic principle: FIRST INIT THEN USE
           ;unfortunately here not needed
PixelGetColor, Color1, 1334, 617 ;Color1 will be created here if not exist and will get value
IfEqual, Color1, 0x0003f1 
{ ;if only 1 command in ifTrue part not needed
goto, labelbattle
}
else
goto, labelfinish

the result:

Labelbattle:
Sleep, 7000
PixelGetColor, Color1, 1334, 617
IfEqual, Color1, 0x0003f1 
     goto, labelbattle 
else goto, labelfinish

still the same code but just shorter.

Now let see what is the idea of this code:

wait 7000 ms (7 sec)

get color at given position 

if color match go wait arain

else go other way

Labelbattle:
loop 
{ Sleep, 7000
  PixelGetColor, Color1, 1334, 617
  IfNotEqual, Color1, 0x0003f1 
    break ;break the loop
} 
;runing go here after break 
goto, labelfinish
return ;not needed but for any case

hm, we wait while color is 0x0003F1 let modify the code

Labelbattle:
while PixelGetColor(1334, 617) = 0x0003F1 ;while color is 0x0003F1
  Sleep 7000                              ;sleep 7 sec 
goto labelfinish                          ;else go labelfinish
return

;let get color be function
PexelGetColor(x, y) ;lol the name is possible
{ PixelGetColor, c, %x%, %y% ;dont forget %
  return c ;function return the color at x:y position
}

Trust me it is the same code like in the beginning - the same principle - the same work.

What the code do when it run:

1.check pixel color for about       1 ms

2.sleep                                  7000 ms

3.in all the time we cant use script for other purpose - script just sleep

AHK have internal mechanism to start some things at some time intervals: SetTimer, LABEL, interval

SetTimer, Labelbattle, 7000 ;this line init internal timer and going to next line
;here we must do other things with the same script while AHK will start Labelbattle any 7000 ms :P
return

Labelbattle:
  if PixelGetColor(1334, 617) != 0x0003F1 ;if color is not 0x0003F1
  { SetTimer, Labelbattle, Off            ;switch OFF timer
    goto labelfinish                      ;go labelfinish
  }  
return

PexelGetColor(x, y)
{ PixelGetColor, c, %x%, %y% ;dont forget %
  return c
}

Now:

1.AHK get control to start Labelbattle any 7 sec - it mean no sleep and scrip is free to do other things

2.we have function PixelGetColor that is better in use

 

code is the same only in logic but in run it is different (this way script use less CPU time and may do other things)

SetTimer, Labelbattle, 7000 
SetTimer, Labelfun   , 3000
return

Labelbattle:
  if PixelGetColor(1334, 617) != 0x0003F1 ;if color is not 0x0003F1
  { SetTimer, Labelbattle, Off            ;switch OFF timer
    goto labelfinish                      ;go labelfinish
  }  
return
Labelfun: ;next lines doit nothing :P
  if PixelGetColor(someX, someY) = someColor
       ToolTip, FUN IS ON
  else ToolTip
return    ;end of Labelfun

PexelGetColor(x, y)
{ PixelGetColor, c, %x%, %y% ;dont forget %
  return c
}

the code check color at 1334:617 and if not equal 0x0003F1 go labelfinish any 7 sec

and in the same time

check color at someX:someY and if equal someColor void text FUN IS ON near mouse pointer else clear that text any 3 sec.

LOL what will happen if Labelfun is runed and going time to Labelbattle or vice versa? It is for homemade.

THINK and ENJOY.



_3D_
  • Members
  • 79 posts
  • Last active: Mar 14 2014 07:49 PM
  • Joined: 28 Feb 2013

InGame continue here: http://www.ahkscript...php?f=19&t=2400

Why?

Answer here: http://www.autohotke...he-forum-theme/