Всем привет!
Недавно начал оптимизировать все что до этого написал
И сейчас возникла необходимость Сокращать триггеры
есть триггеры которые делают почти одно и тоже
вот пример
function Trig__Conditions takes nothing returns boolean
if(not(UnitHasItemOfTypeBJ(GetManipulatingUnit(),0x6F646566)==true))then
return false
endif
if(not(UnitHasItemOfTypeBJ(GetManipulatingUnit(),0x6F736C6F)==true))then
return false
endif
if(not(UnitHasItemOfTypeBJ(GetManipulatingUnit(),0x6F666972)==true))then
return false
endif
if(not(UnitHasItemOfTypeBJ(GetManipulatingUnit(),0x6F636F72)==true))then
return false
endif
if(not(UnitHasItemOfTypeBJ(GetManipulatingUnit(),0x6F76656E)==true))then
return false
endif
if(not(UnitHasItemOfTypeBJ(GetManipulatingUnit(),0x4930304C)==true))then
return false
endif
return true
endfunction
это условие которое проверяет если все предметы которые нужны есть у героя
его и хочу Оптимизировать
приглянулся этот пример
function tt_Cond takes unit u returns boolean
return(LoadBoolean(H,1,StringHash(("A")))) 
endfunction 
практически ничем не отличается от возвращаемого значения т.е True или False
но как превратить функцию которая возвращает boolean
чтобы она проверяла все 5 параметров и возвращала True когда у героя будут эти предметы?
как лучше использовать
return(LoadBoolean(H,1,StringHash(("A")))) 
чтобы она проверяла 5 параметров?
или, как оптимизировать вот это?
function F_Remove_Items_Cond takes unit u, integer id1, integer id2, integer id3, integer id4, integer id5, integer id6 returns boolean
if(id1 == 0) then
else // != null
if (F_GetInventoryIndex(u, Item[id1]) > 0) then 
else
return false
endif
endif
if(id2 == 0) then
else
if (F_GetInventoryIndex(u, Item[id2]) > 0) then
else
return false
endif
endif
if(id3 == 0) then
else
if (F_GetInventoryIndex(u, Item[id3]) > 0) then
else
return false
endif
endif
if(id4 == 0) then
else
if (F_GetInventoryIndex(u, Item[id4]) > 0) then
else
return false
endif
endif
if(id5 == 0) then
else
if (F_GetInventoryIndex(u, Item[id5]) > 0) then
else
return false
endif
endif
if(id6 == 0) then
else
if (F_GetInventoryIndex(u, Item[id6]) > 0) then
else
return false
endif
endif
return true
endfunction

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

Раз уж мы всем хгмом делаем наработку для крафтов, то вкачусь тоже В луа я бы сделал так. Ну, если все предметы разные, без повторений.
RequiredItems = {0x6F646566, 0x6F736C6F, 0x6F666972, 0x6F636F72, 0x6F76656E, 0x4930304C}

function checkItems(u)
    for _, v in ipairs(RequiredItems) do
        if not UnitHasItemOfTypeBJ(u, v) then
            return false
        end
    end
    return true
end
Результат
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...
1
37
2 недели назад
Отредактирован ScorpioT1000
1
Положить всё повторяющееся в массив и выполнить действия со всеми элементами массива

loop
  if ...
    return true
  endif
endloop
return false
Ответы (2)
0
8
2 недели назад
0
ScorpioT1000, отличный пример Беру на вооружение :)
0
8
2 недели назад
0
ScorpioT1000, напишу готовый пример и выложу
0
13
2 недели назад
Отредактирован SoulRazor
0
Я вот так просто делаю.
function UnitHaveItem takes unit UnitItem, integer ItemTypeID returns boolean
    local integer i = 0
    local boolean ItemLog = false
    
    loop
    exitwhen i >= bj_MAX_INVENTORY
        if GetItemTypeId(UnitItemInSlot(UnitItem, i)) == ItemTypeID then
            set ItemLog = true
        endif
    set i = i + 1
    endloop
    
    return ItemLog
endfunction

function A takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    
    if UnitHaveItem( caster, 'I000') and UnitHaveItem( caster, 'I001') and UnitHaveItem( caster, 'I002') and UnitHaveItem( caster, 'I003') then
        //Твои действия
    endif
    
    set caster = null
endfunction
можно конечно извращаться и делать так например
function UnitHaveItem takes unit UnitItem, integer ItemTypeID returns boolean
    local integer i = 0
    local boolean ItemLog = false
    
    loop
    exitwhen i >= bj_MAX_INVENTORY
        if GetItemTypeId(UnitItemInSlot(UnitItem, i)) == ItemTypeID then
            set ItemLog = true
        endif
    set i = i + 1
    endloop
    
    return ItemLog
endfunction

function CheckItems takes unit caster, integer ItemA, integer ItemB, integer ItemC, integer ItemD, integer ItemE returns boolean
    return UnitHaveItem( caster, ItemA) and UnitHaveItem( caster, ItemB) and UnitHaveItem( caster, ItemC) and UnitHaveItem( caster, ItemD) and UnitHaveItem( caster, ItemE)
endfunction

function B takes nothing returns nothing
    local unit Unit = GetTriggerUnit()
    if CheckItems(Unit, 'I000', 'I001', 'I002', 'I003', 'I004') then
        //True
    else
        //False
    endif
    set Unit = null
endfunction
Ответы (1)
0
8
2 недели назад
0
SoulRazor, конечно хороший пример но это я как раз пытаюсь избежать
у меня тоже самое реализовано но я использую Функции, причем несколько, этого и пытаюсь избежать
0
18
2 недели назад
Отредактирован EugeAl
0
Вот тебе готовая протестированная в разных комбинация функция по проверке всех нужных предметов. Проверяет кол-во, и все ид предметов. Нужно также задать макс кол-во. Если не хватает предметов и инвентаре, или другие предметы, хоть 1, или и то и другое, будет false. Если все предметы есть, в любом порядке, будет true.
function SbornItem takes unit hero, integer iditem1, integer iditem2, integer iditem3, integer iditem4, integer iditem5, integer iditem6, integer maxkolvo returns boolean
local integer index = 0
local integer kolvo = 0
local integer ItemId = 0

    loop
    exitwhen kolvo == maxkolvo or index >= bj_MAX_INVENTORY
        set ItemId = GetItemTypeId ( UnitItemInSlot ( hero, index) )

        if ItemId > 0 then
            if ( ItemId == iditem1 or ItemId == iditem2 ) or ( ItemId == iditem3 or ItemId == iditem4 ) or ( ItemId == iditem5 or ItemId == iditem6 ) then
                set kolvo = kolvo + 1
            endif
        endif

        set index = index + 1
    endloop

    if kolvo == maxkolvo then
        return true
    endif
    return false

endfunction
Ответы (9)
0
8
2 недели назад
0
EugeAl, тоже хороший вариант, но слегка можно доработать, Слегка чтобы использовал Массивы а не Конкретные предметы
0
18
2 недели назад
0
Centyrion, здесь не предметы, а их равкоды ) в аргументы integer можно и ячейки из массива пихать )
0
8
2 недели назад
0
EugeAl, в курсе, у меня Массив в виде
set Item[1] = 'I001'
globals
integer array Item
endglobals
0
18
2 недели назад
0
Centyrion, пойдет, ведь можно написать примерно так
if SbornItem ( GetTriggerUnit(), Item[1], Item[4], Item[7], Item[3], Item[6], Item[8], 6 ) then
	//выполнять код
endif
0
8
2 недели назад
0
EugeAl, конечно пойдет, этот вариант тоже нормальный но многовато аргументов он принимает, а вычислять его в функции тоже не красиво
0
18
2 недели назад
Отредактирован EugeAl
0
Centyrion, Попробуй тогда вариант специально под массив. В игре я это не проверял, если что, так что подправь, если потребуется.
function SbornItemArray takes unit hero, integer indMin, integer indMax, integer maxkolvo returns boolean
// indMin - минимальный индекс куска массива, indMax - конечный индекс куска массива
local integer index = 0
local integer arrayindex = 0
local integer kolvo = 0
local integer ItemId = 0

    loop
    exitwhen kolvo == maxkolvo or index >= bj_MAX_INVENTORY

        set ItemId = GetItemTypeId ( UnitItemInSlot ( hero, index) )
        set arrayindex = indMin

        if ItemId > 0 then
            loop// цикл по массиву. Ид предметов в массиве должны располагаться друг за другом, на каждый сборный предмет свой кусок массива.
            exitwhen arrayindex > indMax
                if ItemId == Item[arrayindex] then
                    set kolvo = kolvo + 1
                endif
                set arrayindex = arrayindex + 1
            endloop
        endif

        set index = index + 1
    endloop

    if kolvo == maxkolvo then
        return true
    endif
    return false

endfunction
0
8
2 недели назад
0
EugeAl, этот вариант тоже не лишен недостатков но и Задумка интересная а плодить 2 цикла внутри функции это еще больше строк кода
1
18
2 недели назад
1
Centyrion, ну, либо 2 цикла, либо огромная бд на один цикл, с учётом всех 6 слотов, что также будет большой цикл, из за данных х 6, что по итогу выльется в ещё больше строк кода )
0
8
2 недели назад
0
EugeAl, ну да в принципе... другого не дано, либо так либо никак, подумаю
1
23
2 недели назад
Отредактирован Makeba
1
Раз уж мы всем хгмом делаем наработку для крафтов, то вкачусь тоже В луа я бы сделал так. Ну, если все предметы разные, без повторений.
RequiredItems = {0x6F646566, 0x6F736C6F, 0x6F666972, 0x6F636F72, 0x6F76656E, 0x4930304C}

function checkItems(u)
    for _, v in ipairs(RequiredItems) do
        if not UnitHasItemOfTypeBJ(u, v) then
            return false
        end
    end
    return true
end
Результат
Загруженные файлы
Принятый ответ
Ответы (2)
0
8
2 недели назад
Отредактирован Centyrion
0
Makeba, Хм, Задумка интересная,
RequiredItems //можно и массив, переменная у меня под массив но Интересно
где-то я это уже видел и чем-то напоминает наработку
set giRequireScroll[6]='I007'
set Item_Slot1[6]='penr'
set Item_Slot2[6]='prvt'
set Item_Slot3[6]='rde3'
set giRequireScrollp[6]=3
set Created_Item[6]='blba'
прописать необходимые предметы в Одну переменную под индексом и одним Изящным циклом вычислять все необходимое
Изящно
Беру на вооружение :)
0
23
2 недели назад
0
где-то я это уже видел
В первом ответе то же самое предложено
Чтобы оставить комментарий, пожалуйста, войдите на сайт.