// 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 from botty reference (720p scaled to 1080p) // Health orb RED: OpenCV H 178-183 → our H 356-366, wraps around 360 // Using H 350-360 + H 0-10 range (handled by wrapping in colorInRange) HealthFilled: HSVRange{350, 100, 80, 370, 255, 255}, // H wraps: 350-370 means 350-360,0-10 // Mana orb BLUE: actual H 225-245 from screenshot ManaFilled: HSVRange{225, 100, 60, 245, 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_globe": image.Rect(325, 915, 470, 1040), // Full health globe region "mana_globe": image.Rect(1475, 900, 1655, 1055), // Full mana globe region "health_slice": image.Rect(395, 920, 405, 1040), // Thin vertical strip through orb center "mana_slice": image.Rect(1505, 900, 1515, 1055), // Thin vertical strip through orb center "health_orb": image.Rect(325, 915, 470, 1040), // Alias for backward compat "mana_orb": image.Rect(1475, 900, 1655, 1055), // Alias for backward compat "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_globe": image.Rect(217, 610, 313, 693), "mana_globe": image.Rect(983, 600, 1103, 703), "health_slice": image.Rect(263, 613, 270, 693), "mana_slice": image.Rect(1003, 600, 1010, 703), "health_orb": image.Rect(217, 610, 313, 693), "mana_orb": image.Rect(983, 600, 1103, 703), "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) }