// D2R-specific configuration: colors, timings, and resolution profiles. package d2r import ( "image" "git.cloonar.com/openclawd/iso-bot/pkg/engine/resolution" ) // HSVRange defines a color range in HSV space. type HSVRange struct { LowerH, LowerS, LowerV int UpperH, UpperS, UpperV int } // Colors defines HSV ranges for game elements. type Colors struct { HealthFilled HSVRange ManaFilled HSVRange ItemUnique HSVRange ItemSet HSVRange ItemRare HSVRange ItemRuneword HSVRange PortalBlue HSVRange } // Timings defines game-specific delay constants. type Timings struct { LoadingScreenMaxMs int TownPortalCastMs int TeleportDelayMs int PotionCooldownMs int PickupDelayMs int } // Config holds all D2R-specific configuration. type Config struct { Colors Colors Timings Timings // Loot settings PickupUniques bool PickupSets bool PickupRares bool PickupRunes bool MinRuneTier int PickupGems bool // Safety thresholds (0.0 - 1.0) HealthPotionThreshold float64 ManaPotionThreshold float64 ChickenThreshold float64 // exit game if health below this } // DefaultConfig returns the default D2R configuration. func DefaultConfig() Config { return Config{ Colors: Colors{ // Calibrated HSV ranges from real D2R screenshot (testdata/d2r_1080p.png) // Health orb is bright RED: RGB ~(236,15,20) → HSV H 0-10, S 150+, V 150+ HealthFilled: HSVRange{0, 150, 150, 10, 255, 255}, // Mana orb is BLUE: H 200-240, S 100+, V 80+ ManaFilled: HSVRange{200, 100, 80, 240, 255, 255}, ItemUnique: HSVRange{15, 100, 180, 30, 255, 255}, ItemSet: HSVRange{35, 100, 150, 55, 255, 255}, ItemRare: HSVRange{15, 50, 200, 25, 150, 255}, ItemRuneword: HSVRange{15, 100, 180, 30, 255, 255}, PortalBlue: HSVRange{90, 150, 150, 120, 255, 255}, }, Timings: Timings{ LoadingScreenMaxMs: 15000, TownPortalCastMs: 3500, TeleportDelayMs: 150, PotionCooldownMs: 1000, PickupDelayMs: 300, }, PickupUniques: true, PickupSets: true, PickupRares: true, PickupRunes: true, MinRuneTier: 10, PickupGems: false, HealthPotionThreshold: 0.5, ManaPotionThreshold: 0.3, ChickenThreshold: 0.2, } } // RegisterProfiles registers D2R resolution profiles with the resolution registry. func RegisterProfiles(registry *resolution.Registry) error { profiles := []*resolution.Profile{ // 1920x1080 (1080p) - Primary resolution // Calibrated from real D2R screenshot (testdata/d2r_1080p.png) { Width: 1920, Height: 1080, Label: "1080p", Regions: map[string]image.Rectangle{ "health_orb": image.Rect(370, 945, 460, 1030), "mana_orb": image.Rect(1580, 910, 1670, 1000), "xp_bar": image.Rect(0, 1058, 1920, 1080), "belt": image.Rect(500, 990, 900, 1040), "minimap": image.Rect(1600, 0, 1920, 320), "inventory": image.Rect(960, 330, 1490, 770), "stash": image.Rect(430, 330, 960, 770), "skill_left": image.Rect(200, 1030, 250, 1078), "skill_right": image.Rect(1670, 1030, 1730, 1078), }, }, // 1280x720 (720p) - Secondary resolution (scaled from 1080p) { Width: 1280, Height: 720, Label: "720p", Regions: map[string]image.Rectangle{ "health_orb": image.Rect(247, 630, 307, 687), "mana_orb": image.Rect(1053, 607, 1113, 667), "xp_bar": image.Rect(0, 705, 1280, 720), "belt": image.Rect(333, 660, 600, 693), "minimap": image.Rect(1067, 0, 1280, 213), "inventory": image.Rect(640, 220, 993, 513), "stash": image.Rect(287, 220, 640, 513), "skill_left": image.Rect(133, 687, 167, 718), "skill_right": image.Rect(1113, 687, 1153, 718), }, }, } return registry.RegisterMultiple("d2r", profiles) }