Skip to content
This repository has been archived by the owner on Apr 19, 2023. It is now read-only.

Commit

Permalink
Fix widescreen
Browse files Browse the repository at this point in the history
  • Loading branch information
NG0N committed Dec 5, 2022
1 parent cfa409c commit 64712d3
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 25 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ Note: The buying timings are designed for a brand new Bloodweb level, meaning th
### Currently supported resolutions
|16:9 |16:10 |
| ----------| ----------|
|3840 × 2160|2560 × 1600|
|2560 × 1440|1680 × 1050
|1920 × 1080
|1366 × 768
|3840 × 2160|3840 × 2400|
|2560 × 1440|2560 × 1600|
|1920 × 1080|1680 × 1050|
|1366 × 768|1600 × 1024|
|1360 × 768

## Options
Expand Down
3 changes: 2 additions & 1 deletion data/resolutions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
1680x1050: 593,564
1366x768: 481,414
1360x768: 480,414.5
1600x1024: 564.5, 547.5
1600x1024: 564.5, 547.5
3440x1440: 903.5, 777.5
14 changes: 7 additions & 7 deletions src/autobuy/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,21 +129,21 @@ def main():
metavar='For unsupported resolutions: Midpoint X',
default=0,
help='X coordinate of the Bloodweb midpoint',
widget='IntegerField',
widget='DecimalField',
gooey_options = {
'min' : 0,
'max' : 12800,
'increment' : 1})
'increment' : 0.5})

advanced_group.add_argument('--unsupported_resolution_mid_y',
metavar='For unsupported resolutions: Midpoint Y',
default=0,
help='Y coordinate of the Bloodweb midpoint',
widget='IntegerField',
widget='DecimalField',
gooey_options = {
'min' : 0,
'max' : 12800,
'increment' : 1})
'increment' : 0.5})

advanced_group.add_argument('-v', '--verbose',
metavar='Verbose output',
Expand All @@ -166,7 +166,7 @@ def main():
analyzer = WebAnalyzer()
analyzer.set_bring_to_front(not bool(args.activate_window))
analyzer.set_override_monitor_index(int(args.monitor_index))
analyzer.set_custom_midpoint(int(args.unsupported_resolution_mid_x), int(args.unsupported_resolution_mid_y))
analyzer.set_custom_midpoint(float(args.unsupported_resolution_mid_x), float(args.unsupported_resolution_mid_y))
try:
analyzer.initialize()
except (WebAnalyzer.GameResolutionError, WebAnalyzer.WindowNotFoundError):
Expand Down Expand Up @@ -197,8 +197,8 @@ def main():
autobuy.web_analyzer.set_node_tolerance(int(args.node_color_threshold))
autobuy.web_analyzer.set_color_available(tuple(bytes.fromhex(args.ring_color[1:])))

custom_x = int(args.unsupported_resolution_mid_x)
custom_y = int(args.unsupported_resolution_mid_y)
custom_x = float(args.unsupported_resolution_mid_x)
custom_y = float(args.unsupported_resolution_mid_y)
if custom_x != 0 and custom_y != 0:
autobuy.web_analyzer.set_custom_midpoint(custom_x, custom_y)

Expand Down
31 changes: 20 additions & 11 deletions src/autobuy/web_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def __init__(self, handle, position, size) -> None:
# Reference resolution is used in sample point coordinates
# The points are scaled from this resolution to whatever the game window size is
REF_RESOLUTION = (2560,1440)
REF_ASPECT_CUTOFF = 16/9

### These values are only valid for 2560x1440 and are scaled during runtime
# Width of the square of pixels that is used to determine the node rarity
Expand Down Expand Up @@ -161,8 +162,8 @@ def set_node_tolerance(self, node_tolerance: int) -> None:
def set_override_monitor_index(self, index: int) -> None:
self._override_monitor_index = index

def set_custom_midpoint(self, x: int, y: int):
self._custom_midpoint = np.array([x,y],int)
def set_custom_midpoint(self, x: float, y: float):
self._custom_midpoint = np.array([x,y], float)

def set_bring_to_front(self, bring_to_front : bool):
self._bring_to_front = bring_to_front
Expand Down Expand Up @@ -207,6 +208,7 @@ def _get_positions_approx_color(self, image, positions, color, tolerance, sampli
diffs = rim_imgs - color
dists = np.linalg.norm(diffs, axis=(2))
min_dists = np.min(np.abs(dists),axis=1)

return (min_dists < tolerance).nonzero()[0]

# Takes a screen capture, samples the node positions, sorts by rarity, most common first
Expand All @@ -227,7 +229,6 @@ def find_buyable_nodes(self) -> np.ndarray:
edge_positions = self._web_points - bbox[0]
# Get indices of the positions that are close to the color of a buyable node
buyable = self._get_positions_approx_color(image, edge_positions, self._color_node_available, self._color_tolerance, 2)

# Extract node images
node_positions = self._web_nodes[buyable] - bbox[0]

Expand Down Expand Up @@ -266,7 +267,6 @@ def find_buyable_nodes(self) -> np.ndarray:
hue[hue < 0] += 360

rarities = np.array([self._find_closest_rarity(a) for a in hue],int)

# Sort by rarity and return
if len(buyable) > 0:
p = rarities.argsort()
Expand All @@ -289,6 +289,8 @@ def find_buyable_nodes(self) -> np.ndarray:
if np.max(dists, axis=0) < self._color_tolerance + max(self._color_tolerance * 1.5, 20):
return PRESTIGE_ONLY

return []

# Find minimum angle difference in hue
def _find_closest_rarity(self, hue):
return np.argmin([180 - abs(abs(hue - b) - 180) for b in RARITIES_HUE])
Expand Down Expand Up @@ -369,7 +371,7 @@ def debug_draw_points(self, groups_to_show: list) -> Image.Image:

if groups_to_show.count("edges") > 0:
buyable = self.find_buyable_nodes()
print(buyable)

draw = ImageDraw.Draw(im, "RGBA")
for pt_group in groups_to_show:
pts = pts_groups[pt_group]
Expand Down Expand Up @@ -433,15 +435,22 @@ def _import_points(self, filename: str, resolution: tuple[int,int] = None) -> np
self._center_pos = self._custom_midpoint
print(f"Using custom midpoint {self._custom_midpoint}", flush=True)
else:
self._center_pos = center_points[resolution]
self._center_pos = center_points[resolution]

aspect = resolution[0] / resolution[1]
# Remove web position from the points so they are centered around [0,0]
local_pts = (self._sample_points - ref_center).astype(float)
# Scale according to game window width
self._scaling = resolution[0] / REF_RESOLUTION[0]
if aspect > REF_ASPECT_CUTOFF:
# Scale according to game window height
self._scaling = resolution[1] / REF_RESOLUTION[1]
else:
# Scale according to game window width
self._scaling = resolution[0] / REF_RESOLUTION[0]

local_pts *= self._scaling
# Add the web offset back
self._sample_points = np.round(local_pts + self._center_pos).astype(int)

# Precalculate scaling dependent values
self._rarity_sample_width = int(RARITY_CROP_SIZE * self._scaling)
# Create array views for iterating
Expand Down Expand Up @@ -515,8 +524,8 @@ def save_debug_images(self):
x = self._custom_midpoint[0]
y = self._custom_midpoint[1]

edges_filename = f"BAB_{x}_{y}_edges.png"
nodes_filename = f"BAB_{x}_{y}_nodes.png"
edges_filename = f"BAB_{'{:.1f}'.format(x)}_{'{:.1f}'.format(y)}_edges.png"
nodes_filename = f"BAB_{'{:.1f}'.format(x)}_{'{:.1f}'.format(y)}_nodes.png"

desktop = Path.home() / "Desktop"
edges_image_path = desktop / edges_filename
Expand Down
3 changes: 1 addition & 2 deletions src/autobuy/web_autobuy.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,7 @@ def _try_buy(self):
# Move mouse out of the way
self._reset()
nodes = self.web_analyzer.find_buyable_nodes()
if nodes is None:

if len(nodes) == 0:
self._level_bought_nodes = 0
# Prevent repeating
if self._verbose and not self._found_none_prev:
Expand Down

0 comments on commit 64712d3

Please sign in to comment.