XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Закрытая тема
 
Preveder
StarCraft II® Inside
offline
Опыт: 1,927
Активность:
Проблема с GroupEnumUnits в .ai-скрипте.
Очень странно работают функции набора в группу. Сколько ни пробовал, а заставить аи собрать нужную мне группу не удалось. В чём проблема: В обычном кастом скрипте отлично пашет следующий код -
Код:
set TOWER_TYPE[10] = 'h01B'
//выше по коду через несколько функций глобалка с равкодом.
function IsSiegeTower takes nothing returns boolean
    return (GetUnitTypeId(GetFilterUnit()) == TOWER_TYPE[10])
endfunction

function FocusSiegeTower takes nothing returns nothing
    local group g = CreateGroup()
    call GroupEnumUnitsOfPlayer(g, AIPLAYER, Filter(function IsSiegeTower))
    set SIEGETOWERUPFOCUS = FirstOfGroup(g)
    if SIEGETOWERUPFOCUS == null then
        call Echo("SIEGE TOWER FOCUS IS EMPTY!")
    endif
    set SIEGETOWERUP = 0
    call DestroyGroup(g)
    set g = null
endfunction


Значение глобалок AIPLAYER и TOWER_TYPE[10] валидное, оно выставляется один раз и не меняется.
При любом раскладе группа оказывается пустой и выводится сообщение. При использовании аналогов - сбор башен в радиусе определённого ректа или от координат юнита ничего не даёт. Проблему не смог решить самостоятельно. Кто-нибудь сталкивался с таким?
Есть подозрение, что во время сбора не действуют глобалки на вызываемый фильтр (имхо бред, но не знаю что и думать).
Как всё-таки оживить фильтрацию по равкоду в данном случае?

Отредактировано Preveder, 07.05.2009 в 12:28.
Старый 06.05.2009, 19:01
alexprey
познающий Unity
offline
Опыт: 68,501
Активность:
Preveder, Filter?? первый раз вижу такую функцию(Можно еще Condition) А зачем использовать глобалку, когда можно сразу тип подставить??? SIEGETOWERUPFOCUS - а это глобальная переменна?
Старый 06.05.2009, 20:19
Preveder
StarCraft II® Inside
offline
Опыт: 1,927
Активность:
Цитата:
Сообщение от King Ksel
Preveder, Filter?? первый раз вижу такую функцию(Можно еще Condition) А зачем использовать глобалку, когда можно сразу тип подставить??? SIEGETOWERUPFOCUS - а это глобальная переменна?

Спасибо, что хоть кто-то откликнулся. Да, есть такая функция:
Код:
native Filter           takes code func returns filterfunc

В чём их разница с Кондишен я не знаю, ибо оба являются boolexpr, но Filter короче по написанию :).
SIEGETOWERUPFOCUS - глобальная типа юнит.
Сразу значение подставить невыгодно, ибо скрипт планируется размножить с отличиями в основном в именно в башнях (равкодах) и логике остройки компьютера. Основные оперирующие функции останутся теми же, так что глобалки будут актуальны - меньше переписывать.

Как ни пыхтел, а заставить компа "фильтровать базар" не смог. Думаю поизвращаться с РБ и кэшем. Основной скрипт карты посылает ИИ команду с H2I(кэш), ИИ скрипт определяет её как кэш, пишет в этот кэш каким образом надо отбирать юнитов и ставится в цикл с ожиданием изменения значения переменной, а основной скрипт карты в это время каждую секунду мониторит значения в кэше, извлекает значение фильтра для ИИ, сортирует, выбирает юнита и отправляет его как команду ИИ... Опять же, как H2I. ИИ отвечает на эту команду изменением глобалки (из интеджера в юнит), и скрипт выходит из цикла... Попробую этот дикий изврат реализовать, если с фильтром ничего не выйдет....

Отредактировано Preveder, 06.05.2009 в 20:43.
Старый 06.05.2009, 20:29
alexprey
познающий Unity
offline
Опыт: 68,501
Активность:
Preveder, есть большая разница! Filter возвращает filterfunc, а Condition - conditionfunc!
Код:
native Filter takes code func returns filterfunc
native Condition takes code func returns conditionfunc

А вот какая разница между filterfunc и conditionfunc, я ненашел!))

King Ksel добавил:
хотя обе образованы от boolexpr
Ты попробуй выводить какие значения выдает фильтрация! Мне лично это помогает!
Старый 06.05.2009, 21:32
Preveder
StarCraft II® Inside
offline
Опыт: 1,927
Активность:
Цитата:
Сообщение от King Ksel
Preveder, есть большая разница! Filter возвращает filterfunc, а Condition - conditionfunc!
Код:
native Filter takes code func returns filterfunc
native Condition takes code func returns conditionfunc

А вот какая разница между filterfunc и conditionfunc, я ненашел!))

King Ksel добавил:
хотя обе образованы от boolexpr
Ты попробуй выводить какие значения выдает фильтрация! Мне лично это помогает!

Разницы между filterfunc и conditionfunc на мой взгляд нету, ибо и то и то boolexpr. Видимо, задумывалось близзами, что одно логическое выражение для условий в триггере и конструкциях if/then/else, а другое для фильтров.

Фильтрация возвращает ложь в моём случае. Проверял. Даже проверил ручным вбиванием интеджера. И всё равно ложь :). Целый вечер развлекаюсь с этим весёлым скриптом.
Старый 06.05.2009, 22:07
Hellfim
Новичок
offline
Опыт: 79,707
Активность:
Preveder, что забито в переменных AIPLAYER и SIEGETOWERUPFOCUS?
Старый 06.05.2009, 22:53
Preveder
StarCraft II® Inside
offline
Опыт: 1,927
Активность:
В AIPLAYER забит сам комп. а в SIEGETOWERUPFOCUS изначально null, вышеуказанная функция должна её заполнить, но проблема с фильтром, потому и не набирается группа.
Старый 07.05.2009, 08:32
SRes
1110101000
offline
Опыт: 9,997
Активность:
Я понимаю, мысль глупая - но попробуй убрать лишние скобки, т.е.
Код:
return GetUnitTypeId(GetFilterUnit()) == TOWER_TYPE[10]

Врядли это на что-то повлияет, но всеже. Та и хз что там за особенности у близзов в ИИ скрипте. Имхо, лучше писать как обычную функцию в самой мапе. Ну не будет у тебя парочки функций и что? Зато мешочек глюков останется ждать другую жертву.
Старый 07.05.2009, 10:01
Preveder
StarCraft II® Inside
offline
Опыт: 1,927
Активность:
Попробую. Извращался с искусственным фильтром а.к.а. собрать всех юнитов игрока через ReturnTrue а потом уже сортировать через GetEnumUnit().

Даже при
Код:
function ReturnTrue takes nothing returns boolean
    return true
endfunction

function FocusTower takes nothing returns nothing
    if GetUnitTypeId(GetEnumUnit()) == TOWER_TYPE[10] and SIEGETOWERUPFOCUS == null then
    set SIEGETOWERUPFOCUS = GetEnumUnit() 
    endif
endfunction

function FocusSiegeTower takes nothing returns nothing
    local group g = CreateGroup()
    call Sleep(0.5)
    call GroupEnumUnitsOfPlayer(g, AIPLAYER, Filter(function ReturnTrue)
    call ForGroup(g, function FocusTower)
    if SIEGETOWERUPFOCUS == null then
        call Echo("SIEGE TOWER FOCUS IS EMPTY!")
    endif
    set SIEGETOWERUP = 0
    call DestroyGroup(g)
    set g = null
endfunction


SIEGETOWERUPFOCUS остаётся null. Значит, группы и впрямь пустые тут получаются....
Старый 07.05.2009, 10:22
J
expert
offline
Опыт: 48,447
Активность:
Код:
globals
    group GG = CreateGroup()
endglobals

function FocusSiegeTower_Filter takes nothing returns boolean
    local unit f = GetFilterUnit()
    if GetUnitTypeId(f) == TOWER_TYPE[10] then    
        set SIEGETOWERUPFOCUS = f
        call Echo("Бинго!")        
        return true
    else
        call Echo(I2S(GetUnitTypeId(f))+" - "+GetUnitName(f))
        return false
    endif
endfunction

function FocusSiegeTower takes nothing returns nothing
    call Sleep(0.5)
    if (TOWER_TYPE[10] == 0) then
        call Echo("Шозанах1 o_O")
    endif
    if (AIPLAYER == null) then
        call Echo("Шозанах2 O_o")
    endif
    if (GG == null) then
        call Echo("Как так?...")
    endif
    if (false) then
        call Echo("это магия!")  
        if (false and false) then
            call Echo("Мы все умрем!")
        endif
    endif
    call GroupEnumUnitsOfPlayer(GG, AIPLAYER, Filter(function FocusSiegeTower_Filter))
    if SIEGETOWERUPFOCUS == null then
        call Echo("фейл=/")       
    endif
    set SIEGETOWERUP = 0
    call GroupClear(GG)
endfunction

Отредактировано J, 07.05.2009 в 11:04.
Старый 07.05.2009, 10:46
Preveder
StarCraft II® Inside
offline
Опыт: 1,927
Активность:
Выводит phail при попытке маркануть фокусную сиедж башню и её проапгрейдить.
Может быть ИИ с фильтрациями не знаком вообще? Проблема в том, что никто не знает, по-видимому, какие функции из common.j ИИ-скрипт кушает. Кстати говоря, значения в кэш ИИ записывать может.
Миниатюры
Кликните на картинку для увеличения
Название:  phail.jpg
Просмотров: 26
Размер:  12.5 Кбайт  
Старый 07.05.2009, 11:15
J
expert
offline
Опыт: 48,447
Активность:
call Echo(I2S(GetUnitTypeId(f))+" - "+GetUnitName(f))
а это вообще ни разу не срабатывает что ли?
Старый 07.05.2009, 11:21
Preveder
StarCraft II® Inside
offline
Опыт: 1,927
Активность:
Не-а, вообще. Всё, что выводится при попытке обозначить сиедж, это phail=\. Видимо, GetFilterUnit() он не знает или не умеет использовать.
Мало того, return true тоже не сработал! Не может даже собрать всех юнитов игрока. Потом попытаюсь через триггеры основного скрипта добавлять компу всех юнитов в выделение. А потом обозначать глобалкой группу всех выделенных, оттуда сортировать первую попавшуюся осадную.

Preveder добавил:
Попытки создать триггер для отлова через регион тоже не увенчались успехом.
Код:
function TriggerSelectActions takes nothing returns nothing
    if IsTriggerEnabled(SELECTOR) == true then
        call Echo("TRIG ENABLED AND FIRES.")
    endif
    if SELECTOR == GetTriggeringTrigger() then
        call Echo("TRIGGER IS OK.")
    endif
    if GetUnitTypeId(GetTriggerUnit()) == TOWER_TYPE[10] then
        call Echo("Gotcha!")
    endif
    if GetTriggerUnit() == null then
        call Echo("SHIT HAPPENS!")
    endif
endfunction

function TriggerSelectInit takes nothing returns nothing
    set SELECTOR = CreateTrigger()
    call TriggerRegisterEnterRegion(SELECTOR, CreateWorld(GetWorldBounds()), IS_TRUE)
    call TriggerAddAction(SELECTOR, function TriggerSelectActions)
    call EnableTrigger(SELECTOR)
    if SELECTOR != null then
        call Echo("Trigger Just Created!")
    endif
    if IsTriggerEnabled(SELECTOR) == true then
        call Echo("TRIGGER ENABLED!")
    endif
endfunction

Пишет только последние две строчки из инициализатора. Значит воистину фильтры в ИИ не работают. (IS_TRUE - глобальная boolexpr возвращающая return true.)

Отредактировано Preveder, 07.05.2009 в 11:35.
Старый 07.05.2009, 12:21
J
expert
offline
Опыт: 48,447
Активность:
Цитата:
Пишет только последние две строчки из инициализатора. Значит воистину фильтры в ИИ не работают. (IS_TRUE - глобальная boolexpr возвращающая return true.)
в таких сулчая принято null вместо IS_TRUE ставить
Старый 07.05.2009, 12:50
Preveder
StarCraft II® Inside
offline
Опыт: 1,927
Активность:
Цитата:
Сообщение от J
в таких сулчая принято null вместо IS_TRUE ставить

Знаю, но я на всякий случай сделал через return true. Но результат и при null, и при return true одинаковый.
Старый 07.05.2009, 13:22
Preveder
StarCraft II® Inside
offline
Опыт: 1,927
Активность:
Методом научного тыка мной были перепробованы практически все комбинации фильтров в ai-скрипте (если придумаете ещё какую-нибудь очень извращённую реализацию этого - напишите) и были успешно признаны недееспособными. Придётся часть служебных функций компа писать в специальной библиотеке в основном скрипте, для последующего обмена данными с ИИ-скриптом. Аминь.
Старый 08.05.2009, 17:52
Закрытая тема

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

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

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 10:48.