Barotrauma Guide

MouseControl AutoHotKey PoC for Barotrauma

MouseControl AutoHotKey PoC

Overview

Small Autohotkey script to check if mouse control can work with this game.How to play arround with it:- get authotkey- copy all 3 parts of the script into one file named “BT_MouseControl.ahk” – run the game- disable “mouse view” in the options- optional: change resolution to 1920×1080- double click the script (BT_MouseControl.ahk)- go back into the game- hold left mouse button to keep running- click right somewhere to run there

// Part1

//

#CommentFlag // // Script initialization #EscapeChar SetTitleMatchMode, 2 #EscapeChar #Singleinstance, Force #NoEnv SetBatchLines, -1 CoordMode, Pixel, Client CoordMode, Mouse, Client CoordMode, ToolTip, Client // “Mouse View” must be DISABLED in the options! // settings KeyLeft := “a” KeyRight := “d” KeyUp := “w” KeyDown := “s” KeyRun := “Shift” KeySelect := “LButton” EnableRightClickMovement := true // run to position on click // crew icon background colors used for game screen detection, also see UpdateWindowStats() for position factors CrewIconBgRedMin := 105 CrewIconBgRedMax := 112 CrewIconBgGreenMin := 102 CrewIconBgGreenMax := 108 CrewIconBgBlueMin := 90 CrewIconBgBlueMax := 96 // actual script start #IfWinActive Barotrauma // make sure no other window has “Barotrauma” in its title! WinGet, BT_HWND, ID, Barotrauma // non-settings Locked := false LastWindowSize := 0 DoorLastOpenedTicks := 0 LastWindowStatUpdateTicks := 0 CrewIconFound := false HatchLastOpenedTicks := 0 UpdateWindowStats() LButton:: { // leave some time for regular mouse click processing Send {LButton down} Loop, 15 { if (GetKeyState(“LButton”,”P”)) { Sleep 10 } else { Send {LButton up} break } } if (!GetKeyState(“LButton”,”P”)) { return } if (Abs(A_TickCount – LastWindowStatUpdateTicks) > 5000) { UpdateWindowStats() } if GameReady() { Move() } else { Info(“Game not ready”) while GetKeyState(“LButton”,”P”) { Sleep 20 } Send {LButton up} } return } ~RButton:: { if (!EnableRightClickMovement || !GameReady()) { return } entryTicks := A_TickCount while (!Locked && GetKeyState(“RButton”,”P”)) { Sleep 20 } if (!Locked && A_TickCount – entryTicks <= 200 ) { MouseGetPos, mpx, mpy SpeedFactor := 1.8 ticksToMove := Abs(CenterX – mpx) * SpeedFactor Info(“AutoRunning!”) Move(ticksToMove) } return } ~XButton2:: { UpdateWindowStats() MouseGetPos,mpx, mpy GetPixelRGB(mpx, mpy, red, green, blue) // Info(“h: ” GameWindowHeight “w: ” GameWindowWidth “CrewIconX: ” CrewIconX “CrewIconY: ” CrewIconY “x: ” mpx “y: ” mpy “r: ” red “g: ” green “b: ” blue “tmp: ” tmp // GetPixelRGB(CrewIconX, CrewIconY, red, green, blue) // 111,108,96 tmp := GameReady() // Info(“x: ” mpx “y: ” mpy “r: ” red “g: ” green “b: ” blue “tmp: ” tmp) Info(“x: ” mpx ” y: ” mpy ” r: ” red “g: ” green ” b:” blue ” CenterX: ” CenterX ” CenterY: ” . CenterY ” FloorY: ” FloorY ” GWinWidth: ” GameWindowWidth ” GWinHeight: ” GameWindowHeight ” HWND: ” BT_HWND) // OpenHatchIfNecessary() return } Info(msg) { global TipX, TipY ToolTip, %msg%, TipX, TipY } ~Space:: { if (!Locked && GameReady()) { Locked := true if (DoorDetected()) { OpenDoor() } Locked := false } return } DoorDetected() { global CenterX, CenterY, FloorY, DoorDetectionDeltaX, DoorDetectionDeltaY, DoorLastOpenedTicks result := false if (Abs(A_TickCount – DoorLastOpenedTicks) < 500) { return result } MouseGetPos, mpx, mpy if (mpx < CenterX) { x1 := CenterX – DoorDetectionDeltaX x2 := CenterX – Round(DoorDetectionDeltaX * 1.5) } else { x1 := CenterX + DoorDetectionDeltaX x2 := CenterX + Round(DoorDetectionDeltaX * 1.5) } y1 := Round(CenterY + DoorDetectionDeltaY) y2 := Round(CenterY + DoorDetectionDeltaY * 1.5) GetPixelRGB(x1, y1, r1, g1, b1) GetPixelRGB(x2, y2, r2, g2, b2) d := 3 gm := 4 rgb1 := r1 + g1 + b1 rgb2 := r2 + g2 + b2 if (r1 < d && g1 < d && b1 < d && r2 < d && g2 < d && b2 < d && rgb1 <= gm && rgb2 <= gm) { result := true } // xy1 680:553 xy2 658:563 if result { Info(“Door detected! x1: ” x1 ” y1: ” y1 ” r1: ” r1 ” g1: ” g1 ” b1: ” b1 ” x2: ” x2 ” y2: ” y2 ” r2: ” r2 ” g2: ” g2 ” b2: ” b2 ” cy: ” CenterY) } else { // Info(“No Door found! x1: ” x1 ” y1: ” y1 ” r1: ” r1 ” g1: ” g1 ” b1: ” b1 ” x2: ” x2 ” y2: ” y2 ” r2: ” r2 ” g2: ” g2 ” b2: ” b2 ” cy: ” CenterY) } return result } OpenDoor() { global KeySelect, CenterX, CenterY, DoorSwitchDelta, DoorLastOpenedTicks, FloorY MouseGetPos,mx, my // Suspend, ON // ChangeMovement() if (mx < CenterX) { switchX := CenterX – DoorSwitchDelta } else { switchX := CenterX + DoorSwitchDelta } // Info(“switchX: ” switchX “y: ” CenterY) // don’t activate anything other than doors, so click slightly above the floor switchY := FloorY – Round((FloorY – CenterY) / 4) Click, %switchX%, %switchY%, 0 Sleep 80 lbWasPressed := GetKeyState(“LButton”,”P”) if lbWasPressed { Send {LButton up} Sleep 80 Send {LButton down} } // so don’t send activation twice if (KeySelect != “LButton” || !lbWasPressed) { Send {%KeySelect% down} Sleep 50 Send {%KeySelect% up} } Click, %mx%, %my%, 0 if lbWasPressed { // Sleep 200 // wait until door is open Send {LButton Down} } DoorLastOpenedTicks := A_TickCount } WalkingPossible() { global BlockMovementDist, CeilingY, CenterX, FloorY MouseGetPos, mx, my return (Abs(CenterX – mx) > BlockMovementDist) // && my < FloorY && my > CeilingY } ClimbingPossible() { global BlockMovementDist, CeilingY, CenterX, FloorY MouseGetPos, mx, my return (Abs(CenterX – mx) < BlockMovementDist) && (my > FloorY || my < CeilingY) }

// Part2

OpenHatchIfNecessary() { global AboveCeilingY, BelowFloorY, BlockMovementDist, CeilingY, CenterX, CenterY, FloorY, HatchLastOpenedTicks, KeySelect if Abs(A_TickCount – HatchLastOpenedTicks) < 800 { return } MouseGetPos, mx, my if (Abs(CenterX – mx) > BlockMovementDist) { return } if (my > FloorY) { darknessY := BelowFloorY hatchY := FloorY } else if (my < CeilingY) { darknessY := CeilingY // closer to ceiling when on ladder hatchY := CenterY + Round((CeilingY – CenterY) / 2) } else { return } darknessThreshold := 5 GetPixelRGB(CenterX, darknessY, red, green, blue) if (red > darknessThreshold || green > darknessThreshold || blue > darknessThreshold) { return } lbWasPressed := GetKeyState(“LButton”) if lbWasPressed { Send {LButton up} Sleep 50 } Info(“hatchY: ” hatchY) Click, %CenterX%, %hatchY%, 0 Sleep 50 Send {%KeySelect% down} Sleep 50 Send {%KeySelect% up} Sleep 500 // wait until hatch is open // check again, char maybe stuck right above hatch, therefor the ground level is higher if (my > FloorY) { GetPixelRGB(CenterX, BelowFloorY, red, green, blue) if (red <= darknessThreshold && green <= darknessThreshold && blue <= darknessThreshold) { adaptedFloorY := CenterY + Round((FloorY – CenterY) / 2) Info(“mpy:” my “CenterY:” CenterY “adaptedFloorY y:” adaptedFloorY ” r:” red “g:” green “b= ” blue) Click, %CenterX%, %adaptedFloorY%, 0 Sleep 50 Send {%KeySelect% down} Sleep 50 Send {%KeySelect% up} Sleep 500 // wait until hatch is open // Info( Trying again x: %CenterX% (%mx%) y: %correctedAboveFloorY% (%my%) r: %red% g: %green% b=%blue% } } Click, %mx%, %my%, 0 if lbWasPressed { Send {LButton Down} } HatchLastOpenedTicks := A_TickCount // Info( Hatch opened // Info( Hatch Opened! x: %CenterX% (%mx%) y: %FloorY% (%my%) r: %red% g: %green% b=%blue% } SetMovement(keyToPress, keyToRelease1, keyToRelease2, keyToRelease3, keytoRelease4 := “”) { if GetKeyState(keyToRelease1) { Send {%keyToRelease1% up} } if GetKeyState(keyToRelease2) { Send {%keyToRelease2% up} } if GetKeyState(keyToRelease3) { Send {%keyToRelease3% up} } if (keyToRelease4 != “” GetKeyState(keyToRelease4)) { Send {%keyToRelease4% up} } if (keyToPress != “” && !GetKeyState(keyToPress)) { Send {%keyToPress% down} } } ChangeMovement(direction := “”) { global KeyLeft, KeyRight, KeyUp, KeyDown if (direction = “left”) { SetMovement(KeyLeft, KeyRight, KeyUp, KeyDown) } else if (direction = “right”) { SetMovement(KeyRight, KeyLeft, KeyUp, KeyDown) } else if (direction = “up”) { SetMovement(KeyUp, KeyLeft, KeyRight, KeyDown) } else if (direction = “down”) { SetMovement(KeyDown, KeyLeft, KeyRight, KeyUp) } else { SetMovement(“”, KeyLeft, KeyRight, KeyUp, KeyDown) } } Move(ticks := 0) { global BlockMovementDist, CeilingY, CenterX, CursorResetDist, LastWindowStatUpdateTicks, FloorY, Locked, RunningDist, SpeedFactor global KeyLeft, KeyRight, KeyUp, KeyDown, KeyRun if Locked { Info(“Locked!”) return } Locked := true destTickCount := A_TickCount + ticks lastTickCount := A_TickCount wasClimbing := false autoRunning := ticks > 0 While (GameReady() && (GetKeyState(“LButton”,”P”) && ticks = 0 || A_TickCount <= destTickCount) && !GetKeyState(“RButton”,”P”) && !GetKeyState(“XButton1″,”P”)) { direction := “” MouseGetPos, mx, my if (WalkingPossible()) { running := autoRunning || (mx < CenterX – RunningDist || mx > CenterX + RunningDist) if (running) { if !GetKeyState(KeyRun) { Send {%KeyRun% down} } } else if GetKeyState(KeyRun) { Send {%KeyRun% up} } // move left // if (mx < CenterX && my < FloorY) { if (mx < CenterX ) { direction := “left” } // move right // else if (mx > CenterX && my < FloorY) { else if (mx > CenterX) { direction := “right” } } else if (ClimbingPossible()) { // move down if (my > FloorY) { direction := “down” } // move up else if (my < CeilingY) { direction := “up” } else { ksup := GetKeyState(KeyUp) ksdown := GetKeyState(KeyDown) Info(“climb failed! my:” my “CeilingY:” CeilingY “up-key:” ksup “down-key:” ksdown) } } // Info(“mpx: ” mx “mpy: ” my “direction: ” direction “rm: ” running) if (direction = “left” || direction = “right”) { ChangeMovement(direction) Loop, 5 { if (DoorDetected()) { OpenDoor() } Sleep 20 } } else if (direction = “up” || direction = “down”) { OpenHatchIfNecessary() ChangeMovement(direction) wasClimbing := true Sleep 100 } else { Sleep 100 Info(“Doing nothing! direction: ” direction) } // move cursor closer while running enableContinousCursorAdaption := false if (autoRunning && enableContinousCursorAdaption) { dx := Round((A_TickCount – lastTickCount) * SpeedFactor) if (mx < CenterX) Click, mx – dx, %my%, 0 else { Click, mx + dx, %my%, 0 } lastTickCount := A_TickCount } } ChangeMovement() // end running if needed, set cursor right in front of char if GetKeyState(KeyRun) { // Info(“Was running!”) Send {%KeyRun% up} if (my > CeilingY && my < FloorY && !wasClimbing) { ResetCursor() } } Locked := false return } ResetCursor() { global CenterX, CursorResetDist MouseGetPos, mx, my if (mx < CenterX ) { cursorResetX := CenterX – CursorResetDist } else { cursorResetX := CenterX + CursorResetDist } Click, %cursorResetX%, %my%, 0 } WinGetClientPos( Hwnd, ByRef x, ByRef y, ByRef w, ByRef h ) { VarSetCapacity( size, 16, 0 ) DllCall( “GetClientRect”, UInt, Hwnd, Ptr, &size ) DllCall( “ClientToScreen”, UInt, Hwnd, Ptr, &size ) x := NumGet(size, 0, “Int”) y := NumGet(size, 4, “Int”) w := NumGet( size, 8, “Int” ) h := NumGet( size, 12, “Int” ) return { X: x, Y: y, W: w, H: h } }

// Part3

UpdateWindowStats() { global // treat all variables as global WinGetClientPos(BT_HWND, GameWindowTopLeftX, GameWindowTopLeftY, GameWindowWidth, GameWindowHeight) WindowSize := GameWindowWidth * GameWindowHeight WindowSizeChanged := WindowSize != LastWindowSize if (WindowSizeChanged) { CrewIconFound := false MouseGetPos,mpx, mpy Info(“mpx: ” mpx ” mpy: ” mpy “Window Size changed: ” LastWindowSize ” to ” WindowSize ” w: ” LastGameWindowWidth “to ” GameWindowWidth ” h: ” LastGameWindowHeight ” to ” GameWindowHeight) } LastWindowSize := WindowSize LastGameWindowWidth := GameWindowWidth LastGameWindowHeight := GameWindowHeight RunningDist := Round(GameWindowWidth * 0.11) // 280 BlockMovementDist := Round(GameWindowWidth * 0.031) // 80 CursorResetDist := Round(GameWindowWidth * 0.023) // BlockMovementDist – 20 CenterX := Round(GameWindowWidth / 2) // 1286 CenterY := Round(GameWindowHeight / 2) // 558 FloorY := Round(GameWindowHeight * 0.64) // 693 CeilingY := Round(GameWindowHeight * 0.41) AboveCeilingY := Round(GameWindowHeight * 0.35) BelowFloorY := Round(GameWindowHeight * 0.67) DoorSwitchDelta := Round(GameWindowWidth * 0.016) DoorDetectionDeltaX := Round(GameWindowWidth * 0.032) DoorDetectionDeltaY := Round(GameWindowHeight * 0.055) TipX := Round(GameWindowWidth * 0.01) TipY := Round(GameWindowHeight * 0.71) // Crew Icon XY, middle of the right free area, as exact as possible CrewIconX := Round(GameWindowWidth * 0.037) CrewIconY := Round(GameWindowHeight * 0.069) CrewIconXOutSide := Round(GameWindowWidth * 0.05) if (!CrewIconFound && CrewIconActive()) { CrewIconFound := true Info(“Crew Icon found!”) } LastWindowStatUpdateTicks := A_TickCount return } CrewIconActive() { global CrewIconX, CrewIconY, CrewIconBgRedMin, CrewIconBgRedMax, CrewIconBgBlueMin, CrewIconBgBlueMax, CrewIconBgGreenMin, CrewIconBgGreenMax result := true dx := 0 loop, 2 { dy := 0 loop, 2 { x := CrewIconX + dx y := CrewIconY + dy GetPixelRGB(x, y, r, g, b) if ( r < CrewIconBgRedMin || r > CrewIconBgRedMax || g < CrewIconBgGreenMin || g > CrewIconBgGreenMax || b < CrewIconBgBlueMin || b > CrewIconBgBlueMax) { result := false // Info(“Crew icon not found! x:” x “y:” y “r:” r “g:” g “b:” b “(t:” A_TickCount ” ) Info(“Crew icon not found! x:” x “y:” y “r:” r “( ” CrewIconBgRedMin “-” CrewIconBgRedMax ” ) g:” g “( ” CrewIconBgGreenMin “-” CrewIconBgGreenMax ” ) b:” b “( ” CrewIconBgBlueMin “-” CrewIconBgBlueMax) break } dy++ if (!result) { break } } dx++ } return result } GameReady() { global CrewIconFound return (CrewIconFound && CrewIconActive()) } GetPixelRGB(x,y, ByRef red, ByRef green, ByRef blue) { PixelGetColor color, x, y , RGB GetRGB(color, red, green, blue) } GetRGB(color, byRef red, byRef green, byRef blue) { red := color >> 16 green := (color >> 8) & 0x0000FF blue := color & 0x0000FF }
SteamSolo.com