/// mix image and bgcolor to bg buffer static void bg_set_image_grayscale(pixel * img_buf, dword top, dword left, dword width, dword height, dword bgcolor, dword grayscale) { pixel *bg_buf, *bg_end, *bg_line, *bg_lineend; dword r = RGB_R(bgcolor), g = RGB_G(bgcolor), b = RGB_B(bgcolor); for (bg_buf = bg_start + top * PSP_SCREEN_SCANLINE + left, bg_end = bg_buf + height * PSP_SCREEN_SCANLINE; bg_buf < bg_end; bg_buf += PSP_SCREEN_SCANLINE) for (bg_line = bg_buf, bg_lineend = bg_buf + width; bg_line < bg_lineend; bg_line++) { *bg_line = disp_grayscale(*img_buf, r, g, b, grayscale); img_buf++; } }
"Orange", "Yellow", "Bright Blue", "Dark Blue", "Gray", "Bright Green", "Dark Green", "Reverse", "Custom Local", "Custom Global", "SGB" }; word m_pal16[16][3][4] = { { // モノクロ(Monochrome) -GB {RGB_G(255,255,255), RGB_G(168,168,168), RGB_G(88,88,88), RGB_G(0,0,0)}, {RGB_G(255,255,255), RGB_G(168,168,168), RGB_G(88,88,88), RGB_G(0,0,0)}, {RGB_G(255,255,255), RGB_G(168,168,168), RGB_G(88,88,88), RGB_G(0,0,0)} }, { // 明るいセピア(Bright Sepia) {RGB_G(255,255,255), RGB_G(255,204,153), RGB_G(153,76,0), RGB_G(0,0,0)}, {RGB_G(255,255,255), RGB_G(255,204,153), RGB_G(153,76,0), RGB_G(0,0,0)}, {RGB_G(255,255,255), RGB_G(255,204,153), RGB_G(153,76,0), RGB_G(0,0,0)} }, { // 赤(Red) {RGB_G(255,255,255), RGB_G(255,204,204), RGB_G(127,51,51), RGB_G(0,0,0)}, {RGB_G(255,255,255), RGB_G(204,255,204), RGB_G(51,127,51), RGB_G(0,0,0)}, {RGB_G(255,255,255), RGB_G(127,204,204), RGB_G(51,127,204),RGB_G(0,0,0)} }, { // 暗いセピア(Dark Sepia) {RGB_G(255,255,255), RGB_G(204,178,153), RGB_G(153,127,76),RGB_G(76,51,0)},
bool NpcScanAlertor::CheckNpcHeadIcon() { int x = m_targetRect.left; int y = m_targetRect.top; int w = m_targetRect.right - m_targetRect.left; int h = m_targetRect.bottom - m_targetRect.top; if (!ImageUtil::GetWindowSnapshot(m_hwnd, x, y, w, h, m_lpBits)) { Utility::printf_t("Alerter[%d] \"%s\" : GetWindowSnapshot failed!\n", m_pid, m_name.c_str()); Stop(); return false; } const int color_yellow = RGB(175, 175, 0); // 中立怪血条颜色 (300, 33) const int color_yellow_range = RGB(30, 30, 10); const int color_red = RGB(181, 0, 0); // 敌对怪血条颜色 (300, 33) const int color_red_range = RGB(20, 10, 10); // 根据血条颜色判断是否选中了目标 int yellow_count = 0, red_count = 0; int min_x = 8, max_x = 108, step_x = 2; // 目标头像面板位置 int ty = 33; for (int tx = min_x; tx <= max_x; tx += step_x) { int color = ImageUtil::GetColor(m_lpBits, w, h, tx, h - ty); if (ImageUtil::IsColorAlike(color, color_yellow, color_yellow_range)) ++yellow_count; else if(ImageUtil::IsColorAlike(color, color_red, color_red_range)) ++red_count; } bool hasTarget = max(yellow_count, red_count) * step_x * 1.0f / (max_x - min_x) > 0.4f; // 大于40%颜色符合,判定为已选择目标。 if (!hasTarget) { //Utility::printf_t("hasTarget failed\n"); return false; } bool isRed = red_count > yellow_count; bool isYellow = yellow_count > red_count; if (isRed && !(m_colorType & (int)ColorType::Color_Red) && isYellow && !(m_colorType & (int)ColorType::Color_Yellow)) { return false; } if (m_bRare) { // 稀有精英,银龙标识采样区域 RECT rects[] = { { 104, 12, 28, 12 }, // left, top, w, h { 132, 9, 27, 6 }, { 170, 28, 12, 30 }, }; const int rare_range = 10; int total_count = sizeof(rects) / sizeof(RECT); int rare_count = 0; for (int i = 0; i < total_count; ++i) { int min_x = rects[i].left; int max_x = min_x + rects[i].right; int min_y = rects[i].top; int max_y = min_y + rects[i].bottom; int count = 0; for (int x = min_x; x < max_x; ++x) { for (int y = min_y; y < max_y; ++y) { int color = ImageUtil::GetColor(m_lpBits, w, h, x, y); char r = RGB_R(color); char g = RGB_G(color); char b = RGB_B(color); if (r >= 40 && r <= 90 && abs(r - g) < rare_range && abs(r - b) < rare_range) // 银龙标识为近似灰色 ++count; } } if (count * 1.0f / (rects[i].right * rects[i].bottom) > 0.4f) { ++rare_count; } } if (rare_count <= total_count / 2) { //Utility::printf_t("isRare failed.\n"); return false; } } Utility::printf_t("Alerter[%d] \"%s\" : Find target, rare = %d, color = %s\n", m_pid, m_name.c_str(), m_bRare, isRed ? "red" : "yellow"); return true; }