Initial project structure: reusable isometric bot engine with D2R implementation
This commit is contained in:
commit
e0282a7111
44 changed files with 3433 additions and 0 deletions
97
games/d2r/game.py
Normal file
97
games/d2r/game.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
"""Main D2R bot class — orchestrates the bot loop.
|
||||
|
||||
Entry point for the Diablo II: Resurrected bot. Manages the main
|
||||
game loop, state transitions, and routine execution.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
from engine.screen.capture import ScreenCapture
|
||||
from engine.input.humanize import Humanizer
|
||||
from engine.state.events import EventBus
|
||||
from engine.safety.timing import SessionTimer
|
||||
from games.d2r.config import D2RConfig
|
||||
from games.d2r.screens.ingame import InGameDetector
|
||||
from games.d2r.screens.menu import MenuDetector
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class D2RBot:
|
||||
"""Main Diablo II: Resurrected bot."""
|
||||
|
||||
def __init__(self, config: Optional[D2RConfig] = None):
|
||||
self.config = config or D2RConfig()
|
||||
self.screen = ScreenCapture()
|
||||
self.humanizer = Humanizer()
|
||||
self.events = EventBus()
|
||||
self.session_timer = SessionTimer()
|
||||
self.menu_detector = MenuDetector(self.config)
|
||||
self.ingame_detector = InGameDetector(self.config)
|
||||
|
||||
self._running = False
|
||||
self._current_routine = None
|
||||
|
||||
def start(self, routine_name: str = "mephisto") -> None:
|
||||
"""Start the bot with a specific farming routine."""
|
||||
logger.info(f"Starting D2R bot with routine: {routine_name}")
|
||||
self._running = True
|
||||
|
||||
try:
|
||||
self._main_loop(routine_name)
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Bot stopped by user")
|
||||
except Exception as e:
|
||||
logger.error(f"Bot error: {e}", exc_info=True)
|
||||
finally:
|
||||
self._running = False
|
||||
|
||||
def stop(self) -> None:
|
||||
"""Signal the bot to stop."""
|
||||
self._running = False
|
||||
|
||||
def _main_loop(self, routine_name: str) -> None:
|
||||
"""Core bot loop."""
|
||||
while self._running:
|
||||
# Check session timing
|
||||
if self.session_timer.should_stop_session():
|
||||
break_duration = self.session_timer.get_break_duration()
|
||||
logger.info(f"Session break: {break_duration/60:.0f} min")
|
||||
time.sleep(break_duration)
|
||||
self.session_timer.start_new_session()
|
||||
|
||||
# Check for breaks
|
||||
break_time = self.humanizer.should_take_break()
|
||||
if break_time:
|
||||
time.sleep(break_time)
|
||||
|
||||
# Capture screen
|
||||
frame = self.screen.capture_screen()
|
||||
|
||||
# Detect state and act
|
||||
# TODO: Implement state detection and routine execution
|
||||
|
||||
# Small delay between loop iterations
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
def main():
|
||||
"""CLI entry point."""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="D2R Bot")
|
||||
parser.add_argument("--routine", default="mephisto", choices=["mephisto", "pindle", "countess"])
|
||||
parser.add_argument("--resolution", default="1920x1080")
|
||||
args = parser.parse_args()
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(name)s] %(levelname)s: %(message)s")
|
||||
|
||||
config = D2RConfig()
|
||||
bot = D2RBot(config)
|
||||
bot.start(args.routine)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue