Skip to content
This repository was archived by the owner on Jul 1, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed assets/templates/nihlatak/cold_immune.png
Binary file not shown.
Binary file removed assets/templates/nihlatak/cold_immunes.png
Binary file not shown.
Binary file added assets/templates/ui/view/immune_cold.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/templates/ui/view/immune_fire.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/templates/ui/view/immune_lightning.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/templates/ui/view/immune_magic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/templates/ui/view/immune_physical.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/templates/ui/view/immune_poison.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions config/game.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ yellow=27,110,190,33,145,255
gold=20,75,140,26,95,230
orange=20,190,190,23,255,255
red=-9,110,100,12,255,255
light_red=-4,117,230,4,194,255
health_potion=170,100,76,190,255,255
mana_potion=105,20,76,135,255,255
rejuv_potion=140,50,40,160,255,255
Expand Down Expand Up @@ -136,6 +137,8 @@ tab_indicator=31,82,385,14
deposit_btn=454,365,186,43
equipped_inventory_area=861,59,387,287
inventory_bg_pattern=21,622,1236,75
immunities_roi=424,65,432,16
summon_health=88,12,358,10

[path]
; static pathes in format: x0,y0, x1,y1, x2,y2, ...
Expand Down
9 changes: 5 additions & 4 deletions src/char/sorceress/blizz_sorc.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import numpy as np
from screen import convert_abs_to_monitor, grab, convert_screen_to_abs
from config import Config
from ui.view import is_monster_immune
import template_finder

class BlizzSorc(Sorceress):
Expand Down Expand Up @@ -222,17 +223,17 @@ def kill_nihlathak(self, end_nodes: list[int]) -> bool:
# Find nilhlatak position
atk_sequences = max(1, int(Config().char["atk_len_nihlathak"]) - 1)
for i in range(atk_sequences):
nihlathak_pos_abs = self._pather.find_abs_node_pos(end_nodes[-1], grab())
img = grab()
nihlathak_pos_abs = self._pather.find_abs_node_pos(end_nodes[-1], img)
if nihlathak_pos_abs is not None:
cast_pos_abs = np.array([nihlathak_pos_abs[0] * 1.0, nihlathak_pos_abs[1] * 1.0])
wait(0.5)
self._blizzard(cast_pos_abs, spray=0)
wait(0.2)
is_nihl = template_finder.search(["NIHL_BAR"], grab(), threshold=0.8, roi=Config().ui_roi["enemy_info"]).valid
nihl_immune = template_finder.search(["COLD_IMMUNE","COLD_IMMUNES"], grab(), threshold=0.8, roi=Config().ui_roi["enemy_info"]).valid
is_nihl = template_finder.search(["NIHL_BAR"], img, threshold=0.8, roi=Config().ui_roi["enemy_info"]).valid
if is_nihl:
Logger.info("Found him!")
if nihl_immune:
if is_monster_immune("cold", img):
Logger.info("Cold Immune! - Exiting")
return True
wait(0.5)
Expand Down
17 changes: 17 additions & 0 deletions src/target_detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import json
from dataclasses import dataclass
from ui_manager import get_hud_mask
from config import Config
from ui.view import is_monster_immune
import template_finder

FILTER_RANGES=[
{"erode": 1, "blur": 3, "lh": 38, "ls": 169, "lv": 50, "uh": 70, "us": 255, "uv": 255}, # poison
Expand Down Expand Up @@ -55,6 +58,20 @@ def get_visible_targets(
filterimage, rectangles, positions = _add_markers(filterimage, threshz, rect_min_size=100, rect_max_size=200, marker=True) # rather large rectangles
if positions:
for cnt, position in enumerate(positions):
# ignore false positives matching immunity text
if is_in_roi(Config().ui_roi["immunities_roi"], position):
if is_monster_immune("poison", img): continue
if is_monster_immune("cold", img): continue
# ignore false positives matching merc/summon health bar
if is_in_roi(Config().ui_roi["summon_health"], position):
within_merc_bar = False
results = template_finder.search_all("summon_health_smallest", img, threshold=0.8, roi=Config().ui_roi["summon_health"], color_match=Config().colors["green"])
if results:
for result in results:
if is_in_roi(result.region, position):
within_merc_bar = True
break
if within_merc_bar: continue
distance = _dist_to_center(position)
condition = (radius_min <= distance <= radius_max) if use_radius else (not is_in_roi(ignore_roi, position))
if condition:
Expand Down
37 changes: 37 additions & 0 deletions src/ui/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@
from ui_manager import wait_until_hidden, wait_until_visible, detect_screen_object, select_screen_object_match, ScreenObjects, list_visible_objects, is_visible
from inventory import common
from screen import convert_screen_to_monitor
import numpy as np
import template_finder

IMMUNITY_COLOR_MAP = {
"cold": "blue",
"fire": "light_red",
"poison": "green",
"lightning": "yellow",
"physical": "gold",
"magic": "orange"
}

def enable_no_pickup() -> bool:
# """
Expand Down Expand Up @@ -101,6 +112,32 @@ def return_to_play() -> bool:
return False
return True

def is_monster_immune(immunity: str, img: np.ndarray = grab()) -> bool:
"""
Detects if a monster is immune to a given element based on "Immune to X" text under the monster's health bar
:param immunity: The immunity to detect
:param img: The image to detect on (assumes monster info is visible)
:return: True if monster is immune, False otherwise
"""
immunity = immunity.lower()
if not any([immunity == x for x in IMMUNITY_COLOR_MAP.keys()]):
Logger.error(f"is_immune: invalid immunity type {immunity}")
return False
return template_finder.search(
f"IMMUNE_{immunity.upper()}",
img,
threshold=0.8,
roi=Config().ui_roi["immunities_roi"],
color_match=Config().colors[IMMUNITY_COLOR_MAP[immunity]],
).valid

def list_monster_immunities(img: np.ndarray = grab()) -> list:
immunities = []
for key in IMMUNITY_COLOR_MAP.keys():
if is_monster_immune(key, img):
immunities.append(key)
return immunities

# Testing
if __name__ == "__main__":
import keyboard
Expand Down
26 changes: 26 additions & 0 deletions test/target_detect_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,29 @@ def test_target_detect(screen_path, expected_res):
screen.set_window_position(0, 0)
img = cv2.imread(screen_path)
assert bool(len(get_visible_targets(img))) == expected_res

@pytest.mark.parametrize("screen_path, expected_res", [
("test/assets/monster_info.png", 0)
])
def test_ignore_immunity_text(screen_path, expected_res):
screen.set_window_position(0, 0)
img = cv2.imread(screen_path)
assert len(get_visible_targets(img)) == expected_res

@pytest.mark.parametrize("screen_path, expected_res", [
("test/assets/summon_health_bars.png", 1)
])
def test_ignore_health_bar(screen_path, expected_res):
# the test asset has a single green glob and health bars in view. If the health bar is ignored, the glob will be the only result
screen.set_window_position(0, 0)
img = cv2.imread(screen_path)
assert len(get_visible_targets(img)) == expected_res

if __name__ == "__main__":
from config import Config
import template_finder
screen.set_window_position(0, 0)

img = cv2.imread("test/assets/summon_health_bars.png")
res = template_finder.search_all("summon_health_smallest", img, threshold=0.8, roi=Config().ui_roi["summon_health"], color_match=Config().colors["green"])
#print(get_visible_targets(img))