Last active
August 1, 2018 21:35
-
-
Save Acen/11025fd29cfdce8ece1dbeb25310be74 to your computer and use it in GitHub Desktop.
Loopy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from os import getcwd | |
from sys import path | |
from typing import Union | |
from threading import Timer | |
################################ | |
###### CHANGEABLE OPTIONS ###### | |
################################ | |
# None yet fam. | |
################################ | |
#### END CHANGEABLE OPTIONS #### | |
################################ | |
# The amount of time before executing the loop. | |
SLEEP_TIMER = 3 # type: int | |
# The number of pixels the bounds is limited within, when only providing x/y (exact flag on class) | |
KINDNESS_PIXELS = 50 # type: int | |
# The initial state for the jump stage. ¯\(º_o)/¯ | |
JUMP_STATE_INIT = 0 # type: int | |
JUMP_STATE_LABEL = 'jump_state' # type: str | |
LOOPER_STATE_INIT = False # type: bool | |
LOOPER_STATE_RUNNING = True # type: bool | |
LOOPER_STATE_LABEL = 'looper_state' # type: str | |
BOUNDARY_X = 'x' # type: str | |
BOUNDARY_Y = 'y' # type: str | |
BOUNDARY_TOP = 'top' # type: str | |
BOUNDARY_BOTTOM = 'bottom' # type: str | |
BOUNDARY_LEFT = 'left' # type: str | |
BOUNDARY_RIGHT = 'right' # type: str | |
# Breakable imports below. | |
# ლ(ಠ益ಠლ) | |
if not any("SunCat" in s for s in path): | |
path.append(getcwd() + "\SunCat") | |
try: | |
import SunCat | |
import SCHotkey | |
import SCLib | |
except ImportError: | |
print("Couldn't find SunCat module") | |
try: | |
import Character | |
import GameState | |
import Terminal | |
except ImportError: | |
print("Terminal internal libraries not found.") | |
class Bounds: | |
def __init__(self, boundaries: dict, exact: bool = False): | |
if exact: | |
self.kindness_pixels = 0 | |
else: | |
self.kindness_pixels = KINDNESS_PIXELS | |
try: | |
self.top = boundaries[BOUNDARY_X] + self.kindness_pixels | |
self.bottom = boundaries[BOUNDARY_X] - self.kindness_pixels | |
self.left = boundaries[BOUNDARY_Y] - self.kindness_pixels | |
self.right = boundaries[BOUNDARY_Y] + self.kindness_pixels | |
except KeyError: # x/y does not exist. | |
try: | |
self.top = boundaries[BOUNDARY_TOP] | |
self.bottom = boundaries[BOUNDARY_BOTTOM] | |
self.left = boundaries[BOUNDARY_LEFT] | |
self.right = boundaries[BOUNDARY_RIGHT] | |
except KeyError: # One of the above, does not exist | |
raise IndexError('Invalid keys for boundaries. Please use either x/y or top/bottom/left/right.') | |
class CharacterPosition: | |
def __init__(self, x: int, y: int): | |
self.x = x | |
self.y = y | |
self.bounds = None | |
# within_bounds dictates whether the character's current position is within or on specified constraints. | |
# There are two ways to use within_bounds, either with a basic x/y to check if they are ±50px around that area, | |
# or with top/bottom/left/right to check they are inside of the square outlined. | |
# Examples: | |
# bounds = {'x': 500, 'y': 1000} | |
# CharacterPosition(525,960).within_bounds(bounds) -> True | |
# CharacterPosition(266,777).within_bounds(bounds) -> False | |
# CharacterPosition(500,1000).within_bounds(bounds, True) -> True | |
# CharacterPosition(501,999).within_bounds(bounds, True) -> False | |
# | |
# bounds = {'top': 300, 'bottom': 450, 'left': -150, 'right': -222} | |
# CharacterPosition(322,-210).within_bounds(bounds) -> True | |
# CharacterPosition(266,777).within_bounds(bounds) -> False | |
def within_bounds(self, bounds: Union[dict, Bounds], exact: bool = False) -> bool: | |
if isinstance(bounds, dict): | |
self.bounds = Bounds(bounds, exact) | |
else: | |
self.bounds = bounds | |
if self.x > self.bounds.top: | |
return False | |
elif self.x < self.bounds.bottom: | |
return False | |
elif self.y < self.bounds.left: | |
return False | |
elif self.y > self.bounds.right: | |
return False | |
else: | |
return True | |
class Looper: | |
def __init__(self, interval: int, callable, *args, **kwargs): | |
self._timer = None # type: Timer | |
self.state = SCLib.GetVar(LOOPER_STATE_LABEL) # type: bool | |
self.interval = interval # type: int | |
self.function = callable # callable method | |
self.args = args | |
self.kwargs = kwargs | |
def _run(self): | |
SCLib.UpdateVar(LOOPER_STATE_LABEL, LOOPER_STATE_INIT) | |
self.state = LOOPER_STATE_INIT | |
self.function(*self.args, **self.kwargs) | |
def start(self): | |
if not self.state: | |
self._timer = Timer(self.interval, self._run) | |
SCLib.UpdateVar(LOOPER_STATE_LABEL, LOOPER_STATE_RUNNING) | |
self.state = LOOPER_STATE_RUNNING | |
def stop(self): | |
self._timer.cancel() | |
self._timer = None | |
SCLib.UpdateVar(LOOPER_STATE_LABEL, LOOPER_STATE_INIT) | |
self.state = LOOPER_STATE_INIT | |
def build_vars() -> None: | |
SCLib.StopVars() | |
SCLib.PersistVar(JUMP_STATE_LABEL, JUMP_STATE_INIT) | |
SCLib.PersistVar(LOOPER_STATE_LABEL, LOOPER_STATE_INIT) | |
SCLib.StartVars() | |
def close_all(looper: Looper) -> None: | |
looper.stop() | |
SCLib.StopVars() | |
def execute() -> None: | |
build_vars() | |
looper = Looper(SLEEP_TIMER) | |
try: | |
looper.start() | |
finally: | |
close_all(looper) | |
if SCLib.CheckVersion(19): | |
execute() | |
else: | |
print("SunCat library is out of date fam. You'll likely need to restart Terminal completely.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment