Example #1
0
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;
}
Example #2
0
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;
}