Reworked trapsin a bit to include casting/attack delays between skills. Also added mindblast and added to pindle run.
This commit is contained in:
+19
-16
@@ -19,7 +19,7 @@ max_runtime_before_break_m=0
|
||||
; timers / fail handling
|
||||
d2r_path=C:\Program Files (x86)\Diablo II Resurrected
|
||||
max_consecutive_fails=5
|
||||
max_game_length_s=140
|
||||
max_game_length_s=55
|
||||
; if you set this field to 1, botty will attempt to restart d2 after a crash or failure
|
||||
restart_d2r_when_stuck=0
|
||||
|
||||
@@ -38,18 +38,18 @@ pickit_screenshots=0
|
||||
; run_arcane
|
||||
; run_diablo
|
||||
; run_vizier
|
||||
order=run_pindle,run_eldritch_shenk
|
||||
order=run_pindle
|
||||
|
||||
[char]
|
||||
; ==========================
|
||||
; ==== Mandatory Fields ====
|
||||
; ==========================
|
||||
; These configs have to be alligned with your d2r settings and char build
|
||||
type=blizzorb_sorc
|
||||
type=trapsin
|
||||
belt_rows=4
|
||||
casting_frames=8
|
||||
attack_frames=15
|
||||
cta_available=1
|
||||
casting_frames=11
|
||||
attack_frames=10
|
||||
cta_available=0
|
||||
; safer_routines: enable for optional defensive maneuvers/etc during combat/runs at the cost of increased runtime (ex. hardcore players)
|
||||
safer_routines=1
|
||||
|
||||
@@ -70,7 +70,7 @@ show_items=alt
|
||||
; stand_still cannot be the default "shift" as it would interfere with merc healing
|
||||
stand_still=capslock
|
||||
; teleport: leave empty if you can't use
|
||||
teleport=f7
|
||||
teleport=
|
||||
town_portal=f8
|
||||
; call to arms settings:
|
||||
weapon_switch=x
|
||||
@@ -87,7 +87,7 @@ use_merc=1
|
||||
atk_len_arc=2.5
|
||||
atk_len_eldritch=10.0
|
||||
atk_len_nihlathak=8.0
|
||||
atk_len_pindle=7.0
|
||||
atk_len_pindle=8.5
|
||||
atk_len_shenk=8.0
|
||||
atk_len_trav=3.0
|
||||
|
||||
@@ -109,9 +109,9 @@ belt_rejuv_columns=2
|
||||
|
||||
; Potion/chicken settings
|
||||
take_health_potion=0.92
|
||||
take_mana_potion=0.8
|
||||
take_mana_potion=0.40
|
||||
take_rejuv_potion_health=0.75
|
||||
take_rejuv_potion_mana=0.45
|
||||
take_rejuv_potion_mana=0.10
|
||||
heal_merc=0.7
|
||||
heal_rejuv_merc=0.3
|
||||
chicken=0.5
|
||||
@@ -207,13 +207,16 @@ concentration=f5
|
||||
; ==========================
|
||||
; Currently no Trav implementaiton!
|
||||
[trapsin]
|
||||
burst_of_speed=
|
||||
death_sentry=
|
||||
fade=
|
||||
lightning_sentry=
|
||||
shadow_warrior=
|
||||
; We assume fire blast or shock-web is left-click skill which is optional hotkey if pre-assigned.
|
||||
skill_left=
|
||||
|
||||
; Assume all other skills are right-click and hotkey required!
|
||||
burst_of_speed=f1
|
||||
death_sentry=f2
|
||||
fade=
|
||||
lightning_sentry=f3
|
||||
shadow_warrior=f4
|
||||
mind_blast=f5
|
||||
|
||||
; ===========================
|
||||
; ==== Builds: Barbarian ====
|
||||
@@ -338,7 +341,7 @@ message_body_template={{"content": "{msg}"}}
|
||||
message_headers=
|
||||
ocr_during_pickit=0
|
||||
;use "can_teleport_natively" or "can_teleport_with_charges" if you want to force certain behavior in case autodetection isn't working properly
|
||||
override_capabilities="can_teleport_natively"
|
||||
override_capabilities=
|
||||
pathing_delay_factor=4
|
||||
;If you want to control Hyper-V window from host use 0,51 here
|
||||
window_client_area_offset=0,0
|
||||
|
||||
+128
-28
@@ -1,4 +1,5 @@
|
||||
import keyboard
|
||||
from ui import skills
|
||||
from utils.custom_mouse import mouse
|
||||
from char import IChar
|
||||
from pather import Pather
|
||||
@@ -6,6 +7,7 @@ from logger import Logger
|
||||
from screen import convert_abs_to_monitor, convert_screen_to_abs, grab
|
||||
from config import Config
|
||||
from utils.misc import wait, rotate_vec, unit_vector
|
||||
import time
|
||||
import random
|
||||
from pather import Location, Pather
|
||||
import numpy as np
|
||||
@@ -25,16 +27,11 @@ class Trapsin(IChar):
|
||||
wait(0.1, 0.13)
|
||||
mouse.click(button="right")
|
||||
wait(self._cast_duration)
|
||||
if self._skill_hotkeys["shadow_warrior"]:
|
||||
keyboard.send(self._skill_hotkeys["shadow_warrior"])
|
||||
wait(0.1, 0.13)
|
||||
mouse.click(button="right")
|
||||
wait(self._cast_duration)
|
||||
|
||||
def pre_move(self, wait_tp: bool = False):
|
||||
super().pre_move(wait_tp=wait_tp)
|
||||
if self._skill_hotkeys["burst_of_speed"]:
|
||||
keyboard.send(self._skill_hotkeys["burst_of_speed"])
|
||||
wait(0.1, 0.13)
|
||||
mouse.click(button="right")
|
||||
wait(self._cast_duration)
|
||||
self._cast_burst_of_speed()
|
||||
|
||||
def _left_attack(self, cast_pos_abs: tuple[float, float], spray: int = 10):
|
||||
keyboard.send(Config().char["stand_still"], do_release=False)
|
||||
@@ -50,7 +47,6 @@ class Trapsin(IChar):
|
||||
mouse.release(button="left")
|
||||
keyboard.send(Config().char["stand_still"], do_press=False)
|
||||
|
||||
|
||||
def _right_attack(self, cast_pos_abs: tuple[float, float], spray: float = 10):
|
||||
keyboard.send(self._skill_hotkeys["lightning_sentry"])
|
||||
x = cast_pos_abs[0] + (random.random() * 2 * spray - spray)
|
||||
@@ -66,35 +62,139 @@ class Trapsin(IChar):
|
||||
atk(4)
|
||||
keyboard.send(self._skill_hotkeys["death_sentry"])
|
||||
atk(1)
|
||||
|
||||
def _cast_shadow_warrior(self, cast_pos_abs: tuple[float, float], spray: float = 10):
|
||||
if self._skill_hotkeys["shadow_warrior"]:
|
||||
keyboard.send(self._skill_hotkeys["shadow_warrior"])
|
||||
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(0.06, 0.08)
|
||||
mouse.release(button="right")
|
||||
wait(self._cast_duration-0.06)
|
||||
|
||||
def _cast_mind_blast(self, cast_pos_abs: tuple[float, float], spray: float = 10):
|
||||
if self._skill_hotkeys["mind_blast"]:
|
||||
keyboard.send(self._skill_hotkeys["mind_blast"])
|
||||
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(0.06, 0.08)
|
||||
mouse.release(button="right")
|
||||
wait(self._cast_duration-0.06)
|
||||
|
||||
def _cast_burst_of_speed(self):
|
||||
if self._skill_hotkeys["burst_of_speed"]:
|
||||
keyboard.send(self._skill_hotkeys["burst_of_speed"])
|
||||
|
||||
mouse.press(button="right")
|
||||
wait(0.06, 0.08)
|
||||
mouse.release(button="right")
|
||||
wait(self._cast_duration-0.06)
|
||||
|
||||
def _cast_fire_blast(self, cast_pos_abs: tuple[float, float], spray: float = 10, duration: float = 0.3):
|
||||
keyboard.send(Config().char["stand_still"], do_release=False)
|
||||
|
||||
#Get mouse in initial target logcation
|
||||
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)
|
||||
|
||||
#We just hold down left mouse button to ensure we get full attack speed.
|
||||
mouse.press(button="left")
|
||||
now = start = time.time()
|
||||
while (now - start) < duration:
|
||||
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)
|
||||
wait(0.06, 0.08)
|
||||
now = time.time()
|
||||
mouse.release(button="left")
|
||||
|
||||
keyboard.send(Config().char["stand_still"], do_press=False)
|
||||
wait(self._attack_duration-0.06)
|
||||
|
||||
def _cast_lightning_sentry(self, cast_pos_abs: tuple[float, float], spray: float = 10):
|
||||
if not self._skill_hotkeys["lightning_sentry"]:
|
||||
Logger.error("Lightning sentry hotkey not assigned. Required for trapsin!")
|
||||
keyboard.send(self._skill_hotkeys["lightning_sentry"])
|
||||
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(0.06, 0.08)
|
||||
mouse.release(button="right")
|
||||
wait(self._attack_duration-0.06)
|
||||
|
||||
def _cast_death_sentry(self, cast_pos_abs: tuple[float, float], spray: float = 10):
|
||||
if not self._skill_hotkeys["death_sentry"]:
|
||||
Logger.error("Death sentry hotkey not assigned. Required for trapsin!")
|
||||
keyboard.send(self._skill_hotkeys["death_sentry"])
|
||||
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(0.06, 0.08)
|
||||
mouse.release(button="right")
|
||||
wait(self._attack_duration-0.06)
|
||||
|
||||
|
||||
def kill_pindle(self) -> bool:
|
||||
atk_len = max(1, int(Config().char["atk_len_pindle"] / 2))
|
||||
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(atk_len):
|
||||
self._right_attack(cast_pos_abs, 11)
|
||||
self._left_attack(cast_pos_abs, 11)
|
||||
# Move to items
|
||||
wait(self._cast_duration, self._cast_duration + 0.2)
|
||||
cast_pos_abs = [pindle_pos_abs[0] * 1.2, pindle_pos_abs[1] * 1.2]
|
||||
trap_cast_pos_abs = [pindle_pos_abs[0] * 0.45, pindle_pos_abs[1] * 0.40]
|
||||
start = time.time()
|
||||
self._cast_mind_blast(cast_pos_abs=cast_pos_abs)
|
||||
cast_pos_abs = [pindle_pos_abs[0] * 0.8, pindle_pos_abs[1] * 0.8]
|
||||
self._cast_shadow_warrior(cast_pos_abs=cast_pos_abs)
|
||||
for _ in range(4):
|
||||
self._cast_lightning_sentry(cast_pos_abs=trap_cast_pos_abs, spray=5.0)
|
||||
self._cast_death_sentry(cast_pos_abs=trap_cast_pos_abs, spray=5.0)
|
||||
|
||||
|
||||
trap_cast_pos_abs = [pindle_pos_abs[0] * 0.50, pindle_pos_abs[1] * 0.50]
|
||||
time_remaining = Config().char["atk_len_pindle"] - (time.time() - start)
|
||||
self._cast_fire_blast(cast_pos_abs=cast_pos_abs, duration=time_remaining)
|
||||
|
||||
if self.capabilities.can_teleport_natively:
|
||||
self._pather.traverse_nodes_fixed("pindle_end", self)
|
||||
else:
|
||||
self._pather.traverse_nodes((Location.A5_PINDLE_SAFE_DIST, Location.A5_PINDLE_END), self, force_tp=True)
|
||||
return True
|
||||
#Walk just close enough to pindle's position to see items. That way we leave sooner if there is nothing to grab
|
||||
x_m, y_m = convert_abs_to_monitor([pindle_pos_abs[0] * 0.65, pindle_pos_abs[1] * 0.65])
|
||||
self.move((x_m, y_m), force_move=True)
|
||||
return False
|
||||
|
||||
def kill_eldritch(self) -> bool:
|
||||
atk_len = max(1, int(Config().char["atk_len_eldritch"] / 2))
|
||||
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(atk_len):
|
||||
self._right_attack(cast_pos_abs, 90)
|
||||
self._left_attack(cast_pos_abs, 90)
|
||||
# Move to items
|
||||
wait(self._cast_duration, self._cast_duration + 0.2)
|
||||
eldritch_pos_abs = convert_screen_to_abs(Config().path["eldritch_end"][0])
|
||||
cast_pos_abs = [eldritch_pos_abs[0] * 1.5, eldritch_pos_abs[1] * 1.5]
|
||||
trap_cast_pos_abs = [eldritch_pos_abs[0] * 0.70, eldritch_pos_abs[1] * 0.70]
|
||||
|
||||
start = time.time()
|
||||
self._cast_shadow_warrior(cast_pos_abs=cast_pos_abs)
|
||||
for _ in range(4):
|
||||
self._cast_lightning_sentry(cast_pos_abs=trap_cast_pos_abs)
|
||||
self._cast_death_sentry(cast_pos_abs=trap_cast_pos_abs)
|
||||
|
||||
time_remaining = Config().char["atk_len_eldritch"] - (time.time() - start)
|
||||
self._cast_fire_blast(cast_pos_abs=cast_pos_abs, duration=time_remaining)
|
||||
|
||||
if self.capabilities.can_teleport_natively:
|
||||
self._pather.traverse_nodes_fixed("eldritch_end", self)
|
||||
else:
|
||||
self._pather.traverse_nodes((Location.A5_ELDRITCH_SAFE_DIST, Location.A5_ELDRITCH_END), self, timeout=0.6, force_tp=True)
|
||||
x_m, y_m = convert_abs_to_monitor([eldritch_pos_abs[0] * 1.0, eldritch_pos_abs[1] * 1.0])
|
||||
self.move((x_m, y_m), force_move=True)
|
||||
return True
|
||||
|
||||
def kill_shenk(self) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user