Add require/exclude properties to pickit.ini when stashing items. Also more item templates. (#295)

This commit is contained in:
mgleed
2021-12-21 20:46:27 +01:00
committed by GitHub
parent 44d9cb40f2
commit b5805a19aa
370 changed files with 818 additions and 382 deletions
+2 -2
View File
@@ -54,7 +54,7 @@ class Bot:
elif self._config.char["type"] == "trapsin":
self._char: IChar = Trapsin(self._config.trapsin, self._config.char, self._screen, self._template_finder, self._ui_manager, self._pather)
elif self._config.char["type"] == "barbarian":
self._char: IChar = Barbarian(self._config.barbarian, self._config.char, self._screen, self._template_finder, self._ui_manager, self._pather)
self._char: IChar = Barbarian(self._config.barbarian, self._config.char, self._screen, self._template_finder, self._ui_manager, self._pather)
else:
Logger.error(f'{self._config.char["type"]} is not supported! Closing down bot.')
os._exit(1)
@@ -181,7 +181,7 @@ class Bot:
os._exit(1)
else:
Logger.info(f"Please Enter the region ip and hot ip on config to use")
# Run /nopickup command to avoid picking up stuff on accident
if not self._ran_no_pickup:
self._ran_no_pickup = True
+35 -3
View File
@@ -1,7 +1,17 @@
import configparser
import numpy as np
import os
import re
from dataclasses import dataclass
from logger import Logger
@dataclass
class ItemProps:
pickit_type: int = 0
include: list[str] = None
exclude: list[str] = None
include_type: str = "OR"
exclude_type: str = "OR"
class Config:
def _select_val(self, section: str, key: str = None):
@@ -113,7 +123,7 @@ class Config:
self.trapsin = self._config["trapsin"]
if "trapsin" in self._custom:
self.trapsin.update(self._custom["trapsin"])
self.barbarian = self._config["barbarian"]
if "barbarian" in self._custom:
self.barbarian.update(self._custom["barbarian"])
@@ -127,8 +137,8 @@ class Config:
self.items = {}
for key in self._pickit_config["items"]:
self.items[key] = int(self._select_val("items", key))
if self.items[key] and not os.path.exists(f"./assets/items/{key}.png") and self._print_warnings:
self.items[key] = self.parse_item_config_string(key)
if self.items[key].pickit_type and not os.path.exists(f"./assets/items/{key}.png") and self._print_warnings:
print(f"Warning: You activated {key} in pickit, but there is no img available in assets/items")
self.colors = {}
@@ -156,6 +166,28 @@ class Config:
"melee_min_score": int(self._select_val("claws", "melee_min_score")),
}
def parse_item_config_string(self, key: str = None) -> ItemProps:
item_props = ItemProps()
# split string by commas NOT contained within parentheses
item_string_as_list = re.split(r',\s*(?![^()]*\))', self._select_val("items", key).upper())
trim_strs=["AND(", "OR(", "(", ")", " "]
clean_string = [re.sub(r'|'.join(map(re.escape, trim_strs)), '', x).strip() for x in item_string_as_list]
item_props.pickit_type = int(clean_string[0])
try:
item_props.include = clean_string[1].split(',') if clean_string[1] else None
item_props.include_type = "AND" if "AND" in item_string_as_list[1] else "OR"
except IndexError as error:
pass
except Exception as exception:
Logger.error(f"Item parsing error: {exception}")
try:
item_props.exclude = clean_string[2].split(',') if clean_string[2] else None
item_props.exclude_type = "AND" if "AND" in item_string_as_list[2] else "OR"
except IndexError as error:
pass
except Exception as exception:
Logger.error(f"Item parsing error: {exception}")
return item_props
if __name__ == "__main__":
config = Config(print_warnings=True)
+2 -2
View File
@@ -52,7 +52,7 @@ class ItemFinder:
blacklist_item = item_name.startswith("bl__")
# these items will be searched for regardless of pickit setting (e.g. for runes to avoid mixup)
force_search = item_name.startswith("rune_")
if blacklist_item or ((item_name in config.items and config.items[item_name]) or force_search):
if blacklist_item or ((item_name in config.items and config.items[item_name].pickit_type) or force_search):
data = cv2.imread(f"assets/{self._folder_name}/" + filename)
filtered_template = np.zeros(data.shape, np.uint8)
for key in self._template_color_ranges:
@@ -120,7 +120,7 @@ class ItemFinder:
item.roi = [max_loc[0] + x, max_loc[1] + y, template.data.shape[1], template.data.shape[0]]
center_abs = (item.center[0] - (inp_img.shape[1] // 2), item.center[1] - (inp_img.shape[0] // 2))
item.dist = math.dist(center_abs, (0, 0))
if item is not None and self._items_to_pick[item.name]:
if item is not None and self._items_to_pick[item.name].pickit_type:
item_list.append(item)
elapsed = time.time() - start
# print(f"Item Search: {elapsed}")
+1 -1
View File
@@ -130,7 +130,7 @@ class PickIt:
# send log to discord
if found_items and closest_item.name not in picked_up_items:
Logger.info(f"Picking up: {closest_item.name} ({closest_item.score*100:.1f}% confidence)")
self._game_stats.log_item_pickup(closest_item.name, self._config.items[closest_item.name] == 2)
self._game_stats.log_item_pickup(closest_item.name, self._config.items[closest_item.name].pickit_type == 2)
picked_up_items.append(closest_item.name)
else:
char.pre_move()
+1 -1
View File
@@ -18,7 +18,7 @@ class Messenger:
elif " uniq_" in msg or "rare" in msg:
# TODO: It is more gold than yellow, find a better yellow highlight
msg = f"```fix\\n- {msg} \\n```"
elif " eth_" in msg:
elif " gray_" in msg:
msg = f"```python\\n# {msg} \\n```"
else:
msg = f"```\\n{msg} \\n```"
+1 -1
View File
@@ -22,7 +22,7 @@ class TemplateFinder:
Loads images from assets/templates and assets/npc and provides search functions
to find these assets within another image
"""
def __init__(self, screen: Screen, template_pathes: list[str] = ["assets\\templates", "assets\\npc"]):
def __init__(self, screen: Screen, template_pathes: list[str] = ["assets\\templates", "assets\\npc", "assets\\item_properties"]):
self._screen = screen
self._config = Config()
self.last_res = None
+60 -4
View File
@@ -271,10 +271,66 @@ class UiManager():
wait(0.2, 0.3)
_, w, _ = img.shape
img = img[:, (w//2):,:]
item_list = item_finder.search(img)
item_list = [x for x in item_list if "potion" not in x.name and not \
(self._config.items[x.name] == 3 and not self._template_finder.search("ETHEREAL", img).valid)]
return len(item_list) > 0
original_list = item_finder.search(img)
filtered_list = []
for x in original_list:
if ("potion" in x.name) or (self._config.items[x.name].pickit_type == 0): continue
include_props = self._config.items[x.name].include
exclude_props = self._config.items[x.name].exclude
if not (include_props or exclude_props):
Logger.debug(f"{x.name}: Stashing")
filtered_list.append(x)
continue
include = True
include_logic_type = self._config.items[x.name].include_type
if include_props:
include = False
found_props=[]
for prop in include_props:
try:
template_match = self._template_finder.search(prop, img, threshold=0.95)
except:
Logger.error(f"{x.name}: can't find template file for required {prop}, ignore just in case")
template_match = lambda: None; template_match.valid = True
if template_match.valid:
if include_logic_type == "AND":
found_props.append(True)
else:
include = True
break
else:
found_props.append(False)
if include_logic_type == "AND" and len(found_props) > 0 and all(found_props):
include = True
if not include:
Logger.debug(f"{x.name}: Discarding. Required {include_logic_type}({include_props})={include}")
continue
exclude = False
exclude_logic_type = self._config.items[x.name].exclude_type
if exclude_props:
found_props=[]
for prop in exclude_props:
try:
template_match = self._template_finder.search(prop, img, threshold=0.97)
except:
Logger.error(f"{x.name}: can't find template file for exclusion {prop}, ignore just in case")
template_match = lambda: None; template_match.valid = False
if template_match.valid:
if exclude_logic_type == "AND":
found_props.append(True)
else:
exclude = True
break
else:
found_props.append(False)
if exclude_logic_type == "AND" and len(exclude_props) > 0 and all(found_props):
exclude = True
break
if include and not exclude:
Logger.debug(f"{x.name}: Stashing. Required {include_logic_type}({include_props})={include}, exclude {exclude_logic_type}({exclude_props})={exclude}")
filtered_list.append(x)
return len(filtered_list) > 0
def _move_to_stash_tab(self, stash_idx: int):
"""Move to a specifc tab in the stash