Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 7 из 7
  1. #1
    Аватар для somebodies
    Пользователь

    Статус
    Оффлайн
    Регистрация
    03.01.2017
    Сообщений
    30
    Репутация:
    0 ±

    Поиск близжайших "предметов"

    Всем привет! В общем, работаю над survival-модом.
    Столкнулся со следующей проблемой. Есть функция, определяющая ID ближайшего "лута".
    Код:
    stock GetIDLoot(playerid)
    {
    	for(new i=0; i<MAX_LOOT; i++)
     	{
      		if(IsPlayerInRangeOfPoint(playerid,1.1, LootInfo[i][xLoot],LootInfo[i][yLoot],LootInfo[i][zLoot]))
        	        {
         		    return i;
           	        }
    	}
     	return 0;
    }
    Она определяет [!] только 1 ближайший ID лута. Идем далее.
    Функция подбора лута
    Код:
    if(newkeys & KEY_NO)
    	{
    	    if(!IsPlayerInAnyVehicle(playerid))
    		{
    			if(IsPlayerInRangeOfPoint(playerid,1.1,LootInfo[GetIDLoot(playerid)][xLoot],LootInfo[GetIDLoot(playerid)][yLoot],LootInfo[GetIDLoot(playerid)][zLoot]))
    			{
    			    DisplayLootDialogForPlayer(playerid);
    			}
    		}
    	}
    Само форматирование диалога
    Код:
    public DisplayLootDialogForPlayer(playerid)
    {
    	new fmt[MAX_LOOT_NAME];
    	format(fmt,sizeof(fmt),"1\t%s",LootInfo[GetIDLoot(playerid)][nameLoot]);
    	ShowPlayerDialog(playerid,DIALOG_LOOT,DIALOG_STYLE_LIST,"Подбор предмета",fmt,"Взять","Не взять");
    	return 1;
    }
    Ну и вот в чем суть. Среди кучи айтемов (20+) довольно сложно угадать координаты нужного лута и встать к нему близко. Я решил сделать подбор всего лежащего поблизости лута (т.е чтобы в диалоге форматировались и отображались все близлежайшие предметы). Я решил немного поменять логику функций (лучше бы свою логику как-то можно было поменять). Создав переменную, отвечающую за хранение ИДа предыдущего лута, я проверял , совпадает ли этот ид с полученным в рез-тате работы функции (знаю,что быдлокод и можно лучше, но мне нужен был хоть какой-нибудь результат для того чтобы получить возможность переписать функцию)
    Код:
     if(lootid[playerid] == i) continue;
    и пропускал итерацию в случае этого. Это дало возможность просмотреть 2 близлежаших лута, но не больше. Т.к функция просто переходила к прошлому айдишнику , т.к он не равен записанному в переменную. И таким образом, содержание списка просто дублировалось по типу: Аптечка М4 Аптечка М4 Аптечка М4.
    Уже попробовал все различные способы. Прошу помочь в решении проблемы. Надеюсь, все ясно объяснил

  2. #2
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Код и правда не оч. Особенно глупо то, что ты во втором цикле кучу раз прописываешь GetIDLoot, из-за чего у тебя каждое нажатие на кнопку N запускает 3 цикла, которые возвращают одну и ту же информацию.


    Принцип у скрипта должен быть какой-то такой
    PHP код:
    new first_item_id = -1,
        
    second_item_id = -1,
        
    Float:max_item_distance 99999.0,
        
    Float:current_distance;

    for(new 
    iMAX_LOOTi++)
    {
        
    current_distance GetPlayerDistanceFromPoint(playeridLootInfo[i][xLoot], LootInfo[i][yLoot], LootInfo[i][zLoot]);
        if(
    current_distance <= max_item_distance)// Если записанная ранее дистанция больше или ровна той, что получилась в данный момент (то бишь, предмет ближе)
        
    {
            
    max_item_distance current_distance;// Обновляем записанную дистанцию
            
    second_item_id first_item_id;// Предыдущий найденный объект записываем в переменную для второго объекта
            
    first_item_id i;// Текущий объект записываем в переменную первого объекта
        
    }

    И далее уже проверяй, не равны ли first_item_id и second_item_id значению "-1" и если не равны - работай с ними (в них будет ID ячеек для объектов)

    В теории должно работать. На практике не проверял
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  3. Пользователь сказал cпасибо:
    somebodies (20.07.2017)
  4. #3
    Аватар для somebodies
    Пользователь

    Статус
    Оффлайн
    Регистрация
    03.01.2017
    Сообщений
    30
    Репутация:
    0 ±
    По поводу "второго цикла" - спасибо, переделал.
    По поводу кода - не работает. Попросту не записывает в first_item_id и second_item_id ИДы лута. В чем может быть проблема? пробовал менять код даже, но ничего не срабатывало.

  5. #4
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    PHP код:
    const 
        
    Float:default_distance 9999.0;

    new 
    Float:max_item_distance default_distance,
        
    Float:current_distance,
        
    first_item_id = -1,
        
    second_item_id = -1;

    for(new 
    0MAX_LOOTi++)
    {
        
    current_distance GetPlayerDistanceFromPoint(playeridLootInfo[i][xLoot], LootInfo[i][yLoot], LootInfo[i][zLoot]);
        if(
    current_distance <= max_item_distance)
        {
            
    max_item_distance current_distance;
            
    first_item_id i;
        }
    }

    if(
    first_item_id != -1)
    {
        
    max_item_distance default_distance;
        for(new 
    0MAX_LOOTi++)
        {
            if(
    first_item_id == i)
                continue;
            
    current_distance GetPlayerDistanceFromPoint(playeridLootInfo[i][xLoot], LootInfo[i][yLoot], LootInfo[i][zLoot]);
            if(
    current_distance <= max_item_distance)
            {
                
    max_item_distance current_distance;
                
    second_item_id i;
            }
        }

    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  6. 2 пользователя(ей) сказали cпасибо:
    novichok (06.08.2019) somebodies (20.07.2017)
  7. #5
    Аватар для somebodies
    Пользователь

    Статус
    Оффлайн
    Регистрация
    03.01.2017
    Сообщений
    30
    Репутация:
    0 ±
    Огромное спасибо, теперь все иды корректно записываются, и можно форматировать диалог близлежащими предметами.
    Но есть еще вопросик. Можно ли как-то "автоматизировать" записывание идов в переменные? Допустим, под игроком будет лежать 10 предметов. Получается, мне в функции нужно будет делать 10 (и то не факт, что 10, предметов может быть больше) различных проверок на расстояние и использованные иды предметов.Что-то вроде:
    Код:
    if(third_item_id != -1)
    {...}
    if(fourth_item_id != -1)
    {...}
    if(fifth_item_id != -1)
    {...}
    Что, вроде бы, быдлокод не очень. К тому же, каждый раз будет действовать 10 проверок, даже когда возле игрока есть только один предмет
    Есть ли какие-либо способы?
    Последний раз редактировалось somebodies; 20.07.2017 в 07:54.

  8. #6
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Ну так тебе нужно отобразить все предметы, которые есть вокруг или как? Если исключительно 10/20/30/etc самых ближайших - без проверок не обойтись, ибо иначе эти самые ближайшие не найти. А если просто определённое количество в радиусе - уже проще.
    В любом случае ты собираешься сделать механизм, который отсеивает среди кучи объектов лишь нужные. Естественно он будет более сложно реализован, включая в себя дополнительные проверки. Хочешь по простому - просто делай подбор первого найденного в цикле ближайшего объекта и всё.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  9. Пользователь сказал cпасибо:
    somebodies (20.07.2017)
  10. #7
    Аватар для somebodies
    Пользователь

    Статус
    Оффлайн
    Регистрация
    03.01.2017
    Сообщений
    30
    Репутация:
    0 ±
    Спасибо тебе огромное за помощь=)
    можно закрывать

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •