Использование активного акса

Ciske

Новичок
Автор темы
25
7
Версия MoonLoader
.027.0-preview
Приветствую. Задача: заюзать активный надетый акс на Аризоне. То есть, кликнуть сначала по слоту с надетым аксом, а затем по текстдраву 'Использовать'. Вроде бы всё работает (можно как-то упростить?), но инвентарь видел пользователю. Хотелось бы, чтобы всё выполнялось в фоне. Это возможно? Как я могу запретить выводить текстдрав на экран (return false) если я ухожу из события onShowTextDraw в асинхронный поток для ожидания 500 мск? Будто бы никак нельзя, но ведь делают же. Например, /lavka (установка лавки в Арз маркете). Как это реализовано?

(id текстдравов слотов у Аризоны меняются в зависимости от скина и его улучшений: добавляются какие-то иконки >> увеличивается кол-во текстдравов >> id слотов сдвигаются по номерам выше)


Lua:
local MODELID = 370
local status = false
local firstStage = false
local secondStage = false
local SLOT = -1

function main()
    while not isSampAvailable() do wait(0) end
 
    sampRegisterChatCommand('jp', function(arg)
            status = true
            firstStage = true
            SLOT = -1
            sampSendChat('/invent')  - открываем инвентарь
    end)
  
    wait(-1)
end

function samp.onShowTextDraw(id, data)
    if status then
        -- Определяем границу по оси x перед которой искать слот с нужной моделькой.
        if firstStage then
            if data.text == 'GPS'  then  --  текстдрав в инвентаре GPS, он чуть дальше нужного слота
                lua_thread.create(working, data.position.x)
            end
        end
    
        -- после первой фазы, то есть после клика по слоту, ждём появления текстдрава Использовать
        if secondStage then
            if data.text == '…CЊO‡’€O‹AЏ’' or text == "USE" then  -- 'ИСПОЛЬЗОВАТЬ'
                sampSendClickTextdraw(id + 1)  -- контейнер подписи вроде бы всегда id текста + 1
                sampSendClickTextdraw(65535)  -- закрываем
                secondStage = false
                status = false
                return false
            end
        end
    end
end

function working(xCoord)
    wait(500)
    if status and firstStage then
        -- при открытом инвентаре перебираем номера текстдравов в примерном диапазоне
        for i = 2100, 2150 do
            if sampTextdrawIsExists(i) then
                local x, _ = sampTextdrawGetPos(i)
                local model = sampTextdrawGetModelRotationZoomVehColor(i)
                if x < xCoord and model == MODELID then  -- не далее определённой границы по оси x и нужная моделька
                    SLOT = i
                    break
                end
            end
        end
        firstStage = false
    
        if SLOT == -1 then
            sampAddChatMessage('Вы не надели аксессуар в слот!', 16776960)
            sampSendClickTextdraw(65535)  -- закрываем
            status = false
            return
        end
    
        secondStage = true
        sampSendClickTextdraw(SLOT)     -- клик по слоту
    end
end
 
Последнее редактирование:

wojciech?

Известный
Проверенный
418
368
Тебе не нужно ожидание в 500 мс и отдельный поток. В событии находи нужный слот по его позиции, проверяй пустой ли он (по модели) и сразу нажимай на него. Также сразу нажимай использовать, если оно появляется, не делая разделение на две фазы. Пока все эти манипуляции происходят, игнорируй входящие onShowTextDraw. Как только выполнил последнее действие - отключай и закрывай текстдравы.
 
  • Нравится
Реакции: SiarCis

SiarCis

Новичок
11
0
по его позиции
Огромное спасибо. Получается, что и позицию определять-то не надо, просто по наличию модели. А вообще позиция на всех экранах и разрешениях одинакова? Там какие-то условные единицы экранных координат?
 

wojciech?

Известный
Проверенный
418
368
Огромное спасибо. Получается, что и позицию определять-то не надо, просто по наличию модели. А вообще позиция на всех экранах и разрешениях одинакова? Там какие-то условные единицы экранных координат?
Лучше проверить и позицию, вещь может быть не в слоте, а в самом инвентаре (или наоборот). Позиции у всех одинаковые, их можно посмотреть в data.position, поля .x и .y
 
  • Нравится
Реакции: SiarCis

SiarCis

Новичок
11
0
Лучше проверить и позицию, вещь может быть и не в слоте, а в самом инвентаре (или наоборот). Позиции у всех одинаковые, их можно посмотреть в data.position, поля .x и .y
Спасибо! Сам инвентарь — это 5 страниц. Потому вещь должна быть в слоте, делать листание и поиск слишком сложно и долго (системная задержка на листание).

А для более сложных структур, лавка к примеру, надо всё-таки делать задержку в потоке и далее пробегаться по всем идентификаторам (for do)? Так ведь? Там для каждого слота надо получить цену (отдельный текстдрав), название предмета (отдельный текстдрав при его наличии) и модельку (отдельный текстдрав). Нет более простого и быстрого способа?

 

wojciech?

Известный
Проверенный
418
368
А для более сложных структур, лавка к примеру, надо всё-таки делать задержку в потоке и далее пробегаться по всем идентификаторам (for do)? Так ведь? Там для каждого слота надо получить цену (отдельный текстдрав), название предмета (отдельный текстдрав при его наличии) и модельку (отдельный текстдрав). Нет более простого и быстрого способа?
Как удобнее, но отдельными циклами это делать проще, чем пытаться ассоциировать появляющиеся текстдравы друг с другом. И лучше кэшировать какую-то базовую информацию, по которой можно быстро произвести поиск. Например, сохранить все позиции текстдравов в хеш таблицу, и при нахождении слота, быстро находить все связанные с ним значения (цену и может прикрепленную модель, если она отдельно) по их оффсетам относительно самого слота.
 
  • Нравится
Реакции: SiarCis

SiarCis

Новичок
11
0
В принципе, наверное, самый быстрый вариант, это таблицы основная и хэш с координатами.
hash = {136272.22: {"type": price, "slot": 28}, …}
main = {1: {id: [], "price": 123, "model": 242526, "name": nil}, …}

Быстро по хэшу кидать полученную инфу в основную таблицу и каждую итерацию проходить по ней циклом и смотреть, не достаточно ли ещё данных (минимум цена + Id «контейнера» для клика + одно из двух — название / моделька). Вопрос только в том, какой конечный триггер завершения сбора? Сначала прогружается основной интерфейс лавки, потом уже слоты с динамичными ID.