diff --git a/README.md b/README.md index 7707d9e..35f8b6d 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,11 @@ order=run_pindle, run_eldritch | ------------- | ----------------------------------------------------------------------------- | | nova | Required Hotkey for Nova (must be bound to right skill) | +| [hydra_sorc] | Descriptions | +| ------------- | ----------------------------------------------------------------------------- | +| fire_ball | Optional Hotkey for (must be bound to left skill) | +| hydra | Required Hotkey for Hydra (must be bound to right skill) | + | [hammerdin] | Descriptions | | -------------- | ----------------------------------------------------------------------------------- | | teleport | Optional Hotkey for teleport. If left empty hammerdin will run instead of teleport. | diff --git a/config/params.ini b/config/params.ini index 7565b8d..b166aa8 100644 --- a/config/params.ini +++ b/config/params.ini @@ -142,6 +142,13 @@ blizzard= ; nova must be right skill, hotkey required nova=f2 +[hydra_sorc] +; only supports Pindle and Eldritch currently +; alt_attack is any alternate attacking right skill. Fireball,Lightning,Frozen Orb, hotkey required +alt_attack=f3 +; hydra must be right skill, hotkey required +hydra=f2 + ; ========================= ; ==== Builds: Paladin ==== ; ========================= diff --git a/src/bot.py b/src/bot.py index ab7113b..8b90823 100644 --- a/src/bot.py +++ b/src/bot.py @@ -22,7 +22,7 @@ from char import IChar from item import ItemFinder from item.pickit import PickIt from pather import Pather, Location -from char.sorceress import LightSorc, BlizzSorc, NovaSorc +from char.sorceress import LightSorc, BlizzSorc, NovaSorc,HydraSorc from char.trapsin import Trapsin from char.hammerdin import Hammerdin from char.barbarian import Barbarian @@ -59,6 +59,8 @@ class Bot: self._char: IChar = BlizzSorc(Config().blizz_sorc, self._pather) elif Config().char["type"] == "nova_sorc": self._char: IChar = NovaSorc(Config().nova_sorc, self._pather) + elif Config().char["type"] == "hydra_sorc": + self._char: IChar = HydraSorc(Config().hydra_sorc, self._pather) elif Config().char["type"] == "hammerdin": self._char: IChar = Hammerdin(Config().hammerdin, self._pather, self._pickit) #pickit added for diablo elif Config().char["type"] == "trapsin": diff --git a/src/char/sorceress/__init__.py b/src/char/sorceress/__init__.py index fdfc74e..97cbf8c 100644 --- a/src/char/sorceress/__init__.py +++ b/src/char/sorceress/__init__.py @@ -2,3 +2,4 @@ from .sorceress import Sorceress from .light_sorc import LightSorc from .blizz_sorc import BlizzSorc from .nova_sorc import NovaSorc +from .hydra_sorc import HydraSorc diff --git a/src/char/sorceress/hydra_sorc.py b/src/char/sorceress/hydra_sorc.py new file mode 100644 index 0000000..dd555ea --- /dev/null +++ b/src/char/sorceress/hydra_sorc.py @@ -0,0 +1,100 @@ +import time +import keyboard +from char.sorceress import Sorceress +from utils.custom_mouse import mouse +from logger import Logger +from utils.misc import wait +import random +from pather import Location +from screen import convert_abs_to_monitor, convert_screen_to_abs, grab +from config import Config + +class HydraSorc(Sorceress): + def __init__(self, *args, **kwargs): + Logger.info("Setting up HydraSorc Sorc") + super().__init__(*args, **kwargs) + self._hydra_time = None + + def _alt_attack(self, cast_pos_abs: tuple[float, float], delay: tuple[float, float] = (0.16, 0.23), spray: float = 10): + keyboard.send(Config().char["stand_still"], do_release=False) + if self._skill_hotkeys["alt_attack"]: + keyboard.send(self._skill_hotkeys["alt_attack"]) + for _ in range(5): + x = cast_pos_abs[0] + (random.random() * 2 * spray - spray) + y = cast_pos_abs[1] + (random.random() * 2 * spray - spray) + cast_pos_monitor = convert_abs_to_monitor((x, y)) + mouse.move(*cast_pos_monitor) + mouse.press(button="right") + wait(delay[0], delay[1]) + mouse.release(button="right") + keyboard.send(Config().char["stand_still"], do_press=False) + + def _hydra(self, cast_pos_abs: tuple[float, float], spray: float = 10): + if self._hydra_time is None or time.time() - self._hydra_time > 10: + if not self._skill_hotkeys["hydra"]: + raise ValueError("You did not set a hotkey for hydra!") + keyboard.send(self._skill_hotkeys["hydra"]) + self._hydra_time = time.time() + x = cast_pos_abs[0] + (random.random() * 2 * spray - spray) + y = cast_pos_abs[1] + (random.random() * 2 * spray - spray) + cast_pos_monitor = convert_abs_to_monitor((x, y)) + mouse.move(*cast_pos_monitor) + mouse.press(button="right") + wait(2,3) + mouse.release(button="right") + + def kill_pindle(self) -> bool: + pindle_pos_abs = convert_screen_to_abs(Config().path["pindle_end"][0]) + cast_pos_abs = [pindle_pos_abs[0] * 0.9, pindle_pos_abs[1] * 0.9] + for _ in range(int(Config().char["atk_len_pindle"])): + self._hydra(cast_pos_abs, spray=0) + self._alt_attack(cast_pos_abs, spray=11) + # Move to items + wait(self._cast_duration, self._cast_duration + 0.2) + self._pather.traverse_nodes_fixed("pindle_end", self) + self._hydra_time = None + return True + + def kill_eldritch(self) -> bool: + eld_pos_abs = convert_screen_to_abs(Config().path["eldritch_end"][0]) + cast_pos_abs = [eld_pos_abs[0] * 0.9, eld_pos_abs[1] * 0.9] + for _ in range(int(Config().char["atk_len_eldritch"])): + self._hydra(cast_pos_abs, spray=0) + self._alt_attack(cast_pos_abs, spray=90) + # Move to items + wait(self._cast_duration, self._cast_duration + 0.2) + self._pather.traverse_nodes_fixed("eldritch_end", self) + self._hydra_time = None + return True + + def kill_shenk(self) -> bool: + shenk_pos_abs = self._pather.find_abs_node_pos(149, grab()) + if shenk_pos_abs is None: + shenk_pos_abs = convert_screen_to_abs(Config().path["shenk_end"][0]) + cast_pos_abs = [shenk_pos_abs[0] * 0.9, shenk_pos_abs[1] * 0.9] + for _ in range(int(Config().char["atk_len_shenk"] * 0.5)): + self._hydra(cast_pos_abs, spray=0) + self._alt_attack(cast_pos_abs, spray=90) + pos_m = convert_abs_to_monitor((150, 50)) + self.pre_move() + self.move(pos_m, force_move=True) + shenk_pos_abs = convert_screen_to_abs(Config().path["shenk_end"][0]) + cast_pos_abs = [shenk_pos_abs[0] * 0.9, shenk_pos_abs[1] * 0.9] + for _ in range(int(Config().char["atk_len_shenk"] * 0.5)): + self._hydra(cast_pos_abs, spray=0) + self._alt_attack(cast_pos_abs, spray=90) + pos_m = convert_abs_to_monitor((150, 50)) + self.pre_move() + self.move(pos_m, force_move=True) + shenk_pos_abs = convert_screen_to_abs(Config().path["shenk_end"][0]) + cast_pos_abs = [shenk_pos_abs[0] * 0.9, shenk_pos_abs[1] * 0.9] + for _ in range(int(Config().char["atk_len_shenk"])): + self._hydra(cast_pos_abs, spray=0) + self._alt_attack(cast_pos_abs, spray=90) + self.pre_move() + self.move(pos_m, force_move=True) + # Move to items + wait(self._cast_duration, self._cast_duration + 0.2) + self._pather.traverse_nodes((Location.A5_SHENK_SAFE_DIST, Location.A5_SHENK_END), self, timeout=1.4, force_tp=True) + self._hydra_time = None + return True \ No newline at end of file diff --git a/src/config.py b/src/config.py index b2bccf1..69bd111 100644 --- a/src/config.py +++ b/src/config.py @@ -41,6 +41,7 @@ class Config: blizz_sorc = {} light_sorc = {} nova_sorc = {} + hydra_sorc = {} hammerdin = {} trapsin = {} barbarian = {} @@ -317,6 +318,11 @@ class Config: if "nova_sorc" in self.configs["custom"]["parser"]: self.nova_sorc.update(dict(self.configs["custom"]["parser"]["nova_sorc"])) self.nova_sorc.update(sorc_base_cfg) + # hydra sorc + self.hydra_sorc = dict(self.configs["config"]["parser"]["hydra_sorc"]) + if "hydra_sorc" in self.configs["custom"]["parser"]: + self.hydra_sorc.update(dict(self.configs["custom"]["parser"]["hydra_sorc"])) + self.hydra_sorc.update(sorc_base_cfg) # Palandin config self.hammerdin = self.configs["config"]["parser"]["hammerdin"]