всем привет.
начал пилить несколько функций для создания предмета
но столкнулся с проблемой
ItemUserData неправильно работает в цикле
set trig[7] = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig[7],EVENT_PLAYER_UNIT_PICKUP_ITEM)
call TriggerAddAction(trig[7],function F_Pick_Item)
function F_Pick_Item takes nothing returns nothing
set Cnt_Inv = 0
loop
exitwhen Cnt_Inv > Min_Inv // 5
set ItemsInSlots[Cnt_Inv] = UnitItemInSlot(GetManipulatingUnit(), Cnt_Inv)
set ItemUserDataMas[Cnt_Inv] = Cnt_Inv
call SetItemUserData(GetManipulatedItem(), ItemUserDataMas[Cnt_Inv+1]) // от 1 до 6
set Cnt_Inv = Cnt_Inv + 1
endloop

call Text(" == " + I2S( ItemUserDataMas[Cnt_Inv] ))
пытаюсь каждый раз когда юнит получает предмет у которого нет значений добавить 1 к нему чтобы привязать его к предмету
set Item_Init[1] = 'I03D'
set Item_Init[2] = 'I03E'
set Item_Init[3] = 'I03F'
set Item_Init[4] = 'I03G'
set Item_Init_Number_End = 105
пытался следующим образом
set Cnt_Item_Init=1
loop
exitwhen Cnt_Item_Init>Item_Init_Number_End
call SetItemUserData(GetManipulatedItem(), Cnt_Item_Init)
set ItemUserDataMas[Cnt_Item_Init] = Cnt_Item_Init
set Cnt_Item_Init = Cnt_Item_Init + 1
endloop

set Cnt_Inv = 0
loop
exitwhen Cnt_Inv > Min_Inv
set ItemsInSlots[Cnt_Inv] = UnitItemInSlot(GetManipulatingUnit(), Cnt_Inv)
set Cnt_Inv = Cnt_Inv + 1

call Text(" == " + I2S( GetItemUserData(ItemsInSlots[Cnt_Inv]) )) // возвращает значение 106 для всех предметов в инвентаре
endloop
call SetItemUserData(GetManipulatedItem(), Cnt_Item_Init)
Нельзя использовать SetItemUserData в цикле? или надо убрать массив и установить значение без массива?

логика такова
цикл от 1 до всех предметов в карте призван Установить для Каждого Item_Init[Cnt_Item_Init]
Значение взятое из SetItemUserData
для удобства занес эти Значения в Переменную типа Массив чтобы Оперировать с ними там где мне это нужно
и когда в инвентаре окажется Индекс этого предмета я буду знать что этот предмет мне нужен для Удаления
для этого есть функция
function F_H_Section_ReturnItem takes unit u, integer id returns nothing
set Cnt_Inv = 0
loop
exitwhen Cnt_Inv > Min_Inv
set ItemsInSlots[Cnt_Inv] = UnitItemInSlot(u, Cnt_Inv)
if LoadBoolean(H, StringHash("H"), StringHash("RemoveItems")) then
call SaveBoolean(H, StringHash("H"), StringHash("RemoveItems"), false)
call RemoveItem(ItemsInSlots[Cnt_Inv])
else
if GetItemTypeId(ItemsInSlots[Cnt_Inv]) == id then
call SaveBoolean(H, StringHash("H"), StringHash("RemoveItem"), true)
call RemoveItem(ItemsInSlots[Cnt_Inv])
endif
endif
set Cnt_Inv = Cnt_Inv + 1
endloop
set Cnt_Inv = 0
loop
exitwhen Cnt_Inv > Min_Inv
set ItemsInSlots[Cnt_Inv] = null
set Cnt_Inv = Cnt_Inv + 1
endloop
endfunction
достаточно одно SaveBoolean и готово
а дальше Создание предмета ПО Индексу расположенный в Item_Init

call SaveBoolean(H, StringHash("H"), StringHash("RemoveItems"), false)
призван удалить Все предметы из инвентаря Без проверки GetItemTypeId

либо использовать вариант который написал nazarpunk:

тут уже мне решать

function F_Pick_Item takes nothing returns nothing

set Cnt_Item_Init = 1
loop
exitwhen Cnt_Item_Init > Item_Init_Number_End
call SaveBoolean(H, StringHash("H"), StringHash("ItemUserDataSave"), true)
call SaveItemHandle(H, StringHash("H"), StringHash("ItemUserData"), GetManipulatedItem())

if GetItemTypeId(GetManipulatedItem()) == Item_Init[Cnt_Item_Init] then
set ItemUserDataMas[ItemUserDataAmount] = Cnt_Item_Init
endif

set Cnt_Item_Init = Cnt_Item_Init + 1
endloop

call F_H_Section_ItemUserData()

Я походу нашёл где ChatGPT обучается кодить...
я похож на ИИ?
даже мне стало интересно на что он способен :)

function F_H_Section_ItemUserData takes nothing returns integer
local item ItemUserData = LoadItemHandle(H, StringHash("H"), StringHash("ItemUserData"))
local integer I
set I = GetItemUserData(ItemUserData)
if LoadBoolean(H, StringHash("H"), StringHash("ItemUserDataSave")) then
call SaveInteger(H, StringHash("H"), StringHash("GetItemUserData"), I)
call SaveItemHandle(H, StringHash("H"), StringHash("ItemUserDataHandle"), ItemUserData)
call SaveInteger(H, StringHash("H"), StringHash("UserDataPlayerId"), GetPlayerId(GetItemPlayer(ItemUserData)))
call SaveInteger(H, StringHash("H"), StringHash("UserDataItemId"), GetItemTypeId(ItemUserData))
call SaveInteger(H, StringHash("H"), StringHash("ItemLevel"), GetItemLevel(ItemUserData))
call SaveBoolean(H, StringHash("H"), StringHash("ItemUserDataSave"), false)
endif
if ItemUserDataAmount < Size then
call SetItemUserData(ItemUserData, ItemUserDataMas[ItemUserDataAmount])
call SaveInteger(H, StringHash("H"), StringHash("ItemUserDataAmount")+ItemUserDataAmount, ItemUserDataMas[ItemUserDataAmount])
if LoadBoolean(H, StringHash("H"), StringHash("ItemUserDataIndicator")) then
set HRed[2] = GetRandomReal(0, 255)
set HGreen[2] = GetRandomReal(0, 255)
set HBlue[2] = GetRandomReal(0, 255)
call ItemAddIndicatorBJ(ItemUserData, HRed[2], HGreen[2], HBlue[2], 0)
endif
return I
else
call Text("|cFFFF0000ERROR: F_H_Section_ItemUserData - clear bad key|r")
set ItemUserDataAmount = Size - 1
return ItemUserDataAmount
endif
endfunction
constant integer Size = JASS_MAX_ARRAY_SIZE

спасибо за ответы, останусь на этом примере пожалуй
`
ОЖИДАНИЕ РЕКЛАМЫ...
4
globals
integer array Item_Init
integer array ItemUserDataMas
item array ItemsInSlots
integer ItemUserDataAmount = 0
integer Cnt_Inv = 0
integer Cnt_Item_Init = 0
constant integer Min_Inv = 5 // UnitItemInSlot()
endglobals

set Cnt_Item_Init=1
loop
exitwhen Cnt_Item_Init>Item_Init_Number_End
set ItemUserDataMas[Cnt_Item_Init] = Cnt_Item_Init
if ItemUserDataMas[Cnt_Item_Init] == Item_Init[Cnt_Item_Init] then
call SetItemUserData(GetManipulatedItem(), Cnt_Item_Init)
endif
//call Text(" == " + I2S( ItemUserDataMas[Cnt_Item_Init] ))
set Cnt_Item_Init = Cnt_Item_Init + 1
endloop
вернет 0

знаю что проверить можно по GetItemTypeId(ItemsInSlots[Cnt_Inv])
но блок отвечающий за инвентарь не в цикле Cnt_Item_Init

но если поставить
call SetItemUserData(GetManipulatedItem(), Cnt_Item_Init)
внутри блока отвечающий за инвентарь он установит значение для только что полученного предмета
это тоже не вариант

нужно GetManipulatedItem() поставить в блоке Cnt_Item_Init чтобы он установил значение для всех предметов от 1 до 105 а когда герой подбирает этот предмет чтобы значение проверялось через ItemUserDataMas[Cnt_Item_Init]
но конвертировать Предмет к Целочисленной нельзя
call SetItemUserData(ItemsInSlots[Cnt_Inv], Cnt_Item_Init)
//это не вариант

if ItemUserDataMas[Cnt_Item_Init] == Item_Init[Cnt_Item_Init] then
//вообще не сработает та как Item_Init возвращает GetItemTypeId предмета а ItemUserDataMas[Cnt_Item_Init] это значение 1 2 3 и так до 105

как привязать SetItemUserData к предмету который вернет GetItemTypeId?
26
А чего ты отладку вызываешь после цикла, а не внутри него? Раз ссылаешься на ту переменную, которая у тебя толкает сам цикл.
4
А чего ты отладку вызываешь после цикла, а не внутри него? Раз ссылаешься на ту переменную, которая у тебя толкает сам цикл.
это проверка что все значения необходимые для вычисления заданы корректно

//set Cnt_Inv = 1
//loop
//call Text(" == " + I2S( Cnt_Inv ))// 1 2 3 4 5 6 7
//exitwhen Cnt_Inv >Max_Inv
//call Text(" == " + I2S( Cnt_Inv ))// 1 2 3 4 5 6
//set Cnt_Inv = Cnt_Inv + 1
//call Text(" == " + I2S( Cnt_Inv ))// 2 3 4 5 6 7
//endloop
constant integer Max_Inv = bj_MAX_INVENTORY //6
26
Да, поэтому ставить его надо НЕ в конце.
Ты там делаешь x[a]=a, т.е. что бы ссослаться на индекс массива тебе нужно получить его номер, а его номер - это его же индекс... Зачем?
А после этого SetData(i,x[a]+1)
Хотя по сути это равно SetData(i,a+1)

Ааа...я понял, ты как раз этого и НЕ делаешь.
Ты пишешь set x[1]=1, и тут же после этого пишешь SetData(i,x[1+1]), т.е. ссылаешься на x[2], а оно у тебя будет записано только во время следующего такта цикла.
4
Да, поэтому ставить его надо НЕ в конце.
Ты там делаешь x[a]=a, т.е. что бы ссослаться на индекс массива тебе нужно получить его номер, а его номер - это его же индекс... Зачем?
А после этого SetData(i,x[a]+1)
Хотя по сути это равно SetData(i,a+1)
без разницы какой индекс он вернет мне нужно Привязать
Item_Init[Cnt_Item_Init]
к
ItemUserDataMas[Cnt_Item_Init]
при этом не меняя значение Item_Init[Cnt_Item_Init]
чтобы ItemUserDataMas[Cnt_Item_Init] я мог использовать для других целей
Индекс тут не причем
26
А где ты проверяешь чтоту предмета нет значений? Тут нет этого куска.
4
ItemUserDataMas[Cnt_Item_Init] это Целочисленная
Item_Init[Cnt_Item_Init] целочисленная
Предмет в инвентаре служит Только для Проверки
SetItemUserData()
а ItemUserDataMas[Cnt_Item_Init] это Значение которое проверяет SetItemUserData()

здесь проверяю

set Cnt_Item_Init=1
loop
exitwhen Cnt_Item_Init>Item_Init_Number_End
set ItemUserDataMas[Cnt_Item_Init] = Cnt_Item_Init
if ItemUserDataMas[Cnt_Item_Init] == Item_Init[Cnt_Item_Init] then
call SetItemUserData(GetManipulatedItem(), Cnt_Item_Init)
endif
//call Text(" == " + I2S( ItemUserDataMas[Cnt_Item_Init] ))
set Cnt_Item_Init = Cnt_Item_Init + 1
endloop

и здесь
set Cnt_Inv = 0
loop
exitwhen Cnt_Inv > Min_Inv
set ItemsInSlots[Cnt_Inv] = UnitItemInSlot(GetManipulatingUnit(), Cnt_Inv)
set Cnt_Inv = Cnt_Inv + 1

call Text(" == " + I2S( GetItemUserData(ItemsInSlots[Cnt_Inv]) ))
endloop

это отдельный блок который проверяет Инвентарь

меня интересует почему
call SetItemUserData(GetManipulatedItem(), Cnt_Item_Init)
устанавливает для всех предметов значение Item_Init_Number_End
а когда проверяю Значения в инвентаре у них у всех значение 105
а не 1 2 3 4 5 6 7 8 9 исходя из GetItemTypeId
26
Вот смотри далее... Ты задаешь переменную для тела цикла, и считаешь её пока она не упрётся в лимит от инита = 105
Т.е. цикл отработает 105 раз и сделает следующее:
Записывает дату подобранного предмета как тело = это числа от 1 до 105, т.е. тут происходит перезапись сто раз.
Пишет в другую переменную с индексам тела цикла само значение тела цикла.
...всё
Что тут должно произойти? Кроме как дата предмета будет равно 105 после последней перезаписи, а переменная ItemUserDataMas[1...105] = 1...105

Emafusail:
здесь проверяю
Но здесь нигде нет проверки что UserData подобранного предмета равно 0.
Разве не это значит "предмет у которого нет значения" ?

меня интересует почему
call SetItemUserData(GetManipulatedItem(), Cnt_Item_Init)
устанавливает для всех предметов значение Item_Init_Number_End
а когда проверяю Значения в инвентаре у них у всех значение 105
а не 1 2 3 4 5 6 7 8 9 исходя из GetItemTypeId
Из-за того что ты перезаписываешь это UserData для подобранного предмета
4
Вот смотри далее... Ты задаешь переменную для тела цикла, и считаешь её пока она не упрётся в лимит от инита = 105
Т.е. цикл отработает 105 раз и сделает следующее:
Записывает дату подобранного предмета как тело = это числа от 1 до 105, т.е. тут происходит перезапись сто раз.
Пишет в другую переменную с индексам тела цикла само значение тела цикла.
...всё
Что тут должно произойти? Кроме как дата предмета будет равно 105 после последней перезаписи, а переменная ItemUserDataMas[1...105] = 1...105
ДА! Но оно записывает Только Последний Индекс для всех предметов
SetItemUserData
не различает индекс 1 2 3 4 5 6 а записывает только Последний индекс т.е 105 Для всех предметов!
26
А теперь можешь описать что ты пытаешься реализовать?
4
Вот смотри далее... Ты задаешь переменную для тела цикла, и считаешь её пока она не упрётся в лимит от инита = 105
Т.е. цикл отработает 105 раз и сделает следующее:
Записывает дату подобранного предмета как тело = это числа от 1 до 105, т.е. тут происходит перезапись сто раз.
Пишет в другую переменную с индексам тела цикла само значение тела цикла.
...всё
Что тут должно произойти? Кроме как дата предмета будет равно 105 после последней перезаписи, а переменная ItemUserDataMas[1...105] = 1...105

Emafusail:
здесь проверяю
Но здесь нигде нет проверки что UserData подобранного предмета равно 0.
Разве не это значит "предмет у которого нет значения" ?

меня интересует почему
call SetItemUserData(GetManipulatedItem(), Cnt_Item_Init)
устанавливает для всех предметов значение Item_Init_Number_End
а когда проверяю Значения в инвентаре у них у всех значение 105
а не 1 2 3 4 5 6 7 8 9 исходя из GetItemTypeId
Из-за того что ты перезаписываешь это UserData для подобранного предмета
я отсюда его убрал чтобы он не установил данные а поставил в блок установки значений для всех предметов!
26
ДА! Но оно записывает Только Последний Индекс для всех предметов
SetItemUserData
не различает индекс 1 2 3 4 5 6 а записывает только Последний индекс т.е 105 Для всех предметов!
Не "только последний", а "все 105 поочереди с перезаписью".
Сначало предмет имеет значение 0 (видимо), цикл ему тут же делает 1...тут же делает 2...тут же 3...4...5...6...и так до 105, и только тогда отваливает от него.
4
А теперь можешь описать что ты пытаешься реализовать?
в общем SetItemUserData должен установить Значения для Item_Init чтобы когда герой Получил этот предмет он выдавал его Данные записанные в блоке от 1 до 105 но чтобы было удобно занес в переменную Данные записанные в SetItemUserData
и исходя из этих значений указать Индекс Для проверки Предмета Item_Init чтобы удалить его и создать чтото там

ДА! Но оно записывает Только Последний Индекс для всех предметов
SetItemUserData
не различает индекс 1 2 3 4 5 6 а записывает только Последний индекс т.е 105 Для всех предметов!
Не "только последний", а "все 105 поочереди с перезаписью".
Сначало предмет имеет значение 0 (видимо), цикл ему тут же делает 1...тут же делает 2...тут же 3...4...5...6...и так до 105, и только тогда отваливает от него.
у меня он записывает последний индекс для всех предметов

если сделаю так
set Cnt_Item_Init=1
loop
exitwhen Cnt_Item_Init>Item_Init_Number_End

set ItemUserDataMas[Cnt_Item_Init] = Cnt_Item_Init


call SetItemUserData(GetManipulatedItem(), ItemUserDataMas[Cnt_Item_Init])
//запишет для всех предметов которые получаю Значение 105


//call Text(" == " + I2S( ItemUserDataMas[Cnt_Item_Init] ))//1 .....105


set Cnt_Item_Init = Cnt_Item_Init + 1
endloop

этого мне не надо...есть Item_Init который должен принимать значение от 1 до 105 исходя из SetItemUserData
26
Принимать? Или всё-таки возвращать? (при совпадении типа)
4
Принимать? Или всё-таки возвращать? (при совпадении типа)
при совпадении Типа конечно
26
И опять же... ЧТО ИМЕННО ТЫ ПЫТАЕШЬСЯ СДЕЛАТЬ ???
4
но ItemUserDataMas[Cnt_Item_Init] это целочисленная а Item_Init это Тип Предмета грубо говоря который возвращает GetItemTypeId

GetItemTypeId Привязать к ItemUserDataMas[Cnt_Item_Init]
26
Emafusail:
при совпадении Типа конечно
Для этого нужно взять ТИП предмета (число в виде 'I03D'), и сравнить его сотвсеми из списка (а он у тебя длинной в 105), и при первомже совпадении вернуть его номер. Например это будет 37.
И уже с этими 37 делать всё что хочешь, т.к. номер имея ты и данные другие можно подтянуть.
Ну там еще можно лупить базу типа set t['I03D'] = 'I03D'
Хотя тут надо чуть по другому на индекс напирать, но смысмыс в общем такой.
Но одно другого не отменяет вообще

Emafusail, это всё числа, и 'I03D' тоже число.
4
Emafusail:
при совпадении Типа конечно
Для этого нужно взять ТИП предмета (число в виде 'I03D'), и сравнить его сотвсеми из списка (а он у тебя длинной в 105), и при первомже совпадении вернуть его номер. Например это будет 37.
И уже с этими 37 делать всё что хочешь, т.к. номер имея ты и данные другие можно подтянуть.
Ну там еще можно лупить базу типа set t['I03D'] = 'I03D'
Хотя тут надо чуть по другому на индекс напирать, но смысмыс в общем такой.
Но одно другого не отменяет вообще

Emafusail, это всё числа, и 'I03D' тоже число.
это понятно.
цикл запущен
но SetItemUserData Перезаписывается
для этого и занес его в массив
пытаюсь избежать эту перезапись
26
Emafusail, еще раз пытаюсь тебе донести - это делать надо НЕ ТАК.
Ты, со стороны лог;ки движка, пишешь непонятно что непонятно и хочешь получать на выходе в непонятном месте весьма конкретный результат. Это так не работает. Тут нужно совсем по другому всё оформить.
4
это всё числа, и 'I03D' тоже число.
да но оно возвращает 1227895620
а не значение 1

Emafusail, еще раз пытаюсь тебе донести - это делать надо НЕ ТАК.
Ты, со стороны лог;ки движка, пишешь непонятно что непонятно и хочешь получать на выходе в непонятном месте весьма конкретный результат. Это так не работает. Тут нужно совсем по другому всё оформить.
ну хорошо, как ты это видишь?
26
Emafusail:
это всё числа, и 'I03D' тоже число.
да но оно возвращает 1227895620
а не значение 1
Ну так вычти из него 1227895619, и используй остаток как ИНДЕКС массива.
И будут у тебя типы предметов от 1227895620 до 1227895724
Emafusail:
ну хорошо, как ты это видишь?
Запись всех типов предметов в массив от 1 до 105
При подборе предмета проверка его на принадлежность к этим 105 предметам.
Нахождение совпадения, и, соответственно, его номера в массиве.
Работа с найденным номером.
Всё.
4
Emafusail:
это всё числа, и 'I03D' тоже число.
да но оно возвращает 1227895620
а не значение 1
Ну так вычти из него 1227895619, и используй остаток как ИНДЕКС массива.
И будут у тебя типы предметов от 1227895620 до 1227895724
Emafusail:
ну хорошо, как ты это видишь?
Запись всех типов предметов в массив от 1 до 105
При подборе предмета проверка его на принадлежность к этим 105 предметам.
Нахождение совпадения, и, соответственно, его номера в массиве.
Работа с найденным номером.
Всё.
1227895619 отличаются
тоже не вариант
30
А почему просто не использовать хт с O(1) и не бегать по циклам с O(n)?
4
А почему просто не использовать хт с O(1) и не бегать по циклам с O(n)?
вариант хороший но....ну нет....такой подход тоже не подходит
оно проверится когда Юнит Получит Предмет
а использовать конструкцию типа
set Item_Init[ItemUserDataMas[1]] = 'I03D'
тоже не вариант так как Item_Init инициализируется После установки
ItemUserDataMas
Чтобы оставить комментарий, пожалуйста, войдите на сайт.