function transform_coords2($points) { global $DB, $cached_images; // Собираем номера всех карт, где находятся точки $mapids = array(); foreach ($points as $point) { if (!in_array($point['m'], $mapids)) { $mapids[] = $point['m']; } } $areas = $DB->select('SELECT mapID, areatableID, name_loc?d AS name, x_min, y_min, x_max, y_max FROM ?_zones WHERE mapID IN (?a)', $_SESSION['locale'], $mapids); // Сначала выберем самую хорошую карту для каждой точки $bestarea = array(); $mapexists = array(); // cache $maskexists = array(); // cache foreach ($points as $pointid => $point) { foreach ($areas as $areaid => $area) { if ($point['m'] == $area['mapID']) { // Определяем "приоритет" этой карты - насколько хорошо она подходит для данной точки $curpriority = 0; if (!isset($mapexists[$areaid])) { $mapexists[$areaid] = file_exists('images/maps/enus/normal/' . $area['areatableID'] . '.jpg'); } if ($mapexists[$areaid]) { $curpriority |= 1; } $maskfilename = 'images/tmp/' . $area['areatableID'] . '.png'; if (!isset($maskexists[$areaid])) { $maskexists[$areaid] = file_exists($maskfilename); } if ($maskexists[$areaid]) { $curpriority |= 2; } // Note: Dalaran has its coords reversed. if ($point['x'] >= $area['x_min'] && $point['x'] <= $area['x_max']) { $curpriority |= 8; } if ($point['y'] >= $area['y_min'] && $point['y'] <= $area['y_max']) { $curpriority |= 16; } if ($curpriority & 2 && $curpriority & 8 && $curpriority & 16) { if (!$cached_images[$area['areatableID']]) { $cached_images[$area['areatableID']] = imagecreatefrompng($maskfilename); } $game_x = 100 - ($point['y'] - $area['y_min']) / (($area['y_max'] - $area['y_min']) / 100); $game_y = 100 - ($point['x'] - $area['x_min']) / (($area['x_max'] - $area['x_min']) / 100); if (imagecolorat($cached_images[$area['areatableID']], round($game_x * 10), round($game_y * 10)) === 0) { $curpriority |= 4; } } // И сравниваем текущий приоритет с лучшим if (!isset($bestarea[$pointid]) || $bestarea[$pointid]['priority'] < $curpriority || $bestarea[$pointid]['priority'] == $curpriority && $areas[$bestarea[$pointid]['area']]['areatableID'] < $area['areatableID']) { $bestarea[$pointid] = array('priority' => $curpriority, 'area' => $areaid); } } } } // А теперь формируем выходной массив карт $data = array(); $data_ids = array(); // stupid 'areatableID => $data index' array foreach ($points as $pointid => $point) { if (isset($bestarea[$pointid])) { $i = $bestarea[$pointid]['area']; $atid = $areas[$i]['areatableID']; if (!isset($data_idx[$atid])) { $data_idx[$atid] = count($data); $data[] = array('population' => 0, 'name' => $areas[$i]['name'], 'atid' => $atid, 'points' => array()); } if ($point['type'] == 0) { // Account spawn points only, not waypoints $data[$data_idx[$atid]]['population']++; } if ($areas[$i]['x_min'] != $areas[$i]['x_max'] && $areas[$i]['y_min'] != $areas[$i]['y_max']) { $data[$data_idx[$atid]]['points'][] = transform_point($areas[$i], $point); } } else { if (!isset($data_idx[0])) { $data_idx[0] = count($data); $data[] = array('population' => 0, 'name' => '(unknown)', 'atid' => 0, 'points' => array()); } $data[$data_idx[0]]['population']++; } } return $data; }
function transform_coords($recv) { global $DB, $at_dataoffsets; // Cached data $map_data = array(); $at_data = array(); $map_dataoffsets = array(); $zone_dataoffsets = array(); $at_dataoffsets = array(); $at_dataoffsets_offset = 0; $loaded_areas = array(); $data = array(); $i = -1; // на самом деле в этой переменной хранится id последнего элемента в $data // Собираем номера всех карт, где находятся точки $mapids = array(); foreach ($recv as $point) { if (!in_array($point['m'], $mapids)) { $mapids[] = $point['m']; } } // Считываем сколько всего карт существует $result = $DB->select('SELECT mapID, areatableID, name_loc?d AS name, x_min, COUNT(*) AS c FROM ?_zones WHERE mapID IN (?a) GROUP BY mapID', $_SESSION['locale'], $mapids); if (!$result) { return false; } foreach ($result as $record) { $mapid = $record['mapID']; $atid = $record['areatableID']; $map_data[$mapid] = array('name' => $record['name']); // Для этой карты существует всего одна локация, // причем неизвестно, есть для нее карта или нет. if ($record['c'] == 1) { if (file_exists('images/maps/enus/normal/' . $atid . '.jpg')) { $map_data[$mapid]['atid'] = $atid; // Это хак, но пусть так if ($record['x_min'] == 0) { $map_data[$mapid]['coords_not_available'] = true; } else { // Задаем директиву не использовать негативы $map_data[$mapid]['ignore_negatives'] = true; } } else { // Карта не доступна - записываем, что бы потом не жрать ресурсы. $map_data[$mapid]['map_not_available'] = true; } } else { $map_data[$mapid]['multiple_areas'] = true; } } foreach ($recv as $point) { $mapid = $point['m']; $md = $map_data[$mapid]; $point['n'] = $md['ignore_negatives']; // Карта не доступна if ($md['map_not_available'] || $md['coords_not_available']) { if (isset($map_dataoffsets[$mapid])) { // Если у нас уже была точка с такой картой, // то увеличиваем население на ней. $data[$map_dataoffsets[$mapid]]['population']++; } else { // Если нет - создаем новую. $data[++$i] = array('population' => 1, 'name' => $md['name'], 'atid' => $md['map_not_available'] ? 0 : $md['atid']); $map_dataoffsets[$mapid] = $i; } continue; } // Если всего одна зона на карту, // и для нее есть изображение и координаты, // сразу же указываем номер зоны if (!$md['multiple_areas']) { $chosen_area = $md['atid']; } else { $chosen_area = select_zone($at_data, $point); } // Если зон на карту много и/или нужная нам не загружена if (!$chosen_area || !in_array($chosen_area, $loaded_areas)) { // Загружаем зоны $result = $DB->select(' SELECT mapID, areatableID, x_min, x_max, y_min, y_max, name_loc?d AS name FROM ?_zones WHERE (? BETWEEN x_min AND x_max) AND (? BETWEEN y_min AND y_max) AND mapID = ? ', $_SESSION['locale'], $point['x'], $point['y'], $point['m']); foreach ($result as $area) { $loaded_areas[] = $area['areatableID']; $at_dataoffsets[$area['areatableID']] = $at_dataoffsets_offset++; } $at_data = array_merge($at_data, $result); $chosen_area = select_zone($at_data, $point); } // Если зона так и не найдена (исключительный случай) // просто этой точки не будет на карте. // Если мы в финальном массиве уже имеем запись на // данный номер зоны if (isset($zone_dataoffsets[$chosen_area])) { $offset = $zone_dataoffsets[$chosen_area]; // Если у нас уже была точка с такой картой, // то увеличиваем население на ней, записываем новую точку $data[$offset]['population']++; if ($chosen_area) { $data[$offset]['points'][] = transform_point($at_data[$at_dataoffsets[$chosen_area]], $point); } } else { $points_array = $chosen_area ? array(transform_point($at_data[$at_dataoffsets[$chosen_area]], $point)) : array(); // Если нет - создаем новую. $data[++$i] = array('population' => 1, 'name' => $at_data[$at_dataoffsets[$chosen_area]]['name'], 'atid' => $chosen_area, 'points' => $points_array); $zone_dataoffsets[$chosen_area] = $i; } } return $data; }