Да! есть, учимся пользоваться Поиском по сайту! есть куча наработок и примеров как создать юнита как избавится от GUI и начинать писать нормальные системы для спавнов с многоступенчатой системой всяких проверок и при этом чтобы это все дело работало как надо.
по содержимому нашел Кучу багов и бесполезных строк кода которые ничего не решают
Wait 0.10 секунд лучше убрать
Turn Off (этот триггер) тоже
Вейт 15 секунд в проверке идентификатора тоже
Do Nothing тоже
во 2 выбрать всех юнитов без уничтожения утечек
Условие игрока Что должно проверять? кого? Воздух?
а 3 более или менее нормальный?
пользуемся поиском и изучаем что вызывает утечки что нужно уничтожать а что нужно избежать
да и по логики тоже под вопросом
откуда знать когда один игрок закончит волну?
может ему потребуется больше времени а не то что указанно в таймере?
юнит который контролируется 12 игроком умирает
Кто должен умирать? Герой, Вызванная боевая единица Здание?
посоветовал бы сначала убрать все это и создать несколько триггеров в котором будет происходить события связанные Только с 1 игроком
и так для всех но только для других игроков
когда игрок печатает команду проверяется идентификатор что игрок выбрал героя
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 золота а не ему а проверять каждого игрока нету смысла
кто угодно может печатать Событие берет Игрока
но если у этого игрока есть герой?
проверить игрока который напечатал и если у него есть герой для этого и условие есть
исходя из примера
Пример:
-Игрок 1 пишет RP
-Условие (юнит тригера)-это герой равно да
уничтожить героя тригера
или вариант занести в массив героя и удалить его по индексу массива
похоже что какой-то индекс или переменная загрузила или сохранила значение - 1 или -2
такое бывает когда какойто цикл выходит за рамки допустимого
например каждую секунду уменьшить Столбцы Мултиборда пока индекс не дойдет до -1 или - 2 .тогда выскочит подобная ошибка
Событие игрок напечатал RP
Условие если это герой
Действие Удаляем Героя и даем игроку 400 золота
и установить переменную под индексом например 1 что игрок написал эту команду
дальше проверяем переменную и так для всех игроков
в массиве задал бы значения для проверки а по GetHandleId вычислял если оно нужное, а дальше другим массивом подгружал бы значения из GetHandleId
опять же с проверкой если оно нужное и так везде где это нужно потом смело можно освободить Хэндл
тоже столкнулся с таким, поэтому храню значения через StringHash и подгружаю там где мне нужно. Полет нормальный
if (LoadBoolean(H,StringHash((I2S((GetHandleId((O)))) )),StringHash(("Y")))) == GetHandleId((O)) then// если Хэндл юнита совпадает
set Mas[1] = 1 //массиву присваиваем значения и дальше оперируем непосредственно с массивом
endif
//StringHash((I2S((GetHandleId((O41904)))) )) сохраняется под значением StringHash и дополнительно под Хэндл
если есть огромный опыт в понимание всех функций и что они делают +
Второй способ:
Очистить утечки
Очистить только там где это надо
не всегда и не везде это нужно
Третий способ:
Улучшить GUI код, так чтобы не лагал
проще забыть про GUI и начинать пилить свои Функции которые делают ровно то что делал бы GUI в 100 строк вместо 10 в функции
Четвертый способ:
Уменьшить названия областей, триггеров и переменных (это способ для мазохистов, не сильно оптимизирует)
я бы завел массив и привязал бы к GetHandleId а дальше очищать Хэш таблицу оперируя уже массивом, в любой момент можно очищать Индекс массива или перезаписать его не волнуясь что какой-то хэндл гдето сохранил под этот хэндл чтото
логика такова
цикл от 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()
А тебе не это надо? Что б по типу предметы получать номер массива
Тип предмета 'I03D', это 1227895620, если отнять 1227895619 тотполцчаешь 1
Вот у тебя I03D=1
А переменная с индектом 1 = 'I03D'
хороший пример...но надо продумать в каком месте его поставить чтобы функция работала
Запись всех типов предметов в массив от 1 до 105
При подборе предмета проверка его на принадлежность к этим 105 предметам.
Нахождение совпадения, и, соответственно, его номера в массиве.
Работа с найденным номером.
Всё.
Emafusail, еще раз пытаюсь тебе донести - это делать надо НЕ ТАК.
Ты, со стороны лог;ки движка, пишешь непонятно что непонятно и хочешь получать на выходе в непонятном месте весьма конкретный результат. Это так не работает. Тут нужно совсем по другому всё оформить.
Для этого нужно взять ТИП предмета (число в виде 'I03D'), и сравнить его сотвсеми из списка (а он у тебя длинной в 105), и при первомже совпадении вернуть его номер. Например это будет 37.
И уже с этими 37 делать всё что хочешь, т.к. номер имея ты и данные другие можно подтянуть.
Ну там еще можно лупить базу типа set t['I03D'] = 'I03D'
Хотя тут надо чуть по другому на индекс напирать, но смысмыс в общем такой.
Но одно другого не отменяет вообще
А теперь можешь описать что ты пытаешься реализовать?
в общем 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
» WarCraft 3 / Проверка прошли ли все игроки волну и создать новую волну
» WarCraft 3 / Проверка прошли ли все игроки волну и создать новую волну
» WarCraft 3 / Проверка прошли ли все игроки волну и создать новую волну
по содержимому нашел Кучу багов и бесполезных строк кода которые ничего не решают
Wait 0.10 секунд лучше убрать
Turn Off (этот триггер) тоже
Вейт 15 секунд в проверке идентификатора тоже
Do Nothing тоже
во 2 выбрать всех юнитов без уничтожения утечек
Условие игрока Что должно проверять? кого? Воздух?
а 3 более или менее нормальный?
Кто должен умирать? Герой, Вызванная боевая единица Здание?
и так для всех но только для других игроков
» WarCraft 3 / Кто нибудь знает что делает эта функция?
Ред. Emafusail
» WarCraft 3 / Как сделать repick
так как Герой не выбран
у него условие не будет работать потому что Событие проверяет Игрока а герой не привязан к игроку
если игрок выбрал героя и разработчик знает что герой выбран не использовать конструкцию
IsUnitIdType(GetUnitTypeId( (Hero[Pid])), UNIT_TYPE_HERO) == true
а сразу удалить героя когда он напечатает команду
» WarCraft 3 / Как сделать repick
но если у этого игрока есть герой?
проверить игрока который напечатал и если у него есть герой для этого и условие есть
-Игрок 1 пишет RP
-Условие (юнит тригера)-это герой равно да
уничтожить героя тригера
» WarCraft 3 / Как можно хранить значения в юнитах? Аналог SetUnitUserData
Ред. Emafusail
» WarCraft 3 / Недостаточно ресурсов памяти для обработки этой команды...
для этого надо перелопатить все триггеры
отключить по очереди триггеры и смотреть где она вызывается
» WarCraft 3 / Недостаточно ресурсов памяти для обработки этой команды...
например каждую секунду уменьшить Столбцы Мултиборда пока индекс не дойдет до -1 или - 2 .тогда выскочит подобная ошибка
» WarCraft 3 / Как сделать repick
Условие если это герой
Действие Удаляем Героя и даем игроку 400 золота
и установить переменную под индексом например 1 что игрок написал эту команду
дальше проверяем переменную и так для всех игроков
Ред. Emafusail
» WarCraft 3 / как создавать юнитов с уникальным HandleId ?
опять же с проверкой если оно нужное и так везде где это нужно потом смело можно освободить Хэндл
тоже столкнулся с таким, поэтому храню значения через StringHash и подгружаю там где мне нужно. Полет нормальный
» WarCraft 3 / Оптимизация карты
Переписать код с GUI на Jass
Очистить утечки
Очистить только там где это надо
не всегда и не везде это нужно
Улучшить GUI код, так чтобы не лагал
проще забыть про GUI и начинать пилить свои Функции которые делают ровно то что делал бы GUI в 100 строк вместо 10 в функции
Уменьшить названия областей, триггеров и переменных (это способ для мазохистов, не сильно оптимизирует)
» WarCraft 3 / как создавать юнитов с уникальным HandleId ?
Ред. Emafusail
» WarCraft 3 / Создание предмета через itemUserData
цикл от 1 до всех предметов в карте призван Установить для Каждого Item_Init[Cnt_Item_Init]
Значение взятое из SetItemUserData
для удобства занес эти Значения в Переменную типа Массив чтобы Оперировать с ними там где мне это нужно
и когда в инвентаре окажется Индекс этого предмета я буду знать что этот предмет мне нужен для Удаления
для этого есть функция
а дальше Создание предмета ПО Индексу расположенный в Item_Init
даже мне стало интересно на что он способен :)
» WarCraft 3 / Создание предмета через itemUserData
а то и так есть Тяжелые функции которые хочу Имплементировать в карту сохраняя и подгружая Значения из разных Массивов
» WarCraft 3 / Создание предмета через itemUserData
» WarCraft 3 / Создание предмета через itemUserData
» WarCraft 3 / Создание предмета через itemUserData
Ред. Emafusail
» WarCraft 3 / Создание предмета через itemUserData
оно проверится когда Юнит Получит Предмет
а использовать конструкцию типа
ItemUserDataMas
» WarCraft 3 / Создание предмета через itemUserData
тоже не вариант
» WarCraft 3 / Создание предмета через itemUserData
да но оно возвращает 1227895620
а не значение 1
» WarCraft 3 / Создание предмета через itemUserData
цикл запущен
но SetItemUserData Перезаписывается
для этого и занес его в массив
пытаюсь избежать эту перезапись
» WarCraft 3 / Создание предмета через itemUserData
» WarCraft 3 / Создание предмета через itemUserData
Ред. Emafusail
» WarCraft 3 / Создание предмета через itemUserData
и исходя из этих значений указать Индекс Для проверки Предмета Item_Init чтобы удалить его и создать чтото там