Add require/exclude properties to pickit.ini when stashing items. Also more item templates. (#295)
This commit is contained in:
+2
-2
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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```"
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user