Делаю простейший ИИ, функция AISimpleFounder принимает группу (разумеется g - локальная заполненная группа)
Код что делает, код проверяет каждые 2 секунды текущий приказ каждого юнита в группе и если тот нет равен 851983 ("attack"), тогда найти первого попавшегося героя и приказать перейти в его позицию нападая на противников, вроде бы ничего сложного и код действительно прекрасно работает,
function AISimpleFounder(g)
    local e
    local h
    local b=false
    TimerStart(CreateTimer(), 2, true, function()
            ForGroup(g, function()            
            e=GetEnumUnit()
            if GetUnitCurrentOrder(e)~=851983 then
                GroupEnumUnitsInRect(perebor,bj_mapInitialPlayableArea,null)
                    while true do
                    h = FirstOfGroup(perebor)
                    if h == nil then break end
                    if IsUnitEnemy(h, GetOwningPlayer(e)) and IsUnitType(h, UNIT_TYPE_HERO) then
                    --print(GetUnitName(h))
                        IssuePointOrder(e, "attack", GetUnitX(h),GetUnitY(h))   
                    end
                GroupRemoveUnit(perebor,h)
                end
            end
        end)
    end)
end
но, если я стал делать какую-то фигню, прошу меня бить по рукам металлической линейкой, чтобы я больше таких утечек не создавал, очень волнуют моменты:
  1. Что тут утекает
  2. Что может вызвать баги?
  3. Анонимные функции это когда я запустил таймер и форгруп?
  4. Группа локальная, и что с ней произойдёт когда все юниты умрут? надо ли уничтожать саму группу?
Пока что, код элементарнейший и будет неким костяком для других ИИ, поэтому, пока что нет проверок на обнаружение, смерти и прочего, это просто ИИ, который не может потерять свою цель если его застанят

Принятый ответ

1 переменная perebor не обьявлена
2 e и h нет смысла объявлять так высоко, лучше спустить их объявление туда где они реально используются
3 GetOwningPlayer(e) стоит занести в переменную чтобы не дергать каждый раз
4 лучше при возможности всех подходящих под критерий юнитов заносить в группу заранее, чем искать их по всей карте
`
ОЖИДАНИЕ РЕКЛАМЫ...
1
24
5 лет назад
1
1 переменная perebor не обьявлена
2 e и h нет смысла объявлять так высоко, лучше спустить их объявление туда где они реально используются
3 GetOwningPlayer(e) стоит занести в переменную чтобы не дергать каждый раз
4 лучше при возможности всех подходящих под критерий юнитов заносить в группу заранее, чем искать их по всей карте
Принятый ответ
0
32
5 лет назад
0
prog,
  1. ну perebor в другом месте объявлена, тут всё норм
  2. Понял так и сделаю
  3. Тоже понял
  4. Возможно так и будет, будет группа с героями-игроками и поиск будет в ней происходить, а так да, слишком много проверять приходится юнитов, хотя по дебагу это крайне редко происходит
function AISimpleFounder(g)
    TimerStart(CreateTimer(), 2, true, function()
            ForGroup(g, function() 
            local e           
            e=GetEnumUnit()
            if GetUnitCurrentOrder(e)~=851983 then
                GroupEnumUnitsInRect(perebor,bj_mapInitialPlayableArea,null)
                    local h
                    local b=false
                    local p=GetOwningPlayer(e)
                    while true do
                    h = FirstOfGroup(perebor)
                    if h == nil then break end
                    if IsUnitEnemy(h, p) and IsUnitType(h, UNIT_TYPE_HERO) and b==false then
                    print(GetUnitName(h))
                    
                        IssuePointOrder(e, "attack", GetUnitX(h),GetUnitY(h)) 
                        b=true  
                    end
                GroupRemoveUnit(perebor,h)
                end
            end
        end)
    end)
end
По идее вот, кстати весьма забавно вышло, от такого ИИ весьма удобно убегать если есть некие способности перемещения, ибо ИИ идёт в точку где был герой, и идёт туда до тех пор, пока не получит новый приказ атаки
Чтобы оставить комментарий, пожалуйста, войдите на сайт.