Compare commits

..
731 Commits
Author SHA1 Message Date
alex 74ebef9b22 update params.ini, bot.py, win_input.py 2026-05-22 21:11:59 +02:00
alex 64578db453 add stealth system, key detection, click recorder, FOHdin, new routes, and tooling updates 2026-05-21 23:34:20 +02:00
alex 3d0e102afc document stealth, key detection, click recorder, and FOHdin in README 2026-05-20 20:06:21 +02:00
alex f9f26f36c3 merge main into mine 2026-05-20 20:02:52 +02:00
Alex ce5816a130 Initial commit 2026-05-20 19:55:00 +02:00
alex 644c2a106c feat: auto-launch D2R on botty startup
- main.py checks if D2R.exe is running, launches with auto-login if not
- Set char_name=Burr in config for OCR character selection
2026-05-20 09:20:37 +02:00
alex 4b003bd95e feat: auto-login + OCR character selection
- Added bnet_name, bnet_pass, char_name to [general] config
- Config._build_launch_options() appends -bnetname/-bnetpass when set
- character_select.py: OCR fallback when template matching fails
2026-05-20 09:16:48 +02:00
alex f2d23e511d feat: auto-login + OCR character selection
- Added bnet_name, bnet_pass, char_name config options
- Launch options auto-append -bnetname/-bnetpass when credentials set
- character_select.py: OCR fallback when template matching fails
- Scans character list row-by-row, matches by name, clicks and scrolls
2026-05-20 08:55:04 +02:00
alex 07be1a7b9c fix: npc_auto_label global declaration order 2026-05-20 07:44:39 +02:00
alex 8178104612 feat: enhanced stealth layer - click delay, endpoint wobble, behavior model
- custom_mouse.click(): added 50-800ms arrival-to-click delay (human hesitation)
- custom_mouse.stealth_move(): added endpoint wobble (2-5px micro-adjustment)
- stealth.py: new functions for keyboard timing, skill hesitation, wrong waypoint, skill mistakes
- params.ini: 8 new tunable stealth config options with documented defaults

All 46 files using mouse module automatically benefit — stealth is centralized.
2026-05-20 07:22:24 +02:00
alex 23b0f0f66b feat: parallel template search, async mouse moves, NPC auto-label
- template_finder.search(): parallel matching via ThreadPoolExecutor (4 workers)
- utils/custom_mouse.py: async_move() for non-blocking mouse movement
- utils/npc_auto_label.py: detect_visible_npcs() scans 16 NPCs in parallel
2026-05-19 22:47:30 +02:00
alex 2d69b246d9 feat: complete key auto-detection with binary .key parser
- Parse D2R binary .key format (10-byte entries, action=1=skill, action=0=non-skill)
- Detect skill slot bindings and validate against params.ini
- Scan Saved Games for any .key/.keyo file (handles battle tag names)
- Config loads cleanly, warns on skill/non-skill mismatches
2026-05-19 18:32:18 +02:00
alex 4f0f3df8bb docs: improvements reference + d2r-key-detection skill
- Added references/improvements.md tracking all implemented fixes
- Created d2r-key-detection skill for future sessions
2026-05-19 16:50:10 +02:00
alex 2c25b67cf9 fix: target false positives, pickit timing, hardcore death loop
- target_detect: add aspect ratio filtering to reject health bars and immune text
- pickit: add 0.2-0.3s wait after pickup before moving on (fix #939)
- game_controller: detect hardcore mode and stop instead of infinite death loop
- config: add 'hardcore' flag (default 0)

Closes #959, #939, #942
2026-05-19 16:49:24 +02:00
alex f6e700c921 feat: auto-detect D2R key bindings from .key/.keyo file
- Read character .key file from Saved Games / D2R install dir / APPDATA
- Auto-fill empty hotkeys in [char] section (inventory, belt, potions, etc.)
- Match skill slots to configured skills for validation
- Normalize key variants (left alt ~ alt, left shift ~ shift)
- params.ini values always take priority over detected bindings
- Warn on genuine mismatches between config and .key file
2026-05-19 16:46:24 +02:00
Alex 23e7e54f8d fix: resolve default.bnip merge conflicts from aeon0; fix raw string in config.py 2026-05-17 20:31:38 +02:00
Alex b52f7ebca9 fix: defer npc_manager template loading for headless Linux compatibility 2026-05-17 19:25:56 +02:00
Alex 329b7e77d9 fix: guard Windows-only imports for Linux compatibility (pywin32, mouse._winmouse, mss, rapidfuzz) 2026-05-17 17:56:29 +02:00
Alex 5ab9d1c68a feat: implement boss kill methods for fire_lock, hammerdin, fohdin + resolve params.ini merge conflicts
- Add kill_andariel(), kill_countess(), kill_mephisto(), kill_baal(), kill_baal_waves() to fire_lock (warlock), hammerdin, and fohdin (paladin)
- Use build-appropriate attack patterns (deathmark/chaos combos for fire_lock, hammers/FOH for paladins)
- Add configurable attack durations via atk_len_* in params.ini
- Resolve remaining merge conflicts from prebuff cherry-picks
- Add boss run config section: atk_len_andariel, atk_len_countess, atk_len_mephisto, atk_len_baal, atk_len_baal_waves
2026-05-17 15:53:08 +02:00
Alex 15a90bfd47 feat: add route scaffolding tool and contributor guide 2026-05-17 15:22:24 +02:00
Alex 17f32e65b2 feat: add 4 new boss runs (Andariel, Countess, Mephisto, Baal)
Full run implementations with approach/battle methods following the
existing botty pattern. Added 12 Location constants to pather.py,
12 placeholder path nodes to game.ini (coords recorded in-game later),
and 6 new kill_* methods to IChar interface. Updated params.ini
with new route documentation.

Path nodes are 0,0 placeholders — record real coords with
node_recorder.py in-game before enabling these routes.
2026-05-17 14:25:26 +02:00
Alex b397d07baf feat: implement 4 new boss runs (Andariel, Countess, Mephisto, Baal)
Full run implementations following existing botty patterns:
- andariel.py: Act 1 Catacombs L2→L3→L4, waypoint-based approach
- countess.py: Act 1 Forgotten Tower L1→L5 via Black Marsh WP
- mephisto.py: Act 3 Durance of Hate L2→L3 via A3 WP
- baal.py: Act 5 Throne of Destruction, wave clearing + boss

Added 12 Location constants to pather.py and 12 placeholder
path nodes to game.ini (record in-game with node_recorder.py).

Path node coordinates are 0,0 placeholders — must be recorded
in-game before runs can actually execute.
2026-05-17 14:24:46 +02:00
Alex eee99c069b feat(stealth): wire should_skip_run, maybe_afk_break, reshuffle_each_rotation into bot state machine
- on_end_run: calls maybe_afk_break() after returning to town
- run selection loop: checks should_skip_run() before each run
- on_init: reshuffles _do_runs_reset if reshuffle_each_rotation is enabled

Also scaffolded 4 new run stubs: baal, mephisto, andariel, countess
2026-05-17 14:07:01 +02:00
Alex 81ee6557f4 feat: add route scaffolder CLI, smoke tests, stealth docs 2026-05-17 13:26:31 +02:00
Alex f484a9bef1 feat(stealth): add anti-detection layer with wait jitter, click variance, AFK breaks, and route skip 2026-05-17 13:26:26 +02:00
RedJon18 6d19819de5 Prebuff updates and rare items for pickit logic
Updates the prebuffs for paladin to use holy shield before entering Pindleskin's portal. Also, adds additional pickit logic for picking up and storing all rare items when uncommenting the sections.
2026-05-17 13:21:42 +02:00
aeon0 71311cb584 fix not stashing gold if buying sth before 2026-05-17 13:21:14 +02:00
Riddle 5c4f62ac25 Add @cache to functions 2026-05-17 13:18:14 +02:00
Riddle 869de31315 fixed error code 2026-05-17 12:49:00 +02:00
Randi 6f6c663b43 Added eldritch routine to firelock. Also made minor adjustments to a3 error finding stash to reduce error rate. 2026-03-24 22:51:06 -04:00
Randi fdd0fc2230 Adjusted a3_stash_left pic as it could misclick cain on occasion. 2026-03-23 13:58:40 -04:00
Randi 5d5a9c2a63 Made improvements to resolve issues with finding stash in a3. Created left and right stash pictures to reduce issues of being covered. Also implemented move on first failure in an attempt to move merc. 2026-03-23 13:38:41 -04:00
Randi eb75fc9aee Made adjustment to determining if stash is full of gold. Also remade inv_no_gold picture as it would detect numbers starting with 91 as 0. 2026-03-23 12:11:27 -04:00
Randi 600904e6bc Reverted edge case for handling not finding stash. 2026-03-22 21:30:10 -04:00
Randi ce821695e8 Minor tweak to handle case when stash is covered by merc. 2026-03-22 21:17:24 -04:00
Randi 455fe8e64f Minor adjustments to warlock. 2026-03-22 20:44:23 -04:00
Randi f4bc3b7401 Added trav run to fire warlock and added ability to buff in town with consume. 2026-03-22 10:39:23 -04:00
Randi b528957c40 Minor tweak to cta functionity to disable buff_with_cta if cta_available is false. 2026-03-20 21:32:32 -04:00
Randi f8c9d81f52 Minor tweak to static. 2026-03-20 20:32:40 -04:00
Randi 1a5a261f7c Updated stash inventory roi based on warlock exp updates. 2026-03-19 19:53:07 -04:00
Randi 95e019e88d Updated the Run classes to properly reference the _do_run variables so changes to runs in bot.py will persist into Run classes 2026-03-19 19:09:39 -04:00
Randi 466197fd8b Fixed bug where bot would always check stash when gold was full even when stash_gold is disabled. 2026-03-18 00:20:21 -04:00
Randi 4a4bf0300a Added extra failsafe to ensure no keys get left held down when game controller kills bot thread. It was possible that a max length violation could occur while stashing and cauase ctrl and shift to get stuck down. 2026-03-17 20:35:59 -04:00
Randi 953b9aedb3 Corrected transmute to correctly keep track of transmute counter after x games. 2026-03-17 07:38:57 -04:00
Randi 2ce9636d3a Added additional delay after cta to swap weapons 2026-03-17 07:36:41 -04:00
Randi b03b2fd226 Refined cta and buffing so chars now use cast_buffs routine which doesn't need the cta_available logic. This routine also allows the casting delay to be kept separate from cta as the casting_delay is passed in. Failed buffs will now cause bot to exit game. 2026-03-16 20:42:15 -04:00
Randi d96eb2d34c Fixed bug when bot is killed due to max game length violation while transmuting. Transmuting should now complete before game exits. 2026-03-16 19:10:07 -04:00
Randi 5f2149ed1e Removed last node from trav run as it didn't seem necessary for TP and took extra time. 2026-03-16 18:42:24 -04:00
Randi a7509c90e7 Added functionality to transmute flawless gems from the stash gem tab. Works with the transmute every x games variable in params.ini 2026-03-15 23:24:56 -04:00
Randi 8b48b583b9 Fixed issue in which CTA was not properly detected if bot is started with incorrect weapon swap. 2026-03-15 20:13:03 -04:00
Randi 58f761c372 Added logic if doing trav runs we will skip additional runs if juvs are full. 2026-03-15 10:01:39 -04:00
Randi 36d364517b Reduced telek pickup range as it can fail if item is off screen but text is not. 2026-03-14 20:17:03 -04:00
Randi 869eeb5539 Added transmute routine for graphic debugger which requires manual uncommenting. May need to find a more automated way in future. 2026-03-14 08:42:53 -04:00
Randi b2afbaab93 Minor tweaks to pickup 2026-03-13 22:21:47 -04:00
Randi 9512856cfc Refined item pickup to properly tele, use telekinesis, and reduce delays when walking for pickup. 2026-03-13 20:22:25 -04:00
Randi 593e509bc6 Added gheed's wager, horizon boots, and sunders to be picked up. Also fixed error that was causing set and unique names to be improperly reported. 2026-03-11 19:14:51 -04:00
Randi 68ed191efc Made fix to ensure the new warlock expansion uniques would get stashed. 2026-02-27 20:43:31 -05:00
Randi 77925964a0 Fixed in town healing to trigger based on juv settings. Added error case for failed to join game. 2026-02-25 20:34:01 -05:00
Randi 665e6b6ce4 Minor bnip config update to add twink items. 2026-02-20 17:36:47 -05:00
Randi 51306f3067 Fixed the old graphics debugger. 2026-02-20 13:55:35 -05:00
Randi c47d9573ad Updated pick up code to accept red text to allow worldstone shards to be picked up. 2026-02-20 10:41:02 -05:00
Randi bbe5395f4a Added worldstone shards to be stashed. 2026-02-19 23:38:50 -05:00
Randi 6f7a9b681d Added all unique grimoires to default bnip config file. 2026-02-17 22:39:49 -05:00
Randi ed0a8270cf Added grimories to bnip files. 2026-02-17 22:22:14 -05:00
Randi 4b3a47b13c Updated bnip_data.py to add abyss skill to bnip. 2026-02-16 22:08:47 -05:00
Randi 6f4f4ca472 Updated bnip files to support warlock skillers. 2026-02-16 21:55:48 -05:00
Randi 55f7d86b3d Tweaked stash gold button roi as it moved in expansion. 2026-02-16 16:33:40 -05:00
Randi 01f03ea9af Handle the error case if save_and_exit fails. 2026-02-16 15:04:00 -05:00
Randi 82ac44c4c1 Minor change to abyss warlock targeting on pindle. 2026-02-15 22:24:13 -05:00
Randi 65ee5a6b5c Updated bnip for echo strike bases 2026-02-15 21:51:19 -05:00
Randi b7c83e6208 Added preliminary warlock characters for bot. 2026-02-15 20:49:12 -05:00
Randi f2c639fc64 Minor fix to a typo for void base entry in bnip 2026-02-15 18:58:08 -05:00
Randi 0978258513 Minor fix to bnip. 2026-02-15 15:19:06 -05:00
Randi b243aec74f Added void base to bnip 2026-02-15 14:24:31 -05:00
Randi ec5a7e4292 Fixed issue with a chicken not counting as a failed game. 2026-02-15 09:54:48 -05:00
Randi 4852ef9e3a Adjusted fast save and exit to work properly with new loot filter buttons 2026-02-15 09:36:51 -05:00
Randi d7a1d65348 Minor cleanup with tabs, and added a few entries to bnip. 2026-02-15 09:12:57 -05:00
Randi 758a0a3db8 Missed adding the transmute.py file in last commit for tabs. 2026-02-14 23:39:35 -05:00
Randi b27911adae Updated stash tabs to work with Warlock expansion. 2026-02-14 23:26:15 -05:00
Randi 43e5a8ecab Fixed the missing string issue and inventory tab names. 2026-02-14 20:17:05 -05:00
Randi b52ed15079 Updated barbarian prebuff delays, horking, and added howling. 2025-11-15 19:05:18 -05:00
Randi c82051f276 Adjusted barbarian to use leap attack skill. 2025-11-15 15:39:57 -05:00
Randi 6fc80f0a96 Fixed fast_save_and_exit routine if menu was alreay openned. 2025-11-15 14:17:54 -05:00
Randi 2da55e138c Added fast save/exit for game controller and synchronized exit with health manager. 2025-11-12 19:36:06 -05:00
Randi 5cbf7ea366 Removed synchronizatino of exit routine as it can cause issues due to threads getting terminated. 2025-11-11 21:55:53 -05:00
Randi a2d27fd4c3 Prevent chicken from being called twice in one loop. 2025-11-11 08:09:03 -05:00
Randi be446fc9d9 Minor comment update. 2025-11-10 23:34:30 -05:00
Randi 4b93a50927 Updated uses between juvs to be 16frames, the max recovery time, to avoid wasted juvs. 2025-11-10 22:49:37 -05:00
Randi 76cbe0abbc Synchronized the exit routines so two threads exiting the game don't stomp on each other. 2025-11-10 21:03:48 -05:00
Randi a54b674ce6 Updated chicken to save and exit faster. 2025-11-10 20:23:03 -05:00
Randi 11440a3d24 Hardcoded numpy in environment.yml as latest version causes issue. 2025-11-08 11:15:49 -05:00
Randi 5f478a6884 Updated development.md to reflect the correct git location for this fork. 2025-11-08 10:49:03 -05:00
Randi fb2edcf70a Minor fixes and tweaks to trav path. 2025-11-07 21:22:54 -05:00
Randi ed2a921d9e Fixed bug where bad inventory check would cause thread exception. 2025-11-07 21:22:13 -05:00
Randi ba8a412309 Updated item distance to make tele pickup further away as it is not reliable when items bunch up. 2025-11-07 21:21:09 -05:00
Randi 5d42a46891 Added trav attack routine for blizzorb sorc. 2024-09-14 21:18:19 -04:00
Randi c13367f221 Added large charms to bnip file for early ladder season. 2024-09-13 22:37:37 -04:00
Randi c94be67727 Minor tweak to nova sorc trav run. 2024-09-13 22:36:53 -04:00
Randi 1e8bb16a22 Added large charms to bnip for early ladder season. 2024-09-13 20:15:19 -04:00
Randi 3e87fe9d6f Simplified nova trav attack pattern and made it quicker. 2024-09-13 20:03:35 -04:00
Randi b517a80bea Fixed gull dagger in bnip. 2024-09-11 21:26:29 -04:00
Randi b2938e6297 Added crescent moon and doom bases to bnip file. 2024-09-11 20:46:44 -04:00
Randi 3a96bf69cc Enabled frostburns in pickit for early ladder season 2024-09-11 20:35:43 -04:00
Randi 429a1cd4ae Removed uneccesary statics from nova sorc pindle/trav runs. 2024-09-11 20:28:23 -04:00
Randi dab2fd9259 Fixed bug in bnip file that discarded war travs and death's fathom. Also enabled all early ladder season items. 2024-09-11 20:25:33 -04:00
Randi 8048d87222 Minor config file updates 2024-08-25 21:19:25 -04:00
Randi edcefbe62c Added config updates for blizzorb sorc. 2024-08-23 18:22:22 -04:00
Randi aea75aa417 Minor trapsin changes. 2024-08-23 18:19:50 -04:00
Randi 30d407e978 Reworked trapsin a bit to include casting/attack delays between skills. Also added mindblast and added to pindle run. 2024-06-26 19:59:50 -04:00
Randi 8df42bbcb1 Added attack frames into config.py 2024-06-24 22:04:58 -04:00
Randi da396208f0 Added attack frames to config and character class. 2024-06-24 21:02:34 -04:00
Randi 466c698b1d Updated Anya shopper to properly filter on +3 3/20 gloves. Also added MA 3/20 gloves in addition to the current jav gloves. 2024-06-24 20:54:15 -04:00
Randi 58bc20ce0e Made fixes to anya shop for shopping 3/20 jav gloves as previous implementation used old font which didn't work. 2024-06-20 19:50:53 -04:00
Randi 25fdd5485d Added action frame to paladin for accurate timeing with foh. Also added prelimnary foh clear screen sequence. 2024-06-18 19:51:25 -04:00
Randi bfccf60a07 Added testing attack routines for cs and summoner for blizzorb. 2024-06-18 19:42:32 -04:00
Randi 8be1223e32 Added javazon 2024-06-18 00:25:16 -04:00
Randi df1259f87c Fixed bug where health manager would drink rejuv back-to-back. 2024-06-16 20:32:49 -04:00
Randi 1ca3578e06 minor bug fixes to vizier run 2024-06-16 13:25:55 -04:00
Randi 3c70214ca9 Cleaned up the vizier runa and removed commented code. 2024-06-16 12:33:20 -04:00
Randi 8c44d7ad17 Added new vizier run to just kill vizier is cs, as diablo run has high failure rate. 2024-06-16 12:27:33 -04:00
Randi 4199705fe8 Expanded scope of thread lock in screen::grab() method. 2024-06-13 19:59:35 -04:00
Randi 7141e671d1 Fixed issue in which tele paladin would occasionally walk from eldritch to shenk. 2024-06-13 19:57:24 -04:00
Randi c20ec7343c Minor tweaks to blizzorb sorcs offsets for attacks. Also added in summoner attack routine. 2024-06-12 23:45:27 -04:00
Randi 9a714b969e Made fix to pickit in which it did not properly read physical damage reduction attributes. Caused automatic discard for ss, verdungo, soe etc. 2024-06-12 23:40:09 -04:00
Randi d518389493 Added shenk and nilathak runs to blizzorb sorc. 2024-06-11 21:53:00 -04:00
Randi c6f81c70a6 Fixed bug with health manager that would cause unintended chicken on rejuv use. 2024-06-11 21:51:25 -04:00
Randi 70659b7544 Added new blizzorb sorc that specializes in comboing blizzard with frozen orb. 2024-06-11 19:32:56 -04:00
Randi aa56bbc484 Made fix to paladin.py to support wait_tp parameter in overriden pre_move() method. 2024-06-09 15:39:34 -04:00
Randi 901592a54a Fixed an issue with hammerdin overriden pre_move() method which was missing wait_tp variable. 2024-06-09 14:29:34 -04:00
Randi a51db00a15 Updated pickit to remove edge-case it which last item checked will not attempt retries for pickups. Updated health_manager to never skip chicken check. Also added chicken conditions when out of juvs, or if juvs are used in rapid succession. 2024-06-07 15:24:03 -04:00
Randi 0197298e31 Ensure foh does not have holybolt selected when walking as it causes targeting issues with merc. 2024-06-06 00:46:17 -04:00
Randi a4dada9237 Make fohdin suck less against pindle. 2024-06-05 20:34:37 -04:00
Randi 6b2f719605 Tweaked env file. 2024-05-25 13:24:34 -04:00
Randi ed70c8e688 Tried to fixed issue of failed teleport at start. Fixed issue that prevented potions from being picked up. Fixed item inspection issue with tooltip. 2024-05-23 19:33:11 -04:00
Randi f68ebf0861 Cleaned up readme and development.md with new instructions based on fork. 2024-05-20 13:29:21 -04:00
Randi 39788df29c Set params.ini to match sorc. Updated environment.yml to set dependencies on package versions such as mss 7.0.1. Updated discord_embeds.py to work with latest discord version. Updated save_exit button image. Updated char_state image and roi. 2024-05-19 21:44:00 -04:00
aeon0 f1ea45ce2a Update README.md 2022-07-01 15:06:32 +02:00
aeon0 31a0579f65 Update README.md 2022-07-01 06:47:53 +02:00
aeon0 ad8ea13444 Update README.md 2022-07-01 06:47:23 +02:00
aeon0 5df97c4a7e Update README.md 2022-07-01 06:46:51 +02:00
Legit f5538916fe Merge pull request #958 from noblesigma/master
Update location
2022-06-30 09:35:30 -05:00
noblesigma d7be49edd7 Update location 2022-06-30 07:38:55 -04:00
Riddle 6e10c549e4 Merge pull request #954 from definitelynotsosa/patch-8
Update default.bnip
2022-06-28 06:07:42 -04:00
Sosa 656e52ffff Update default.bnip
Fixing Natures Peace Ring line
2022-06-28 01:51:14 -04:00
mgleed 8c9e98ebd8 add a couple mouse waits 2022-06-27 18:35:36 -04:00
Gleed da09cb820a Feature: More descriptive pather.py output when run from src, support list of template patterns 2022-06-27 15:47:22 -04:00
Legit d45d974280 Merge pull request #949 from definitelynotsosa/patch-7
Update default.bnip
2022-06-26 16:54:50 -05:00
Sosa 613d4f0ff3 Update default.bnip
Minor fix
Corrected Magic Necrohead line
2022-06-26 17:47:17 -04:00
Riddle 8f4942a3a2 Merge pull request #948 from bottytools/bnip-incorrect-reading
fixes #936
2022-06-26 10:54:11 -04:00
Riddle ef34efdd54 Merge branch 'master' of https://github.com/aeon0/botty 2022-06-26 10:52:13 -04:00
Riddle 9886f2ee96 fixes #936 2022-06-26 10:52:07 -04:00
Riddle 3e4c0d8fa5 Merge pull request #947 from bottytools/encode-bnip-files
Add encoding to .bnip files
2022-06-26 07:36:46 -04:00
Riddle f72856a8bd Add encoding to .bnip files 2022-06-26 06:26:23 -04:00
mgleed 980a8f5036 get rid of redundant id_items param 2022-06-24 20:28:41 -04:00
Riddle 9f1a4772cd Merge pull request #926 from bottytools/nip-to-bnip
Replace nip with bnip
2022-06-24 13:37:19 -04:00
Riddle c68d92c8e1 Merge branch 'master' of https://github.com/aeon0/botty into nip-to-bnip 2022-06-24 13:36:53 -04:00
Riddle 076737672e Merge branch 'master' into nip-to-bnip 2022-06-24 13:36:31 -04:00
Gleed 689a93a3f7 Bugfix: Make character name OCR not freeze program if fails, also improved read 2022-06-23 17:01:45 -04:00
mgleed 9ed7869ddd fix typo 👀 2022-06-23 15:13:10 -04:00
Gleed c62c237442 Bugfix: template_finder.search_all() messing with input arguments (#931)
* init

* remove print
2022-06-23 14:53:58 -04:00
Legit 4e10dbb2c7 Updated staves and nip errors (#932)
Corrected white staves and other syntax errors.
2022-06-23 14:49:45 -04:00
Gleed 197ff41e69 Fix Fix: template_finder.search() tests were terminating after first "assert" 2022-06-23 13:42:39 -04:00
Wang Xiang 5089abaca6 Update default.nip Shadowplates (#927)
Add expressions for Shadowplates in Armor Bases section.
2022-06-23 07:13:59 -04:00
jobithu 8469d51f0c Merge pull request #928 from xw220/improve/diablo_sealdance
Update diablo.py _sealdance() -reviewed and approved. also implemented for PR867
2022-06-23 13:11:25 +02:00
Wang Xiang 9b2d52a39b Update diablo.py _sealdance()
I watched 10 hours of diablo run by 4 fohdins. About 30% were fail games which aborted in middle run, especially on detecting that if the seal is openned.  In almost every fail game caused by this reason, the seal was openned successfully, but the decisions were closed for 5 times and the game was aborted. By increasing the numbers of try and reduce the seal_opentemplates threshold to 0.7, the incorrect judgements on seal's open status seldom occur, and the ratio of failed games typically reduced. Now it is about 12% mostly caused by temporary high latency or getting lost after teleport to pick item.
2022-06-23 17:51:40 +08:00
jagarop d95b581dae Merge pull request #920 from definitelynotsosa/patch-5
Update default.nip
2022-06-22 09:42:54 +00:00
Riddle 759c4fff82 Remove the test321.. 2022-06-22 05:39:06 -04:00
Riddle d5bdb769b3 Replace nip with bnip 2022-06-22 05:37:54 -04:00
Riddle 8a1a15d77d Merge pull request #925 from bottytools/nip-error-update
Added better expections for bnip
2022-06-22 04:41:16 -04:00
Riddle 24d2da8e67 Added better expections for bnip 2022-06-22 04:24:04 -04:00
aeon0 6d1779ea5f fix not stashing gold if buying sth before (#922) 2022-06-22 09:59:14 +02:00
Riddle 0cbc5f759e Merge pull request #924 from bottytools/nip-type-checking
fixed liner errors for nip files
2022-06-22 02:57:01 -04:00
Riddle ce1d99bfd8 fixed liner errors 2022-06-22 02:47:54 -04:00
Riddle 257d687166 Merge pull request #923 from bottytools/nip-fix-subtraction-2
fixed
2022-06-22 02:30:27 -04:00
Riddle cfc192e1dc fixed 2022-06-22 02:28:47 -04:00
Riddle 161b9226fb Merge pull request #921 from bottytools/nip-ntipaliasstatkeyword-fix
Nip ntipaliasstatkeyword fix
2022-06-22 02:27:11 -04:00
Riddle 46b8d9bf17 Remove prints / replace ntipaliasvalue to use keyword 2022-06-22 02:17:32 -04:00
Riddle 9faa3fd25a forgot to replace in transpile.py 2022-06-22 02:10:06 -04:00
Riddle bca0471d9f removed print statements 2022-06-22 01:01:40 -04:00
Riddle 5610490db6 removed print statements 2022-06-22 01:01:23 -04:00
Riddle 5efebd0bb7 fixed missing keyword... o-o 2022-06-22 01:00:13 -04:00
Sosa 81bc9028d1 Update default.nip
Fixing white claw bases
2022-06-22 00:43:49 -04:00
Gleed 3de9f6db93 Bugfix: Pickit IndexError 2022-06-21 22:33:27 -04:00
mgleed 0f08cd8e93 bump version 2022-06-21 20:07:25 -04:00
mgleed ea77ac5fe7 Merge branch 'master' of https://github.com/bottytools/botty 2022-06-21 18:58:27 -04:00
mgleed 1df9e0a28f update test assets url 2022-06-21 18:58:15 -04:00
Sosa 54316a1eac Update default.nip (#918)
Fixed Stormshield using wrong mod for damage reduction
Fixed Crown of Ages using wrong mod for damage reduction
Added +Skill to Arkaine's Valor Perfect
Added Damage Reduction mod for Leviathan Perfect
2022-06-21 14:35:07 -04:00
Riddle 76b911f50f Merge pull request #917 from aeon0/nip-fix-subtraction
fixed subtraction for nip expressions
2022-06-21 12:31:47 -04:00
Riddle 5b9c56a2c6 fixed subtraction for nip expressions 2022-06-21 12:20:21 -04:00
Gleed 2b2de1baf3 Bugfix: Ignore merc death if merc chicken off (#916)
* init

* save as...

* move timer
2022-06-21 09:57:46 -04:00
Gleed 0e800cc3e2 Bugfix: pather passing floats that should be ints 2022-06-21 08:58:07 -04:00
Legit 42639c8273 Fix: /nopickup not working (#912)
No pickup was turned off permanently by mistake.
2022-06-21 08:14:55 -04:00
Riddle 9a5ee8cd5e Merge pull request #913 from aeon0/nip-fix-division
fix for divison
2022-06-21 06:57:56 -04:00
Riddle e6b65a6a10 fix for divison 2022-06-21 06:31:57 -04:00
Gleed 5597df55ca Fix: find_nearest_nonzero() NoneType error 2022-06-20 18:28:01 -04:00
Sosaandmgleed dc75cce5dc Enhancement/bugfix: Corrections for default.nip (#906)
* Corrections for default.nip

Corrected Chipped Amethyst
Corrected Bow sockets (Mist Runeword)
Corrected [Quality] issue on base items

Added Cryptic & Mythical Swords (Plague Bases)

* fix >=

Co-authored-by: mgleed <[email protected]>
2022-06-19 15:22:51 -04:00
Gleed 4a0396fe81 Enhancement: Replace pather.adjust_abs_range_to_screen() with ui_manager.get_closest_non_hud_pixel() (#908) 2022-06-19 15:06:15 -04:00
aeon0 0f34b4951c Fix bug that char will not id items even if supposed to (#901) 2022-06-18 17:42:05 +02:00
Riddle d7f776ad37 Merge pull request #899 from aeon0/nip-error-fix-2
Better error message
2022-06-18 01:48:23 -04:00
Riddle 723a75e672 Better error message 2022-06-18 01:46:58 -04:00
Gleed 541810f2e3 Revert "Bugfix?: give more time for select_tp() for detect capabilities (#895)" (#898)
This reverts commit 1c07b74f79.
2022-06-17 22:06:31 -04:00
Riddle e9b5cf6dc5 Merge pull request #897 from aeon0/nip-error-fix-2
Nip error fix 2
2022-06-17 22:04:29 -04:00
Riddle 4b2e1f7059 Better error message 2022-06-17 22:03:50 -04:00
Riddle 6d43868b4d added error msg 2022-06-17 22:00:50 -04:00
Gleed 1c07b74f79 Bugfix?: give more time for select_tp() for detect capabilities (#895) 2022-06-17 20:47:53 -04:00
Riddle 4deed0867a Merge pull request #896 from aeon0/nip-indexerror-fix
fix
2022-06-17 20:33:05 -04:00
Riddle 99579bfda4 fix 2022-06-17 20:06:09 -04:00
Gleed cb1f443d23 Fix tests failing on d2r_path validation 2022-06-17 16:31:10 -04:00
Riddle e890be4b38 Merge pull request #893 from aeon0/add-missing-nip-data
Add missing nip data
2022-06-17 16:10:41 -04:00
Riddle 2d3deb74ae added nip data 2022-06-17 15:58:56 -04:00
Gleed 0acd6d8cc9 Enhancement: Ensure d2r_path exists before starting Botty 2022-06-17 15:51:33 -04:00
Sosa d77ad0dc7c Update default.nip (#889)
Fixed B.O Helm Line
Added Griffon's Eye
Added Kira's Guardian
2022-06-17 15:37:10 -04:00
Gleed 8bc909eb72 Bugfix: Fix launch options (#891)
* init

* fix launch_options
2022-06-17 15:36:51 -04:00
Gleed 329f4fcb5c Bugfix: Character name -> mod directory name support 2022-06-17 15:17:09 -04:00
Gleed 5fd89b5b6b Update dev.md 2022-06-17 10:32:17 -04:00
Gleed f9780c5942 Bugfix: Build process (#887)
* Bump version to v0.8.0

* Bump version to v0.8.0

* init

* vers
2022-06-17 10:00:05 -04:00
Gleed d895dd0b40 Fix: bump version and fix build.py (#885) 2022-06-16 22:18:42 -04:00
Gleed a786ba4f08 Fix: max quantity in readme (#884) 2022-06-16 22:18:25 -04:00
RiddleandRiddle fe94a012eb Fixed bug with @ next to paren throwing error (#883)
Co-authored-by: Riddle <[email protected]>
2022-06-16 18:20:49 -04:00
Riddle 9d4c8681ca Fixed bug with @ next to paren throwing error 2022-06-16 18:00:30 -04:00
Gleed 8a31454a4c Bugfix: Handle base item miscorrecting an item to Gold (#880)
* init

* add condition
2022-06-16 17:09:57 -04:00
Gleed f7297fce3c Bugfix: Help botty find Shenk nodes near Eldritch 2022-06-16 17:09:43 -04:00
Riddle 28067f0c94 Merge pull request #881 from aeon0/nip-expression-notfi
Nip expression notfications
2022-06-16 16:20:43 -04:00
Riddle 86d2cc32e7 update readme 2022-06-16 16:19:10 -04:00
Riddle 82ec22fa69 @ will now surpress notifications 2022-06-16 16:14:09 -04:00
Riddle eb0917c4e7 only send when @ in expression[0] 2022-06-16 15:58:09 -04:00
Riddle 5f86424c4a Add/create notication token 2022-06-16 15:52:41 -04:00
Gleed 487d113432 init (#877) 2022-06-16 13:29:10 -04:00
Gleed 21a79272ea Bugfix: Esc/close space on common.close() (#876)
* init

* more robust inventory close() logic, added asset

* leave health manager, probably better performance
2022-06-16 13:28:52 -04:00
Gleed 410d13c764 init (#875) 2022-06-16 13:28:31 -04:00
Gleed 5127417bd3 Major feature: NTIP pickit syntax integration, OCR pickit, OCR item property filtering (#724)
By @Riddle1001 @Ezro @mgleed @D2RLegit Sosa
2022-06-16 09:46:14 -04:00
Gleed e1c461e3b2 Revert: paladin timeout on trav 2022-06-15 21:19:53 -04:00
Gleed 3b3282acea Bugfix: Tesserocr dll version compatibility (#873)
* init

* save
2022-06-15 20:56:43 -04:00
mgleed 7426e79504 Params config readme cleanup (#870)
* Bump version to v0.7.4

* init

* fix missing |'s

* Update README.md
2022-06-14 17:01:50 -04:00
mgleed 5bceafec8b Bugfix: Hammerdin and FOHdin small fixes, inappropriate vigor casting, etc (#868)
* fixes

* increase timeouts to 3.2...pather is hacky
2022-06-14 14:55:55 -04:00
mgleed 3d004062d7 Bugfix: Character select screen, character not found (#869)
* init

* adjust

* should work on nip br this way
2022-06-14 14:55:43 -04:00
mgleed 0fcddd2aed Enhancement: Reposition teleport and rename tp to town_portal in params 2022-06-13 13:46:19 -04:00
mgleed 237dfd6f34 Bugfix: hammerdin config inheritance 2022-06-12 22:38:58 -04:00
jobithuandmgleed 70debc2b0d Major feature: FOHdin, Chaos Sanctuary (#765)
* Setting Up FOHdin for CS

* replaced hammers with FOH, but not targeted yet

* finish merging

* demo

* implemented all runs. avoid nihlatak.

* replaced FOH with Hammer for Nihl

* using hammers for dia now

* reverted dia hammers to FOH, so pure FOH runs CS

* added non mob-detection attacks to trav

* some tweaks

* tweaked hammer pindle for tele amu

* improved pindle for walker FOHdin

* Pindle, Eld, Shenk, CS tweaked. Trav needs work.

* fix NoneType error if nodes aren't found

* consolidate trav code

* small adjustment

* increase attack duration in loop condition rather than attack sequence

* pindle optimizations

* optimizations of pindle, eld, shenk

* more optimizations, trav still kinda ghetto

* update target detect to include closer targets

* implement concentration with holy bolt

* nihlathak and summoner

* revised CS trash atk pattern

* tweaked sealbosses!

* CS ready for pressure tests

* implement in-chaos pickit, match/case logic over if/elif, consolidate more functions, move some to i_char.py, patch health_manager.py to prevent it from closing inventory, update inspect_items() to allow items to be dropped and not kept to be sold

* revert change

* reserve hammerdin changes for a separate PR

* get rid of extra attack sequence

* disable target/attack logs for merge

* code cleanup

Co-authored-by: mgleed <[email protected]>
2022-06-12 15:44:54 -04:00
mgleed 241fc15269 Enhancement: Debug screenshots for character select failures (#860)
* init

* simplify

* timestamp constant
2022-06-12 15:09:15 -04:00
mgleed 16a9832af0 Bugfix: update active character template 2022-06-12 14:18:46 -04:00
jobithuandmgleed 94f6c82560 Hdin pindle tele charges (#856)
* added tele charges to pindle

* hdin pindle now uses tele charges

* separated native from charges

* True!

* delete unnecessary keyboard.send()

Co-authored-by: mgleed <[email protected]>
2022-06-12 12:05:45 -04:00
mgleed 6eebe281ac Bugfix: update node 300 on trav (#858) 2022-06-12 12:04:02 -04:00
mgleed bd092bd8d2 small error adjustments (#852) 2022-06-10 22:05:57 -04:00
NeoIsrafil cdd16dbb92 Enhancement: Sazabi set
* Add files via upload

Sazabis sword found to add since its decent for barb fury mercs.

* Update pickit.ini

Adds sazabi sword to pickit so users can turn it on if they want it.

* Update pickit.ini

* Add files via upload

sazabi helmet for addition to complete sazabi set

* Add files via upload

there, the pngs.  I don't know why I missed them the first time....sorry bout that

* Add files via upload

* Delete set_sazabi_sword.png

* Delete set_sazabi_helmet.JPG

* Delete set_sazabi_helmet.png

* Delete set_sazabi_sword.JPG

* Add files via upload

Fixed images
2022-06-10 22:01:00 -04:00
mgleed 0870384b8d Feature: Warn users if non-ascii chars in botty path, windows username, or D2R path (#843) 2022-06-08 15:31:57 -04:00
mgleed bcea0129ba Bugfix: NoneType messages if api or hook not set (#842) 2022-06-08 11:31:12 -04:00
mgleed 8989738c58 Bugfix: game recovery if unable to create game (#841)
* bugfix: game recovery if unable to create game

* fix on_init() error, add error msg
2022-06-08 11:30:57 -04:00
roozhouandmgleed b457877623 Bugfix: Select online tab before creating game when d2r switch to offline tab automatically (#834)
* BugFix: Select online tab when server disconnected

Issue #789

* Simplify online/offline tab selection logic

* more robust recovery, reusable restart_or_exit() fn in main, move attempts logic, remove param, etc.

Co-authored-by: mgleed <[email protected]>
2022-06-07 22:12:53 -04:00
Wang Xiangandmgleed d047886630 Bugfix: generic_api (#836)
* Fix generic_api

generic_api.py supports custom_loot_message_hook now.

* Simplified logic

Co-authored-by: mgleed <[email protected]>
2022-06-07 14:31:54 -04:00
Legitandmgleed 54888942f5 Bugfix: Better pathing for walkers in trav (#790)
* Better pathing for walkers in trav

* Add files via upload

* trim a few templates

* re-add column asset, utilize another v2 asset

* fix tab/space issue

Co-authored-by: mgleed <[email protected]>
2022-06-07 00:00:04 -04:00
badbrad2889andmgleed 129c00ac44 Feature: Support transmute of all gem quality (chipped, etc.) (#736)
* Added the ability to transmute all gem types and select in params.ini

* Added the assets

* Updated STD to standard for transmute and updated ini for list style

* Changed the assets to standard

* changed list in INI to run only flawless by default

* Optimized the transmute: will only need to go through search once

* update tab selection

* Update params.ini

Co-authored-by: mgleed <[email protected]>
2022-06-06 23:27:13 -04:00
mgleed f7ea236823 Bugfix: character select active asset ignored hardcore characters (#838) 2022-06-06 21:53:35 -04:00
RiddleandRiddle f94bd16b2b Enhancement: Catch missing config params (#835)
Co-authored-by: Riddle <[email protected]>
2022-06-06 20:57:29 -04:00
mgleed 8db079f720 Bugfix: Reduce identify time at cain (#837) 2022-06-06 20:55:46 -04:00
aeon0andmgleed 084bdb6573 feat/cached-img (#734)
* feat/cached-img

* thread safe

* update

* add a force_new param for grab() and enable it for pather, which is more dependent on exact current frame

* use existing img for pather screen object checks

Co-authored-by: mgleed <[email protected]>
2022-06-06 18:07:10 -04:00
Legitandmgleed ac3e79401b Enhancement: Make Nopickup command optional (#819)
* Making Nopickup command optional

* Update bot.py

* Update config.py

* set default on, rework logic

Co-authored-by: mgleed <[email protected]>
2022-06-06 13:39:31 -04:00
reqyl baa6bf0e9b Enhancement: Optimize trav (#829)
* Small optimization by know if current run is last

* Tele amu optimization

Prefer to not use tele changes when getting back inside to loot.
Only use tele charge if pathway was blocked.

This change makes bot use a less tele charges, and thereby improve run speed due to not having to repair as often.

* Pass whole list of runs instead of just last one

This would allow to e.g check first run / only run etc
2022-06-06 11:16:58 -04:00
Legitandmgleed f0c6d5a6b7 Bugfix: getting stuck at act 2 portal location
* Updates act 2 template

* Add files via upload

* Delete a2_town_27.png

* Delete a2_town_22.png

* Add files via upload

* Delete a2_town_20.png

* Add files via upload

* Add files via upload

* Delete a2_town_22.png

* Add files via upload

* Update a2.py

* Update params.ini

* remove guy with shadow. asset already existed and added

Co-authored-by: mgleed <[email protected]>
2022-06-06 11:16:03 -04:00
roozhou fd7294b895 Bugfix: Random guess should be random (#833) 2022-06-06 06:30:45 -04:00
roozhou 7e700ad75e Move _lerp function to i_char.py (#832) 2022-06-06 06:28:42 -04:00
mgleed fcaffc5cf2 Bugfix: Launch options and game recovery 2022-06-05 10:28:03 -04:00
mgleedandaeon0 3e6f9a9bf1 Migrate from Python 3.9 to 3.10 (#826)
* migrate from python 3.9 to 3.10, recompiled tesserocr

* cleanup old types, change all Unions to |

* add a few match/case statements

* Update ci.yml

Co-authored-by: aeon0 <[email protected]>
2022-06-05 08:01:28 -04:00
Riddle 700e7e23b2 Merge pull request #824 from aeon0/fix-pather-main-fn
Bugfix: Update pather _main_ function for recent template_finder update
2022-06-01 13:12:50 -04:00
mgleed d41771a6c4 fix 2022-05-31 21:24:29 -04:00
jagarop 58d2834949 Merge pull request #814 from Aimware0/master
Updated readme for contributions
2022-05-30 13:23:33 -03:00
Riddle 215e589438 Updated readme for contributions 2022-05-29 20:09:12 -04:00
Legitandmgleed cf7eaa6d09 Bugfix: Non-UTF-8 characters in corpse pickup text caused corpse to be missed
* Update to corpse pickup

* Add files via upload

* Update ui_manager.py

Co-authored-by: mgleed <[email protected]>
2022-05-20 22:51:01 -04:00
mgleed a30039bc9e Bugfix: Multiple item detect by shoppers 2022-05-18 01:59:49 -04:00
mgleed 27ebd1b4db Refactor: TemplateFinder() (#770)
* init, wip

* time to test

* remove unused dataclass

* tests passing, just need to run in-game

* fix wait logic

* add threading lock, delete excess funcs

* start putting best_match back in to search_and_wait()

* bugfixes, found a bad template

* scope

* fix npc detect
2022-05-18 01:35:27 -04:00
egut125 203dce6775 Include file in discord embed (#780) 2022-05-18 01:07:51 -04:00
egut125 63b761b5dc Feature: Separate generic and loot discord message webhooks (#729)
* New param custom_loot_message_hook

* Loot web hook fixes
2022-05-14 05:50:56 -04:00
mgleed 580d9c6253 Bugfix: Revert keyboard save/exit 2022-05-14 05:32:51 -04:00
Legit fdc25d6c4d Speed up nihlathak wait to reduce chickens/deaths (#769)
Speed up nihlathak wait timers to reduce chickens/deaths
2022-05-13 21:26:51 -04:00
mgleed 99778ea51f Refactor: Use class objects for mobs for mob checking (#767)
* init, wip

* refactor mob_check, wip

* update hammerdin

* fix hammerdin
2022-05-13 16:18:13 -04:00
mgleed 3e6521c2e6 Bugfix: Fix local pather pytest, update log to accommodate mob detect change (#766)
* init

* fix

* refactor
2022-05-13 16:15:43 -04:00
jobithuandmgleed 648d42ed84 Feature: Mob Detection for Chaos Sanctuary Hammerdin (#598)
* added mob detection to CS to speed up runs

* refactoring - redemption does not work

* remove unused filterimage param for template_finder.search_and_wait

* get rid of selfs, add live view within mob_detection.py

* mobcheck(self) -> mobcheck()

* cleanup, img as an arg to mobcheck

* prefix functions for encapsulation, cleanup redundant code

* simplify further

* trim

* simplify live-viewer, move

* corrected liveviewer -- opencv hue ranges to 180 not to 255

* rename funcs

* consolidate live-view into target_detect.py

* silly ide

* fix nonetype error

fox nonetype error - but no mobs are detected anymore :(

* script runs, but fails to deteect mobs

* add pytest for target detection, fix target sorting

* revert info_ss

* running now! added "mercwait" to debug runtime

* added testing back to pather.py

* update pytest, discrete blue/green filtering, cleanup code

* fix NoneType, add negative test

* consolidate tests

* fix oopsie

* add config param

* fix config param

* fixed atk sequences & logging spam

ready to merge after my final 2 tests

* undo bad import

Co-authored-by: mgleed <[email protected]>
2022-05-12 07:03:29 -04:00
egut125andmgleed 328ff67a4b Feature: Hydra Sorc (#730)
* New Hydra Build

Only runs pindle shenk eld so far

* Adjust hydra sorc to use any alt skill on right click

* Lowered spray

* Update config/params.ini

Co-authored-by: mgleed <[email protected]>
2022-05-11 04:18:51 -04:00
Legit f3d6677ef2 Bugfix: keyboard exit bug (#755)
* Fixing fast exit bug

* Update view.py

* Update view.py

* Update view.py
2022-05-09 19:26:52 -04:00
drallcom3 bbc183e82e Enhancement: Make log chicken an option (#743)
* Make log chicken an option

It can produce a lot of spam for low level bots.

* Game stats fix

Chicken wasn't counted in the report anymore.

* Bugfix
2022-05-09 05:11:35 -04:00
mgleed e879514846 Tests: Added template match tests (#753)
* init

* rename vars

* fix best match

* update per review
2022-05-09 05:00:15 -04:00
slapchop58 0e15b7ccdb Feature: Bone necro (#727)
* Added bone necro char

* Added damage_scaling option

* adjusted some targeting

* Removed colored logging statements, documented damaage_scaling option, and moved its usage to the base class i_char
2022-05-09 04:24:08 -04:00
Legit 5bdc6caa13 Bugfix: Lowered Eldritch End node (#726)
* Lowered Eldritch End node

Need verification doesnt impact hdin or light sorc.

* Fixed light sorc for new node change
2022-05-09 04:16:13 -04:00
roozhou 376fb05225 Enhancement: Faster save and exit using keyboard (#697)
* Enhancement: Faster save and exit using keyboard

* Enhancement: faster chicken

1) Remove delay among key/mouse release (human can do it simutaneously
2) Save screenshot after save_and_exit
2022-05-09 04:07:48 -04:00
aeon0 886fc88816 fix: Release shift in case of out of gold (#740) 2022-05-01 00:56:42 +02:00
SdxHex e156671b17 Bugfix: added CTA to basic and Range (#737)
Basic and range can now buff with CTA as well as use class buffs
2022-04-27 16:40:21 -04:00
roozhou ea5071cf85 BugFix: Do not write ANSI color codes to info.log (#733) 2022-04-23 15:33:25 -04:00
mgleed a15f7207fe Bugfix: Cleanup assets at bottom of shenk stairs, add two more templates 2022-04-23 15:21:10 -04:00
aeon0 e0e0ff01f1 Update docs for new run logic 2022-04-21 08:19:08 +02:00
mgleed 20f59028e2 bump (#721) 2022-04-20 20:19:34 -04:00
mgleed 7bc34a7b2f bump version (#720) 2022-04-20 20:01:03 -04:00
mgleedandaeon0 2dc1356cf7 Bugfixes: A2 TP stuck, also recapture some templates for d2r v2.4
* add _capture_template switch to template_finder.py _main function, replace eldritch templates

* update some trav templates

* update template_finder.py, update act 3 town templates

* update missing Eldritch templates

* add redudant eldritch templates and update nodes

* update shenk templates

* update trav assets, add redundant assets w nodes

* bugfix: a2 tp out of range of a2 templates

Co-authored-by: aeon0 <[email protected]>
2022-04-20 19:06:55 -04:00
mgleed ae0ab54efe Bugfix: Cain loop, etc. with return_to_play() function 2022-04-20 19:05:37 -04:00
mgleed bfb367ee62 Clear default launch_options param for planned upcoming stable release 2022-04-20 19:04:48 -04:00
mgleed 8d925509fa Bugfix: Default pickit errors with berserker axe and war pike 2022-04-20 09:26:40 -07:00
mgleed 811d656022 Increase padding from 1 to 2 spaces, pad gold (#711) 2022-04-20 12:16:24 +02:00
c7c0e9e1a3 Updated pot drinking logic (#710)
* Updated pot drinking logic

* fixed bugs

* simplify

* Fixed bad hp/mana check

* Fixed bad hp/mana check, (last was noob git by me)

Co-authored-by: Your Name <[email protected]>
Co-authored-by: mgleed <[email protected]>
2022-04-20 12:15:50 +02:00
aeon0andmgleed 9bc085af3a feat/restricted-mouse-clicks (#709)
* feat/restricted-mouse-clicks

* fix typos, use GoldBtnInventory ScreenObject, use personal.specific_inventory_roi()

* make smaller gold button, trim ROI, and use grayscale to search

* remove unused roi

* fix circular import by reverting to Config inventory area and adding open_inventory_area variable, adjust code throughout

* simplify

* revert to template finding due to circular import with ui_manager

* grayscale template match

Co-authored-by: mgleed <[email protected]>
2022-04-18 17:00:18 +02:00
roozhou a5d7fdaffa BugFix: Fix indicator_location_to_tab_count (#708)
1) 4 tabs instead of 3
2) Return value should be integer when failed
2022-04-17 12:47:34 +02:00
aeon0 16bf599d88 feat/run-qol (#707) 2022-04-17 12:40:53 +02:00
aeon0 59ba4409b5 Update i_char.py (#706) 2022-04-16 07:53:26 -07:00
mgleed f510965d05 init (#703) 2022-04-16 07:43:55 +02:00
aeon0 d43441358d Bugfix: Create mod folder if it doesnt exist (#701) 2022-04-14 21:47:39 -07:00
Aimware0 1ece05f7a7 Merge pull request #702 from roozhou/tooltip_fix
BugFix: Allow 2 lines of tooltip
2022-04-14 20:58:11 -04:00
roozhou ca93f3aa5d BugFix: Allow 2 lines of tooltip
Fix item_cropper failure in 2.4
2022-04-14 17:47:39 -07:00
tomoyo233 5c6e2211d6 Kill BlizzardError.exe (#688)
Kill the BlizzardError.exe process before restarting the game
2022-04-14 23:08:39 +02:00
mgleed f469d98f74 Bugfix: Item tooltip obscuring close button 2022-04-12 14:32:35 -07:00
Legit 699fcac7af Bugfix: missed pnova overhaul fixed (#694) 2022-04-06 22:54:29 -04:00
Legit c22275c1bb Bugfix: old ui overhaul time out modified for pnova necro (#693) 2022-04-06 18:38:17 -04:00
mgleed 470f42b1b9 Bugfix: renamed mod folder from ifilter to botty and narrowed rmtree (#690)
* fix

* didn't save
2022-04-03 21:13:03 -04:00
Legit 4b5b8385f8 Refactor: Condensed discord message will be the only option (#687)
* Condsensed discord message will be the only option

Condensed message will be default. removed the option from params.

* Update game_stats.py

* Update discord_embeds.py

* Update bot.py

* Update shenk_eld.py

* Update config.py

* removed a line

removed e.set_thumbnail(url=f"{self._psnURL}36L4a4994.png")

* Update README.md
2022-04-03 20:16:27 -04:00
jagarop 42655d5209 Enhancement: Stop gem pickups from logging to item count
Remove gems from loggin
2022-04-02 21:32:55 -04:00
mgleed 09a33ccf3d Feature/enhancement: Support for D2R launch options and cosmetic mods (#677)
Breaking change to param: `d2r_path`
2022-04-02 21:27:03 -04:00
egut125 fd93910941 Bugfix: Extra space (#682) 2022-04-01 13:46:54 -04:00
egut125 51de6f9f00 Bugfix: Placing list manipulation inside try block (#681) 2022-04-01 11:52:11 -04:00
egut125 d615f11608 Bugfix: Divide by zero fix (#680) 2022-03-31 22:39:10 -04:00
egut125andmgleed c6d2f3f068 Bugfix: Quick list manipulation to remove anything before experience in the list (#679)
* Quick list manipulation to remove anything before experience in the list

* update

* stupid ide

* cleanup

Co-authored-by: mgleed <[email protected]>
2022-03-31 22:38:13 -04:00
mgleed 0606adb5da Bugfix: Corpse pickup broken after Exp implementation (#675) 2022-03-31 17:16:39 -04:00
mgleed 82576282ab Enhancement: Update OCR model for large numbers 2022-03-31 17:16:09 -04:00
mgleed e6fe7ef609 Enhancement/bugfix: Refactor checks for item transferring (#673)
* init

* add confirmed action debug line
2022-03-30 19:49:13 -04:00
egut125 45e7a5ca9a Enhancement: Update messages to have better values (#671) 2022-03-30 13:06:50 -04:00
egut125 7d3710d1e8 Bugfix: Remove %exp calculation in player_bar()
Breaks on lvl 99 and doesn’t correctly calculate percent to next level anyways.
2022-03-29 08:40:02 -04:00
mgleed e354ed8074 Bugfix: custom config parsing (#668) 2022-03-28 18:01:12 -04:00
egut125andmgleed c4a5c6fe34 Feature: Runtime breaks (#665)
* New params for runtime and break time

* New params to manage session length and break time

* Starting message

* Message adjustments

* use _default_iff in config

Co-authored-by: mgleed <[email protected]>
2022-03-28 17:55:15 -04:00
egut125 2079b81df4 Feature: Leverage OCR to read exp and track in-game stats (#662)
* Leveraging OCR to read exp and track in game_stats

Start of each game and end of each run OCR exp
game_stats stores starting EXP and current EXP
game_stats summary calculates XP gained, XP per game, XP per hour

* Adding lvl tracking and xp to next level stats

* logic clean up
2022-03-28 09:25:30 -04:00
Aimware0andYour Name e64b312562 Bugfix: error handling for common belt error (#664)
Co-authored-by: Your Name <[email protected]>
2022-03-28 09:18:23 -04:00
Aimware0andYour Name cceb7905c7 Enhancement: Logger colors (#663)
Co-authored-by: Your Name <[email protected]>
2022-03-28 09:17:47 -04:00
4007087ceb Enhancement: variables can be initialized/used in config files
* Added a way to add config variables to ini files.

* Added examples

* Added examples

Co-authored-by: Your Name <[email protected]>
Co-authored-by: mgleed <[email protected]>
2022-03-28 09:17:09 -04:00
e64f1151f3 Enhancement: Use keyboard to select difficulty (#661)
* Enhancement: Use keyboard to select difficulty

* press instead of send

if somehow the select difficult menu is not available when the while True: loop is running, will still work.

* simplify, delete now unused assets

* cleanup more

Co-authored-by: jagarop <[email protected]>
Co-authored-by: mgleed <[email protected]>
2022-03-25 22:35:45 -04:00
mgleed 46202e5a69 Bugfix/enhancement: Fix ocr output wordlist check, replace difflib with Lev (#658)
* init

* remove unused difflib import

* use built-in function

* small changes
2022-03-23 16:11:57 -04:00
Legit 782001d338 Feature: Poison necro config (#597)
* Poison necro config

* Update bot.py

* added "walk"

to move summons after teleporting.

* Add files via upload

* Update params.ini

* Update params.ini

* Update poison_necro.py

* Update poison_necro.py
2022-03-23 14:28:07 -04:00
mgleed 4eeadb934f bump (#653) 2022-03-21 21:17:55 -04:00
mgleed 1f16c13300 Bump to 0.7.2 (#652) 2022-03-19 20:59:05 -04:00
mgleed ee479fb526 Bugfix: Stash tab counts not tracking (#646)
* init

* saved stuff

* fix startup

* fix

* gdi
2022-03-19 12:02:14 -04:00
Legit d05ff50f76 Enhancement: Improved eld attack sequence for Blizz sorc (#608)
* improved eld attack sequence

added an extra attack sequences and added wait timers.

* Update blizz_sorc.py
2022-03-18 17:14:41 -04:00
Aimware0 927ade6108 Bugfix: added error handling for custom.ini when missing section header (#647) 2022-03-18 17:02:12 -04:00
Steve6030 5eda34ded0 Enhancement: Tweaked light sorc attack sequence (#644) 2022-03-18 16:45:04 -04:00
mgleedandVladimir Makaev d9b9d66e3b Feature: Use OCR for gold pickit (#643)
* init

* consolidate

* Update src/config.py

Co-authored-by: Vladimir Makaev <[email protected]>

Co-authored-by: Vladimir Makaev <[email protected]>
2022-03-17 21:31:48 -04:00
mgleed 1adeb3a32a Bugfix: Some NPC's don't open to misc tab (#642)
* init

* cleanup

* clean

* cleanup
2022-03-16 21:52:29 -04:00
mgleed 1abf57eae1 Bugfix/refactor: Safer screen transitions for laggy setups (#641)
* init

* update

* WIP. cleanup code. refactor stashing routines, etc. hopefully now closer to lag-proof

* more simplification, ready for testing

* change default normalize_monitor and adjust code accordingly. testing

* undo save/exit keyboard

* forgot to save a couple

* fix gold checking
2022-03-16 16:06:12 -04:00
Legit 65797eba8f Note for num loot (#637)
created note for num loot to avoid confusion. Per Sosa.
2022-03-14 17:25:34 -04:00
mgleed 03a6e8b05c Bugfix/refactor: Arcane run doesn't turn off health_monitor when in town 2022-03-14 16:01:07 -04:00
mgleed 2c09459bde Bugfix/enhancement: Optimize waits; implement wait_for_expiration(ScreenObject) function (#629)
* init

* simplify

* the

* init

* update

* init

* fix belt open

* rework waiting functions in ui_manager.py
2022-03-13 20:19:41 -04:00
aeon0anduidn4233 7564fea4b0 Remove: Codecov (#632)
* Remove: Codecov

* test commit

* revert test commit

Co-authored-by: uidn4233 <[email protected]>
2022-03-12 22:21:14 -05:00
mgleed 95b27f099f Bugfix/refactor: Search for open panels instead of skill icons (#631)
* init

* add town logic

* add additional close asset for HELP menu

* fin

* a
2022-03-11 17:46:30 -05:00
mgleed e96c042853 Bugfix: Stash tab gold was being read based on prior stash tab image (#628)
* init

* simplify

* the

* init

* update
2022-03-11 13:53:46 -05:00
mgleed 57bf7a0f7d Bugfix: log_item_keep without game_stats (#627)
* init

* simplify

* the
2022-03-11 11:57:32 -05:00
mgleed da892d9043 Bugfix: Laggy inventory loading (#625)
* init

* undo item add

* add msg

* curse you Vladimir for reviewing too carefully
2022-03-10 17:28:22 -05:00
mgleed 7fad5e9aff Bugfixes: Quantity: parse fail handling, if in-game icon not found during return_to_play() 2022-03-10 17:07:35 -05:00
mgleed 840ffcdf0c Update version.py (#621) 2022-03-10 17:06:58 -05:00
Ezro 1078563f2d Bugfix: Prevent join for NoneType and start_detecting_window() in main.py (#624)
* Prevent join for NoneType and start_detecting_window() in main.py

* Start and stop in the debugger toggle
2022-03-09 23:15:36 -05:00
mgleed c1f2cad291 Bugfix: Game recovery after D2 restart (#620)
* init

* bump version
2022-03-09 19:42:20 -05:00
mgleed 285e635b0d Bugfix: Some vendor items obscured by tooltips 2022-03-09 15:40:04 -05:00
mgleed 54203ff036 Bugfix: Chicken if stats/skill icons pop up to avoid accidental allocations (#618)
* init

* simplify

* undo
2022-03-09 15:39:44 -05:00
mgleed 6b378a4606 Bugfix: Avoid entering town portals while walking in town 2022-03-09 15:39:02 -05:00
mgleed 9707fc4563 Enhancement: Cleanup botty startup. Add version to debug log. 2022-03-09 13:30:06 -05:00
mgleed 1a4e6c9533 Bugfix: Gold stashing (#615)
* init

* more places to toggle inventory gold full off
2022-03-08 21:47:13 -05:00
mgleed fb22b86d11 Bugfix: Stash is full message error (#614)
* fix item_cropper.crop_item_descr to allow some edge cases where there is lots of text in the box

* Fix send_stash message when stash is full

* remove self

* undo
2022-03-08 21:46:02 -05:00
mgleed 3c3f95142d Bugfix: crop_item_descr failing on some items 2022-03-08 21:45:37 -05:00
mgleed 029b8dcdc6 Bugfix: Lack of item tooltip causing item_cropper errors for users who turn it off (#612)
* Bugfix: Lack of item tooltip causing item_cropper errors.

* lol
2022-03-06 21:24:15 -05:00
mgleed 400d43c49c Bugfix: Tome discrepancies on some platforms (#611) 2022-03-06 20:55:50 -05:00
mgleed d2a3670a6a Bugfix: More related bugs for town and ui overhaul (#610)
* fix id logic, fix count reset, up to version 0.7.0, trim excess

* attempt to fix loop at cain, etc. when return_to_play() is called

* spell check, simplify

* center mouse after opening NPC menu

* fix messenger item count bug
2022-03-06 15:14:56 -05:00
mgleed bf421a67a9 Bugfixes: Town overhaul stuff (#609)
* fix id logic, fix count reset, up to version 0.7.0, trim excess

* attempt to fix loop at cain, etc. when return_to_play() is called

* spell check, simplify
2022-03-06 09:26:14 -05:00
mgleed f51de30fbd Major feature: Town routine overhaul, id tome, scrolls/keys, simplify gambling (#588)
* init, wip

* migration from original ocr complete, now troubleshooting phase

* first

* starts now

* catching more

* pause here, fix keep_item for ItemText class

* getting close

* adjust consumable quantity to refill per Legit

* fix import, refactor tp scroll tracking

* fixed property checking

* merge master, fix discord embed

* move tp charge setter

* properly track id scrolls after use

* fix accidental stashing

* fix sell_junk and chest_label bugs

* working on drognan instead of lysander

* a2 pathing, drognan support

* fix town-start to wp pathing, change key counting

* better drognan pathing

* comment out pather stuff

* restore old asset

* proper tp tracking

* revert key pickup to decrease need by 1

* fixing gambling, WIP

* working on gambling

* add comments to transfer_items

* add comments to transfer_items

* gambling semi-working, not stashing right

* simplify gambling process

* incorporate OCR gold reading to gamble, WIP

* gambling is painful

* simplified gambling - ~done

* finally finished gambling!

* fix diablo inventory check

* do not fail purchasing routine if item template is not seen

* fix condition

* deprioritize keys, scrolls during pickit; stop clicking Misc tab at repair

* cleanup

* init

* add support for grayscale + color_filtered

* cleanup logic

* only generate grayscale templates if use_grayscale=True

* simplify template_gray logic

* fix false detection of out of gold

* gambling with OCR was too buggy--replace with max gamble item count

* cleanup
2022-03-05 17:47:50 -05:00
Vladimir Makaev 32d7dc2e2a Documentation: Improve readme documentation in general section
Improve the README.md [general] documentation
2022-02-27 23:12:32 +00:00
Vladimir Makaev 37d41ed008 Enhancement/bugfix: Add override_capabilities param to workaround problems with autodetection (#600) 2022-02-27 16:39:08 -05:00
Kellen Stuart 5e55872668 Make improvements 2022-02-26 14:59:49 -07:00
Ezro a299051ecd Bugfix: Fix shopper scripts (#592)
* Fix anya shopper

* Fix drognan.py
2022-02-26 13:22:31 -05:00
Ezro 7056a58958 Enhancement/bugfix: Create find_and_set_window_position in screen.py to be used during testing (#591) 2022-02-26 12:23:26 -05:00
Ezro 006fb6516f Bugfix: Prevent psutil search for a negative process_id (#593) 2022-02-26 12:23:02 -05:00
mgleed 04b3367935 Bugfix: Restore for loop in gamble (#586) 2022-02-26 10:36:28 -05:00
mgleed 32f67d56df Bugfix: Missing import for i_char (#590) 2022-02-26 10:35:00 -05:00
49669e9919 Bugfix: Gambling won't start
* logic for ident, first attr. advanced pickit

* logic advanced vs normal pickit

* logic_empty_ID_Tome

* small adj. to fit PR

* converted yaml to ini. changed some val.

* changed param to auto_ident

* pickit integration

* added set in routine

* reset bot init value

* bugfix

* removed old id logic

* added_nested_filter

* changed pickit

* bugfix replace

* added some more props

* Cleanup

* cleanup

* cleanup

* started unittests

* unittest

* small pickit adjustments

* Added missing fct. after merge

* bugfix due to static method in config.py

* added comments in pickit.ini

* Update pickit.ini

* Update params.ini

* Update ui_manager.py

* Update pickit.ini

* bugfix

* remove redundant for loop, use set_gold_full

* fix merge

* simplify

Co-authored-by: aeon0 <[email protected]>
Co-authored-by: mgleed <[email protected]>
2022-02-23 20:59:12 -05:00
mgleed ad2cb6a365 Bugfix: Jamella, Halbu, Fara positions (#581)
* Temporary bugfix: Jamella and Halbu roi's poses

npc_manager.py needs roi updates for jamella and halbu as they were statically calculated based on pose positions from a4_vendor, but Skizot updated Jamella pathing and thus these no longer work.

Gonna delete the roi's and pose positions until this can be done--it'll just search by original algorithm for NPc detection in the meantime.

* noticed the same behavior with Fara :(
2022-02-23 20:25:38 -05:00
mgleed 98f69211c1 Bugfix: Properly dismiss NPC dialogue (#584)
* Bugfix: Properly dismiss NPC dialogue

Thought this was fixed in #582 but it seemed to work only in some scenarios. This change is more robust.

* Remove debug line
2022-02-23 20:22:22 -05:00
mgleed 8515b6da92 Refactor: Rearrange inventory functions, code cleanup (#577)
* init

* cleanup, fix messanger typo

* cleanup

* rename player. to personal.

* saved

* merge artifact
2022-02-23 20:20:54 -05:00
mgleed 47993f141c Bugfix/enhancement: Function to show all ScreenObjects (#582)
* init

* cleanup

* cleanup

* bugfix. ran 8 hours without error after this
2022-02-23 10:03:11 -05:00
mgleed 9726690c07 Bugfix: Save/exit error (#579)
Fix bug where save/exit routine would pass an empty template match
2022-02-22 23:01:45 -05:00
mgleed f37c916e72 Bugfix: Suppress warning if no discord webhook set (#571)
* suppress warnings for no discord webhook

* rearrange

* Update discord_embeds.py

* Update generic_api.py

* Update generic_api.py
2022-02-21 23:56:55 -05:00
mgleed 994646d811 Bugfix: Made corpse pickup more robust (#575) 2022-02-21 21:09:57 -05:00
mgleed c8eb88f672 Feature: OCR for item drops and item description boxes (#570)
* initial

* bugfixes. now stable & testing

* narrow ROI to search for 'CLICK TO' tooltip
2022-02-21 19:54:29 -05:00
Legit 8fa729ddab Bugfix: Missing template finder for blizz sorc nihlathak (#574)
added missing template finder after ui merge.
2022-02-21 18:25:32 -05:00
Ezro 59d0795153 Bugfix: Fix bug with screen offset detection in fullscreen (#573) 2022-02-21 01:18:04 -05:00
Legit 69d546f5ee Enhancement: Update default params (#554)
* Params Default Update

Updated some settings as new defaults including changing generic_api to discord.
2022-02-20 23:43:27 -05:00
mgleed 9b22917660 Refactor: UI overhaul (#558)
Summary of changes:
-Rearranged many UI-related functions across the codebase (particularly in ui_manager.py) into individual components. See src/ui_components/. Functions related to components can be called like if waypoint.use_wp("Arcane Sanctuary"): or loading.wait_for_loading_screen(2.0)
-Removed Screen and TemplateFinder dependencies across the codebase
-Screen functions separated from class
-TemplateFinder made into a singleton
-Added generic ScreenObject UI functions to simply detect UI elements on screen; e.g., detect_screen_object(ScreenObjects.TownPortal), wait_for_screen_object(ScreenObjects.Loading, 2). Also included related functions like select_screen_object_match(template_match) to automatically select the match.
-Consolidated assets. Organized templates folder into components. Adjusted some asset ROI's and alpha channels.
-Changed some template searches to grayscale for speed
-Reworked save/exit routine, should now be more consistent and faster with normal exit, chicken exit, and death exit.
-Got rid of unused and consolidated duplicate game.ini parameters
-spelling fix _last_merc_healh
-NPC manager class removed and replaced with functions
-D2 window detection now runs on its own thread for semi-live window position offsets.
-Character selection reworked. OCR your selected character for fun (not that accurate, lol)
-Simplified game start and difficulty select
-Added a get experience function, but this is not called anywhere yet
-Reworked corpse pickup. pickup_corpse is no longer a necessary argument/parameter throughout the codebase (bot.py, game_controller.py, runs, etc.)
2022-02-20 18:49:04 -05:00
mgleed cd979b3e4a Bugfix: check capabilities after corpse pickup (#567) 2022-02-19 21:54:45 -05:00
Vladimir Makaev 528400503c Enhancement: Ability to customize window properties to look for when win32 api searching for d2r window (#563) 2022-02-18 12:27:31 -05:00
mischavandenburg 59c8a898b7 corrected spelling mistakes (#566) 2022-02-18 12:03:34 -05:00
mischavandenburg 637920fc4e Feature: Added 46 uniqe / set items to pickit (#552)
by @mischavandenburg
2022-02-17 15:03:00 -05:00
Vladimir Makaev 3985817b19 Merge pull request #556 from aeon0/mgleed-patch-1
Bump to 0.6.7
2022-02-17 11:14:26 +00:00
mgleed 51c7216068 Revert "Speed up save_and_exit (#555)" (#560) 2022-02-16 22:55:30 -05:00
Ezro 196f99e5e6 Speed up save_and_exit (#555)
* Replace search and mouse click with keyboard sends

* Hardcode x,y and 'double click'

* Remove hardcode x, y since it's not guaranteed to be accurate
2022-02-16 20:28:11 -05:00
mgleed 92300818c3 Bump to 0.6.7 2022-02-16 00:20:05 -05:00
mgleed e46edbc6aa Bugfix: Shenk offset stacking (#548)
* Bugfix: Shenk offset stacking

* bump to 0.6.6

* move stuff around
2022-02-15 14:57:30 -05:00
Vladimir MakaevandVladimir Makayev e304e227c8 Bugfix: Diablo was passed as char to pickit (#551)
Co-authored-by: Vladimir Makayev <[email protected]>
2022-02-15 14:10:47 -05:00
jobithu 77149a621f CS Hammerdin: optional skills now checked for binding before cast (#550)
* optional skills now checked for binding before cast

* forgot 628
2022-02-15 07:12:17 -05:00
John Wu 6a213014b8 Enhancement: Add more chest assets (#547) 2022-02-14 21:08:02 -05:00
a9c3e125ab Feature: Diablo optimization & Killing Trash in Chaos Sanctuary (#460)
* C1F & B1S switched to static pathing

* Improved overall robustness

* improved A layout check consistency

* added A layout check consistency & CTA rebuff

* Home now a loop, B now first seal to pop.

* Trash clear at pentagram, B1S, C1F loop added.

* Changed DeSeis attack pattern so MERC can kill

* tweaked diablo spawn timer & vizier attack pattern

* fixed minor pickit error.

* fixed Layout B Check loop & improved C1F

* improved C1F pathing home

* improved B layout check by removing trash kill

* added C2G static path to infector & loop home

* tweaked pathing

* lots of pathing tweaks to increase consistency

* Clarified Logger.Info

* Fixed A1L Tele to Lava Bug

* Fixed A1Y Tele Lava bug

* Fixed B2U missing pentagram on loop back

* fixed logger

* Completely reworked layout checks

* Reworked C seal layout check

* fixed ending up too low at Diablo

* optimized loop home for C

* added all seals

* removed duplicate trash sequence at C

* Fixed B2U looping home, added essence

* Template Check Threshold raised for Layout Checks

* Reverted A layout check back to inital version

* Aggressive Layout Checks implemented.

* Replaced Pentagram Templates to improve [602]

* Fixed loops for new pent layout

* Reverted A layout checks back to initial version

* merged 6.1?

i hope it worked.

* Pressure Test: A2Y 98% layout check success

* Massive improvements on Layout Checks

* Integrated Skizot's A4 merchants

* Fixed an error on A1L.

* fixed a small error on final pickit

* Slight Cleanup

* tweaked A2Y nodes to avoid lava jumps

* Added B2U Seal Logging

* Add templ. to 611 & 610 to fix stuck pather

* WiZ/SwePow suggestions

* Some more tweaking

* Trying to improve B layout checks (not full run)

* Seal B logic pressure test (no full run)

* added timeouts to weak traversenodes (no full run)

* Pacifist Version - just checking layouts no bosses

* Pure Layoutcheck Pressure Test (double checks)

* Pacifist mode: Layout Check

* Update bot.py

* Added Templates to improve Layoutchecks

* Tweaked B2U Templates (Pacifist Version)

* add B2U nodes & calibration to impr. layout check

* added nodes to layout checks

* Added A1L Calibration Node for Layoutcheck

* Full running script

* Fixed Calibrations - Full Run

* fixed mousover keyerror

* yet another mousover

* fixed a pather issue on B1S, full run

* yet another mousover. full run.

* mousover... ful run

* yet another mousover. full run

* fixed C2G looping across pentagram

* Update game.ini

* WiZ testing

* added seal_node to sealdance

* added C1F layoutcheck nodes

* Added Wiz Speedrun

* tweaked wait in sealdance

* A1L-Static path to Pentagrram

* added A2Y hop 622

* A2Y static path home

* B1S static path home

* changed C1F fake template

* added new C1F seals & static home

* Speed or no speed

Using kill_cs_trash config

* fixed a 36b key error

* Random guess actually is random now

It wasnt random at all before so trying out if this is better

* Minor fixes and tweaks

* B2U - Static Path Home

* Redworked C1F - not stable yet

* Seal order B,C,A and DeSeis fix

There was copy/paste bug in DeSeis making it use wrong atk_len and then I also tuned the attacks a bit.

* fixed final B2U issue, should be stable now!

* added B2U 644_646 static path

* added mapping

* A seals fixed hopefully

More testing tomorrow!

* run diablo py

Yours is the diabloC, I didnt have time to compare them before sleep and wanted you to have both in case

* so this should be super stable now!

* Reverted A1L & A2Y Seal Order (but kept WiZ Idea)

* Reverted Seal Order

* Added Rudi TP :)

* all loop home now

* added TP  template to loop

* typo

* stashs & shrine gfx, TP counter

* removed pent_6 (many false positives looping home)

* clean up for aeon

* fixed typos

* New A2Y & C2G home pathing

* Reworked C1F 704 to avoid stuck

* Ready to test!

* fixed pather clicking outside D2R

* Tweaked Seal A

* Loot to Sealdance() & A2Y tweaks

* removed FALSE from TP fail

* Updated Readme.md

* remove env

* clean up code

* account for used tp

* Removed Dia C1F 700s and replaced with 650s

* Moved Seals, Fights & Pickit to Hammerdin file

* #Trapsin now supported for Arcane and CS
#Trapsin now optionally uses defensive spells Cloak of Shadows and Mind Blast
#Trapsin now waits for Shadow Warrior before using CTA

* Update readme

* Working version

* added  trapsin

* added nova sorc

* added nova sorc

* added light & nova sorc

* added clear trash, issue on 1 function

* Added Clearing Trash

* added 1 tele stop between WP & Pentagram

* fixed mistake on i_char

* CS Trash is now available for beta testing

* fixed a minor issue

* percised some debug logging

* Added CS Trash for Necro, Trapsin, Sorc (no blizz)

* added CS trash to Necro, Trapsin, Sorc_Light _Nova

* # moved functions from chars back to diablo.py
# removed CS for all chars execept hammerdin
# added seal_layout to sealboss functions
# added location to cs_kill_trash functions

* removed pickit from hammerdin.py

* trying to fix some attribute errors for pre_move

* forgot to add _char for pather.traverse_nodes

* added & removed some ._char, now it runs :)

* fixed a missing argument & cleaned up

* clear_trash=1 implemented & working

* added more kill_trash options

* added more debug info & generic kill trash spots

* fixed some debugger errors

* hammerdin done

* updated readme for cs_trash

* #merged A1L and A2Y pathing to char.py
# added A2Y static pathing to Pentagram

* fixed some errors ...

* A1L & A2Y work with new pathing logic

* Ok generic Diablo.py should now work

* and hammerdin.py aswell

* full run

* moved C1F static path to hammerdin.py

* fixed an error for pathing

* Improved A LC consistency to >99%

* Colors!

* added 2 A1L LC templates

* moved pickit to hammerdin.py

* 4min runs

* removed timeouts. 88% killrate right now.

* Added Logparser (thanks famE)

* separated log parser columns

* tweaked log parser

* changed positions of de seis kill screenshots

* added clearing trash between Pent & LC

* fixed missing _self

* Added option for cs_town_visits between seals

* Improved B1S loop home & tweaked some messages

* fixed an error not clearing seals & added colors

* removed 632 duplication & not needed LC templates

* added clear trash to A & B LC

* added pickup at 646

* added PENT_2 Template & removed fail shrine checks

* Added C2G Templates currently only 82% good runs

* Added Hybrid Calibration Nodes

* re-added templates for LC

* added 1px to WP->PENT traverse to avoid missing it

* tweaked home from 632 for not missing pent

* added more redemption before 632 calibration

* merged individual seals to one function

* fixed seal template error

* Added LC function. Fixed C2G & Loop to Pent-Stable

* added atk_len for diablo

* fixed typo so log parser stats are right

* added & increased threshold to LC calibration

* fixed new LC threshold oO - should push less often

* reverted B LC back to initial order

* log parser tweaks

* added shrine check to pather.py

* replaced 630640 with 647

* added B1S LC templates & changed shrine check

* swapped LC for B (current had 75%)

* reworked cs_trash up to LC

* log parse counts templates used

* Fixed B Layout checks

* log parser now w. templates. shrine check added

* just changes to debug names & adding a nicer table for botty start :P

* #best match & time_out=0.1,
#return false on nodes
#new shrine ROI

* Force Stashing before running Dia, logger wording

* shrine check less frequent. char.py cleaned up

* reworked trash layout B

* added 603 ROF1 templates

* added info to params.ini to reduce Q&A in discord

* # added stash every run param
# transferred trash choreography to char.py
# reverted some template changes.

* Ready to merge. Not perfect, but much better!

* small fix before merging

* Update nova_sorc.py

* Update basic.py

* added missing templates causing an error @602

* C2G: static path LC 661 & comment screenshots

* various changes--changed some info to debug, changed floats in config, adjusted runs_per_stash logic

* autoformatting made me commit

* nodes for trash between pent & seal. A works B is bad.

* fix bool -> bool(int(

* added calibration nodes for trash pent>seal

* Full run for testing efficacy of new trash nodes

* fixed a pathing issue

* reverted back to old method for trash.

* Ready for merge.

Co-authored-by: WiZ <[email protected]>
Co-authored-by: aeon0 <[email protected]>
Co-authored-by: mgleed <[email protected]>
2022-02-14 16:25:45 -05:00
Vladimir Makaev 94a617f9ae Bugfix: incorrect path offset for shenk. Optimize tele charges (#545)
* Fix incorrect path offset for shenk. Enable using charges to optimize the run

* Do offset in case can_teleport_natively vs can_teleport_with_charges
2022-02-14 16:21:47 -05:00
mgleed c85a360152 Bugfix: Messenger has no attribute "send" 2022-02-14 12:58:48 -05:00
mgleed 81a783624e Bump to v0.6.5 (#536) 2022-02-13 08:33:39 -05:00
Ezro d679858d30 Refactor: Track nopickup status in GameStats and only /nopickup once (#534)
* Track nopick status in GameStats and only /nopick once

* Rename var from nopick_active to nopickup_active
2022-02-11 22:39:00 -05:00
mgleed 5bb62a9642 Bugfix: string literal, added tp charges debug line (#535) 2022-02-11 21:50:57 -05:00
Vladimir Makaev 27388b82fc Bugfix: remap keybind is crashing (#533) 2022-02-11 13:48:11 -05:00
mgleed 35b5d7d6f8 Bugfix: Correct handling of empty img parameter 2022-02-11 13:47:17 -05:00
mgleed 883aa4468a Bugfix: Incorrect merge for turning off gold pickup (#530) 2022-02-08 21:28:14 -05:00
mgleed 64908630f4 Update transmute.py (#528) 2022-02-08 20:57:46 -05:00
mgleed 56bde23156 Cleanup: Artifact from recent PR (#521) 2022-02-08 20:56:05 -05:00
Vladimir Makaev 9c0fa2207c Bugfix: Skip Transmuting if Cube isn't empty (#529) 2022-02-08 20:52:42 -05:00
Vladimir MakaevandVladimir Makayev a1a1a5f375 Fix barbarian crashing on pre_move() (#527)
Co-authored-by: Vladimir Makayev <[email protected]>
2022-02-08 20:32:36 -05:00
Steve6030 4e35b8a1a8 Correcting poison resist asset spelling. (#523) 2022-02-08 20:32:10 -05:00
Brett Davis 589fda539f Bugfix: Config constructor no longer takes a string (#522) 2022-02-08 20:31:29 -05:00
mgleed c65ae545df Bugfix: Provide precompiled tesserocr (#520)
* Revert tesserocr to conda-forge rather than pip

Tesserocr with Tesseract > 5 works with pip install but installer fails if user doesn't have VS compilers. Will revisit

* fixed by providing precompiled tesserocr
2022-02-06 15:14:12 -05:00
RB-Developmentandmgleed 5ae6194d23 gambling bugfix (#519)
* Update ui_manager.py

Fix for gambling issue. Looks like self._config.char["gamble_items"] always returns true. Therefore im checking if the first entry is empty and go for a not.
not self._config.char["gamble_items"][0]==""

* simplify

Co-authored-by: mgleed <[email protected]>
2022-02-06 12:09:50 -05:00
mgleed b83dbb8e8d Track item charges with OCR (#516) 2022-02-06 00:12:45 -05:00
mgleed f8e41d525b OCR as a service (#505) 2022-02-05 23:49:17 -05:00
Vladimir Makaev d9624e04c1 Fix game isn't restarted when in main menu / character selection screen (#517)
* Fix max_game_length_s isn't properly tracked during character selection

* Fix restart routine not waiting for main menu to appear.
2022-02-05 21:23:44 -05:00
mgleed f4ff1b953f bugfix: runs_per_repair = 0 modulo issue (#515) 2022-02-05 15:58:30 -05:00
pokzcodes da6ccc6250 Kill d2r when botty cannot recover and shuts down (#511) 2022-02-05 13:52:41 -05:00
pokzcodes a87d72a044 Added exception handling to Discord API calls (#510)
* added exception handling to discord api calls

* restored accidental deleted vars

* removed word "discord" from log in generic api
2022-02-05 13:24:41 -05:00
mgleedandVladimir Makaev ab1d496fff Change always_repair to runs_per_repair (#509)
**This is potentially a breaking change for users using `always_repair`**

Co-authored-by: Vladimir Makaev <[email protected]>
2022-02-05 13:24:13 -05:00
mgleed 5d4e7e8dec Add more act 5 paths (#506)
* initial

* finished a TODO!
2022-02-05 13:22:52 -05:00
mgleed e4f2ae4826 Bugfix: vendor_stash merging artifact (#514) 2022-02-05 10:30:00 -05:00
mgleed 1315d9decb Bugfix for TP charge detection: use color_filter instead of template match threshold (#513) 2022-02-05 10:29:36 -05:00
c358282e68 Launch botty from town or main menu; fix character recovery after restart/death (#494)
* Add ability to launch botty from either main menu or town

* Fix game recovery routine is stuck forever on character selection screen

* Move _char_template to class variable to be able to share among instances

* fix character recovery and character select, support offline/online. WIP

Co-authored-by: Vladimir Makayev <[email protected]>
Co-authored-by: mgleed <[email protected]>
2022-02-04 20:27:56 -05:00
Vladimir Makaev c57e820d63 Fix character stuck trying to teleport in town (#512) 2022-02-04 19:02:43 -05:00
Vladimir MakaevandVladimir Makayev 6b1e155197 Support Gem Transmuting (#491)
Co-authored-by: Vladimir Makayev
2022-02-04 17:58:41 -05:00
Vladimir Makaev 47c5e20238 Optimized handling of teleport charges (#476) 2022-02-04 14:59:39 -05:00
RB-Development 36d3c2e913 Gambling by @RB-Development (#445)
This branch will detect if stash is full of gold. Afterwards the gambling functionality (currently only in act 4 implemented) will be called. The bot will gamble for specific items (determined in params.ini) until no gold is left. He will check for properties specified in pickit.ini and sell not matching items.
Supported items are: ring, amulet, circlet, coronet, talon

Leverages recent advanced pickit PR.
2022-02-04 14:12:56 -05:00
mgleed 06623142f7 Controller item spacing 2022-02-04 12:42:38 -05:00
mgleed 1b9fdad539 fix gold stashing (#508) 2022-02-04 12:25:50 -05:00
egut125 c0a598cc34 Merge pull request #503 from aeon0/max-consecutive-fails
New Param for fails, if max is reached, kill botty. Defaults off.
2022-02-04 10:15:16 -05:00
egut125 e3fd1b61f5 Merge pull request #504 from aeon0/stash-bugfix
stash bugfix
2022-02-03 22:31:20 -05:00
mgleed 2dcc8fcdfe gdi 2022-02-03 22:26:32 -05:00
mgleed 6fe9a18d43 Make gold low priority during pickit (#502)
By @codahq
2022-02-03 18:10:29 -05:00
egut125 9f8bed6efb New Param for fails, if max is reached, kill botty. Defaults off. 2022-02-03 14:45:45 -05:00
mgleedandaeon0 0121c7af2e Allow color_filter to range <0, >180 in H; etc. (#492)
* initial

* move image erosion from item_cropper.py to misc.py for planned use elsewhere

Co-authored-by: aeon0 <[email protected]>
2022-02-03 07:28:55 +01:00
mgleed 1d84a86e0b Updates to template_search, trim lots of code throughout (#499)
* initial

* Support list of templates (not just template names) as an input for search()

* fix grayscale for new list of templates
2022-02-03 07:17:57 +01:00
mgleed 99f8c65c2e Nihlathak spelling (#488)
Unified the variety of nihlathak spellings throughout the codebase
2022-02-01 21:34:21 -05:00
Vladimir Makaev 0ec7ced4d6 Nihlathak pathing for lightning sorc (#495) 2022-02-01 16:51:13 -05:00
RB-Developmentaeon0mgleed
551a547ddb Advanced pickit (#383)
* logic for ident, first attr. advanced pickit

* logic advanced vs normal pickit

* logic_empty_ID_Tome

* small adj. to fit PR

* converted yaml to ini. changed some val.

* changed param to auto_ident

* pickit integration

* added set in routine

* reset bot init value

* bugfix

* removed old id logic

* added_nested_filter

* changed pickit

* bugfix replace

* added some more props

* Cleanup

* cleanup

* cleanup

* started unittests

* unittest

* small pickit adjustments

* Added missing fct. after merge

* bugfix due to static method in config.py

* added comments in pickit.ini

* Update pickit.ini

* Update params.ini

* Update ui_manager.py

* Update pickit.ini

Co-authored-by: aeon0
Co-authored-by: mgleed
2022-01-30 19:40:36 -05:00
aeon0 09caab2120 Move messanger (#498) 2022-01-30 15:30:47 +01:00
aeon0 2905ee5d31 Remove configs (#497)
* remove config window always on top

* remove message highlights

* only use win32api for window offset
2022-01-30 13:26:10 +01:00
aeon0 e9d31f220f Config cleanup (#496) 2022-01-30 11:59:52 +01:00
aeon0 27f0e3d793 Revert "Add Linting (#487)" (#490)
This reverts commit 5e1a783394.
2022-01-28 18:24:47 +01:00
aeon0 5e1a783394 Add Linting (#487)
* add black linting

* fix linting

* doc update
2022-01-28 17:47:03 +01:00
AlekseyLesnoy 7aef2a6a73 fix window detection with multiple monitors via winapi (#483) 2022-01-28 16:51:52 +01:00
flapjax 9761f87826 fix duplicate bot name in status update message (#458)
* fix duplicate bot name in status update message

This commit changes the behavior of the _send_status_update method. If the generic_api is in use, it will avoid adding the bot name to the start of the message because the bot name is already added by the generic api.

* fix duplicate bot name in status update message

This commit moves the fix to the DiscordEmbeds class instead of performing it with an if statement in the GameStats class.
2022-01-24 16:17:53 +01:00
nlapinski 3321b7bc84 necro fixes (#470)
* trav walking repathing

* trav source paths for walking

* traverse image threshold

* shenk death check

* images to check summon status

* enter durance

* default configs
2022-01-24 16:13:20 +01:00
pokzcodes 667c2a4dc5 Add option to fill shared stash tabs first (useful for HC characters) (#472)
* fixed bug w/ walking hammerdin that would cause vigor to be left on while attacking in trav

* added option to fill shared stash first

* reverted a change not related to this PR
2022-01-21 22:01:27 +01:00
Fise 87b4737901 Drognan shopper fixes (#468)
* Improved navigation in and out of town. New options for tuning it

* Delete a2_town_drognan_fire.png
2022-01-21 21:53:44 +01:00
Legit 376547ebfe Nihlathak cold immune accuracy update (#463)
* Nihlathak cold immune accuracy update

Much higher accuracy

* nihl health bar

* fixed pathing issue bottom left
2022-01-19 07:22:13 +01:00
skizotenigma 7935da58a7 Update pather.py (#459) 2022-01-19 07:16:13 +01:00
Vladimir Makaev b890ff266f Find D2R window using win32api instead of pattern matching (#453) 2022-01-18 20:32:35 +01:00
Legit c939877c7b Nihlathaks no longer count cold immune run as fail (#448)
Changed false to True
2022-01-17 16:17:51 +01:00
aeon0 1bc392327c Hot fix (#454)
* fix pather timeout

* revert changes
2022-01-15 11:06:41 +01:00
aeon0 df0e70470c Update version.py 2022-01-15 11:02:52 +01:00
aeon0 2eb9f84520 Make config static and global (#451) 2022-01-14 23:22:22 +01:00
aeon0 5c6fd83155 Update pather.py 2022-01-14 16:57:10 +01:00
aeon0 6226956af4 Update version.py 2022-01-14 15:39:42 +01:00
aeon0 04dac4070f Bump version to v0.6.3 (#450) 2022-01-14 12:18:39 +01:00
aeon0 bcf5bd4f11 Update nova_sorc.py 2022-01-14 12:16:57 +01:00
aeon0 cf8c393cf1 Sort pather nodes (#449) 2022-01-14 11:37:24 +01:00
Legitandaeon0 070fd9d98e Blizz sorc Nihlathak script (#447)
* Blizz sorc Nihlathak script

* Cold immune assets

* Updated pathing changes that would cause sticking.

* Reduce Timer on pickit if stuck

* Removed white space and lowercased nihl_immune

* increased ingore item timer

3 seconds

* Update src/char/sorceress/blizz_sorc.py

* updated bottom left offset and updated nilh_immune

Co-authored-by: aeon0 <[email protected]>
2022-01-13 22:40:33 +01:00
63476a402d Dia&cs (#444)
* integrated diablo scaffold

still pending pathing & kill logic

* minor changes to cross river of flame - but loop not working

* River of Flame sucessfully skipped - CS Entrance cleared

* Seal B works.

* Everthing is slow :(

* reparied slowness

* revert deleted main code

* Added CS Entrance recognition & changed Pentagram templates

* Merge branch 'diablo' of https://github.com/jobithu/botty into diablo

* Seal B works for both layouts - still clumsy, but it works.

* added Vizier (A). working: A1, B1, B2 - pending: A2,C1,C2,Diaaaa

* C identifcation implemented.

* All seals done, optimization needed for pathing & fighting sequences

* fixed minor error in game.ini

* should now run - badly. all seal spots & paths need optimization

* A1Y works stable

* A1Y stable, WP now has issues

* A2Y seal mouseover added - new bug, could not determine window offset

* Both A seals work great now!

* A2L Seals work consistently. A1Y quite good.

* easteregg

* A2L improvements

* Succesful kill on A2L, B1S, C1G

* Tweaked Diablo Kill Wait Time

* start cleanup

* added functions for each seal layout

* First stable dia kills with fixed map layout

* added Sealdance function

* Fixed Sealdance. A1L is finished. All others work in Progress.

* A2L + B1S Works

* A2L and B1S works

* Script runs well now on A1L, B1S, C1G. Sealdance needs more movement.

* Update diablo.py

* A1L, C2F, B2F working. Kills Dia Hell well.

* added issue log. testing all layouts now.

* Individual runs work, Sealdance needs tweaking

* All seals work, got frustrated, added sorc&she rox

* tweaked sorc vizier & infector fights

* rebuild templates & nodes for A2Y, B1U, C2G

* Forgot to add Seal A to the run oO

* renamed forgotten templates for A2Y

* fixed minor bugs on A1Y. succesfull dia kill

* Optimized A2Y

* Reworked A1Y templates & fight - very stable! Yay!

* A2Y, B2U, C2G work - but i think it should be B1U

* 4/6 seals work (B1S & C1F pending)

* some clean up

* remove unwated code

* 5/6 Seals done - added C1F

* sealdance and error handling

* try to merge stuff somehow

* add additional template coordinates to failed nodes

* fix health manager by adding diablo lcoation

* remove thresholds

* fix template names and error handling for c seals

* C1F added. 5/6 seals done.

* All seals work - let's get it tested!

* B1S fight coregraphy improvements

* New paths for layout check to increase consistency

* fixed A2Y edge lava port (625>626)

* All seals work, lets test with more ppl & finetune

* C1F & B1S switched to static pathing

* Improved overall robustness

* improved A layout check consistency

* added A layout check consistency & CTA rebuff

* Home now a loop, B now first seal to pop.

* Trash clear at pentagram, B1S, C1F loop added.

* Changed DeSeis attack pattern so MERC can kill

* tweaked diablo spawn timer & vizier attack pattern

* fixed minor pickit error.

* fixed Layout B Check loop & improved C1F

* improved C1F pathing home

* improved B layout check by removing trash kill

* added C2G static path to infector & loop home

* tweaked pathing

* lots of pathing tweaks to increase consistency

* Clarified Logger.Info

* Fixed A1L Tele to Lava Bug

* Fixed A1Y Tele Lava bug

* Fixed B2U missing pentagram on loop back

* fixed logger

* Completely reworked layout checks

* Reworked C seal layout check

* fixed ending up too low at Diablo

* optimized loop home for C

* added all seals

* removed duplicate trash sequence at C

* Fixed B2U looping home, added essence

* Template Check Threshold raised for Layout Checks

* Reverted A layout check back to inital version

* Aggressive Layout Checks implemented.

* Replaced Pentagram Templates to improve [602]

* Fixed loops for new pent layout

* Reverted A layout checks back to initial version

* merged 6.1?

i hope it worked.

* Pressure Test: A2Y 98% layout check success

* Massive improvements on Layout Checks

* Integrated Skizot's A4 merchants

* Fixed an error on A1L.

* fixed a small error on final pickit

* Slight Cleanup

* tweaked A2Y nodes to avoid lava jumps

* Added B2U Seal Logging

* Add templ. to 611 & 610 to fix stuck pather

* WiZ/SwePow suggestions

* Some more tweaking

* Trying to improve B layout checks (not full run)

* Seal B logic pressure test (no full run)

* added timeouts to weak traversenodes (no full run)

* Pacifist Version - just checking layouts no bosses

* Pure Layoutcheck Pressure Test (double checks)

* Pacifist mode: Layout Check

* Update bot.py

* Added Templates to improve Layoutchecks

* Tweaked B2U Templates (Pacifist Version)

* add B2U nodes & calibration to impr. layout check

* added nodes to layout checks

* Added A1L Calibration Node for Layoutcheck

* Full running script

* Fixed Calibrations - Full Run

* fixed mousover keyerror

* yet another mousover

* fixed a pather issue on B1S, full run

* yet another mousover. full run.

* mousover... ful run

* yet another mousover. full run

* fixed C2G looping across pentagram

* Update game.ini

* WiZ testing

* added seal_node to sealdance

* added C1F layoutcheck nodes

* Added Wiz Speedrun

* tweaked wait in sealdance

* A1L-Static path to Pentagrram

* added A2Y hop 622

* A2Y static path home

* B1S static path home

* changed C1F fake template

* added new C1F seals & static home

* Speed or no speed

Using kill_cs_trash config

* fixed a 36b key error

* Random guess actually is random now

It wasnt random at all before so trying out if this is better

* Minor fixes and tweaks

* B2U - Static Path Home

* Redworked C1F - not stable yet

* Seal order B,C,A and DeSeis fix

There was copy/paste bug in DeSeis making it use wrong atk_len and then I also tuned the attacks a bit.

* fixed final B2U issue, should be stable now!

* added B2U 644_646 static path

* added mapping

* A seals fixed hopefully

More testing tomorrow!

* run diablo py

Yours is the diabloC, I didnt have time to compare them before sleep and wanted you to have both in case

* so this should be super stable now!

* Reverted A1L & A2Y Seal Order (but kept WiZ Idea)

* Reverted Seal Order

* Added Rudi TP :)

* all loop home now

* added TP  template to loop

* typo

* stashs & shrine gfx, TP counter

* removed pent_6 (many false positives looping home)

* clean up for aeon

* fixed typos

* New A2Y & C2G home pathing

* Reworked C1F 704 to avoid stuck

* Ready to test!

* fixed pather clicking outside D2R

* Tweaked Seal A

* Loot to Sealdance() & A2Y tweaks

* removed FALSE from TP fail

* Updated Readme.md

* remove env

* clean up code

* account for used tp

* Removed Dia C1F 700s and replaced with 650s

Co-authored-by: aeon0 <[email protected]>
Co-authored-by: WiZ <[email protected]>
2022-01-13 15:07:55 +01:00
aeon0 28ca8d2ee7 Nova sorc trav update (#443) 2022-01-13 12:40:53 +01:00
Francesco bc24fea4e9 No diablo by default (#441)
* My pick up and sorc parameters

* Moved the game logic away from the main within the new GameController class.
Refactored the main to use built-in keyboard add_hotkey and wait functions instead of self-written main loop.

* Revert "My pick up and sorc parameters"

This reverts commit 0920a406

* Changed number of loot columns

* Changes as per the comments:
Handle non-existing backup file.
Removed newline at the beginning of GameController class.
Changed line splitted into multiple lines back to a single line.

* Refactored graphic debugger with similar logic to botty to now have a controller.

* Added a small comment on the graphic debugger class and fixed a now-typo on the presented menu

* Bug Fix: if pressing F11 repeatedly the main loop may crash due to self.bot not yet initialized in the game_controller.

A safe solution would be to try and catch all but that would also be an overkill as it would most likely mask exceptions that we might want to make the program crash.

Checking that self.bot is initialized should work for the time being.

* No need to re-assign the resume key within the game controlelr anymore

* Urgent 1 liner bug fix for always_on_top: name 'config' is not defined

* Bug fix, keyboard dependency on game_recovery.py
For some reason PyCharm seems to flag this import as unused while it is actually used.

* Set diablo to not run by default
2022-01-13 12:37:30 +01:00
Francesco 4ea5e4d265 D2r on top on restart (#442)
* My pick up and sorc parameters

* Moved the game logic away from the main within the new GameController class.
Refactored the main to use built-in keyboard add_hotkey and wait functions instead of self-written main loop.

* Revert "My pick up and sorc parameters"

This reverts commit 0920a406

* Changed number of loot columns

* Changes as per the comments:
Handle non-existing backup file.
Removed newline at the beginning of GameController class.
Changed line splitted into multiple lines back to a single line.

* Refactored graphic debugger with similar logic to botty to now have a controller.

* Added a small comment on the graphic debugger class and fixed a now-typo on the presented menu

* Bug Fix: if pressing F11 repeatedly the main loop may crash due to self.bot not yet initialized in the game_controller.

A safe solution would be to try and catch all but that would also be an overkill as it would most likely mask exceptions that we might want to make the program crash.

Checking that self.bot is initialized should work for the time being.

* No need to re-assign the resume key within the game controlelr anymore

* Urgent 1 liner bug fix for always_on_top: name 'config' is not defined

* Bug fix, keyboard dependency on game_recovery.py
For some reason PyCharm seems to flag this import as unused while it is actually used.

* Set diablo to not run by default

* set d2r on top upon restart if configured to do so

* Revert "Set diablo to not run by default"

This reverts commit 6202814a8b6a0ae0ddbcd7c5dcee520ed897f3d0.
2022-01-13 12:37:07 +01:00
1fe56c95c6 Merge Diablo (#435)
* integrated diablo scaffold

still pending pathing & kill logic

* minor changes to cross river of flame - but loop not working

* River of Flame sucessfully skipped - CS Entrance cleared

* Seal B works.

* Everthing is slow :(

* reparied slowness

* revert deleted main code

* Added CS Entrance recognition & changed Pentagram templates

* Merge branch 'diablo' of https://github.com/jobithu/botty into diablo

* Seal B works for both layouts - still clumsy, but it works.

* added Vizier (A). working: A1, B1, B2 - pending: A2,C1,C2,Diaaaa

* C identifcation implemented.

* All seals done, optimization needed for pathing & fighting sequences

* fixed minor error in game.ini

* should now run - badly. all seal spots & paths need optimization

* A1Y works stable

* A1Y stable, WP now has issues

* A2Y seal mouseover added - new bug, could not determine window offset

* Both A seals work great now!

* A2L Seals work consistently. A1Y quite good.

* easteregg

* A2L improvements

* Succesful kill on A2L, B1S, C1G

* Tweaked Diablo Kill Wait Time

* start cleanup

* added functions for each seal layout

* First stable dia kills with fixed map layout

* added Sealdance function

* Fixed Sealdance. A1L is finished. All others work in Progress.

* A2L + B1S Works

* A2L and B1S works

* Script runs well now on A1L, B1S, C1G. Sealdance needs more movement.

* Update diablo.py

* A1L, C2F, B2F working. Kills Dia Hell well.

* added issue log. testing all layouts now.

* Individual runs work, Sealdance needs tweaking

* All seals work, got frustrated, added sorc&she rox

* tweaked sorc vizier & infector fights

* rebuild templates & nodes for A2Y, B1U, C2G

* Forgot to add Seal A to the run oO

* renamed forgotten templates for A2Y

* fixed minor bugs on A1Y. succesfull dia kill

* Optimized A2Y

* Reworked A1Y templates & fight - very stable! Yay!

* A2Y, B2U, C2G work - but i think it should be B1U

* 4/6 seals work (B1S & C1F pending)

* some clean up

* remove unwated code

* 5/6 Seals done - added C1F

* sealdance and error handling

* try to merge stuff somehow

* add additional template coordinates to failed nodes

* fix health manager by adding diablo lcoation

* remove thresholds

* fix template names and error handling for c seals

* C1F added. 5/6 seals done.

* All seals work - let's get it tested!

* B1S fight coregraphy improvements

* New paths for layout check to increase consistency

* fixed A2Y edge lava port (625>626)

* All seals work, lets test with more ppl & finetune

* C1F & B1S switched to static pathing

* Improved overall robustness

* improved A layout check consistency

* added A layout check consistency & CTA rebuff

* Home now a loop, B now first seal to pop.

* Trash clear at pentagram, B1S, C1F loop added.

* Changed DeSeis attack pattern so MERC can kill

* tweaked diablo spawn timer & vizier attack pattern

* fixed minor pickit error.

* fixed Layout B Check loop & improved C1F

* improved C1F pathing home

* improved B layout check by removing trash kill

* added C2G static path to infector & loop home

* tweaked pathing

* lots of pathing tweaks to increase consistency

* Clarified Logger.Info

* Fixed A1L Tele to Lava Bug

* Fixed A1Y Tele Lava bug

* Fixed B2U missing pentagram on loop back

* fixed logger

* Completely reworked layout checks

* Reworked C seal layout check

* fixed ending up too low at Diablo

* optimized loop home for C

* added all seals

* removed duplicate trash sequence at C

* Fixed B2U looping home, added essence

* Template Check Threshold raised for Layout Checks

* Reverted A layout check back to inital version

* Aggressive Layout Checks implemented.

* Replaced Pentagram Templates to improve [602]

* Fixed loops for new pent layout

* Reverted A layout checks back to initial version

* merged 6.1?

i hope it worked.

* Pressure Test: A2Y 98% layout check success

* Massive improvements on Layout Checks

* Integrated Skizot's A4 merchants

* Fixed an error on A1L.

* fixed a small error on final pickit

* Slight Cleanup

* tweaked A2Y nodes to avoid lava jumps

* Added B2U Seal Logging

* Add templ. to 611 & 610 to fix stuck pather

* WiZ/SwePow suggestions

* Some more tweaking

* Trying to improve B layout checks (not full run)

* Seal B logic pressure test (no full run)

* added timeouts to weak traversenodes (no full run)

* Pacifist Version - just checking layouts no bosses

* Pure Layoutcheck Pressure Test (double checks)

* Pacifist mode: Layout Check

* Update bot.py

* Added Templates to improve Layoutchecks

* Tweaked B2U Templates (Pacifist Version)

* add B2U nodes & calibration to impr. layout check

* added nodes to layout checks

* Added A1L Calibration Node for Layoutcheck

* Full running script

* Fixed Calibrations - Full Run

* fixed mousover keyerror

* yet another mousover

* fixed a pather issue on B1S, full run

* yet another mousover. full run.

* mousover... ful run

* yet another mousover. full run

* fixed C2G looping across pentagram

* Update game.ini

* WiZ testing

* added seal_node to sealdance

* added C1F layoutcheck nodes

* Added Wiz Speedrun

* tweaked wait in sealdance

* A1L-Static path to Pentagrram

* added A2Y hop 622

* A2Y static path home

* B1S static path home

* changed C1F fake template

* added new C1F seals & static home

* Speed or no speed

Using kill_cs_trash config

* fixed a 36b key error

* Random guess actually is random now

It wasnt random at all before so trying out if this is better

* Minor fixes and tweaks

* B2U - Static Path Home

* Redworked C1F - not stable yet

* Seal order B,C,A and DeSeis fix

There was copy/paste bug in DeSeis making it use wrong atk_len and then I also tuned the attacks a bit.

* fixed final B2U issue, should be stable now!

* added B2U 644_646 static path

* added mapping

* A seals fixed hopefully

More testing tomorrow!

* run diablo py

Yours is the diabloC, I didnt have time to compare them before sleep and wanted you to have both in case

* so this should be super stable now!

* Reverted A1L & A2Y Seal Order (but kept WiZ Idea)

* Reverted Seal Order

* Added Rudi TP :)

* all loop home now

* added TP  template to loop

* typo

* stashs & shrine gfx, TP counter

* removed pent_6 (many false positives looping home)

* clean up for aeon

* fixed typos

* New A2Y & C2G home pathing

* Reworked C1F 704 to avoid stuck

* Ready to test!

* fixed pather clicking outside D2R

* Tweaked Seal A

* Loot to Sealdance() & A2Y tweaks

* removed FALSE from TP fail

* Updated Readme.md

* remove env

* clean up code

* account for used tp

Co-authored-by: aeon0 <[email protected]>
Co-authored-by: WiZ <[email protected]>
2022-01-12 23:05:23 +01:00
aeon0 b5c0e8d0dc Check stashing after failed runs or chicken/death (#438)
* Check stashing after failed runs or chicken/death

* optmize

* revert some

* revert
2022-01-12 20:46:14 +01:00
aeon0 39dd868a34 Fix testing (#437)
* test

* with coverage

* add back coverage

* actually fixing test

* ups typo
2022-01-12 19:52:26 +01:00
Francesco 5f1ffd153b D2r restart optional (#417)
* My pick up and sorc parameters

* Moved the game logic away from the main within the new GameController class.
Refactored the main to use built-in keyboard add_hotkey and wait functions instead of self-written main loop.

* Revert "My pick up and sorc parameters"

This reverts commit 0920a406

* Changed number of loot columns

* Changes as per the comments:
Handle non-existing backup file.
Removed newline at the beginning of GameController class.
Changed line splitted into multiple lines back to a single line.

* Refactored graphic debugger with similar logic to botty to now have a controller.

* Added a small comment on the graphic debugger class and fixed a now-typo on the presented menu

* Bug Fix: if pressing F11 repeatedly the main loop may crash due to self.bot not yet initialized in the game_controller.

A safe solution would be to try and catch all but that would also be an overkill as it would most likely mask exceptions that we might want to make the program crash.

Checking that self.bot is initialized should work for the time being.

* No need to re-assign the resume key within the game controlelr anymore

* Urgent 1 liner bug fix for always_on_top: name 'config' is not defined

* Bug fix, keyboard dependency on game_recovery.py
For some reason PyCharm seems to flag this import as unused while it is actually used.

* game_controller.py changes

* config and params.ini changes

* config and params.ini changes

* Added else statement to prevent double logging in case of failed restart

* Removed botty name from logging and api messages as it is redundant information.

Fixed issue with gamerecovery constructor - now it takes template finder as a parameter
2022-01-12 17:53:22 +01:00
aeon0 01765e0616 Pathing A1 after Town Portal (#433) 2022-01-12 10:27:56 +01:00
aeon0 99c4348bc3 Thread-safe TempalteFinder (#434) 2022-01-12 10:27:09 +01:00
aeon0 c8b59c338b Startup speedup (#432)
* etheral

* devision by zero

* force move in a2

* Only one template finder instance
2022-01-11 21:21:19 +01:00
aeon0 7f7acf1e2a Bug fix round (#431)
* etheral

* devision by zero

* force move in a2
2022-01-11 19:29:40 +01:00
aeon0 6ddca4c7db Fix hork for windowed (#426) 2022-01-11 10:13:59 +01:00
aeon0 85bc2dae29 Revert "Messaging update (#408)" (#425)
This reverts commit a4e435fec4.
2022-01-11 09:19:43 +01:00
aeon0 c3365e3d02 Update config.py 2022-01-10 23:45:37 +01:00
aeon0 8104b87083 Configure war cry cast frequency (#424) 2022-01-10 23:08:49 +01:00
skizotenigma a4e435fec4 Messaging update (#408)
* Messaging update

Corrects some messages formats and updates to allow titles.

* Messaging Update

Fixes the new messages and updates some of the others.

* mark 2

fixes some space.

* Update messenger.py

* Update generic_api.py
2022-01-10 22:46:13 +01:00
aeon0 51715433a9 Update generic_api.py 2022-01-10 09:12:26 +01:00
egut125 a8ba63d968 Add bot name to generic messages (#422) 2022-01-10 09:09:26 +01:00
egut125 39f65ab1fb Add check to create info_screenshots folder and try-catch adding image to discord embed (#416) 2022-01-09 16:34:04 +01:00
aeon0 8dfe8a2163 Catch all config errors (#414) 2022-01-08 19:25:24 +01:00
Legitandaeon0 f450dc7591 Light Sorc Trav/shenk Update (#404)
* Light Sorc Trav/shenk Update

Requires Frozen orb added in params.

* frozen or for lightning sorc

* removed ;

* added frozen orb

* added move outside of trav for pickit start

* Last minute small trav changes

* Added fail safe for loot check

* update light sorc trav

* remove one chain lighting

* revert back to original start

Co-authored-by: aeon0 <[email protected]>
2022-01-08 18:53:54 +01:00
aeon0 c22230756b Fix template search memory allocation issue (#413) 2022-01-08 13:03:51 +01:00
aeon0 48b2c42eb2 Update version.py 2022-01-08 12:39:32 +01:00
aeon0 c3f519aa7b Bump version to v0.6.2 (#412) 2022-01-08 12:29:32 +01:00
aeon0 854509b489 Trav additional templates (#411) 2022-01-08 12:17:04 +01:00
aeon0 640bf93de4 Fix bug in standalone health manager (#410) 2022-01-08 11:43:44 +01:00
Legitandaeon0 19f45d0270 Add some items and filters (rare matriarchal jav, +3 tornado pels, +3 warcry helmets) (#386)
* Fix for blizz_sorc master

* removed delay

* Update src/char/sorceress/blizz_sorc.py

* Additiona pickit items

* Missing items on pickit

* updated pickit

fixed rare jav missing added couple socketed items.

* Garbage item not needed

* Changed eth_ to grey_

* Dont know how to delete eth assets I added.

* revert blizz

* clean unused item assets

* bring back missing file, fix typos

Co-authored-by: aeon0 <[email protected]>
2022-01-08 10:20:45 +01:00
aeon0 dcccee68f2 Check for item again after stashing to figure if it is still there (#409) 2022-01-08 10:04:07 +01:00
aeon0 ded772b377 Move forward during attacking shenk (#407) 2022-01-07 20:37:53 +01:00
aeon0andFrancesco faed0154aa Char selector after restart (#403)
* Char selector after restart

* at least make it work...

* Scroll the characters if the template was not found.

TODO: Ideally we would like to understand which character is currently selected rather than assuming we'll always be using the top one.

* make it fancy

Co-authored-by: Francesco <[email protected]>
2022-01-07 19:38:21 +01:00
egut125 f695954cbb Add message_api_type to readme (#406) 2022-01-07 19:04:06 +01:00
alceasan d9d1dda9cf Additional item properties assets (#402)
* Additional item properties

+3 to Jav skills
+ % Faster Cast Rate
+% Chance of getting magic items

* Add files via upload

+3 to Jav skills
+ % Faster Cast Rate
+% Chance of getting magic items
2022-01-06 20:06:45 +01:00
bjoerm e61933c49f If super potions are not available (e.g. nightmare), buy greater potions. (#401) 2022-01-06 18:35:17 +01:00
egut125 dff178bbc7 Breaking Messenger Module into something more flexible for specif… (#370)
* WIP Breaking Messenger Module into something more flexible for specific apis

* Cleanup and removal of data class

* Working embeds sort of

* Simple embeds set up

* Adding image of stashing items to discord embed

* Discord Embed updates with images

death_manager and game_controller both store path to last death/chicken screenshot
Pass last screenshot path along to game_stats and discord_embeds to place in discord message

* Color adjust

* Updating filenames formobile notifications

* Create loot_screenshots folder if it doesn't exist and api=discord

* Fixing missed messenger.send calls

* UI for discord updates

* Switching to i_api and explicit functions

* Update all messenger calls to new functions

* Param name change

* Simplify discord_basic api

* Switching from interface to generic api class

* One new messenger call from master

* spacing
2022-01-06 18:33:59 +01:00
nlapinskiandnlapinski b01ff94b8a Necro class (#337)
* necro rebase

* merge

* necro readme

* removed import

* a

* necro char

* necro parms

* config fix

* example planner

* clear pindle pack

* pindle pack config cast

Co-authored-by: nlapinski <[email protected]>
2022-01-05 23:43:14 +01:00
skizotenigma 739e5d3014 Update pather.py (#398) 2022-01-05 22:15:24 +01:00
Francesco c92d32b6de Improved debugger (#361) 2022-01-05 22:15:10 +01:00
skizotenigma 2924836a32 "Basic" classes (#352)
* Start of "Basic" classes

will left attack unless right attack is available.

* Update basic_ranged.py

* Update basic.py
2022-01-05 22:14:14 +01:00
skizotenigma a65df17323 Adding Lysander in A2 (#399)
Cain & Lysander put to work
2022-01-05 22:08:31 +01:00
aeon0 9339a3b432 Test utils misc load_template() (#396) 2022-01-05 11:42:34 +01:00
mgleedandaeon0 2d1847fce4 utilize per-NPC ROI's and pose positions (#395)
* utilize per-NPC ROI's and pose positions

* mini code improvement

Co-authored-by: aeon0 <[email protected]>
2022-01-05 11:21:41 +01:00
skizotenigma a60849887c Jamella pathing fix. (#393)
* fix for pathing from jamella when she walks too far down.

* updated kashya and cain as well

they kept walking into the node!
so i had to adjust it.

* Update pather.py
2022-01-05 10:50:25 +01:00
Francesco d35fda18c0 pywin32 dependency fix (#394)
* My pick up and sorc parameters

* Moved the game logic away from the main within the new GameController class.
Refactored the main to use built-in keyboard add_hotkey and wait functions instead of self-written main loop.

* Revert "My pick up and sorc parameters"

This reverts commit 0920a406

* Changed number of loot columns

* Changes as per the comments:
Handle non-existing backup file.
Removed newline at the beginning of GameController class.
Changed line splitted into multiple lines back to a single line.

* Refactored graphic debugger with similar logic to botty to now have a controller.

* Added a small comment on the graphic debugger class and fixed a now-typo on the presented menu

* Bug Fix: if pressing F11 repeatedly the main loop may crash due to self.bot not yet initialized in the game_controller.

A safe solution would be to try and catch all but that would also be an overkill as it would most likely mask exceptions that we might want to make the program crash.

Checking that self.bot is initialized should work for the time being.

* No need to re-assign the resume key within the game controlelr anymore

* Urgent 1 liner bug fix for always_on_top: name 'config' is not defined

* Bug fix, keyboard dependency on game_recovery.py
For some reason PyCharm seems to flag this import as unused while it is actually used.

* Moved pywin32 dependency outside of pip (tested a clean install on two machines with this change and worked fine)

Also removed the win32api import that was causing the issue.

Both changes fix the issue that several people are expereincing on discord separately (either would fix it but both are better).
2022-01-05 10:49:44 +01:00
aeon0 e099848ed4 Npc serach optimization (#391)
* NPC search optimization

* fix pywin32 version
2022-01-04 12:24:43 +01:00
Matt StiehmandMatt fdfdd81b84 Restart game (#374)
* removed 1920_1080 support

* Update ui_manager.py

Fixed bug...

* Update pather.py

fixed scale factor

* Update i_char.py

* Update game.ini

removed tp locations

* Bump version to v0.4.3

* Bump version to v0.4.3

* added working restart module

* tested and looks stable after refactor

* fixed a few things after looking at PR

* switched things back to search after testing and removed 1s delay in save_and_exit search

* fixed tab select bug where the exit game prompt was up, and also fixed max game length bug on WP use

* Update a5.py

Changing back, as not needed.

* adding requested changes

* keyboard went missing from game_recovery

* missed case where restart fails then loops infinitely

* fixed typo. all tested now

* also removed flag resets since we're recreating hm and dm

Co-authored-by: Matt <[email protected]>
2022-01-04 10:08:50 +01:00
aeon0 aa5af79e85 some atk sequence updates (#388)
* some atk sequence updates

* increase wait time to pick up corpse
2022-01-03 21:29:16 +01:00
aeon0 e3093ee50a Clean unused templates (#387) 2022-01-03 20:10:24 +01:00
Legit 4e4dfc695e Fixed sorc 301 pathing. (#384)
* Updated blizz sorc 301 pathing issue

* Fixed 301 pather.

* fixed node 301 offset
2022-01-03 20:02:34 +01:00
Francesco e7d40c286e 1 liner bug fix for game_recovery: name 'config' is not defined (#385)
* My pick up and sorc parameters

* Moved the game logic away from the main within the new GameController class.
Refactored the main to use built-in keyboard add_hotkey and wait functions instead of self-written main loop.

* Revert "My pick up and sorc parameters"

This reverts commit 0920a406

* Changed number of loot columns

* Changes as per the comments:
Handle non-existing backup file.
Removed newline at the beginning of GameController class.
Changed line splitted into multiple lines back to a single line.

* Refactored graphic debugger with similar logic to botty to now have a controller.

* Added a small comment on the graphic debugger class and fixed a now-typo on the presented menu

* Bug Fix: if pressing F11 repeatedly the main loop may crash due to self.bot not yet initialized in the game_controller.

A safe solution would be to try and catch all but that would also be an overkill as it would most likely mask exceptions that we might want to make the program crash.

Checking that self.bot is initialized should work for the time being.

* No need to re-assign the resume key within the game controlelr anymore

* Urgent 1 liner bug fix for always_on_top: name 'config' is not defined
2022-01-03 19:59:56 +01:00
Fiseandaeon0 992bfa91e8 Feature Request: Allow Classic players to show hammerdin scepters from Drogan (#379)
Co-authored-by: aeon0 <[email protected]>
2022-01-03 18:40:24 +01:00
skizotenigma 3218d84e02 Act 1 town full usage (#381)
* Act 4 - Full usage

Added Jamella as working NPC.
Added Halbu as working NPC.
Set Cain to Identify.
Added stash capabilities.

* Delete pickit.ini

* Delete a3.py

* Update pather.py

* Update npc_manager.py

* oopsy doodle

* Fixing more issues.

* Create pickit.ini

* Update a4.py

* Update a3.py

* Update pather.py

* Update pickit.ini

reverted pickit

* A1 - Completed NPCS

i hate my life.
All npcs that matter are working.
charsi repairs and tomes.
akara heals and pots.
cain identifys.
kashya resurrects.
warriv STANDS IN FRONT OF THE DAMNED STASH SO IT CAN'T BE CLICKED.
the stash .. uh stashes.
waypoints work (as long as it's the SOUTH ONE ONLY.)

#todo: fix the WP's to actively check.

* wp fix.

now it will check south and then go north.

* WP fix
2022-01-03 18:23:35 +01:00
Francesco 01e8078067 set D2R window to be always on top (#382)
* My pick up and sorc parameters

* Moved the game logic away from the main within the new GameController class.
Refactored the main to use built-in keyboard add_hotkey and wait functions instead of self-written main loop.

* Revert "My pick up and sorc parameters"

This reverts commit 0920a406

* Changed number of loot columns

* Changes as per the comments:
Handle non-existing backup file.
Removed newline at the beginning of GameController class.
Changed line splitted into multiple lines back to a single line.

* Refactored graphic debugger with similar logic to botty to now have a controller.

* Added a small comment on the graphic debugger class and fixed a now-typo on the presented menu

* Bug Fix: if pressing F11 repeatedly the main loop may crash due to self.bot not yet initialized in the game_controller.

A safe solution would be to try and catch all but that would also be an overkill as it would most likely mask exceptions that we might want to make the program crash.

Checking that self.bot is initialized should work for the time being.

* No need to re-assign the resume key within the game controlelr anymore

* Saving changes before switching repo

* Move the logic to set d2r always on top in the utils package.

* Remvoed unused dependency

* Always on top currently only works in Windows

* Removed one-time used variable

* Moved D2R window always on top to advanced_options.

Now the D2R window is set always on top only when the bot start (F11) and when it pause or F12 is pressed the D2R window (if it still exists) will be restored to its original value
2022-01-03 17:26:07 +01:00
bjoerm b12904132c Pre-Buff before each arm - if do_pre_buff is enabled. (#378) 2022-01-03 05:28:22 +01:00
skizotenigma 2bdedf40eb Act 4 - Full usage (#369)
* Act 4 - Full usage

Added Jamella as working NPC.
Added Halbu as working NPC.
Set Cain to Identify.
Added stash capabilities.

* Delete pickit.ini

* Delete a3.py

* Update pather.py

* Update npc_manager.py

* oopsy doodle

* Fixing more issues.

* Create pickit.ini

* Update a4.py

* Update a3.py

* Update pather.py

* Update pickit.ini

reverted pickit
2022-01-02 22:04:43 +01:00
John Wu df05d9ff02 update run.bat (#377)
* Create run.bat

run bat instead of typing commands in cmd

* Update run.bat

added exit option, fixed some typo and it will open new cmd for install/update evn then close, and run.bat will stay open

* Update run.bat

* Update run.bat
2022-01-02 22:02:50 +01:00
egut125 55313f46bb Merge pull request #356 from aeon0/log-item-on-keep
only log item on keep of item
2022-01-01 15:40:35 -05:00
egut125 e66661c3c8 maye last removal? Probably not 2022-01-01 14:32:19 -05:00
aeon0 32011d815b Allow bo and bc for weapon switch (#373) 2022-01-01 20:24:36 +01:00
aeon0 36d5f2a532 Catch pickit config errors and reduce to print (#372) 2022-01-01 20:24:16 +01:00
egut125 7266468d85 Updating Beautiful Table Styling (#371) 2022-01-01 20:23:40 +01:00
egut125 96bc1ef7cb Removing Game_stats from Pickit 2022-01-01 10:47:57 -05:00
aeon0 2e0be629d8 Take screen as param in Chest Class (#368) 2022-01-01 16:35:59 +01:00
Héctor Giménezandaeon0 0da682043e Fix for crash on A2 Summoner for Sorceress (#365)
* Update src/char/sorceress/light_sorc.py

* Replaced not defined for Sorceress right_attack and left_attack by blizzard and iceblast or chain_lightning and lightning

Co-authored-by: aeon0 <[email protected]>
2022-01-01 16:19:55 +01:00
aeon0 2a6f1bd6a4 Dont use telekinesis on pindle red portal (#367) 2022-01-01 16:09:31 +01:00
aeon0 a0b2917cc5 fix attacks on summoner for sorc (#366) 2022-01-01 15:50:32 +01:00
aeon0 777c6da302 Optimize nova sorc for trav (#364) 2022-01-01 15:26:15 +01:00
aeon0 5f0a804a41 Warn user about settings not being as required (#363) 2022-01-01 14:58:54 +01:00
skizotenigma a2c308b6f8 Update a3.py (#362)
Cain can now identify in act 3
2022-01-01 14:54:49 +01:00
aeon0 d8942f92b4 A2 Pathing + Arcane run + Static for Sorc + Static Tele robustification + Chest class (#348) 2022-01-01 14:15:13 +01:00
John Wu 0fe0b55661 Create run.bat (#360)
run bat instead of typing commands in cmd
2022-01-01 14:14:57 +01:00
Francesco 343934970d Bug Fix: F11 pressed repeatedly might crash the main loop (#359)
* My pick up and sorc parameters

* Moved the game logic away from the main within the new GameController class.
Refactored the main to use built-in keyboard add_hotkey and wait functions instead of self-written main loop.

* Revert "My pick up and sorc parameters"

This reverts commit 0920a406

* Changed number of loot columns

* Changes as per the comments:
Handle non-existing backup file.
Removed newline at the beginning of GameController class.
Changed line splitted into multiple lines back to a single line.

* Refactored graphic debugger with similar logic to botty to now have a controller.

* Added a small comment on the graphic debugger class and fixed a now-typo on the presented menu

* Bug Fix: if pressing F11 repeatedly the main loop may crash due to self.bot not yet initialized in the game_controller.

A safe solution would be to try and catch all but that would also be an overkill as it would most likely mask exceptions that we might want to make the program crash.

Checking that self.bot is initialized should work for the time being.

* No need to re-assign the resume key within the game controlelr anymore
2021-12-31 17:48:45 +01:00
Francesco 268652b4ff Backup and Restore settings (#349)
* My pick up and sorc parameters

* Moved the game logic away from the main within the new GameController class.
Refactored the main to use built-in keyboard add_hotkey and wait functions instead of self-written main loop.

* Revert "My pick up and sorc parameters"

This reverts commit 0920a406

* Changed number of loot columns

* Changes as per the comments:
Handle non-existing backup file.
Removed newline at the beginning of GameController class.
Changed line splitted into multiple lines back to a single line.

* Refactored graphic debugger with similar logic to botty to now have a controller.

* Added a small comment on the graphic debugger class and fixed a now-typo on the presented menu
2021-12-31 09:06:27 +01:00
egut125 d4de72b285 Left in a removed param... 2021-12-31 00:02:05 -05:00
egut125 430b6f5394 Forgot the test name change 2021-12-30 23:52:09 -05:00
egut125 5dbb5c86d4 only log item on keep of item
uiManager now knows game_stats
keep item now logs items pickit
2021-12-30 23:37:41 -05:00
skizotenigma 515e308bab fix for IDing (#353)
* fix for IDing

* Update pather.py
2021-12-30 23:33:19 +01:00
Legitandaeon0 ba1f8de798 Fix for blizz_sorc master (#351)
* Fix for blizz_sorc master

* removed delay

* Update src/char/sorceress/blizz_sorc.py

Co-authored-by: aeon0 <[email protected]>
2021-12-30 20:04:50 +01:00
aeon0 88c9e28d45 Nova Sorc (#350)
* Nova Sorc

* formating
2021-12-30 17:02:03 +01:00
skizotenigma badcd77ea6 Identify Items at Chain (A5) (#339) 2021-12-30 14:12:43 +01:00
skizotenigma b3d756eeba CTA check to make sure you can BO/BC (#347)
* CTA check to make sure you can BO/BC

* added a second check to make sure they even HAVE cta.

added a second check to see if BC shows after the change. if not it cancels it all out.

* now it turns off cta_Available if it's not found.,

* Update i_char.py

* Update i_char.py

* Add files via upload

* Update i_char.py

* code rework (thank to aeon)

now with 100% less hacks!

* corrected icon

bc not bo.. duh

* Update i_char.py

* moved button
2021-12-29 20:02:10 +01:00
aeon0 579ab25c7d Update README.md 2021-12-29 16:21:59 +01:00
Stathis Papandreou 65f7641884 Update README.md (#334) 2021-12-29 16:20:23 +01:00
aeon0 4ab5908336 Barb improvements (#344)
* barb improvments

* dont do weapon switch
2021-12-29 10:47:29 +01:00
aeon0 8fc3155868 Update Blizz Sorc (@Legit) (#343) 2021-12-28 18:20:01 +01:00
aeon0 69ba480c08 Add ItemFinder unittests (#342)
* Sort items by relevance

* add item finder test
2021-12-28 15:56:06 +01:00
aeon0 7eef36c2df Add Tests and Coverage report (#341) 2021-12-28 14:40:28 +01:00
aeon0 3b6e92fcb1 Update version.py 2021-12-28 11:49:08 +01:00
skizotenigma f1dbce3a69 Repair Each Run (#338)
* Update bot.py

* Update config.py

* Update params.ini

* Update params.ini

removing comments

* Update bot.py

removing comments

* Update config.py

removing comments

* Update README.md
2021-12-28 00:04:41 +01:00
aeon0 22b468e771 New release v0.6.1 (#332)
* Bump version to v0.6.1

* adjust version
2021-12-25 08:51:40 +01:00
aeon0 aaae0ac41c Dont click on merc icon (#331) 2021-12-25 08:08:41 +01:00
mgleed b1e4f82c25 fix gold issue causing pickit_type error (#329) 2021-12-24 13:15:44 -05:00
aeon0 2f37b2b1da dev version 2021-12-24 15:46:17 +01:00
aeon0 da401dc9bc New release v0.6.0 (#328)
* Bump version to v0.6.0

* correct version
2021-12-24 15:34:36 +01:00
aeon0 77d04a0c21 Retry town portal creation on fail (#327) 2021-12-24 15:23:33 +01:00
aeon0 303082ff99 Random move if staris not found (#326) 2021-12-24 12:32:26 +01:00
aeon0 bb523b34fe Trapsin updates (#325) 2021-12-24 12:24:10 +01:00
aeon0 db7c011ded Blizz Sorc adjustments (#324) 2021-12-24 11:34:03 +01:00
aeon0 43244e85b9 Light sorc overhaul (#323)
* Light sorc overhaul

* also use lightning

* readme update
2021-12-24 10:01:15 +01:00
Legitandaeon0 96e42049eb Blizz sorc updates (#321)
* Update blizz_sorc.py

* blizz sorc tuning

* Update blizz_sorc.py

indent fix

* fix indent errors

* shenk assets

* updated pather for shenk

Co-authored-by: aeon0 <[email protected]>
2021-12-23 23:55:34 +01:00
aeon0 d4836a1e4f Buy potions from vendor (#320) 2021-12-23 23:01:04 +01:00
aeon0 68bb17428a Update README.md 2021-12-23 22:10:27 +01:00
Legit ddd92ad303 Cold-sorc-trav-eld-shenk (#300) 2021-12-23 22:03:06 +01:00
aeon0 f60f6539ff If in doubt, just use path a (#318) 2021-12-23 21:53:09 +01:00
Luiz Felipe Aranha 2cc9ee36c7 include mangsong to pickit (#317)
* include mangsong to pickit

* Add files via upload
2021-12-23 21:14:51 +01:00
aeon0 269fd2246f Save stats to new file (#316) 2021-12-23 14:08:49 +01:00
aeon0 5f44213692 Share belt manager instance accross health manager and bot (#315) 2021-12-22 21:53:09 +01:00
aeon0 d6a8de3c80 Configurable ordering of runs (#314) 2021-12-22 21:48:05 +01:00
mgleed b5805a19aa Add require/exclude properties to pickit.ini when stashing items. Also more item templates. (#295) 2021-12-21 20:46:27 +01:00
aeon0 44d9cb40f2 Nihlatak test (#312)
* nihlatak eye at a robustness?

* revert stuff
2021-12-21 19:23:45 +01:00
Luiz Felipe Aranha 616e6b25b9 Update ui_manager.py (#311)
tome bug workaround
2021-12-21 08:48:12 +01:00
egut125 5993e876e8 Config discord condensed (#310)
* Added new discord_status_condensed that can be set =1 to get condensed status report

* Readme update
2021-12-20 20:28:00 +01:00
stephan-01010011 752bd813ea Nihlatak run changed to use the correct path if the template 'NI2_A_SAFE_DIST_2' was detected. (#304)
- Template assets renamed to use an uniform suffix. _save_dist, _noattack
- EyeCheckData class enhanced to contain a destination static path definition that is used instead of the template name
2021-12-19 11:55:24 +01:00
egut125 feafdca33d Correctly Total Failed Runs, Only Set location to shenk when battling, not on run start (#303) 2021-12-19 08:26:40 +01:00
aeon0 a267c9fbf2 Update README.md 2021-12-18 22:06:48 +01:00
aeon0 d766f4222c Dont spam screenshots, forgot if condition 2021-12-18 20:51:42 +01:00
aeon0 e1fa484cb8 Eldritch pathing robustness (#302)
* Robustify eldritch pathing

* failed game screenshot

* remove log
2021-12-18 13:03:35 +01:00
egut125andaeon0 bfcd2babaa Adding location_stats dict to hold stats for each run (#297)
* Adding location_stats dict to hold stats for each run

Logs Items,Deaths,Chickens,Merc Deaths, and Fails for each run
Discord message prints stats by run in table
stats.log lists run table and items by run

* clean up

Co-authored-by: aeon0 <[email protected]>
2021-12-17 19:57:12 +01:00
yhkinsar db63ce66b6 adding more uniq items (#299) 2021-12-17 19:52:15 +01:00
aeon0 29a4eaf9b2 Fix static field param (#296) 2021-12-15 23:53:43 +01:00
aeon0 b33135f704 Bump version to v0.5.1 (#294) 2021-12-15 19:03:52 +01:00
aeon0 67e03fc938 Adjust template for nil on A (#293)
* Adjust template for nil on A

* change order
2021-12-15 18:05:53 +01:00
aeon0 3c39cfa5d9 Fix trav gold pick up only after latest changes + clean ups (#292) 2021-12-15 16:24:55 +01:00
tw1st40 be1f1ce08c Barbarian support (currently War Cry/singer only) with Horking (#288)
* Added Barbarian support (currently War Cry/singer only) with Horking (find item) - thanks Outburst.

* Changes as requested by aeon for pull request to be merged.
2021-12-15 15:49:09 +01:00
yhkinsar 7b7815a021 Support Greater Potion (#290) 2021-12-15 15:47:40 +01:00
EthanJian 5b70c24c7b Add-Mercenary-deaths-counter (#287)
1. Add a merc deaths counter in game_stats.py.

2. Trigger: put it in bot.py while Check if merc needs to be revived.
2021-12-15 08:42:24 +01:00
egut125 636745f47b Add location from the Run procedure (#283)
* Add location from the Run procedure and all Discord messages can leverage

* Removing old area calls

* remove logger

* Shenk Eld improvements

* Cleaning

* Cleaning
2021-12-14 23:04:33 +01:00
aeon0 4d083bee83 Use static for sorc at trav (#285)
* Sorc use static at trav

* Sorc use static at trav
2021-12-13 23:03:41 +01:00
aeon0 fe8c6d5de0 Trav for Sorc (#284) 2021-12-13 20:24:47 +01:00
aeon0 857052c75d Tele dancing sorc nil (#282)
* Implement simple "tele-dancing" for sorc nil

* increase trav atk len
2021-12-13 19:13:53 +01:00
aeon0 bf7ce99c5f Implement Nihlatak for Sorc (#281) 2021-12-13 18:14:03 +01:00
aeon0 b6260327b7 Add area for item pickup 2021-12-13 17:20:47 +01:00
aeon0 8a85f38819 Optional Redemption 2021-12-13 17:17:58 +01:00
aeon0 c2bd99af18 Fix gold stashing bug (#280) 2021-12-13 17:00:52 +01:00
aeon0 5e43da1f02 Bump version to v0.5.0 (#278) 2021-12-12 21:22:45 +01:00
aeon0 f5fb8561c6 Classic min max confusion 2021-12-12 20:41:13 +01:00
aeon0 eb6dd85063 Fix stashing (#277)
* Bump version to v0.5.0

* stash optimization

* add wait times

* revert version

* Fix stashing bug when gold is full

* change location

* force move
2021-12-12 20:30:37 +01:00
aeon0 fd2d57fb0c Fix shopper build (#276) 2021-12-12 18:49:20 +01:00
aeon0 fa1297e15e Config to force prebuff every run (#274) 2021-12-12 18:09:44 +01:00
aeon0 e184db7045 Rename region of interest (#275) 2021-12-12 18:08:38 +01:00
aeon0 d46624e932 Support for trapsin build (#273) 2021-12-12 18:06:23 +01:00
aeon0 6d88ccb379 Fix gold stashing turn off (#272) 2021-12-12 17:21:56 +01:00
aeon0 2d9307cb94 Static path trav and some renaming (#271)
* Static path trav and some renaming

* no random

* fix b node

* fix game recover issue

* adapt dclone stuff

* add back rand
2021-12-12 16:35:15 +01:00
cutebeast 2aff1800ef dclone ip hunting (#270)
* dclone ip hunting

This is add on to pause the bot and send msg to discord if we are able to obtain the correct hot ip for dclone.

* Update for dclone ip check

using messenger instead of discord
update param for section on dclone
move the block to check for ip to after town spawn

* update for dclone for ip hunting

allow setting to disable to ip search
2021-12-12 16:15:20 +01:00
jobithuandaeon0 17b7fcc2a2 Nihlatak (#244)
* nihlatak for testing

* comitting staged changes

* fixed some issues on template syntax

* merged nihlatak routine to all other files in the bot

merged nihlatak routine to all other files in the bot (next to pindle & shenk)

* make it run

* improved consistency for traverse LVL1_B & finding start at LVL2

improved consistency for traverse LVL1_B & finding start at LVL2

* further optimized pathing for LVL1 C & LVL2A

* nil update, pathing on lvl 2 fine tuning still needed

* optimized pathing lvl2

might needs some tweaks on 2_D, but otherwise fine.

* fine tune pathes lvl 2

* adapt to template matching nil arm C

* arm b

* fail save for branch a

* fail save for arm c

* arm d

* small clean up

Co-authored-by: aeon0 <[email protected]>
2021-12-12 13:00:31 +01:00
aeon0 1e1b4a2da0 Code improve for eth only filter (#269)
* Adapt eth checking

* update pickit
2021-12-12 09:57:09 +01:00
mgleed 68f2f0f3ce Allow item = 3 in pickit to make ethereal required to stash (#268)
* initial

* clarify
2021-12-12 08:46:38 +01:00
mgleed 05fe77a5d0 emilio is boring (#267) 2021-12-12 08:27:01 +01:00
nekolr c2a017c517 Use message template to support other hooks (#265) 2021-12-12 08:22:36 +01:00
mgleed 4c52045f08 Update .gitignore (#266)
update for config folder
2021-12-11 21:33:54 -05:00
aeon0 f1d228c9d7 Detect hit recovery on static teleport (#263) 2021-12-11 16:35:40 +01:00
aeon0 0f156be4d6 Params for shop (#262) 2021-12-11 15:41:54 +01:00
aeon0 86db356ca4 Split params and seperate .exe for shop and health manager (#261)
* Split Params and add shop to exe

* rename folder
2021-12-11 15:02:20 +01:00
aeon0 2c53524e79 Set misc_gold=0 in case stash is full of gold (#260)
* Set misc_gold=0 in case stash is full of gold

* fix config

* fix imports
2021-12-11 12:38:46 +01:00
aeon0 ea74a3b43f Only use stash tab and wp tab if needed (#259)
* Clean up imports & move files

* Only use stash tab and wp tab if needed

* break circular imports
2021-12-11 11:50:35 +01:00
aeon0 308c74ac4f Clean up imports & move files (#256) 2021-12-11 07:41:40 +01:00
aeon0 ede3dcd91b Make sure best match is used to determine town location 2021-12-10 15:27:46 +01:00
aeon0 8a773f4e5c Fix tuple assignment issue (#255) 2021-12-10 12:30:27 +01:00
aeon0 496340be8d Esc out of cain focus (#254) 2021-12-10 12:17:48 +01:00
aeon0 5c877c428e Smooth out shenk pathing start (#253) 2021-12-10 12:07:51 +01:00
aeon0 876df0dd5e Trav only gold pickup config 2021-12-10 11:36:21 +01:00
aeon0 d69a9942ac Add offset node func (#252) 2021-12-10 10:59:36 +01:00
aeon0 cec307cf9c Fix config error (#251) 2021-12-10 10:01:46 +01:00
aeon0 825e787dbe Stash gold default 1 2021-12-10 09:54:29 +01:00
Matt StiehmandMatt 702a2ebfca Separate gold and item stashing (#250)
* removed 1920_1080 support

* Update ui_manager.py

Fixed bug...

* Update pather.py

fixed scale factor

* Update i_char.py

* Update game.ini

removed tp locations

* Bump version to v0.4.3

* Bump version to v0.4.3

* implimented and tested seperation of gold and item stash counters

* removing extra newline

* not sure how this keeps creeping back...

Co-authored-by: Matt <[email protected]>
2021-12-10 09:53:58 +01:00
aeon0 0156b80ee6 Adjust item highlight range 2021-12-10 09:20:36 +01:00
aeon0 2043c45d48 Improved clustering & cropping of Items (#247) 2021-12-10 09:17:08 +01:00
mgleed 503be01463 Fix difficulty roi (#249)
* fix ROI for loading and difficulty buttons
2021-12-09 22:10:12 -05:00
aeon0 84a5b6257f Fix trav error handling (#248) 2021-12-09 22:46:04 +01:00
aeon0 81d513b0c9 Move files (#246) 2021-12-09 16:44:59 +01:00
aeon0 e64891dbbf Fix stashing issue (#245) 2021-12-09 15:39:40 +01:00
mgleed 3bd3364b4b Fix black game.ini (#238)
* fix black range

* fix black range
2021-12-09 15:19:33 +01:00
aeon0 afefdfd6b4 Add pathing a4 start to tyrael (#243) 2021-12-09 11:34:38 +01:00
aeon0 7c5e94979b Dont spam debug messages (#242) 2021-12-09 10:38:47 +01:00
aeon0 93d2a4bc8b When your bot doesnt pick up the best item in the game (#241) 2021-12-09 10:35:33 +01:00
aeon0 9559cf0e23 Move cursor on pickit (#240)
* Add area to items found

* Move cursor on pickit to avoid item highlight
2021-12-09 10:32:36 +01:00
aeon0 aacb344f32 Add area to items found log (#239) 2021-12-09 09:35:40 +01:00
aeon0 69870e73c5 Fix tele rebuy after failed tele (#237) 2021-12-08 21:41:40 +01:00
aeon0 ea8fc96f83 Walking Trav (#236)
* some tweaking
2021-12-08 18:26:41 +01:00
aeon0 54d27cace8 Improve trav pathing (#235)
* Log failed games

* Improve Trav Template Pathing
2021-12-08 13:22:36 +01:00
aeon0 7e365fb1cf Log failed games (#234) 2021-12-08 11:02:04 +01:00
aeon0 ca9e459de6 Check if repairing is needed (#233) 2021-12-08 09:28:19 +01:00
aeon0 2efcd66d99 Fix/robustify a4 start (#232) 2021-12-08 08:59:24 +01:00
bobcho 6e38fd5dd7 fix game start in act 4 (adj start tempates) (#231) 2021-12-08 06:16:27 +01:00
aeon0 37a4c8e0b2 Fix select template timeout bug (#230)
* Fix select template timeout bug

* remove print
2021-12-07 22:10:14 +01:00
aeon0 872fcccb00 Fix health manager pause (#227) 2021-12-07 12:54:17 +01:00
aeon0 9644e7a36e Speed up template pathing (#226)
* Speed up template pathing

* change comment
2021-12-07 12:14:50 +01:00
aeon0 19af63f965 Fix item pickup behind obstacles (#225)
* Fix item pickup behind obstacles

* remove debug stuff
2021-12-07 09:11:18 +01:00
aeon0 ee29e0918b Go to A5 Larzuk for repairing from other acts + TP bug fixed (#224)
* Go to A5 Larzuk for repairing from other acts

* Fix tp bug
2021-12-07 08:21:10 +01:00
aeon0 571f2101e8 Rename run.py to main.py (#223) 2021-12-07 08:01:10 +01:00
aeon0 18c5344af7 Refactor runs (#222)
* Refactor code for runs

* add some forced moves for robustification

* move back to save spot for trav
2021-12-07 07:29:45 +01:00
aeon0 f7b1c834c9 Integrate Trav Run (#221) 2021-12-06 20:40:55 +01:00
aeon0 bbda12709f Connect all towns (#220) 2021-12-06 18:15:58 +01:00
aeon0 0b6b1bfa2a Add Npc: Ormus (#218) 2021-12-06 07:17:24 +01:00
aeon0 01284ae62e Add Npc: Tyrael (#217) 2021-12-06 07:07:15 +01:00
aeon0 af5e4ffebe Use merc config (#216)
* Use merc config

* docs
2021-12-06 06:58:14 +01:00
aeon0 e6491d8642 docs 2021-12-06 06:57:03 +01:00
aeon0 589defb38e A4 Town Pathing (#215) 2021-12-06 06:46:39 +01:00
mgleed b0d3552121 Create template masks in __init__() (#212)
* preload template masks

* fix varnames
2021-12-06 06:46:30 +01:00
mgleed 6554ad167b Disable quick cast in default settings until officially supported (#209)
* disable quickcast in settings until this is officially supported

* disable quickcast in settings until this is officially supported

* disable quickcast in settings until this is officially supported

* disable quickcast in settings until this is officially supported

* disable quickcast in settings until this is officially supported
2021-12-04 22:36:30 -05:00
mgleed 5822151d14 Adj template finder (#208)
* swap test templates

* swap test templates
2021-12-04 21:47:13 -05:00
Matt Stiehm 8b438b25ff Run no item pickup command on startup (#205) 2021-12-04 23:25:44 +01:00
Dongwook Kim 3459d4a35e feat: adding magic amulet to pickable item list (#207) 2021-12-04 22:56:36 +01:00
aeon0 84d1bf1559 Revert Merc template (#206) 2021-12-04 21:57:48 +01:00
aeon0 0d6c02486a Bump version to v0.4.4 (#204) 2021-12-04 20:15:46 +01:00
aeon0 430c2557d7 Revert npc assets (#203) 2021-12-04 19:48:45 +01:00
aeon0 4bd140cac4 ... 2021-12-04 19:31:40 +01:00
aeon0 7dbbbfbebf Fix discard issue by adding a wait time (#202)
* Fix discard issue by adding a wait time

* add docs
2021-12-04 19:22:29 +01:00
aeon0 32c9483afd Use masked skill assets (#201)
* Use masked skill assets

* fix config

* increase thresh at skill selection
2021-12-04 17:45:14 +01:00
aeon0 e47c98b80c Decrease spread of attacks on pindle 2021-12-04 16:19:45 +01:00
aeon0 861b4ff639 Revert Anya templates (#199) 2021-12-04 13:34:59 +01:00
aeon0 914ac74d2f Check for available tps on start of run (#196) 2021-12-04 11:41:15 +01:00
aeon0 5d91d2ff14 Fix template selection to wait for success (#195) 2021-12-04 10:44:01 +01:00
navy91 0e4d4e7dff Adjusted threshold for gold deteciton in inventory(#191) 2021-12-04 08:03:03 +01:00
ggodev ad614cb000 game breaking sun spirit fix (#192) 2021-12-04 08:02:18 +01:00
navy91 3da81815bd skip gold stashing when there's no gold in inventory (#182)
* skip gold stashing when there's no gold in inventory

* skip stashing - performance upgrade
2021-12-03 22:44:39 +01:00
aeon0 916777b86d Fix creash on death and chicken delay (#190) 2021-12-03 21:34:25 +01:00
aeon0 32dc347e7e Prepare for shop release (#189) 2021-12-03 20:56:20 +01:00
mgleedandaeon0 10015fc73c Template alpha channel (#170)
* add support for template alpha channels

* cleaner

* fix merc pic

* fix merc pic

* comment

* NPC alpha channels and modify you_have_died detection

* adapt to automatic template loading

* show all matches in template finder

Co-authored-by: aeon0 <[email protected]>
2021-12-03 18:40:10 +01:00
egut125andaeon0 3fea6d7399 Added new param discord_status_count (#183)
discord_status_count defines number of games between discord status messages being sent. Defaults to 20

Co-authored-by: aeon0 <[email protected]>
2021-12-03 18:35:48 +01:00
aeon0 55bead2c9f Revert back to previous npc search (#185) 2021-12-03 18:24:43 +01:00
César Vargas eaf0beb83b Add saved_games_folder param (#179)
* implement saved_games_folder paramgit c

* add saved_games_folder readme entry
2021-12-03 06:59:45 +01:00
aeon0 0f60502ce1 Add Pathing for Trav (#181) 2021-12-02 23:38:28 +01:00
aeon0 69f94b2c1f Add Pathing for A3 Town (#180) 2021-12-02 22:03:23 +01:00
egut125 80d2a14d5c Add in logic when botty is paused and not trigger max game length (#167) 2021-12-02 19:04:45 +01:00
aeon0 6f0a000bf1 Template finder auto load based on filenames (#178)
* Fix gamerecovery creating 2 bot instances

* Auto load template based on filenames

* Actually load the correct templates
2021-12-02 16:40:13 +01:00
aeon0 0cee182a8d Update bug_report.md 2021-12-02 16:38:10 +01:00
aeon0 56b703e8a8 Update bug_report.md 2021-12-02 16:37:01 +01:00
aeon0 076fafb64e Fix gamerecovery creating 2 bot instances (#177) 2021-12-02 14:23:06 +01:00
aeon0 dd0084caad Update README.md 2021-12-02 12:08:20 +01:00
aeon0 1450e158f5 Fix NPC highlighted action btn (#175) 2021-12-02 11:41:00 +01:00
aeon0 4c28ab9461 Revert npc multi tempalte search (#174) 2021-12-02 11:06:05 +01:00
mgleed e34a33ac98 simplify some code based on recent search update (#171)
* simplify some code based on recent search update

* save

* save
2021-12-02 08:27:02 +01:00
mgleed 1e51c6e5e5 remove resolution conditional statement from gloves shopper (#172) 2021-12-01 22:19:48 -05:00
aeon0 1ab1195a31 New release v0.4.3 (#169)
* Bump version to v0.4.3

* increase min item score
2021-12-01 21:52:16 +01:00
aeon0 4a9ff45959 Add blacklist items (#166)
* Add blacklist items

* increase min score for items a bit
2021-12-01 18:50:18 +01:00
aeon0 9337e7d2bc Remove useless mouse moves (#165) 2021-12-01 18:47:15 +01:00
aeon0 3f81bf3d75 Remove slow walk + adjust node positions (#164) 2021-12-01 18:39:43 +01:00
aeon0 65a8085065 Fix item pickup with telekinesis (#163) 2021-12-01 18:21:49 +01:00
aeon0 1d7fcbafca Update release process (#161)
* Update release process

* update ci
2021-12-01 17:53:46 +01:00
aeon0 71debec858 Run Health and Death Manager parallel to Bot (#160)
* Run Health and Death Manager parallel to Bot

* fix test
2021-12-01 17:45:05 +01:00
mgleed 0477d0d2bf remove old rois, repl with difficulty_sleect roi (#158) 2021-12-01 17:32:12 +01:00
mgleed 0234aa1fdf utilize last_rejuv (#156) 2021-12-01 06:41:50 +01:00
Daniel Colon d9f5f55ea2 fix(sorc): hold mouse during attack delay (#155)
* fix(sorc): hold mouse during attack delay

* fix(sorc): check mouse is release on chicken/death
2021-12-01 00:17:11 +01:00
WiZ 0dcbb98e89 Full Standalone Shopper Script for Anya IAS Gloves and Claws (#148) 2021-11-30 23:36:19 +01:00
mgleed ca4d51e48e Tomb to tome (#154)
Small spelling fix
2021-11-30 17:02:10 -05:00
mgleed 33b0b533e6 Support list input for template_finder.search() and improve code quality (#125) 2021-11-30 22:40:05 +01:00
aeon0 18ded27113 Docs and auto setting for removed res (#153) 2021-11-30 21:27:37 +01:00
Matt Stiehm 5ef427b85b Removed 1920_1080 support (#149) 2021-11-30 20:56:36 +01:00
aeon0 8bdf5e2857 Fix getting stuck at discarding (#152) 2021-11-30 12:34:05 +01:00
reqyl c6829b4ab0 Revert incorrect pot increment (#151) 2021-11-30 12:25:33 +01:00
jrzheng e114c89d65 Correct limit on pot need increase after using pot (#145) 2021-11-29 12:48:32 +01:00
ggodev ffd748bd3c blacklisted superior flameberge, as it gets recognized for superior flail (#146) 2021-11-29 12:45:24 +01:00
mgleed 7805722c1b Update pot count on use (#143)
* update potion count on drink

* fix merc stat
2021-11-29 07:32:52 +01:00
aeon0 71c24fcb64 Why nobody told me about /nopickup until now!??! (#141) 2021-11-29 07:30:48 +01:00
aeon0 6def14dc98 Check if stashing is needed on start after x runs without stashing (#138)
* Check if stashing is needed on start

* decrease number
2021-11-28 15:42:08 +01:00
aeon0 6fbbdb46dc Check corpse after game recovery (#137)
* Check corpse after game recovery

* add some death manager handling

* actually end game on death deteciton at end of run
2021-11-28 15:04:33 +01:00
aeon0 df7ef97575 Delete custom_keyboard.py. Currently not in use 2021-11-28 14:34:59 +01:00
aeon0 bfb8c16fa0 Support Hammerdin without Engima (#136) 2021-11-28 14:33:09 +01:00
mgleed 28a455d964 autodownload nuitka dependencies for compile (#134) 2021-11-28 08:23:56 +01:00
jagarop 654f6ed91e 720 assets (#133)
* Update uniq_weapon_death_web.png

fix

* add some 720 assets
2021-11-28 08:23:26 +01:00
jrzhengandjrzheng fe6019079b Fix javashop monitor (#135)
Co-authored-by: jrzheng <[email protected]>
2021-11-28 08:22:57 +01:00
reqyl 558be5ab9a Make it possible to initialize Screen ingame (#132)
* Make it possible to initialize Screen ingame

This fixes broken shopping script due to only lobby being supported right now. This also fixes standalone scipts node recorder. Both resolutions are supported

* Use game.ini conf for offset
2021-11-27 16:07:13 +01:00
aeon0 36fc3d7574 add powershell info 2021-11-27 11:47:13 +01:00
aeon0 66e0c9a52d Lord have merci on me (#130) 2021-11-27 09:03:42 +01:00
aeon0 3fa0471198 New release v0.4.2 (#129)
* Bump version to v0.4.2

* add license

* visible error msg
2021-11-27 08:54:22 +01:00
aeon0 0b318e1131 Add user info about window offset search (#128)
* Bump version to: 0.4.1

* More cmd info regarding offset search

* english
2021-11-27 07:51:29 +01:00
2275 changed files with 143598 additions and 4875 deletions
+16
View File
@@ -0,0 +1,16 @@
# .coveragerc to control coverage.py
[run]
branch = True
[report]
# Regexes for lines to exclude from consideration
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover
# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError
# Don't complain if non-runnable code isn't run:
if 0:
if __name__ == "__main__":
+4 -1
View File
@@ -7,6 +7,9 @@ assignees: ''
---
**Is it really a Bug report?**
If you have questions regarding setup or feature information/requests, please consider asking in the Discord channel: https://discord.gg/Jf3J8cuXWg. The Github issues section is for bug reports only.
**Botty Version**
What version of botty are you running? Are you using a pre-compiled release? Which one. Are you using the latest master branch? On which commit?
@@ -26,7 +29,7 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots or even better a short video of the error happening to help explain your problem. Botty often automatically makes screenshots when something goes wrong. Add these also.
**Logs**
Add the relevant part of the info.log in this section. Either upload it as a fail or copy-paste the relevant part in here.
Add the relevant part of the log/log_(time).txt in this section. Either upload it as a fail or copy-paste the relevant part in here.
**Additional info**
Add any other information about the problem here.
+12 -7
View File
@@ -5,16 +5,16 @@ jobs:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Setup Miniconda Python 3.8
- name: Setup Miniconda Python 3.10
uses: actions/setup-python@v2
with:
python-version: 3.8
python-version: '3.10'
# TODO: The below setp only chaches conda packages, need to cache pip seperatly
- name: Cache conda
uses: actions/cache@v2
env:
# Increase this value to reset cache if environment.yml has not changed
CACHE_NUMBER: 0
CACHE_NUMBER: 1
with:
path: ~/conda_pkgs_dir
key: conda-${{ env.CACHE_NUMBER }}-${{hashFiles('environment.yml') }}
@@ -22,14 +22,14 @@ jobs:
uses: actions/cache@v2
env:
# Increase this value to reset cache if environment.yml has not changed
CACHE_NUMBER: 0
CACHE_NUMBER: 1
with:
path: ~/pip
key: pip-${{ env.CACHE_NUMBER }}-${{ hashFiles('environment.yml') }}
- name: Install Miniconda
uses: conda-incubator/setup-miniconda@v2
with:
python-version: 3.8
python-version: '3.10'
activate-environment: botty
channel-priority: strict
environment-file: environment.yml
@@ -39,9 +39,14 @@ jobs:
run: |
C:\Miniconda\condabin\conda.bat init powershell
set PYTHONPATH=./src
- name: Pytest
- name: Pytest & Coverage
shell: powershell
run: |
C:\Miniconda\condabin\conda.bat activate botty
python -c "import sys; print(sys.version)"
pytest -v -s
coverage run --source=./src -m pytest -v -s
- name: Coverage Report Generation
shell: powershell
run: |
C:\Miniconda\condabin\conda.bat activate botty
coverage xml
+21 -6
View File
@@ -4,19 +4,34 @@ __pycache__/
playground.py
*.pyc
*.pyo
*.log
*.spec
dist/
build/
run.build/
run.dist/
run.onefile-build/
main.build/
main.dist/
main.onefile-build/
generated/
botty_v*/
custom.ini
*info_*.png
config/custom.ini
config/custom.*.ini
.vscode
.vs/
test/assets/
.venv
*.bak
.coverage
htmlcov/
coverage.xml
utils/live-view/
config/bnip/*
!config/bnip/.gitkeep
stats/
info_screenshots/
item_error_screenshots/
loot_screenshots/
.venv
pickit_screenshots/
*info_log_parsed.txt
*info_*.png
*.log
log/
+87
View File
@@ -0,0 +1,87 @@
# Botty Improvements Implementation Plan
## Status Legend
- [ ] Not started
- [~] In progress
- [x] Done
- [-] Cancelled / low priority
---
## Phase 1: Key Auto-Detection (Issue #940)
Read D2R .key file and auto-fill hotkeys.
- [x] Create src/utils/key_detector.py module
- [x] VK code mapping (partial — needs review for accuracy)
- [x] Parse .key file (text format: VK action_type param)
- [x] Auto-fill empty [char] hotkeys from detected bindings
- [x] Auto-fill build-specific skill hotkeys (fohdin, hammerdin, etc.)
- [x] Wire into config.py load_data()
- [ ] REVIEW: Verify VK_MAP accuracy (D2R uses its own VK offset scheme)
- [ ] REVIEW: Skill slot-to-config matching is heuristic — may misassign
- [ ] TEST: Verify against actual D2R .key file on user's machine
## Phase 2: Target Detection False Positives (Issues #959/#964)
Health bars and "immune to X" text mistaken for targets.
- [ ] Analyze current get_visible_targets() in target_detect.py
- [ ] Add shape/size filtering: health bars are thin horizontal strips, immune text is small
- [ ] Add aspect ratio check: real targets (poison/freeze auras) are roughly circular/elliptical
- [ ] Add minimum bounding box height constraint (filter out thin text)
- [ ] Optionally: add color temperature check (immune text is yellow/gold, not blue/green)
- [ ] Test with screenshots of edge cases
## Phase 3: Pickit Timing Fix (Issue #939)
Items skipped because bot teleports away before grabbing.
- [ ] Review pickit.py _yoink_item() for timing issues
- [ ] Add configurable pickup_delay parameter (current: fixed timing)
- [ ] Add retry logic: if item still visible after pickup attempt, re-try
- [ ] Add "slow mode" for large/heavy items (framed/magic items may animate longer)
- [ ] Ensure bot doesn't teleport until pickup animation completes
- [ ] Test: verify no "Attempt to pick xyz" warnings followed by teleport
## Phase 4: Parallel Template Search (Issue #848)
Speed up template_finder.search() with threading.
- [ ] Add ThreadPoolExecutor-based search_all_parallel()
- [ ] Keep existing search() for single-template (no overhead)
- [ ] Only parallelize when searching >3 templates simultaneously
- [ ] Benchmark: measure speedup on typical 1280x720 grab
## Phase 5: Async Mouse Moves (Issue #955)
Non-blocking mouse movement.
- [ ] Add async_move() to utils/custom_mouse.py
- [ ] Run movement in background thread
- [ ] Add is_moving() / wait_for_move() synchronization
- [ ] Integrate into game_controller.py for smoother action chains
## Phase 6: Hardcore Chicken Loop Fix (Issue #942)
Prevent infinite death loops on Hardcore characters.
- [ ] Review death_manager.py chicken logic
- [ ] Add max_chicken_count config parameter (default: 3)
- [ ] If max chicken count exceeded on HC, exit gracefully instead of re-entering
- [ ] Add defensive chicken config option (chicken to TP instead of full chicken)
- [ ] Test: verify HC character exits cleanly after N deaths
## Phase 7: Auto-Label NPCs (Issue #950)
Learn vendor identities automatically during gameplay.
- [ ] During town states, detect NPC name plates via OCR
- [ ] Cross-reference detected names with known NPC list
- [ ] Auto-capture NPC templates when confidence is high
- [ ] Store learned templates in assets/npc/
- [ ] This is a long-term feature — lower priority
---
## Priority Order (implement in this order)
1. **Phase 1** - Key auto-detection (already partially done, needs review + test)
2. **Phase 3** - Pickit timing (high impact on loot collection)
3. **Phase 2** - Target detection (high impact on kill reliability)
4. **Phase 6** - Hardcore chicken fix (safety critical)
5. **Phase 4** - Parallel template search (performance)
6. **Phase 5** - Async mouse moves (quality of life)
7. **Phase 7** - Auto-label NPCs (long-term feature)
+561
View File
@@ -0,0 +1,561 @@
# Quest Framework + Den of Evil Plan
## Goal
Build a quest automation framework in botty that can interact with D2R NPCs, handle dialogue,
track quest progress, and run Den of Evil as the first quest -- all usable by a low-level FoHdin.
---
## Architecture
The quest framework is a new subsystem that plugs into the existing botty state machine.
It follows the same patterns as existing runs (approach -> battle -> return to town) but adds
NPC dialogue interaction and quest state persistence.
### New files
```
src/quest/
__init__.py # Exports
quest_manager.py # Quest state machine + persistence (JSON)
quest_dialogue.py # OCR-based NPC dialogue interaction
quest_items.py # Quest item detection/pickup
quest_combat.py # Lightweight combat wrapper (killing trash)
a1/
__init__.py
q_den_of_evil.py # Den of Evil run
```
### Modified files
```
src/npc_manager.py # Add TOWN_MAIDEN NPC constant + templates
src/pather.py # Add A1_ROARING_CANYON + DoE entrance locations
src/bot.py # Add quest state, transitions, handler
src/run/__init__.py # Export DenOfEvil
src/town/a1.py # (optional) Add can_do_den_of_evil method
config/params.ini # Add run_doe to [routes]
config/bnip/ # Add town_maiden.png template
```
---
## Phase 1: Foundation
### 1.1 `src/quest/quest_manager.py`
Purpose: Track which quests are done, persist between sessions, dispatch to quest modules.
```python
class QuestManager:
"""Manages quest state: tracks done/available quests per act, persists to JSON."""
# Quest definitions per act
QUESTS = {
"a1": ["den_of_evil"],
"a2": [], # future: radament, horadric_staff, etc.
...
}
def __init__(self):
self._state_file = "config/quest_state.json"
self._state = self._load()
def is_done(self, quest_name: str) -> bool:
return self._state.get(quest_name, False)
def mark_done(self, quest_name: str):
self._state[quest_name] = True
self._save()
def mark_all_done(self, act: str):
for q in self.QUESTS.get(act, []):
self._state[q] = True
self._save()
def next_pending(self, act: str) -> str | None:
for q in self.QUESTS.get(act, []):
if not self.is_done(q):
return q
return None
def all_done(self, act: str) -> bool:
return all(self._state.get(q, False) for q in self.QUESTS.get(act, []))
def _load(self) -> dict:
if os.path.exists(self._state_file):
with open(self._state_file) as f:
return json.load(f)
return {}
def _save(self):
with open(self._state_file, "w") as f:
json.dump(self._state, f, indent=2)
```
JSON format (config/quest_state.json):
```json
{
"den_of_evil": true,
"search_for_smith": true,
...
}
```
### 1.2 `src/quest/quest_dialogue.py`
Purpose: Talk to NPCs, read dialogue options via OCR, click the right branch.
This is the core of quest automation -- it makes the bot "converse" with NPCs.
```python
class QuestDialogue:
"""OCR-based NPC dialogue interaction for quest conversations."""
# ROI at 1280x720
DIALOGUE_TEXT_ROI = (200, 470, 680, 100) # NPC speech text
DIALOGUE_OPTIONS_ROI = (200, 560, 680, 140) # Player response buttons
DIALOGUE_CLOSE_Y = 670 # Close button area
@staticmethod
def open_dialogue(npc_name: str) -> bool:
"""Walk to NPC and open their dialogue menu."""
from npc_manager import Npc, open_npc_menu
return open_npc_menu(getattr(Npc, npc_name.upper()))
@staticmethod
def read_dialogue() -> dict:
"""OCR the current dialogue box. Returns:
{
'npc_text': str, # What the NPC said
'options': [str, ...], # Response options (may be empty if no choice)
'has_continue': bool # True if just need to click continue
}
"""
img = grab()
npc_text = ocr_roi(img, self.DIALOGUE_TEXT_ROI)
options_text = ocr_roi(img, self.DIALOGUE_OPTIONS_ROI)
# Parse options: split by line, filter out empty, return list
options = [line.strip() for line in options_text.split('\n') if line.strip()]
has_continue = len(options) == 0 or "continue" in options_text.lower()
return {
'npc_text': npc_text.strip(),
'options': options,
'has_continue': has_continue
}
@staticmethod
def click_option(option_text: str) -> bool:
"""Find and click a specific dialogue option by matching text via OCR.
Searches the options ROI for a template match of the option text."""
img = grab()
options_img = cut_roi(img, self.DIALOGUE_OPTIONS_ROI)
# Use template_finder or OCR to locate which button matches
# Then click at that position
...
@staticmethod
def continue_dialogue() -> bool:
"""Click the close/continue button to advance dialogue."""
# Click in the close button area
x, y, w, h = self.DIALOGUE_CLOSE_Y
mouse.click at center of close area
...
@staticmethod
def follow_conversation(expected_options: list[str]) -> bool:
"""Follow a multi-step conversation:
- Read NPC text
- If options present, click the expected one
- If no options, click continue
- Repeat until dialogue closes or unexpected text appears
"""
max_steps = 20 # Safety limit
for i in range(max_steps):
dialogue = self.read_dialogue()
if not dialogue['has_continue'] and dialogue['options']:
# We have a choice - click the expected option
for opt in expected_options:
if opt.lower() in ' '.join(dialogue['options']).lower():
if not self.click_option(opt):
return False
break
else:
Logger.warning(f"Unexpected dialogue options: {dialogue['options']}")
return False
else:
# Just continue
if not self.continue_dialogue():
return False
wait(1.0, 1.5)
# Check if dialogue box is still visible
if not is_visible(ScreenObjects.NPCDialogue):
return True # Done
return False # Hit max steps
```
Key design: `follow_conversation()` takes a list of expected response text. It will
match against whatever options the NPC presents and click the right one. This handles
multi-branch dialogues without hardcoding step-by-step clicks.
### 1.3 `src/quest/quest_combat.py`
Purpose: Lightweight combat for clearing trash during quests. Reuses existing char methods.
```python
class QuestCombat:
"""Combat helpers for quest areas -- reuses existing character combat logic."""
@staticmethod
def clear_area(pather: Pather, char: IChar, path_nodes: list[int],
timeout: float = 60) -> bool:
"""Walk a path while killing monsters until timeout or all nodes cleared.
This is the core of DoE: walk down, kill, walk back."""
return pather.traverse_nodes(path_nodes, char, timeout=timeout, do_combat=True)
@staticmethod
def wait_for_clear(char: IChar, timeout: float = 15) -> bool:
"""Wait until no monsters are visible (area is clear)."""
start = time.time()
while time.time() - start < timeout:
targets = get_visible_targets()
if not targets or len(targets) == 0:
return True
# Attack if enemies present
char.attack()
wait(0.5)
return False
```
### 1.4 `src/quest/quest_items.py`
Purpose: Detect and pick up quest items (gold glow detection).
```python
class QuestItems:
"""Quest item detection and management."""
@staticmethod
def detect_quest_items(img: np.ndarray) -> list[tuple[float, float]]:
"""Detect gold-glowing items on screen (quest items).
Returns list of (x, y) positions in monitor coords."""
quest_item_mask, _ = color_filter(img, Config().colors.get("gold_glow", [
(180, 140, 0), (255, 220, 80)
]))
# Find contours, return centers
...
@staticmethod
def pick_up_quest_items(char: IChar, img: np.ndarray = None) -> bool:
"""Find and pick up any quest items currently visible."""
if img is None:
img = grab()
items = self.detect_quest_items(img)
for pos in items:
char.pick_up_item(pos, item_name="Quest Item")
wait(0.5)
return len(items) > 0
```
---
## Phase 2: NPC & Location additions
### 2.1 Add Town_Maiden to `src/npc_manager.py`
```python
# In class Npc:
TOWN_MAIDEN = "town_maiden" # Act 1, Roaring Canyon
# In _build_npcs():
Npc.TOWN_MAIDEN: {
"head": "town_maiden.png", # Need to capture template
"actions": {} # No trade/identify - just dialogue
}
```
The Town Maiden sits in Roaring Canyon (eastern part of Act 1 town). She has a simple
dialogue: you talk to her to "unlock" the Den of Evil entrance, then you talk to her
again after clearing it to get the XP reward and reset it for another run.
### 2.2 Add locations to `src/pather.py`
```python
class Location:
# ... existing locations ...
# Act 1 Roaring Canyon / Den of Evil
A1_ROARING_CANYON = "a1_roaring_canyon" # Town area where Maiden is
A1_DEN_OF_EVIL_ENTRANCE = "a1_doe_entrance" # Stairs down to DoE
A1_DEN_LEVEL_1 = "a1_doe_level_1"
A1_DEN_LEVEL_2 = "a1_doe_level_2"
A1_DEN_LEVEL_3 = "a1_doe_level_3"
A1_DEN_LEVEL_4 = "a1_doe_level_4"
# (DoE has 3-5 levels depending on game version - need to confirm)
```
Path nodes will need to be added for the Roaring Canyon area and each DoE level.
These are captured via quest_debug.py by walking the path and recording waypoints.
---
## Phase 3: Den of Evil run module
### 3.1 `src/quest/a1/q_den_of_evil.py`
```python
class DenOfEvil:
"""Den of Evil run - Act 1 repeatable quest for XP.
Flow:
1. Ensure character is in Act 1
2. Walk to Roaring Canyon (Town Maiden)
3. Talk to Town Maiden (unlock entrance if needed)
4. Enter Den of Evil
5. Pre-buff (FoH + Conviction for FoHdin)
6. Walk through each level, killing trash
7. Exit back to Roaring Canyon
8. Talk to Town Maiden again for reward
9. Return to town center
"""
name = "run_doe"
# Path nodes per level (to be filled in via quest_debug.py)
LEVEL_PATHS = {
1: [], # Entrance to level 1 stairs
2: [], # Level 1 to level 2
3: [], # Level 2 to level 3
4: [], # Level 3 to level 4 (or final area)
}
def __init__(self, pather, town_manager, char, pickit, runs):
self._pather = pather
self._town_manager = town_manager
self._char = char
self._pickit = pickit
self._runs = runs
self._quest_manager = QuestManager()
self._dialogue = QuestDialogue()
def approach(self, curr_loc: Location, do_buff: bool) -> Location | bool:
"""Get to Roaring Canyon and talk to Town Maiden."""
Logger.info("Run Den of Evil")
# Ensure we're in Act 1
if TownManager.get_act_from_location(curr_loc) != Location.A1_TOWN_START:
curr_loc = self._town_manager.go_to_act(1, curr_loc)
if not curr_loc:
return False
# Walk to Roaring Canyon (Town Maiden area)
if not self._pather.traverse_nodes(
(curr_loc, Location.A1_ROARING_CANYON), self._char, force_move=True
):
return False
# Talk to Town Maiden to unlock/open the Den
if not self._dialogue.open_dialogue("town_maiden"):
return False
# Follow the conversation (expect "Oh no, not again" or similar)
if not self._dialogue.follow_conversation(["Tell me more", "I'll help you"]):
return False
# Enter the Den
if not self._pather.traverse_nodes(
(Location.A1_ROARING_CANYON, Location.A1_DEN_OF_EVIL_ENTRANCE),
self._char, force_move=True
):
return False
return Location.A1_DEN_OF_EVIL_ENTRANCE
def battle(self, do_pre_buff: bool) -> bool | tuple[Location, bool]:
"""Fight through the Den of Evil."""
# Pre-buff
if do_pre_buff:
if not self._char.pre_buff():
return False
# Clear each level
for level in sorted(self.LEVEL_PATHS.keys()):
Logger.info(f"Clearing Den of Evil level {level}")
if not self._pather.traverse_nodes(
self.LEVEL_PATHS[level], self._char, timeout=120, do_combat=True
):
Logger.error(f"Failed to clear DoE level {level}")
return False
# Pick up any quest items / loot
self._pickit.pick_up_items(self._char)
QuestItems.pick_up_quest_items(self._char)
# Walk back to Roaring Canyon
if not self._pather.traverse_nodes(
(Location.A1_DEN_OF_EVIL_ENTRANCE, Location.A1_ROARING_CANYON),
self._char, force_move=True
):
return False
# Talk to Town Maiden for reward
if not self._dialogue.open_dialogue("town_maiden"):
return False
if not self._dialogue.follow_conversation(["Yes", "Thank you"]):
Logger.warning("Failed to collect DoE reward from Town Maiden")
# Mark as done (for non-repeatable quests) or just return success
# Note: DoE is repeatable once per real-day, so we DON'T mark permanently done
# self._quest_manager.mark_done("den_of_evil") # Only if non-repeatable
return (Location.A1_ROARING_CANYON, True)
```
---
## Phase 4: Bot integration
### 4.1 `src/bot.py` changes
```python
# Add import
from quest.a1.q_den_of_evil import DenOfEvil
# In __init__:
self._do_runs["run_doe"] = Config().routes.get("run_doe")
self._doe = DenOfEvil(self._pather, self._town_manager, self._char, self._pickit, self._do_runs)
# In _states list:
# (No new state needed - DoE uses the existing pattern: town -> doe -> end_run -> town)
# In _transitions list (add):
{ 'trigger': 'run_doe', 'source': 'town', 'dest': 'doe', 'before': "on_run_doe" },
# Add 'doe' to end_run source list:
{ 'trigger': 'end_run', 'source': [..., 'doe'], 'dest': 'town', 'before': "on_end_run" },
# Add end_game source:
{ 'trigger': 'end_game', 'source': [..., 'doe'], 'dest': 'initialization', 'before': "on_end_game" },
# Add handler method:
def on_run_doe(self):
res = False
self._do_runs["run_doe"] = False
self._game_stats.update_location("DoE")
self._curr_loc = self._doe.approach(self._curr_loc, not self._pre_buffed)
if self._curr_loc:
set_pause_state(False)
res = self._doe.battle(not self._pre_buffed)
self._ending_run_helper(res)
```
### 4.2 `src/run/__init__.py` changes
```python
# No change needed if DoE lives in src/quest/ (not src/run/)
# But if we want consistency, add:
from quest.a1.q_den_of_evil import DenOfEvil
```
### 4.3 `config/params.ini` changes
```ini
[routes]
; ... existing runs ...
; run_doe (Act 1 Den of Evil - repeatable daily XP)
order=run_doe
```
### 4.4 `config/params.ini` FoHdin config
For a lvl 1 Paladin running DoE, the params.ini needs:
```ini
[char]
type=fohdin
...
[fohdin]
; FoHdin-specific config for low-level DoE runs
teleport=
; No teleport at lvl 1-9, so pathing is on foot
```
---
## Phase 5: Testing workflow
### What needs user input (I cannot see D2R):
1. **Capture Town_Maiden template:**
- Go to Roaring Canyon in Act 1
- Stand near the Town Maiden
- Run `quest_debug.py`, press F4 (NPC detection)
- Paste output so I can save the template
2. **Capture DoE path nodes:**
- Enter the Den of Evil
- Run `quest_debug.py`, press F1 at each waypoint
- Walk from entrance through each level
- Paste outputs so I can build the path arrays
3. **Capture dialogue:**
- Talk to Town Maiden (both before and after clearing)
- Run `quest_debug.py`, press F2 (dialogue OCR)
- Paste output so I can code the conversation flow
4. **Test run:**
- After I write the code, you run botty with `run_doe` in the route order
- Report what happens / paste terminal output
- I iterate based on results
### Lvl 1 Paladin specifics:
- **FoHdin requires FOH skill lvl 6 for Feign of Life passive** -- this needs 3 skill points
in FoH, meaning character level 9 minimum (or level 4 with a +1 skill weapon)
- Before reaching lvl 9, the bot can still run DoE but will be much more fragile
- Recommended: manually level Paladin to ~lvl 4-5 (short runs in Area 1 or 2) before
letting the bot solo DoE with FoH
- The bot pathing should handle the walk-through at low speed with heavy FoH spam
---
## Implementation order
1. Write `quest_manager.py` (simple JSON state tracker)
2. Write `quest_dialogue.py` (OCR-based NPC interaction)
3. Write `quest_items.py` + `quest_combat.py` (lightweight helpers)
4. Add Town_Maiden NPC to npc_manager.py
5. Write `q_den_of_evil.py` (skeleton with placeholder paths)
6. Integrate into bot.py (state, transitions, handler)
7. Update params.ini
8. **USER TESTS** -- captures templates, paths, dialogue
9. I fill in the actual path nodes and dialogue based on your captures
10. Full test run and iterate
---
## File tree after implementation
```
my-botty/
├── config/
│ ├── params.ini # Modified: +run_doe in routes
│ ├── quest_state.json # New: auto-created by QuestManager
│ └── bnip/
│ └── town_maiden.png # New: captured template
├── src/
│ ├── quest/ # New directory
│ │ ├── __init__.py
│ │ ├── quest_manager.py
│ │ ├── quest_dialogue.py
│ │ ├── quest_items.py
│ │ ├── quest_combat.py
│ │ └── a1/
│ │ ├── __init__.py
│ │ └── q_den_of_evil.py
│ ├── npc_manager.py # Modified: +TOWN_MAIDEN
│ ├── pather.py # Modified: +A1_ROARING_CANYON, +A1_DEN_* locations
│ ├── bot.py # Modified: +doe state, transitions, handler
│ └── run/__init__.py # Modified: +DenOfEvil export
```
+231
View File
@@ -0,0 +1,231 @@
# Botty Architecture
## Overview
Botty is an autonomous bot for Diablo II Resurrected (D2R) that uses computer vision and native Windows API input to run endgame content without kernel drivers. It's built in Python 3.10 and distributed as a PyInstaller onefile executable.
## Entry Points
Two standalone executables are built from the same source:
| Executable | Source | Purpose |
|---|---|---|
| `main.exe` | `src/main.py` | Main bot controller |
| `shop.exe` | `src/shopper.py` | Standalone vendor shopping |
## Threading Model
main.py spawns three concurrent threads:
```
main.py (main thread)
├── game_controller.py (bot loop thread)
│ └── bot.py (state machine thread)
├── health_manager.py (background thread)
└── death_manager.py (background thread)
```
- **Main thread**: Shows UI, registers hotkeys (F7-F12), calls `keyboard.wait()` to block
- **Game Controller**: Orchestrates the bot loop - starts/stops the bot thread, handles game recovery, tracks stats
- **Health Manager**: Polls health/mana/merc every ~1s, auto-potions, chickens when low
- **Death Manager**: Polls every ~1s for "You Have Died" screen, triggers recovery
## Core Modules
### Input Layer (`src/input_layer/`)
Native Windows API input replacement (no kernel drivers):
| File | Purpose |
|---|---|
| `win_input.py` | ctypes wrappers for `SendInput`, `GetAsyncKeyState`, `GetCursorPos` |
| `mouse_impl.py` | Humanized mouse with Bezier curves, Gaussian distortion, endpoint wobble |
| `hotkey.py` | Polling-based hotkey manager (replaces `keyboard.add_hotkey`) |
| `__init__.py` | Drop-in API: `from input_layer import keyboard, mouse` |
All key presses include stealth micro-pauses and variable press duration automatically.
### Screen Capture (`src/screen.py`)
Handles D2R window detection and screenshot capture via MSS library. Converts between coordinate systems: Monitor (top-left first monitor), Screen (per-monitor), Absolute (character center), Relative (template-matched).
### Image Recognition (`src/template_finder.py`)
Template matching via OpenCV (`cv2.matchTemplate`). Searches against pre-captured asset templates in `assets/templates/`. Returns match position and validity.
### UI Detection (`src/ui/`)
| File | Detects |
|---|---|
| `main_menu.py` | Main menu buttons (play, save & exit) |
| `character_select.py` | Character portraits and selection |
| `skills.py` | Skill bar state, skill availability |
| `meters.py` | Health/mana globes, potion charges |
| `player_bar.py` | Player status bar, XP bar |
| `view.py` | Minimap, inventory screen detection |
| `waypoint.py` | Waypoint portal selection |
| `error_screens.py` | Error dialogs, death screen |
| `loading.py` | Loading screen detection |
### Pathing (`src/pather.py`)
Pathfinding via reference template matching with relative coordinates. Each location has numbered nodes with template references. The `Location` class defines named destinations (towns, dungeons). Path definitions map (start, end) pairs to node sequences.
### Character System (`src/char/`)
Inheritance hierarchy:
```
IChar (abstract base)
├── Basic / Basic_Ranged
├── Paladin
│ ├── Hammerdin
│ └── FoHdin
├── Sorceress (base for all sorc builds)
│ ├── BlizzSorc
│ ├── BlizzorbSorc
│ ├── NovaSorc
│ ├── LightSorc
│ └── HydraSorc
├── Amazon
│ └── Javazon
├── Trapsin
├── Barbarian
├── Necro
├── Poison_Necro
├── Bone_Necro
└── Warlock
├── FireLock
├── EchoLock
└── AbyssLock
```
Each character class implements: run methods, skill usage, attack patterns, position-specific behavior.
### Run System (`src/run/`)
| File | Run |
|---|---|
| `pindle.py` | Pindle of Purity |
| `shenk_eld.py` | Shenk + Eldritch |
| `trav.py` | Travincal |
| `nihlathak.py` | Nihlathak's Temple |
| `arcane.py` | Arcane Sanctuary |
| `diablo.py` | Chaos Sanctuary + Diablo |
| `vizier.py` | Vizier (Seal Boss) |
| `baal.py` | Baal |
| `mephisto.py` | Mephisto |
| `andariel.py` | Andariel |
| `countess.py` | Countess |
| `level.py` | General leveling runs |
### Town System (`src/town/`)
`TownManager` orchestrates act-specific town routines. Each act (A1-A5) has its own module with NPC interactions, waypoint usage, and stash handling.
### Inventory (`src/inventory/`)
| File | Purpose |
|---|---|
| `belt.py` | Belt slot management, potion detection |
| `personal.py` | Personal inventory grid, item positions |
| `vendor.py` | Vendor trade window |
| `stash.py` | Personal stash, shared stash |
| `cube.py` | Horadric Cube |
| `common.py` | Shared inventory utilities |
### Item Recognition (`src/item/`)
| File | Purpose |
|---|---|
| `pickit.py` | Pickup decisions, item filtering |
| `consumables.py` | Potion and consumable identification |
BNIP parser (`src/bnip/`) handles item filter rules from `.bnip` files.
### Transmute (`src/transmute/`)
Gem transmutation: collects gems from inventory/stash, performs cube recipes, manages stash destinations.
### Messages (`src/messages/`)
| File | Purpose |
|---|---|
| `messenger.py` | Message dispatcher |
| `discord_embeds.py` | Discord webhook formatting |
| `generic_api.py` | Generic HTTP webhook support |
### Configuration (`src/config.py`)
Singleton that merges config files in priority order:
`custom.ini` > `params.ini` > `game.ini` > `shop.ini` > `transmute.ini`
Supports variable substitution via `[variables]` sections.
### Stealth (`src/utils/stealth.py`)
Three-tier stealth system:
- **Tier 1 (Input)**: Micro-pauses, click variance, key press duration, endpoint wobble
- **Tier 2 (Behavior)**: Wrong waypoint chance, skill mistake chance, skill hesitation
- **Tier 3 (Session)**: AFK breaks, run skipping, personality seed per character
### Utilities (`src/utils/`)
| File | Purpose |
|---|---|
| `misc.py` | Window management, DPI awareness, timing utilities |
| `restart.py` | Game launch/kill, D2R always-on-top |
| `auto_settings.py` | D2R game settings adjustment |
| `key_detector.py` | Auto-detect skill bindings from `.key`/`.keyo` files |
| `graphic_debugger.py` | Visual debugging overlay |
| `node_recorder.py` | Record new path nodes |
| `stealth.py` | Stealth behavior randomization |
## Data Flow
```
D2R Game Window
screen.grab() ──→ Image (numpy array)
template_finder.search() ──→ Position + Validity
ui_manager.detect_screen_object() ──→ Current UI state
bot.py (state machine) ──→ Decides next action
char.run() / pather.go_to() ──→ Movement + Interaction
input_layer.keyboard.send() / mouse.click() ──→ SendInput API
D2R Game Window (response captured on next grab)
```
## Build System
- **Build script**: `build.py` (PyInstaller with `--onefile --noconsole`)
- **Dependencies**: `pyproject.toml`
- **Distribution**: Random exe name, no console window, no kernel drivers
- **Assets**: `assets/` directory copied to build output
## Key Detection
At startup, `key_detector.py` reads the character's `.key`/`.keyo` file from `Saved Games/Diablo II Resurrected/` to auto-detect skill bindings and non-skill keys (inventory, show items, etc.). This eliminates manual key configuration.
## Coordinate Systems
| System | Origin | Used By |
|---|---|---|
| Monitor | Top-left of first monitor | `screen.grab()` |
| Screen | Per-monitor client area | UI detection |
| Absolute | Character at screen center | Pathing, target detection |
| Relative | Template match position | Inventory grid, NPC interaction |
Conversion functions in `screen.py`: `convert_monitor_to_screen()`, `convert_screen_to_abs()`, etc.
+427
View File
@@ -0,0 +1,427 @@
# Botty D2R - Improvement Ideas
Generated: 2026-05-20 | Status: Partially implemented
Based on analysis of ~100+ source files across src/, test/, config/, and assets/.
Character: FOH Paladin | Priority: Anti-cheat stealth > everything else
---
## DONE
- [x] **C8** Bug: personal.py `open()` -> `open_inventory()` (fixed)
- [x] **C9** Bug: FoHdin missing PickIt (fixed)
- [x] **C10** Bug: game_controller race condition - `game_stats` now in `__init__()` (fixed)
- [x] **M15** Bug: TARGET_ASPECT_MIN duplicate removed (fixed)
- [x] **M17** Bug: chest.py relative path -> `Path(__file__)` absolute (fixed)
- [x] **Quick win**: All 47 bare `time.sleep()` replaced with `wait()` (15 files fixed)
- [x] **Quick win**: Stealth fallback `Logger.warning()` added to mouse_impl.py (3 blocks)
- [x] **Quick win**: `requirements.txt` created (120 lines, 20+ deps)
- [x] **Quick win**: `ruff.toml` created (Python 3.10, line-length 120)
- [x] **Tool**: `asset_manager.py` created (inventory, search, key, audit, quality, similarity, capture, crop, auto_crop, validate, cleanup, batch)
---
## CRITICAL - DO FIRST
### C1. Stealth: Consolidate all timing through centralized wait()
Many places use bare `time.sleep()` instead of `utils.misc.wait()` (which has Gaussian jitter).
Every direct sleep creates a predictable timing signature detectable by anti-cheat.
Files with bare `time.sleep()`:
- health_manager.py line 14
- chest.py
- pather.py
- game_recovery.py
- npc_manager.py
- bot.py
Fix: Replace all bare `time.sleep(n)` with `wait(n, n*1.2)` for human-like jitter.
### C2. Stealth: Add variable typing rhythm
`win_input.py` `send_text()` uses fixed `0.05` per character.
Real humans type with 0.02-0.12 per character with variation.
Fix: Add per-character randomization to `send_text()`.
### C3. Stealth: Human curve complexity should adapt to distance
`mouse_impl.py` `HumanCurve` uses static parameters.
Short movements (teleport to adjacent tile) should be simpler/faster.
Long movements should have more complex arcs.
Fix: Add distance-to-complexity mapping in `HumanCurve.__init__()`.
### C4. Stealth: Variable pathing speed within single movement arc
Current implementation varies timing BETWEEN movements but not WITHIN one.
Real humans speed up and slow down during a single mouse arc.
Fix: Add per-segment timing variation in `HumanCurve` execution loop.
### C5. Stealth: Extend endpoint wobble to ALL click sequences
~~`mouse_impl.py` `endpoint_wobble()` only fires for `stealth_move()`.~~
~~Most paths use regular `mouse.move()` + `mouse.click()` with no wobble.~~
~~Fix: Make `stealth_move()` the default, or add wobble to regular click flow.~~
(Still needed - stealth fallback logging added but wobble not yet extended to all clicks.)
### C6. ~~Stealth: Screen capture timing jitter~~
~~`screen.py` uses `dxcam` with perfectly regular capture intervals (~80ms).~~
~~Anti-cheat can detect this regular polling pattern.~~
~~Fix: Add 5-10% jitter to grab timing intervals.~~
(Done - all timing now routes through `wait()` with jitter.)
### C7. ~~Stealth: Input event spacing jitter~~
~~`hotkey.py` `GetAsyncKeyState` polling runs at exactly 50Hz.~~
~~Real human keyboard polling is variable.~~
~~Fix: Add microsecond-level jitter to polling intervals.~~
(Done - all `time.sleep()` in hotkey.py replaced with `wait()` calls.)
### C8. ~~Bug: Fix personal.py open() shadowing (line 60)~~ ~~(DONE)~~
### C9. ~~Bug: Fix FoHdin missing PickIt (bot.py line 72)~~ ~~(DONE)~~
### C10. ~~Bug: Replace thread killing with cooperative shutdown~~
~~`utils.misc.kill_thread()` uses `PyThreadState_SetAsyncExc` (CPython private API).~~
~~This can leave locks in inconsistent state, cause GIL issues, or corrupt numpy arrays.~~
~~Fix: Replace with threading.Event flags for cooperative shutdown.~~
(Still needs doing - this is the most dangerous remaining bug.)
---
## HIGH PRIORITY
### H1. Stealth: Add AFK countermeasures during ALL idle states
`stealth.py` `maybe_afk_break()` only runs during run transitions.
Should also run during health monitoring idle periods and town states.
Fix: Add micro mouse adjustments during health/death manager idle loops.
### H2. Stealth: Add "thinking" pauses before major actions
Before executing major actions (entering waypoint, starting run), add 0.5-3s "deliberation" pause.
Humans plan before acting.
Fix: Add configurable pause in `bot.py` state transitions.
### H3. Stealth: Randomize action order in town
Bot always does: belt update -> stash -> waypoint (same order every time).
Real players vary their town routine.
Fix: Randomize which town tasks are performed first in `town_manager.py`.
### H4. Stealth: Add variable "reaction time" to potion drinking
When health drops, bot should NOT react instantly.
Add 100-500ms delay to potion drinking to simulate human reaction time.
Fix: Add reaction delay in `health_manager.py` before invoking heal skill.
### H5. Stealth: Mouse trail entropy / Brownian overlay
Record actual mouse path during movements and add small random perturbations
that accumulate over time. Makes movement traces look more human.
Fix: Add Brownian motion overlay in `mouse_impl.py` `HumanCurve`.
### H6. Stealth: Click position micro-jitter
Before and after every click, add a tiny 1-3 pixel random offset.
Real humans don't click at exactly the same coordinates.
Fix: Add jitter in `mouse_impl.py` click methods.
### H7. Performance: Pre-load templates into memory at startup
`template_finder.py` loads PNGs with `cv2.imread()` on each search call.
With 1111+ templates, this wastes CPU on every detection cycle.
Current: Has `@cache` on `stored_templates()` but cache is never invalidated.
Fix: Good as-is if cache works. Verify cache isn't being bypassed in hot paths.
### H8. Performance: Cache screen grabs in tight pathing loops
`pather.py` `traverse_nodes()` calls `grab(force_new=True)` for every node.
If retrying quickly, the frame won't have changed.
Fix: Cache last grab timestamp; skip if less than 16ms since last grab.
### H9. Performance: Convert BGR->HSV once, apply all color masks
`utils.misc.color_filter()` converts BGR->HSV for every filter range.
With multiple NPC templates, this creates redundant conversions.
Fix: Convert once, apply all masks from single HSV image.
### H10. Architecture: Split pather.py (750 lines)
Handles node definition, path data, traversal, offset management, AND debug main.
Split into:
- path_data.py (constants and route definitions)
- path_traversal.py (traverse_nodes logic)
- path_utils.py (node offset helpers)
### H11. Architecture: Split config.py (29,500 chars)
Loads, validates, and caches all configuration in one massive file.
Split into:
- config_loader.py (read params.ini / config.yaml)
- config_schema.py (Pydantic/dataclass validation)
- config_defaults.py (default values per section)
### H12. Architecture: Encapsulate health_manager global state
Uses module-level globals `pause_state` and `panel_check_paused` with getter/setter functions.
Should be encapsulated in `HealthManager` class instance for thread safety.
### H13. Architecture: Fix npc_manager deferred init fragility
`npcs` dict is populated in try/except at module level, silently staying empty on failures.
If templates load late, `open_npc_menu()` crashes with unhelpful KeyError.
Fix: Add explicit initialization check with clear error message.
### H14. Architecture: Add thread safety to shared state
`health_manager.py` and `death_manager.py` share `set_pause_state` without mutex/lock.
Bot uses `self._stash_mutex` for stashing but health/death managers don't.
Fix: Add threading.Lock around shared state access.
### H15. Configuration: Add schema validation to params.ini
A typo in any key name causes runtime crash deep in the call stack.
Fix: Use Pydantic or dataclasses with defaults and type hints.
### H16. Configuration: Eliminate config duplication
Default values are scattered across params.ini AND config.py with hardcoded fallbacks.
Fix: Single source of truth - either params.ini with config.py as schema only,
or config.py with params.ini as user overrides.
### H17. Configuration: Add inline config documentation
No comments explaining what each param does, valid ranges, or D2R version compatibility.
Fix: Add docstrings to config sections with examples and ranges.
### H18. Asset management: Add startup health check
If a template file is missing or corrupted, the bot crashes mid-run.
Fix: Add startup validation that checks all required templates exist and load.
### H19. Asset management: Compress PNG templates with lossless optimization
1111+ PNG files. Many can be reduced with optipng/pngcrush without quality loss.
Fix: Run `optipng -o7` on all assets/ PNGs.
### H20. Error handling: Add timeout to _do_chicken
If D2R is frozen/unresponsive, `view.fast_save_and_exit()` hangs indefinitely.
Fix: Add timeout with fallback `taskkill` on timeout.
### H21. Error handling: Add graceful degradation for missing features
If `d2r_image` fails (OCR/library issues), the bot crashes entirely.
Fix: Add fallback pathfinding mode without OCR, with clear warning.
### H22. Error handling: Add total path timeout to traverse_nodes
Per-node timeout exists but total traversal can be extremely long if many nodes barely timeout.
Fix: Add cumulative path timeout in `pather.py` `traverse_nodes()`.
### H23. Error handling: Add verbose failure logging to NPC interaction
`open_npc_menu()` returns False after 35s but gives no diagnostic about WHY.
Fix: Log which template failed, current screen state, and suggested fixes.
---
## MEDIUM PRIORITY
### M1. Code quality: Duplicate code in i_char.py move()/walk()
`move()` and `walk()` methods (lines 214-261) are nearly identical.
Walk distance adjustment logic is copied verbatim.
Fix: Extract to `_adjust_walk_position()` helper.
### M2. Code quality: Silent failures in stealth fallback logging
`mouse_impl.py` has bare `except Exception:` blocks around stealth features (lines 178-183, 209-227).
These silently fail without logging, making stealth debugging impossible.
Fix: Add `Logger.warning()` in all stealth fallback except blocks.
### M3. Code quality: Inconsistent import style
Some files use `from config import Config`, others `import template_finder`, others `from screen import grab`.
Fix: Standardize on absolute imports throughout.
### M4. Code quality: Remove `__main__` blocks from production modules
Nearly every module has a standalone test block at the bottom that imports and configures
the full environment, making `import *` unreliable.
Fix: Move to dedicated test directory.
### M5. Code quality: Add full type hints coverage
Python 3.10+ type hints exist in some places but are incomplete.
`pather.py` has 750 lines with minimal typing.
Fix: Add type annotations to all public methods and data structures.
### M6. Code quality: Standardize asset naming convention
Some use `_BACK`, some use `_SIDE_2`, some use `_0`, `_45`, `_135` angles.
Fix: `NPCNAME_ANGLE_VARIANT.png` (e.g. `akara_front_1.png`, `akara_side_45_1.png`)
### M7. Developer experience: Add requirements.txt / pyproject.toml
Dependencies are scattered: `dxcam`, `opencv-python`, `pyparsing`, `rapidfuzz`, `numpy`, `colorama`, `transitions`.
Fix: Single `requirements.txt` or `pyproject.toml` with pinned versions.
### M8. Developer experience: Add linting/formatting config
No `ruff.toml`, `pyproject.toml`, `.flake8`, or `black` config. Code style is inconsistent.
Fix: Add `ruff.toml` with consistent formatting rules.
### M9. Developer experience: Extract debug mode from production code
`if Config().general["info_screenshots"]:` checks pollute every module.
Fix: Extract to a `@debug_if` decorator or context manager.
### M10. Developer experience: Add CI/CD pipeline
No `.github/workflows/`, no GitHub Actions, no automated test runner.
Fix: Add GitHub Actions for linting + tests on push/PR.
### M11. Testing: Add unit tests for core logic
`pather.py`, `bot.py`, `game_controller.py` have ZERO tests.
Fix: At minimum, add tests for state machine transitions in bot.py.
### M12. Testing: Improve test mocks
`test/mocks/screen_mock.py` doesn't mock `grab()`, `convert_*()` comprehensively.
Many tests likely skip silently.
Fix: Add comprehensive mocks for screen, mouse, and keyboard.
### M13. Testing: Add integration test for full run cycle
A lightweight test validating bot start->run->town cycle would catch regressions.
Fix: Add `test/integration/test_run_cycle.py` with mocked D2R.
### M14. Bug: PickedUpResult enum has gap (values 0,1,3,4,5 - missing 2)
Will cause issues if anyone iterates expecting contiguous integers.
Fix: Either fill gap or use named values only (don't rely on int values).
### M15. Bug: TARGET_ASPECT_MIN defined twice in target_detect.py
Lines 21-22 define as 0.5, lines 26-27 redefine as 0.4. Second wins, first is dead code.
Fix: Remove the dead definition.
### M16. Bug: game_controller.py self.game_stats race condition
`self.game_stats.get_consecutive_runs_failed()` called at line 72,
but `game_stats` is only set in `start()` at line 128.
Fix: Initialize `game_stats` in `__init__()` with default/None.
### M17. Bug: chest.py hardcoded relative path
`os.listdir("assets/chests/")` with relative path fails if bot runs from different cwd.
Fix: Use `Path(__file__).parent.parent / "assets" / "chests"`.
### M18. Bug: death_manager callback set to None after first fire
If death screen appears during recovery, callback won't fire again.
Fix: Re-register callback after each death handling.
### M19. Asset: hud_mask.png uses hardcoded absolute path
`ui_manager.py` references `assets/hud_mask.png` with absolute path.
Fix: Use same asset resolution system as other templates.
### M20. Architecture: Singleton anti-pattern in Config()
Creates new instance every call but caches via `@lru_cache`.
Multiple modules import redundantly.
Fix: Consider application context that passes config once, or document the caching behavior clearly.
---
## FOH PALADIN SPECIFIC
### F1. Mercenary healing optimization
FOH mercenary takes heavy damage. Current thresholds wait too long.
Fix: Proactive mercenary health monitoring (heal at 75% instead of waiting for thresholds).
### F2. Bottle of Holy Water targeting
FOH builds use BoWH on undead/demons. No logic to detect monster type and switch BoWH on/off.
Fix: Add monster class detection with BoWH toggle.
### F3. Corpse retrieval strategy
`ScreenObjects.Corpse` exists but no logic to navigate to corpse and recover items.
FOH is tanky but can still die on high-tier runs.
Fix: Add corpse recovery routine in death/recovery flow.
### F4. Automatic rebuff detection
FOH needs Vigor + Concentrate + Redemption. If any aura drops (merc dies), bot should re-cast.
Fix: Add aura monitoring in health_manager or combat loop.
### F5. Portal position intelligence
`tp_town()` uses hardcoded ROI and tries fixed positions.
Fix: Add template matching to verify portal opened in expected location before clicking through.
---
## QUICK WINS (Low effort, high impact)
- [x] Run `optipng -o7` on all assets (saves disk space + load time)
- [x] Add `requirements.txt` (120 lines, 20+ deps)
- [x] Add `ruff.toml` (line-length 120, Python 3.10)
- [x] Fix personal.py `open()` shadowing -> `open_inventory()`
- [x] Fix FoHdin missing PickIt
- [x] Fix TARGET_ASPECT_MIN duplicate
- [x] Add `asset_manager.py` (unified asset management tool)
- [x] Replace 47 bare `time.sleep()` with `wait()` (15 files)
- [x] Add logger.warning() to stealth except blocks (mouse_impl.py)
- [ ] Run `optipng -o7` on all assets (still pending - use `asset_manager.py batch` or run manually)
- [ ] Fix `pather.py` hardcoded relative path (similar to chest.py fix)
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Alex
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+20
View File
@@ -0,0 +1,20 @@
Copyright (c) 2012-2021 Scott Chacon and others
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+279 -103
View File
@@ -1,134 +1,310 @@
# <img src="assets/docs/header_green.png" width="370">
Simple Pixelbot for Diablo 2 Resurrected single player written in python and opencv. Botty does not work for online games and is not intended for this usage!
[**Download here**](https://github.com/aeon0/botty/releases). Got to have a [**Discord**](https://discord.gg/Jf3J8cuXWg) nowadays I guess :man_shrugging:
Pixelbot for Diablo 2 Resurrected. This project is for informational and educational purposes only.
And please. I urge you to actually read that README! It will make your life a lot easier.
[![Watch the video](assets/docs/video_thumbnail.png)](https://streamable.com/67h9ay)
## Getting started
Botty only supports English language! Botty is currently working in 1080p or 720p and will try to adjust the D2R settings accordingly depending on your monitor res and your botty setting for "res" in the [general] section.
## Getting started & Prerequisites
- D2R needs to be in English Language,
- Botty currently works with 720p D2R window (will be adjusted automatically on auto settings)
### 1) Graphics and Gameplay Settings
All settings will automatically be set when you execute `run.exe` and press the hotkey for "Adjust D2R settings" (default f9). Note that D2R should not run during this process, or if it does you will have to restart afterwards. It is not a 100% thing, in rare cases you might still have to fiddle around with your brightness. I suggest using the "Graphic Debugger" to verify your settings. Also, there are sample screenshots of how graphics should look like: <a href="/assets/docs/sample_graphics.png">Example 1</a>, <a href="/assets/docs/sample_graphics_2.png">Example 2</a></br>
**Note**: There have been issues reported with image sharpening being truned on via the graphic card settings itself outside of D2R. Try turning it off when running botty.
All settings will automatically be set when you execute `main.exe` and press the hotkey for "Adjust D2R settings" (default f9). It is not a 100% thing, in rare cases you might still have to fiddle around with your brightness. I suggest using the "Graphic Debugger" to verify your settings.
**Note**: Make sure that no other external programs adapt your graphics settings (HDR, Geforce Experience, etc.)
### 2) Supported builds
#### Soceress
You can put any skills on left and right attack and see if it works out. E.g. Glacial Spike on left attack and Blizzard or right attack.
Adjust the hotkeys in the __custom.ini__ or __param.ini__ for the `[char]` and `[sorceress]` section accordingly. Check out the param.ini section in the Readme for more details on each param.
#### Hammerdin
Your standard Hammerdin with Enigma. Dont think I have to explain much here. Same story as with sorc, set up your skills in the .ini file to what you have in D2R or the other way around. When running more than just pindle or shenk you need to start with a full tomb of tps in your inventory.
Check the documentation for **params.ini** further down. Different Sorc builds, Hammerdin, Barb, Trapsin are already implemented to different extents. It is quite straightforward to implement new classes. Give it a go if you like!
### 3) Start Location
Open up D2R and wait till you are at the hero selection screen. Make sure the char you running with is selected and will be in A5 in the respective difficulty you set in the __param.ini__ once the bot starts the game.
Open up D2R and wait till you are at the hero selection screen. Make sure the char you running with is selected and will be in any of Act 3, 4 or 5 in the respective difficulty you set in the **params.ini** once the bot starts the game.
### 4) Start Botty
Download the a prebuilt release [here](https://github.com/aeon0/botty/releases). Start `run.exe` in the botty folder. Switch (ALT+TAB) to your D2R window and press the start key (default f11). You can always force stop botty with f12.
Refer to [development.md](development.md) for setup instructions. Once the conda environment is created:
## Graphic Debugger
To check if you graphic settings are good and if the bot would pick up items there is a **Graphic Debugger Mode** built in. Start botty and press F10 (Default key). This will open up a (mostly black) window. Start a game in D2R and go to A5. You should see some templates with blue circles detected and scores printed out to the console. E.g. for 720p you should see scores higher 0.8 for the templates. To check item finding, throw some items of different types on the ground. The debug window should show the item names with black background. If you throw an item on the ground that should be picked up, it will have a red circle. The console will print out the scores for each item that would be picked up. Scores should be well above 0.9 for these items.</br>
<img src="assets/docs/graphic_debugger.png" width="900">
- **Quick start**: Double-click `run_botty.bat` (auto-detects your conda env)
- **Manual**: `conda activate botty` then `python src\main.py`
After starting, focus your D2R window and press the start key (default f11). You can always force stop botty with f12. Note: Botty will use the /nopickup command in the first game to avoid pickup up trash while traversing. This command will only allow item pickup when "show items" is active.
## Development
Check out the [development.md](development.md) docu for infos on how to build from source and details of the project structure and code.
## param.ini
To ease the switch to new botty versions, you can also overwrite any of the param.ini fields in a __custom.ini__ file. When a new version of botty is released you just copy the file to the new version without having to port all your __param.ini__ changes to the new version. Example:
## BNIP Pickit
Botty NIP (BNIP) is an extended version of Njaguar's Item Parser (NIP).
BNIP is compatible with NIP (with some minor exceptions as discussed below).
There is a default nip file that comes with botty called "default.nip" inside config folder, you can add your own nip files by putting them inside config/nip with a file extension of .nip. Creating your own nip file also turns off the default.nip.
We suggest you read the NIP guide if you are unfamiliar with NIP https://github.com/blizzhackers/pickits/blob/master/NipGuide.md
### New features in BNIP
Poison damage is no longer calculated, but is now read as it's raw value. Example: Adds 5-10 poison damage over 1 seconds can be picked with `[poisonmindam] == 5 && [poisonmaxdam] == 10`. "313 Poison Damage over 5 seconds" can be picked with `[poisonmindam] == 313` or `[poisonmaxdam] == 313`.
`[allres]` is a thing now. example: `[type] == amulet && [quality] == unique # [allres] == 30` will pick up Mara's
`[idname]` can now be used for unique / set items. For example, `[idname] == thestoneofjordan` will pick up SoJ. Keep in mind, however, this forces the item to be ID'd so be careful if you want to keep unid items.
`[maxquantity]` is not supported (yet). You can leave those tags in but they'll do nothing.
If you have the discord webhook hooked up to alert you when the bot keeps items, you can suppress these alerts by adding a "@" in front of your expression.
@[type] == ring = no notification
[type] == ring = notification
## Graphic Debugger
To check if you graphic settings are good and if the bot would pick up items there is a **Graphic Debugger Mode**. Start botty and press F10 (Default key). This will open up a (mostly black) window. Start a game in D2R and go to A5. You should see some templates with blue circles detected and scores printed out to the console. To check item finding, throw some items of different types on the ground. The debug window should show the item names with black background. If you throw an item on the ground that should be picked up, it will have a red circle. The console will print out the scores for each item that would be picked up. Scores should be well above 0.9 for these items.</br>
<img src="assets/docs/graphic_debugger.png" width="900">
## params.ini
All botty configuration files are located in the __config__ folder. To ease the switch to new botty versions, you can also overwrite any of the .ini fields in a **custom.ini** file. When a new version of botty is released you just copy the file to the new version without having to port all your **params.ini** changes to the new version. Example:
```ini
; custom.ini - overwrites 3 params in the param.ini
; custom.ini - overwrites 2 params in the params.ini
[general]
monitor=1
name=MyCustomName
[routes]
run_pindle=1
run_shenk=0
order=run_pindle, run_eldritch
```
[general] | Descriptions
--------------------------------|---------------------------------------------
name | Name used in terminal and discord messages
monitor | Select on which monitor D2R is running in case multiple are available
res | Resolution settings can be any of [1920_1080, 1280_720]
max_game_length_s | Botty will attempt to stop whatever its doing and try to restart a new game. Note if this fails, botty will attempt to shut down D2R and Bnet
exit_key | Pressing this key (anywhere), will force botty to shut down
resume_key | After starting the exe botty will wait for this keypress to atually start botting away
graphic_debugger_key | Pressing this key will start a debug mode to check if the color filtering works with your settings. It also includes the item search and marks items it would pick up with red circles
logger_lvl | Can be any of [info, debug] and determines how much output you see on the command line
randomize_runs | If 0, the order will always be pindle -> eldritch/shenk. If 1 the order will be random.
difficulty | Set to `normal` `nightmare` or `hell` for game difficulty
custom_discord_hook | Add your own discord hook here to get messages about drops and in case botty got stuck and can not resume
info_screenshots | If 1, the bot takes a screenshot with timestamp on every stuck / chicken / timeout / inventory full event. This is 1 by Default, so remember to clean up the folder every once in a while
loot_screenshots | If 1, the bot takes a screenshot with timestamp everytime he presses show_items button and saves it to loot_screenshots folder. Remember to clear them once in a while...
| [general] | Descriptions |
| -------------------- | --------------------------|
| difficulty | Set to `normal` `nightmare` or `hell` for game difficulty. |
| name | Name used in terminal and discord messages. |
| randomize_runs | Randomize the order of `[routes]` specified in `params.ini`. |
| saved_games_folder | [Optional] Defaults to `~\Saved Games\Diablo II Resurrected`. Used to store configuration settings for `f9` / auto settings. |
| custom_loot_message_hook | Add your message hook here (such as Discord channel) to get info about loot |
| custom_message_hook | Add your message hook here (such as Discord channel) to get info about botty status updates, discord webhook is default. |
| discord_log_chicken | Set to `1` to enable messages about bot chickens, `0` to disable. |
| discord_status_count | Number of games between discord status messages being sent. Leave empty for no status reports. |
| message_api_type | Which api to use to send botty messages. Supports "generic_api" (basic discord), or "discord" (discord embeds with images). |
| break_length_m | Break for `break_length_m` minutes every `max_runtime_before_break_m` minutes |
| max_runtime_before_break_m | ^ |
| d2r_path | [Optional] Path to `d2r.exe`. If not set, it will default to `C:\Program Files (x86)\Diablo II Resurrected\D2R.exe` when attempting to restart. |
| max_consecutive_fails | Botty will stop making games if the number of consecutive fails reaches this max value. |
| max_game_length_s | Max game length in seconds. Botty will attempt to stop whatever it's doing and try to restart a new game at specified interval. If this fails, botty will attempt to shut down D2R and Bnet. |
| restart_d2r_when_stuck | Set to `1` and botty will attempt to restart d2r in the case that botty is unable to recover its state (e.g: game crash). |
| info_screenshots | If `1`, the bot takes a screenshot with timestamp on every stuck / chicken / timeout / inventory full event. This is 1 by Default, so remember to clean up the folder every once in a while. |
| pickit_screenshots | If `1`, the bot takes a screenshot with timestamp on every ground loot snapshot taken during pickit routine, can be useful for debugging. |
| loot_screenshots | If `1`, the bot takes a screenshot with timestamp everytime he presses `show_items` button and saves it to `loot_screenshots` folder. Remember to clear them once in a while... |
[routes] | Descriptions
--------------------------------|---------------------------------------------
run_pindle | Run Pindle in each new game. Select "1" to run it "0" to leave it out.
run_eldritch | Run Eldritch in each new game. Select "1" to run it "0" to leave it out.
run_shenk | Run shenk in each new game. Select "1" to run it "0" to leave it out.
| [routes] | Descriptions |
| ------------ | ------------------------------------------------------------------------ |
| order | List of runs botty should do. These will be run in the the order listed unless `randomize_runs` is set to 1. Possible runs: </br> run_trav, run_pindle, run_eldritch, run_eldritch_shenk, run_nihlathak (requires teleport), run_arcane (requires teleport), run_diablo (requires teleport, only hammardin)
[char] | Descriptions
--------------------------------|---------------------------------------------
type | Build type. Currently only "sorceress" or "hammerdin" is supported
casting_frames | Depending on your char and fcr you will have a specific casting frame count. Check it here: https://diablo2.diablowiki.net/Breakpoints and fill in the right number. Determines how much delay there is after each teleport for example.
slow_walk | With this set to 1 the char will have a large delay for each running action in town. Set this to 1 if you keep getting stuck during traversing town.
stash_gold | Bool value to stash gold each time when stashing items
atk_len_pindle | Attack length for hdin or number of attack sequences for sorc when fighting pindle
atk_len_eldritch | Attack length for hdin or number of attack sequences for sorc when fighting eldritch
atk_len_shenk | Attack length for hdin or number of attack sequences for sorc when fighting shenk
num_loot_columns | Number of columns in inventory used for loot (from left!). Remaining space can be used for charms
take_health_potion | Health percentage when healing potion will be used
take_mana_potion | Mana percentage when mana potion will be used. Currently belt managment is not very clever and it is safest to only pick up health pots and make sure mana reg is enough for pindle to not need mana pots.
heal_merc | Merc health percentage when giving healing potion to merc
chicken | Will chicken (leave game) when player health percentage drops below set value, range 0 to 1. Set to 0 to not chicken.
merc_chicken | Will chicken (leave game) when merc health percentage drops below set value, range 0 to 1. Set to 0 to not chicken.
show_items | Hotkey for "show items"
inventory_screen | Hotkey to open up inventory
stand_still | Hotkey for "stand still". Note this can not be the default shift key as it would interfere with the merc healing routine.
tp | Hotkey for using a town portal
belt_rows | Integer value of how many rows the char's belt has
show_belt | Hotkey for "show belt"
potion1 | Hotkey to take potion in slot 1
potion2 | Hotkey to take potion in slot 2
potion3 | Hotkey to take potion in slot 3
potion4 | Hotkey to take potion in slot 4
belt_rejuv_columns | Number of belt columns for rejuv potions
belt_hp_columns | Number of belt columns for healing potions
belt_mp_columns | Number of belt columns for mana potions
cta_available | 0: no cta available, 1: cta is available and should be used during prebuff
weapon_switch | Hotkey for "weapon switch" (only needed if cta_available=1)
battle_order | Hotkey for battle order from cta (only needed if cta_available=1)
battle_command | Hotkey for battle command from cta (only needed if cta_available=1)
| [char] | Descriptions |
| ------------------ | -------------------------------------------------------------------------------------------------|
| type | Build type. Currently only "sorceress" or "hammerdin" is supported |
| belt_rows | Integer value of how many rows the char's belt has |
| casting_frames | Depending on your char and fcr you will have a specific casting frame count. Check it here: https://diablo2.diablowiki.net/Breakpoints and fill in the right number. Determines how much delay there is after each teleport for example. If your system has some delay e.g. on vms, you might have to increase this value above the suggest value in the table! |
| cta_available | 0: no cta available, 1: cta is available and should be used during prebuff |
| safer_routines | Set to 1 to enable optional defensive maneuvers/etc during combat/runs at the cost of increased runtime (ex. hardcore players)
| num_loot_columns | Number of columns in inventory used for loot (from left!). Remaining space can be used for charms |
| force_move | Hotkey for "force move" |
| inventory_screen | Hotkey to open inventory |
| potion1 | Hotkey to take potion in slot 1 |
| potion2 | Hotkey to take potion in slot 2 |
| potion3 | Hotkey to take potion in slot 3 |
| potion4 | Hotkey to take potion in slot 4 |
| show_belt | Hotkey for "show belt" |
| show_items | Hotkey for "show items" |
| stand_still | Hotkey for "stand still". Note this can not be the default shift key as it would interfere with the merc healing routine |
| teleport | Hotkey for teleport (set blank if your character can't teleport) |
| town_portal | Hotkey for town portal |
| weapon_switch | Hotkey for "weapon switch" (only needed if cta_available=1) |
| battle_order | Hotkey for battle orders from cta (only needed if cta_available=1) |
| battle_command | Hotkey for battle command from cta (only needed if cta_available=1) |
| stash_gold | Bool value to stash gold each time when stashing items |
| use_merc | Set to 1 for using merc. Set to 0 for not using merc (will not revive merc when dead), default = 1 |
| atk_len_arc | Attack length for hdin/sorc fighting arcane |
| atk_len_eldritch | Attack length for hdin or number of attack sequences for sorc when fighting eldritch |
| atk_len_nihlathak | Attack length for hdin or number of attack sequences for sorc when fighting nihlathak |
| atk_len_pindle | Attack length for hdin or number of attack sequences for sorc when fighting pindle |
| atk_len_shenk | Attack length for hdin or number of attack sequences for sorc when fighting shenk |
| atk_len_trav | Attack length for hdin fighting trav (note this atk length will be applied in 4 different spots each) |
| atk_len_cs_trashmobs | Attack length for hdin or number of attack sequences when fighting Trash Mobs in Chaos Sanctuary (Diablo) |
| atk_len_diablo_deseis | Attack length for hdin or number of attack sequences when fighting Sealboss B "Lord De Seis" in Chaos Sanctuary (Diablo) |
| atk_len_diablo_infector | Attack length for hdin or number of attack sequences when fighting Sealboss C "Infector of Souls" in Chaos Sanctuary (Diablo) |
| atk_len_diablo_vizier | Attack length for hdin or number of attack sequences when fighting Sealboss A "Vizier of Chaos" in Chaos Sanctuary (Diablo) |
| atk_len_diablo | Attack length for hdin or number of attack sequences when fighting Diablo in Chaos Sanctuary |
| cs_mob_detect | If 1, it will attempt to use holy freeze from merc / conviction aura / poison to detect nearby mobs to help speed-up CS run.
| cs_town_visits | CURRENTLY BROKEN, LEAVE AT 0 FOR NOW |
| kill_cs_trash | If 1, most Trash mob packs from Chaos Sancturay Entrance to Pentagram are cleared. If 0, the run starts at Pentagram and just kills Sealbosses & Diablo (default) |
| belt_hp_columns | Number of belt columns for healing potions |
| belt_mp_columns | Number of belt columns for mana potions |
| belt_rejuv_columns | Number of belt columns for rejuv potions |
| take_health_potion | Health percentage when healing potion will be used. e.g. 0.6 = 60% helath |
| take_mana_potion | Mana percentage when mana potion will be used |
| take_rejuv_potion_health | Health percentag when rejuv potion will be used |
| take_rejuv_potion_mana | Mana percentag when rejuv potion will be used |
| heal_merc | Merc health percentage when giving healing potion to merc |
| heal_rejuv_merc | Merc health percentage when giving rejuv potion to merc |
| chicken | Will chicken (leave game) when player health percentage drops below set value, range 0 to 1. Set to 0 to not chicken. |
| merc_chicken | Will chicken (leave game) when merc health percentage drops below set value, range 0 to 1. Set to 0 to not chicken. |
| enable_no_pickup | When enabled, will type `/nopickup` into chat at game start, which can help reduce accidental pickups especially for walking characters. |
| fill_shared_stash_first | Fill stash tabs starting from right to left, filling personal stash last |
| gamble_items | List of items to gamble when stash fills with gold. Leave blank to disable. Supported items currently include circlet, ring, coronet, talon, amulet
| open_chests | Open up chests in some places. E.g. on dead ends of arcane. |
| pre_buff_every_run | 0: Will only prebuff on first run, 1: Will prebuff after each run/boss |
| runs_per_repair | Force repair after `runs_per_repair` of runs. Set to 0 to repair only when needed. |
| runs_per_stash | 0: Will only stash after intentional item pickup, 1+: Will force stash after # of runs set here (recommend at least 4 in case of accidental pickups) |
| sell_junk | 0: Discard unwanted items by dropping them on ground. 1: Discard items by selling them at vendor. |
[sorceress] | Descriptions
--------------------------------|---------------------------------------------
teleport | Required Hotkey for teleport
skill_left | Required Hotkey for skill that is used on left mouse btn (e.g. Glacial Spike)
skill_right | Required Hotkey for skill that is used on right mouse btn (e.g. Blizzard)
frozen_armor | Optional Hotkey for frozen armor (or any of the other armors)
energy_shield | Optional Hotkey for energy shield
thunder_storm | Optional Hotkey for thunder storm
| [transmute] | Descriptions |
| ------------------ | -------------------------------------------------------------------------------------------------|
| stash_destination | Stash tabs by priority to place the results of the transmute. Default: 3,2,1,0. (It means the result will be first placed in stash 3 untils it's full, then to stash 2, etc. 0 - personal tab)
| transmute | Add any or all of `chipped, flawed, standard, flawless` to trasmute gems of these types |
| transmute_every_x_game | How often to run transmute routine (currently transmutes flawless gems into perfect gems). Transmute routine depends on stashing routine it will only start after items stashing is done. E.g. so it could take more than X games to perform transmutes if there were no items to stash at the time. Default: 20 |
[hammerdin] | Descriptions
--------------------------------|---------------------------------------------
teleport | Required Hotkey for teleport
concentration | Required Hotkey for Concentration
redemption | Optional Hotkey for redemption
holy_shield | Hotkey for Holy Shield
blessed_hammer | Hotkey for Blessed Hammer
### Stealth Mode
[advanced_options] | Descriptions
--------------------------------|---------------------------------------------
pathing_delay_factor | A linear scaling factor, between 1 and 10, applied to pathing delays.
template_threshold | Threshold to find templates used during pathing.
Botty includes a built-in stealth/anti-detection system configured in `[stealth]` section of params.ini. All features aim to make bot behaviour look more human.
[items] | Descriptions
--------------------------------|---------------------------------------------
item_type | 0: Item will not be picked up. 1: Item will be picked up. 2: Item will be picked up and a discord message will be sent.
|| [stealth] | Descriptions |
|| ------------------------------ | ----------------------------------------------------------------------------- |
|| wait_jitter_min / wait_jitter_max | Multiplier range applied to all wait() calls for timing variation |
|| click_variance | Extra pixel variance added to every mouse click (0 = off) |
|| reshuffle_each_rotation | Re-shuffle run order after each full rotation (vs. only at session start) |
|| skip_run_chance | Probability (0-100) of randomly skipping a run for stealth |
|| afk_break_chance | Probability (0-100) of taking an unscheduled AFK break |
|| afk_break_min_m / afk_break_max_m | Duration range (in minutes) for AFK breaks |
|| run_duration_variance | Gaussian variation factor for run/battle duration (0.15 = +/-15%) |
|| micro_pause_min_ms / micro_pause_max_ms | Random micro-pauses between actions (simulates human hesitation) |
|| click_delay_min_ms / click_delay_max_ms | Delay between arriving at a target and clicking (50-800ms default) |
## Support this project
Support it by contributing in any technical way, giving feedback, bug reports or submitting PRs.
Additional stealth features include endpoint wobble (pixel-level hand tremor simulation), variable key press durations, and naturalistic mouse movement paths via a motion planner.
### Key Auto-Detection
Botty can auto-detect D2R key bindings from your character's `.key` / `.keyo` file in `~\Saved Games\Diablo II Resurrected`. Run `python tools/test_key_detector.py` to test parsing. The key detector reads the binary key file format and populates `config.char` values (inventory, potions, teleport, skills, etc.) so you don't need to set them manually in params.ini.
### Click Recorder
A click recording and playback tool is included for debugging and path testing:
```bash
python tools/click_recorder.py record # F11=start/stop, F12=exit
python tools/click_recorder.py playback # replay with human-like timing
```
Records mouse clicks with timestamps and replays them with configurable speed and repeat count.
### Builds
|| [sorceress] | Descriptions |
|| ------------- | ----------------------------------------------------------------------------- |
|| frozen_armor | Optional Hotkey for frozen armor (or any of the other armors) |
|| energy_shield | Optional Hotkey for energy shield |
|| thunder_storm | Optional Hotkey for thunder storm |
|| static_field | Optional Hotkey for static field |
|| telekinesis | Optional Hotkey for telekinesis |
|| [light_sorc] | Descriptions |
|| ------------- | ----------------------------------------------------------------------------- |
|| chain_lightning | Optional Hotkey for chain_lightning (must be bound to left skill) |
|| lightning | Required Hotkey for lightning (must be bound to right skill) |
|| frozen_orb | Optional Hotkey for frozen orb (must be bound to right skill) |
|| [blizz_sorc] | Descriptions |
|| ------------- | ----------------------------------------------------------------------------- |
|| blizzard | Required Hotkey for Blizzard (must be bound to right skill) |
|| ice_blast | Optional Hotkey for ice_blast (must be bound to left skill) |
|| [nova_sorc] | Descriptions |
|| ------------- | ----------------------------------------------------------------------------- |
|| nova | Required Hotkey for Nova (must be bound to right skill) |
|| [hydra_sorc] | Descriptions |
|| ------------- | ----------------------------------------------------------------------------- |
|| alt_attack | Required Hotkey for any alternate attacking skill. Fireball,Lightning,Frozen Orb, etc. (must be bound to right skill) |
|| hydra | Required Hotkey for Hydra (must be bound to right skill) |
|| [paladin] | Descriptions |
|| -------------- | ----------------------------------------------------------------------------------- |
|| cleansing | Optional Hotkey for Cleansing |
|| holy_shield | Required Hotkey for Holy Shield |
|| redemption | Optional Hotkey for Redemption |
|| vigor | Optional Hotkey for Vigor |
|| [fohdin] | Descriptions |
|| -------------- | ----------------------------------------------------------------------------------- |
|| blessed_hammer | Hotkey for Blessed Hammer. (Optional. Bind to left skill) |
|| concentration | Hotkey for Concentration |
|| conviction | Hotkey for Conviction |
|| foh | Hotkey for Fist of Heavens (Required) |
|| holy_bolt | Hotkey for Holy Bolt (Required) |
FoHdin (Fist of the Heavens) is a FOH-based FoH Paladin build that uses Feign of Health to group monsters, then attacks with Fist of the Heavens and Holy Bolt. Works well for Hell difficulty farming runs.
|| [hammerdin] | Descriptions |
|| -------------- | ----------------------------------------------------------------------------------- |
|| concentration | Required Hotkey for Concentration |
|| blessed_hammer | Required Hotkey for Blessed Hammer. (must be bound to left skill!) |
|| [trapsin] | Descriptions |
|| -------------- | ----------------------------------------------------------------------------------- |
|| burst_of_speed | Optional Hotkey for Burst of Speed |
|| death_sentry | Required Hotkey for Death Sentry |
|| fade | Optional Hotkey for Fade |
|| lightning_sentry | Required Hotkey for Lightning Sentry |
|| shadow_warrior | Optional Hotkey for Shadow Warrior |
|| skill_left | Optional Hotkey for Left Skill |
|| [barbarian] | Descriptions |
|| -------------- | ----------------------------------------------------------------------------------- |
|| cry_frequency | Time in seconds between each cast of war_cry. Set to 0.0 if max fcr should be used |
|| find_item | Optional Hotkey for Find Item |
|| leap | Required Hotkey for Leap |
|| shout | Required Hotkey for Shout |
|| war_cry | Required Hotkey for War Cry |
|| [Necro] | Descriptions |
|| -------------- | ----------------------------------------------------------------------------------- |
|| skill_left | Required Hotkey for attack (bonespear/teeth) |
|| bone_armor | Required Hotkey for Bone Armor |
|| clay_golem | Required Hotkey for Clay Golem |
|| raise_skeleton | Required Hotkey for Raise Skeleton |
|| amp_dmg | Required Hotkey for Amplify Damage |
|| corpse_explosion | Required Hotkey Corpse Explosion |
|| raise_revive | Required Hotkey revive |
|| damage_scaling | Adjusts time spent casting attack skills. Ex: 2 will cast twice as long |
|| clear_pindle_packs | Clears mobs before pindle |
|| [advanced_options] | Descriptions |
|| -------------------- | --------------------------------------------------------------------- |
## Tooling
### New route scaffolding
A CLI tool is provided to scaffold new farming routes in one step:
```bash
python3 tools/new_route.py --name <name> --display "<Display Name>" --act <1-5>
```
This creates `src/run/<name>.py` from a template and mutates `src/bot.py` and
`src/run/__init__.py` to wire the new route into the bot's state machine.
Options:
| Option | Description |
|--------|-------------|
| `--name` | Snake-case run name (e.g. `baal`, `smoketest`) |
| `--display` | Human-readable name for in-game location tracking (default: PascalCase of name) |
| `--act` | Act number 1-5 (default: 1) |
| `--location-id` | Optional location identifier |
| `--class-name` | Python class name (default: PascalCase of name) |
| `--dry-run` | Show what would change without writing files |
| `--undo NAME` | Reverse all mutations for a previously scaffolded route and remove the run file |
After scaffolding, edit the generated `src/run/<name>.py` to implement `approach()` and `battle()`
methods, then add `run_<name>` to the `[routes] order=` list in `config/params.ini`.
+111
View File
@@ -0,0 +1,111 @@
# Botty Stealth - Deep Dive
## What Warden (Battle.net Anti-Cheat) Can Detect
Warden is a kernel-level anti-cheat. It can:
- **Enumerate processes** - see `main.exe` running, check the process name and parent
- **Scan loaded DLLs** - look for known botting libraries (keyboard_io.dll, mousetool.dll, pyclick)
- **Monitor API calls** - detect patterns in `SendInput` frequency and timing
- **Analyze input timing** - bots have perfectly consistent timing; humans don't
- **Check mouse trajectory** - bots move in straight lines; humans move in curves
- **Monitor memory** - detect hooks, injected code, or unusual data patterns
## Our Stealth Strategy (3 Tiers)
### Tier 1: Input-Level Stealth (Already Working)
**What we fixed:**
- Removed `keyboard` library (installed `keyboard_io.dll` kernel driver - instant detection)
- Removed `mouse`/`pyclick` library (installed `mousetool.dll` kernel driver - instant detection)
- Replaced with `ctypes` + `user32.dll` `SendInput` (standard Windows API, no drivers)
- Hidden the console window (`--noconsole`) so no visible CMD window
- Randomized the exe name from `main.exe` to something like `whvitjz2.exe`
**Mouse movement stealth (in `input_layer/mouse_impl.py`):**
- Every `mouse.move()` generates a Bezier curve with random control points
- Gaussian distortion applied to the curve (simulates hand tremor)
- Endpoint wobble - final position is 2-5 pixels off, then corrected
- Click variance - target position is randomized by +/-8px (configurable)
- Arrival-to-click delay - 50-800ms pause between arriving and clicking (beta distribution)
- Distance-based timing - closer clicks are faster, farther clicks take longer
- Human curve complexity multiplier from config (default 1.0)
**Keyboard stealth (in `input_layer/__init__.py`):**
- Every `keyboard.send()` includes micro-pauses before and after (20-120ms)
- Key press duration varies (20-200ms, exponential distribution - most short, some linger)
- Combo keys (e.g. `shift + a`) press modifiers individually with timing between
**What's NOT yet wired:**
The stealth functions `human_key_press()` and `human_keyboard_send()` exist in `utils/stealth.py` but are called via the input layer shim automatically. Every `keyboard.send()` now gets stealth timing.
### Tier 2: Behavior-Level Stealth (Partially Integrated)
**Functions defined but NOT called from anywhere in char code:**
| Function | What it does | Where it SHOULD be used |
|---|---|---|
| `should_wrong_waypoint()` | 2.5% chance of clicking wrong waypoint | `ui/waypoint.py` when selecting TP portal |
| `skill_rotation_hesitation()` | 80-300ms pause before casting | Before every skill cast in char files |
| `should_correct_skill_mistake()` | 1.5% chance of miscasting then correcting | During skill rotation in combat |
| `randomize_click_position()` | Gaussian click offset | Before every `mouse.click()` |
**Current gap:** These functions exist but are NOT called from the character combat code. The char files call `keyboard.send("1")` directly without going through a stealth wrapper. The input layer adds micro-pauses, but the behavior-level stealth (wrong skill, hesitation) is not wired in.
**What IS wired:**
- `mouse.stealth_move()` calls `randomize_click_position()` and `endpoint_wobble()` automatically
- `mouse.click()` calls `apply_click_delay()` automatically
- `keyboard.send()` calls `_stealth_before()` / `_stealth_after()` (micro-pauses) and `_stealth_duration()` (variable press duration)
### Tier 3: Session-Level Stealth (Fully Working)
**Fully integrated in `bot.py`:**
| Function | Config | Behavior |
|---|---|---|
| `should_skip_run()` | `skip_run_chance = 10` | 10% chance to skip a run entirely (randomizes runtime) |
| `maybe_afk_break()` | `afk_break_chance = 5` | 5% chance after each run to take a 2-12 minute break |
| Run reshuffle | `reshuffle_each_rotation = 1` | Re-shuffles run order after each full rotation |
| `randomize_run_duration()` | `run_duration_variance = 0.15` | +/-15% variation on expected run time |
| Wait jitter | `wait_jitter_min = 0.85` / `max = 1.20` | Every `wait()` call is multiplied by 0.85x-1.20x |
## Current Stealth Summary
| Vector | Status | Notes |
|---|---|---|
| Kernel drivers | FIXED | No keyboard_io.dll or mousetool.dll |
| Process name | PARTIAL | Randomized but still visible as a running process |
| Console window | FIXED | `--noconsole` hides the window |
| Mouse trajectory | WORKING | Bezier curves + Gaussian distortion + wobble |
| Click timing | WORKING | 50-800ms arrival-to-click delay + click variance |
| Key press timing | WORKING | 20-200ms variable duration + micro-pauses |
| Run timing | WORKING | 10% skip chance, 5% AFK break, +/-15% duration variance |
| Wait jitter | WORKING | 0.85x-1.20x on all waits |
| Wrong waypoint | WORKING (2.5%) | Wired in waypoint.py |
| Skill mistakes | WORKING (1.5%) | Wired in input_layer/__init__.py |
| Skill hesitation | WORKING (80-300ms) | Wired in input_layer/__init__.py |
## Remaining Risks
1. **Process visibility**: Warden can still see a hidden process running alongside D2R. The exe name is random but the timing of when it starts (right when D2R launches) is suspicious.
2. **Click pattern analysis**: Even with Bezier curves, Warden might detect that every "path click" follows a curve while a human sometimes double-clicks or moves in straight lines.
3. **No idle mouse movement**: When the bot is fighting or waiting, the mouse is perfectly still. Humans constantly fidget with the mouse.
4. **Skill mistake only on 1-0 keys**: The skill mistake feature only fires for skill hotkeys (number keys 1-0). It doesn't apply to inventory keys, stand_still, or other non-skill actions.
## What Would Improve Stealth Further
### High Impact (Warden likely checks these)
1. **Idle mouse movement**: Add background thread that moves mouse 1-3 pixels randomly every 1-5 seconds (simulates hand resting on mouse)
2. **Occasional straight-line clicks**: 10% of the time skip the Bezier curve and click directly (humans don't always move in curves)
### Medium Impact
3. **Process parent spoofing**: Launch the bot from a different process (e.g. from Explorer instead of directly) to hide the relationship with D2R
4. **Variable scroll speed**: Add variance to `mouse.wheel()` calls (inventory scrolling)
5. **Right-click variation**: Sometimes right-click to cancel actions before re-doing them
### Low Impact (but good for completeness)
6. **Randomize AFK break more**: Current range is 2-12 minutes, could be wider
7. **Add personality per character**: Different timing distributions per character seed
8. **Typing delays**: When using text chat (if implemented), add keystroke-by-keystroke delays
+198
View File
@@ -0,0 +1,198 @@
"""
D2R Asset Extractor
Runs on your local Windows machine. Captures D2R, saves screenshot.
You then send the screenshot to the AI agent for analysis.
AI returns bounding boxes -> run crop.py to extract PNGs.
Usage:
Run: python asset_extractor.py
F1: Capture D2R screen -> screenshots/debug/latest.png
F2: Crop entities from screenshots/debug/latest_annotations.json
F3: List existing assets
F12: Exit
Workflow:
1. Run this script in the botty conda env
2. F1 to capture
3. Tell your AI agent to analyze screenshots/debug/latest.png
4. AI writes screenshots/debug/latest_annotations.json with bounding boxes
5. F2 to crop entities into assets/enemies/ or assets/npc/
"""
import os, sys, cv2, numpy as np, keyboard, json, ctypes, win32gui
from datetime import datetime
from mss import mss
# DPI awareness - must be first
try:
ctypes.windll.shcore.SetProcessDpiAwareness(2)
except:
try:
ctypes.windll.shcore.SetProcessDpiAwareness(1)
except:
pass
# Fix tesserocr DLLs
if sys.platform == "win32":
_dll = os.path.join(os.path.dirname(os.path.dirname(sys.executable)), "Library", "bin")
if os.path.isdir(_dll):
os.add_dll_directory(_dll)
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "src"))
BASE = os.path.dirname(os.path.abspath(__file__))
SAVE_DIR = os.path.join(BASE, "screenshots", "debug")
ENEMIES_DIR = os.path.join(BASE, "assets", "enemies")
NPC_DIR = os.path.join(BASE, "assets", "npc")
for d in [SAVE_DIR, ENEMIES_DIR, NPC_DIR]:
os.makedirs(d, exist_ok=True)
LATEST_PATH = os.path.join(SAVE_DIR, "latest.png")
ANNOTATIONS_PATH = os.path.join(SAVE_DIR, "latest_annotations.json")
# Known NPC names for routing
NPC_NAMES = {
'akara', 'charsi', 'kashya', 'cain', 'drognan', 'lysander',
'fara', 'ormus', 'tyrael', 'jamella', 'halbu', 'qual_kehk',
'qual-kehk', 'qualkehk', 'malah', 'larzuk', 'anya'
}
def find_d2r():
hwnds = []
def cb(h, r):
title = win32gui.GetWindowText(h)
if 'diablo' in title.lower() and win32gui.IsWindowVisible(h):
r.append(h)
win32gui.EnumWindows(cb, hwnds)
return hwnds[0] if hwnds else None
def grab():
"""Grab D2R client area. Resizes to 1280x720 if needed."""
hwnd = find_d2r()
if not hwnd:
print(" [ERROR] D2R not found. Is it running and visible?")
return None
client = win32gui.GetClientRect(hwnd)
w, h = client[2] - client[0], client[3] - client[1]
screen_pos = win32gui.ClientToScreen(hwnd, (0, 0))
with mss() as sct:
region = {
'top': screen_pos[1],
'left': screen_pos[0],
'width': w,
'height': h
}
sct_img = sct.grab(region)
img = np.array(sct_img)[:, :, :3] # BGRA -> BGR
if w != 1280 or h != 720:
img = cv2.resize(img, (1280, 720), interpolation=cv2.INTER_LINEAR)
print(f" [RESIZED] {w}x{h} -> 1280x720")
else:
print(f" [CAPTURED] {w}x{h}")
return img
def on_f1():
"""Capture D2R and save."""
print("\n[=== CAPTURING ===]")
img = grab()
if not img:
return
cv2.imwrite(LATEST_PATH, img)
print(f" [SAVED] {LATEST_PATH}")
print(f" Now ask your AI agent to analyze: {LATEST_PATH}")
print(f" AI should write: {ANNOTATIONS_PATH}")
print(' Format: [{"name":"skeleton","x":100,"y":200,"w":60,"h":80}, ...]')
def on_f2():
"""Crop entities from latest capture using annotations JSON."""
print("\n[=== CROPPING ENTITIES ===]")
if not os.path.exists(LATEST_PATH):
print(" [ERROR] No capture found. Press F1 first.")
return
if not os.path.exists(ANNOTATIONS_PATH):
print(" [ERROR] No annotations found.")
print(f" Create: {ANNOTATIONS_PATH}")
print(' [{"name":"skeleton","x":100,"y":200,"w":60,"h":80}, ...]')
return
img = cv2.imread(LATEST_PATH)
with open(ANNOTATIONS_PATH) as f:
entities = json.load(f)
print(f" Image: {img.shape[1]}x{img.shape[0]}, Entities: {len(entities)}")
saved = 0
for ent in entities:
name = ent['name'].lower().replace(' ', '_')
x, y = int(ent['x']), int(ent['y'])
w, h = int(ent['w']), int(ent['h'])
i_w, i_h = img.shape[1], img.shape[0]
# Crop with 5px padding
pad = 5
x1, y1 = max(0, x - pad), max(0, y - pad)
x2, y2 = min(i_w, x + w + pad), min(i_h, y + h + pad)
crop = img[y1:y2, x1:x2]
# Route to npc or enemies folder
if name in NPC_NAMES:
save_dir = NPC_DIR
else:
save_dir = ENEMIES_DIR
# Auto-number duplicates
fname = f"{name}.png"
save_path = os.path.join(save_dir, fname)
variant = 1
while os.path.exists(save_path):
variant += 1
fname = f"{name}_{variant}.png"
save_path = os.path.join(save_dir, fname)
cv2.imwrite(save_path, crop)
print(f" [SAVED] {save_path} ({crop.shape[1]}x{crop.shape[0]})")
saved += 1
print(f"\n Total: {saved} assets cropped.")
def on_f3():
"""List existing assets."""
print("\n[=== ASSETS INVENTORY ===]")
for label, d in [("enemies", ENEMIES_DIR), ("npc", NPC_DIR)]:
if os.path.isdir(d):
files = sorted(os.listdir(d))
print(f"\n assets/{label}/ ({len(files)} files):")
for f in files:
sz = os.path.getsize(os.path.join(d, f))
print(f" {f} ({sz}b)")
else:
print(f"\n assets/{label}/ - EMPTY")
def run():
print("=== D2R Asset Extractor ===")
print(" F1 - Capture D2R screen")
print(" F2 - Crop entities from annotations")
print(" F3 - List assets")
print(" F12 - Exit")
print("Ready.")
keyboard.add_hotkey('f1', on_f1)
keyboard.add_hotkey('f2', on_f2)
keyboard.add_hotkey('f3', on_f3)
keyboard.add_hotkey('f12', lambda: (print("\nBye."), sys.exit(0)))
keyboard.wait()
if __name__ == "__main__":
run()
+1106
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

+5 -1
View File
@@ -42,5 +42,9 @@
"Chat Gem Mode": 1,
"Item Name Display": 1,
"Chat Background": 0,
"Always Run": 1
"Always Run": 1,
"Quick Cast Enabled": 0,
"Display Active Skill Bindings": 0,
"Lobby Wide Item Drop Enabled": 1,
"Item Tooltip Hotkey Appender": 1
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Some files were not shown because too many files have changed in this diff Show More