Files
my-botty/src/pickit.py
T

125 lines
5.5 KiB
Python

from belt_manager import BeltManager
from ui_manager import UiManager
from item_finder import ItemFinder
import time
from utils.custom_mouse import mouse
import keyboard
import cv2
from config import Config
from char.i_char import IChar
from logger import Logger
from screen import Screen
from ui_manager import UiManager
from game_stats import GameStats
class PickIt:
def __init__(self, screen: Screen, item_finder: ItemFinder, ui_manager: UiManager, belt_manager: BeltManager, game_stats: GameStats = None):
self._item_finder = item_finder
self._screen = screen
self._belt_manager = belt_manager
self._ui_manager = ui_manager
self._game_stats = game_stats
self._config = Config()
def pick_up_items(self, char: IChar) -> bool:
"""
Pick up all items with specified char
:param char: The character used to pick up the item
:return: Bool if any items were picked up or not. (Does not account for picking up scrolls and pots)
"""
found_nothing = 0
found_items = False
keyboard.send(self._config.char["show_items"])
time.sleep(1.0) # sleep needed here to give d2r time to display items on screen on keypress
#Creating a screenshot of the current loot
if self._config.general["loot_screenshots"]:
img = self._screen.grab()
cv2.imwrite("./loot_screenshots/info_debug_drop_" + time.strftime("%Y%m%d_%H%M%S") + ".png", img)
Logger.debug("Took a screenshot of current loot")
start = prev_cast_start = time.time()
time_out = False
picked_up_items = []
while not time_out:
if (time.time() - start) > 24:
time_out = True
Logger.warning("Got stuck during pickit, skipping it this time...")
break
img = self._screen.grab()
item_list = self._item_finder.search(img)
# Check if we need to pick up certain pots more pots
need_pots = self._belt_manager.get_pot_needs()
if need_pots["mana"] <= 0:
item_list = [x for x in item_list if "mana_potion" not in x.name]
if need_pots["health"] <= 0:
item_list = [x for x in item_list if "healing_potion" not in x.name]
if need_pots["rejuv"] <= 0:
item_list = [x for x in item_list if "rejuvenation_potion" not in x.name]
if len(item_list) == 0:
# if two times no item was found, break
found_nothing += 1
if found_nothing > 1:
break
else:
found_nothing = 0
closest_item = item_list[0]
for item in item_list[1:]:
if closest_item.dist > item.dist:
closest_item = item
x_m, y_m = self._screen.convert_screen_to_monitor(closest_item.center)
if closest_item.dist < self._config.ui_pos["item_dist"]:
# if potion is picked up, record it in the belt manager
if "potion" in closest_item.name:
self._belt_manager.picked_up_pot(closest_item.name)
# no need to stash potions, scrolls, or gold
if "potion" not in closest_item.name and "tp_scroll" != closest_item.name and "misc_gold" not in closest_item.name:
found_items = True
Logger.info(f"Picking up: {closest_item.name} ({closest_item.score*100:.1f}% confidence)")
prev_cast_start = char.pick_up_item((x_m, y_m), item_name=closest_item.name, prev_cast_start=prev_cast_start)
if self._ui_manager.is_overburdened():
Logger.warning("Inventory full, skipping pickit!")
# TODO: should go back to town and stash stuff then go back to picking up more stuff
# but sm states are not fine enough for such a routine right now...
break
else:
# send log to discord
if found_items and closest_item.name not in picked_up_items:
self._game_stats.log_item_pickup(closest_item.name, self._config.items[closest_item.name] == 2)
picked_up_items.append(closest_item.name)
else:
char.pre_move()
char.move((x_m, y_m))
time.sleep(0.1)
keyboard.send(self._config.char["show_items"])
return found_items
if __name__ == "__main__":
import os
from config import Config
from char.sorceress import Sorceress
from ui_manager import UiManager
from template_finder import TemplateFinder
from pather import Pather
from game_stats import GameStats
import keyboard
keyboard.add_hotkey('f12', lambda: Logger.info('Force Exit (f12)') or os._exit(1))
keyboard.wait("f11")
config = Config()
game_states = GameStats()
screen = Screen(config.general["monitor"])
t_finder = TemplateFinder(screen)
ui_manager = UiManager(screen, t_finder)
belt_manager = BeltManager(screen, t_finder)
belt_manager._pot_needs = {"rejuv": 0, "health": 2, "mana": 2}
pather = Pather(screen, t_finder)
item_finder = ItemFinder()
char = Sorceress(config.sorceress, config.char, screen, t_finder, ui_manager, pather)
pickit = PickIt(screen, item_finder, ui_manager, belt_manager, game_states)
pickit.pick_up_items(char)