4

» WarCraft 3 / Проверка прошли ли все игроки волну и создать новую волну

For Each A from 1 to 10 //Это Цикл внутри цикла создаешь
If all Condition Are True then
//если все условия верны ТО
вот как выглядит Группа Игроков
в условие и будет проверка игроков

по простому если объяснить а дальше проверять все остальное в этом же примере, зачем создавать 3 триггера с Одинаковым Событием?
Загруженные файлы
4

» WarCraft 3 / Проверка прошли ли все игроки волну и создать новую волну

Не придется использовать куча действий на перемещение юнитов.
Да вариант тоже не-очень но пока научится создавать Функции которые будут задавать определенные параметры пройдет много времени
4

» WarCraft 3 / Проверка прошли ли все игроки волну и создать новую волну

Да! есть, учимся пользоваться Поиском по сайту! есть куча наработок и примеров как создать юнита как избавится от GUI и начинать писать нормальные системы для спавнов с многоступенчатой системой всяких проверок и при этом чтобы это все дело работало как надо.
по содержимому нашел Кучу багов и бесполезных строк кода которые ничего не решают
Wait 0.10 секунд лучше убрать
Turn Off (этот триггер) тоже
Вейт 15 секунд в проверке идентификатора тоже
Do Nothing тоже
во 2 выбрать всех юнитов без уничтожения утечек
Условие игрока Что должно проверять? кого? Воздух?
а 3 более или менее нормальный?
пользуемся поиском и изучаем что вызывает утечки что нужно уничтожать а что нужно избежать

да и по логики тоже под вопросом

откуда знать когда один игрок закончит волну?

может ему потребуется больше времени а не то что указанно в таймере?

юнит который контролируется 12 игроком умирает
Кто должен умирать? Герой, Вызванная боевая единица Здание?

посоветовал бы сначала убрать все это и создать несколько триггеров в котором будет происходить события связанные Только с 1 игроком
и так для всех но только для других игроков
4

» WarCraft 3 / Как сделать repick

когда игрок печатает команду проверяется идентификатор что игрок выбрал героя
local integer Pid = GetPlayerId(GetTriggerPlayer())

if HeroIsChoosed[Pid] == true then
call RemoveUnit((Hero[Pid]) )
endif
HeroIsChoosed[Pid] это идентификатор

этот идентификатор устанавливается в True когда тыкаю на кнопку Создать Героя

а Pid это тот кто тыкнул на кнопку

и сразу вставляю HeroIsChoosed[Pid] в False
так как Герой не выбран
у него условие не будет работать потому что Событие проверяет Игрока а герой не привязан к игроку
есть вариант
    local integer Pid = GetPlayerId(GetTriggerPlayer())
    if IsUnitIdType(GetUnitTypeId( (Hero[Pid])), UNIT_TYPE_HERO) == true then
    call RemoveUnit(Hero[Pid])
    endif

либо другой
если игрок выбрал героя и разработчик знает что герой выбран не использовать конструкцию
IsUnitIdType(GetUnitTypeId( (Hero[Pid])), UNIT_TYPE_HERO) == true
а сразу удалить героя когда он напечатает команду

оптимальный вариант занести героя в переменную и работать непосредственно с ней

а выдать Игроку 1 золото можно также через Pid так как если напечатает кто-то другой эту команду только 1 игроку выдадут 400 золота а не ему а проверять каждого игрока нету смысла
4

» WarCraft 3 / Как сделать repick

кто угодно может печатать Событие берет Игрока
но если у этого игрока есть герой?
проверить игрока который напечатал и если у него есть герой для этого и условие есть

исходя из примера
Пример:
-Игрок 1 пишет RP
-Условие (юнит тригера)-это герой равно да
уничтожить героя тригера

или вариант занести в массив героя и удалить его по индексу массива

без условий

но можно и проверять если герой массива это герой
4

» WarCraft 3 / Как можно хранить значения в юнитах? Аналог SetUnitUserData

Вариант
set PointValue[GetUnitPointValue(unit[1])] = unit[1] //Опыт боевой единицы в РО
4

» WarCraft 3 / Недостаточно ресурсов памяти для обработки этой команды...

вот ошибка

ну узнать в каком месте это ошибка появляется
для этого надо перелопатить все триггеры
отключить по очереди триггеры и смотреть где она вызывается
Загруженные файлы
4

» WarCraft 3 / Недостаточно ресурсов памяти для обработки этой команды...

похоже что какой-то индекс или переменная загрузила или сохранила значение - 1 или -2

такое бывает когда какойто цикл выходит за рамки допустимого
например каждую секунду уменьшить Столбцы Мултиборда пока индекс не дойдет до -1 или - 2 .тогда выскочит подобная ошибка
4

» WarCraft 3 / Как сделать repick

Событие игрок напечатал RP
Условие если это герой
Действие Удаляем Героя и даем игроку 400 золота
и установить переменную под индексом например 1 что игрок написал эту команду
дальше проверяем переменную и так для всех игроков
4

» WarCraft 3 / как создавать юнитов с уникальным HandleId ?

я бы завел массив и привязал бы к GetHandleId
Каким образом?
в массиве задал бы значения для проверки а по GetHandleId вычислял если оно нужное, а дальше другим массивом подгружал бы значения из GetHandleId
опять же с проверкой если оно нужное и так везде где это нужно потом смело можно освободить Хэндл
тоже столкнулся с таким, поэтому храню значения через StringHash и подгружаю там где мне нужно. Полет нормальный

вот пример
call SaveBoolean(H,StringHash((I2S((GetHandleId((O)))) )),StringHash(("Y")), (true))
if (LoadBoolean(H,StringHash((I2S((GetHandleId((O)))) )),StringHash(("Y")))) == GetHandleId((O)) then// если Хэндл юнита совпадает
set Mas[1] = 1 //массиву присваиваем значения и дальше оперируем непосредственно с массивом
endif

//StringHash((I2S((GetHandleId((O41904)))) )) сохраняется под значением StringHash и дополнительно под Хэндл
4

» WarCraft 3 / Оптимизация карты

Первый способ:
Переписать код с GUI на Jass
если есть огромный опыт в понимание всех функций и что они делают +
Второй способ:
Очистить утечки
Очистить только там где это надо
не всегда и не везде это нужно
Третий способ:
Улучшить GUI код, так чтобы не лагал
проще забыть про GUI и начинать пилить свои Функции которые делают ровно то что делал бы GUI в 100 строк вместо 10 в функции
Четвертый способ:
Уменьшить названия областей, триггеров и переменных (это способ для мазохистов, не сильно оптимизирует)
+

а еще лучше начинать писать свои Library
4

» WarCraft 3 / как создавать юнитов с уникальным HandleId ?

я бы завел массив и привязал бы к GetHandleId а дальше очищать Хэш таблицу оперируя уже массивом, в любой момент можно очищать Индекс массива или перезаписать его не волнуясь что какой-то хэндл гдето сохранил под этот хэндл чтото
4

» WarCraft 3 / Создание предмета через itemUserData

логика такова
цикл от 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

» WarCraft 3 / Создание предмета через itemUserData

привязывая данные к Предмету
А тебе не это надо? Что б по типу предметы получать номер массива
Тип предмета 'I03D', это 1227895620, если отнять 1227895619 тотполцчаешь 1
Вот у тебя I03D=1
А переменная с индектом 1 = 'I03D'
хороший пример...но надо продумать в каком месте его поставить чтобы функция работала

много чем, это Разные Предметы из Разных категорий из других Разрядов из Кампании и у них у всех отдельные значения
Ну так сгруппируй их
а тут другие проблемы возникают это отдельная тема для разговора

впрочем придумал решение по лучше

//if GetItemTypeId(GetManipulatedItem()) == Item_Init[Cnt_Item_Init] then
//call SetItemUserData(GetManipulatedItem(), Cnt_Item_Init)

//endif
в угоду Компактности
а то и так есть Тяжелые функции которые хочу Имплементировать в карту сохраняя и подгружая Значения из разных Массивов
4

» WarCraft 3 / Создание предмета через itemUserData

Item_Init инициализируется После установки
ItemUserDataMas
Всмысле "после" ?
ну это я сделаю, Первичные Функции необходимые для Работы Всего в карте устроены по Близовскому принципу "Поочередно"
4

» WarCraft 3 / Создание предмета через itemUserData

1227895619 отличаются
Чем?
много чем, это Разные Предметы из Разных категорий из других Разрядов из Кампании и у них у всех отдельные значения
4

» WarCraft 3 / Создание предмета через itemUserData

А почему просто не использовать хт с O(1) и не бегать по циклам с O(n)?
вариант хороший но....ну нет....такой подход тоже не подходит
оно проверится когда Юнит Получит Предмет
а использовать конструкцию типа
set Item_Init[ItemUserDataMas[1]] = 'I03D'
тоже не вариант так как Item_Init инициализируется После установки
ItemUserDataMas
4

» WarCraft 3 / Создание предмета через itemUserData

Emafusail:
это всё числа, и 'I03D' тоже число.
да но оно возвращает 1227895620
а не значение 1
Ну так вычти из него 1227895619, и используй остаток как ИНДЕКС массива.
И будут у тебя типы предметов от 1227895620 до 1227895724
Emafusail:
ну хорошо, как ты это видишь?
Запись всех типов предметов в массив от 1 до 105
При подборе предмета проверка его на принадлежность к этим 105 предметам.
Нахождение совпадения, и, соответственно, его номера в массиве.
Работа с найденным номером.
Всё.
1227895619 отличаются
тоже не вариант
4

» WarCraft 3 / Создание предмета через itemUserData

это всё числа, и 'I03D' тоже число.
да но оно возвращает 1227895620
а не значение 1

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

» WarCraft 3 / Создание предмета через itemUserData

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

Emafusail, это всё числа, и 'I03D' тоже число.
это понятно.
цикл запущен
но SetItemUserData Перезаписывается
для этого и занес его в массив
пытаюсь избежать эту перезапись
4

» WarCraft 3 / Создание предмета через itemUserData

но ItemUserDataMas[Cnt_Item_Init] это целочисленная а Item_Init это Тип Предмета грубо говоря который возвращает GetItemTypeId

GetItemTypeId Привязать к ItemUserDataMas[Cnt_Item_Init]
4

» WarCraft 3 / Создание предмета через itemUserData

Принимать? Или всё-таки возвращать? (при совпадении типа)
при совпадении Типа конечно
4

» WarCraft 3 / Создание предмета через itemUserData

А теперь можешь описать что ты пытаешься реализовать?
в общем 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