Изменить состояние фиксированного слота вряд-ли возможно, главное зачем это делать, если на слоте всегда будет один и тот же ИИ? Просто при инициализации запускаешь нужный скрипт и всё
все верно, можно еще в Игровые константы изменить имя компьютерного игрока и дальше запилить свой ИИ
он имел в виду
Где-то на гитхабе видел готовый брутфорсер на java.
ну про взлом я пока не думаю )) да и врятли кто-то заморочиться внедрять читпаки и мемхаки, это больше делаю для проверки имени игрока и проверки если игрок который насолил кому-то зашел поиграть а тут бац не может играть потому что он в списке забаненых игроков.
смотри я тебе дал готовый пример как должно все работать, он будет крашится если не соблюдать правила
даю тебе карту где наглядно есть подобный механизм от него и отталкивайся
я тебе в 10 раз говорю НИКОГДА не используй вейты в Циклах
Ну не знаю, я использовал на практике специальную функцию, где есть таймер и цикл, а в цикле вейт(!) на 1 сек, цикл работает, пока не истекает таймер. Так вот, с ней никогда никаких ошибок и крашей не было, всё стабильно. Даже на паузе. Версия 1.26а
в мултиплеере она себя проявит. это только надо поиграть на 2 машинах которые не находятся в одной локалке
Остаётся узнать - ПОЧЕМУ? Почему способность сама по себе работает, а обращение к ней тригера, даже если сам тригер не активируется, ломает игру?
потому что нельзя кастовать пассивную способность.
function BackEnd takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer id=GetHandleId(t)
local unit c=LoadUnitHandle(udg_HT,id,0)
call UnitRemoveAbility(c,'A06I') // здесь убираем абилку и очищаем следы
call DestroyTimer(t)
call FlushChildHashtable(udg_HT,id)
set t=null
set c=null
endfunction
function Back takes nothing returns nothing
local unit u=GetSpellAbilityUnit()
local timer t=CreateTimer()
call SaveUnitHandle(udg_HT,GetHandleId(t),0,u)
call UnitAddAbility(u,'A06I') // это пассивная абилка
call TimerStart(t,0.5,false,function BackEnd) //запускаем таймер чтобы делать чтото
set u=null
set t=null
endfunction
ответ дал. как надо кастовать скил и как с ним работать
Я в коде полный 0. Скилл сейчас переделаю, поменяю по-разному, посмотрю.
тогда иди читай гайды как создать первоклассный скил
Centyrion, это обыкновенный хэш. Там нечему утекать и ломаться в мультиплеере. Его часто используют для именования ключей хэш-таблиц.
Да и чтоб вызвать просадки производительности, его нужно очень много раз вызвать.
Ну, мне известно что каждый объект который создается занимает в памяти определенное кол-во байтов, поэтому я постараюсь его особо не использовать,
вот пример где это используется
((цитата
создает ли эта нативка утечки или чтото такое
Нет.
и в мултиплеере как она себя поведет не вызовет десинх или все нормально будет
Не вызовет.
))
спасибо) побоялся что если при инициализации карты сохраню все имена игроков в хэш таблицу и когда попытаюсь достать эти значения по ключу игра крашнится или вылетит
в блоке кода неважно что будет
меня интересует 2 вещи
создает ли эта нативка утечки или чтото такое
и в мултиплеере как она себя поведет не вызовет десинх или все нормально будет
Centyrion, Может способность не для героя, либо юнит не герой. Краш бывает, если проводить манипуляции с характеристиками на простых юнитах
может быть, я даю способность вампиризм когда юнит выучил способность, триггер проверяет уровень способности и если уровень абилки больше 0 то даю герою пасивку на основе вампиризма, у него тут рекурсивная абилка в 2 Скрине которая стопорит поток, в цикле никогда не надо использовать Wait, дал все что нужно герою и запустил таймер далее достаешь значения из переменных и работаешь с ними.
В моем случае мне нужно было чтобы тригер работал с другими игроками, но при этом на "нужном" игроке, счётчик не увеличивался. Поэтому просто выключить его я не могу. И потому, я решил таким образом попробовать реализовать. Цикл я ещё даже не тестил, можно не обращать на него внимание.
В принципе если конкретно то в чем проблема не найдем, я попробую завтра снести полностью этот тригер, и переделать его как только смогу. Мне просто интересно что конкретно может вызывать эту проблему.
Мне просто интересно что конкретно может вызывать эту проблему.
я тебе в 10 раз говорю НИКОГДА не используй вейты в Циклах
Centyrion, Может способность не для героя, либо юнит не герой. Краш бывает, если проводить манипуляции с характеристиками на простых юнитах
может быть, я даю способность вампиризм когда юнит выучил способность, триггер проверяет уровень способности и если уровень абилки больше 0 то даю герою пасивку на основе вампиризма, у него тут рекурсивная абилка в 2 Скрине которая стопорит поток, в цикле никогда не надо использовать Wait, дал все что нужно герою и запустил таймер далее достаешь значения из переменных и работаешь с ними.
тогда убирай циклы переменные и вейты и юзай таймеры.
перестроить скил надо
function BackEnd takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer id=GetHandleId(t)
local unit c=LoadUnitHandle(udg_HT,id,0)
call UnitRemoveAbility(c,'A06I')
call DestroyTimer(t)
call FlushChildHashtable(udg_HT,id)
set t=null
set c=null
endfunction
function Back takes nothing returns nothing
local unit u=GetSpellAbilityUnit()
local timer t=CreateTimer()
call SaveUnitHandle(udg_HT,GetHandleId(t),0,u)
call UnitAddAbility(u,'A06I')
call TimerStart(t,0.5,false,function BackEnd)
set u=null
set t=null
endfunction
WorldEdition:
UPD1: А есть какой-то метод отслеживания ошибок? Где-то логи можно посмотреть?
для этого есть замечательная функция BJDebugMsg, вставляешь и смотришь где она стопорится
конечно русская локализация радует глаз но с первым триггером Скрин 1 все нормально а со 2 Скрином, бред, юзай таймеры вместо вейтов, они утечные и не универсальные, и фатал вызывает что в цикле от 1 до 30 ты стопоришь поток, конечно он выкинет игрока который кастовал способность
Если бы. Цикл я добавил позже, и знаю что он скорее всего нерабочий. Оно и без цикла крашит или не даёт запустить карту. =(
UPD: Сейчас даже удалил цикл, на всякий, как и говорил - та же история. Карту не запускает, сразу в меню варика выкидывает.
UPD1: Если удалить первый тригер, то игра крашается. Если его не удалять, то не крашается, но не запускается. =/
конечно русская локализация радует глаз но с первым триггером Скрин 1 все нормально а со 2 Скрином, бред, юзай таймеры вместо вейтов, они утечные и не универсальные, и фатал вызывает что в цикле от 1 до 30 ты стопоришь поток, конечно он выкинет игрока который кастовал способность
Да возможно.
когда игрок загружает игру, что бы музыка стартовала с рандомного места (ну типа с 10 минуты или с 20 минуты)
с рандомного места : завел переменную типа Muzic_Theme с массивом, прописываешь номер от 1 до 100 к примеру и вместо цифры вставляешь GetRandomInt(1, 100) все
переменная Muzic_Theme это Звук
function F_GetInventoryIndex takes unit u,integer id returns integer
local integer slot = 0
local integer cnt = 0
local item ite
loop
set ite = UnitItemInSlot(u,slot)
if ( ite != null ) and ( GetItemTypeId(ite) == id ) then
set cnt = cnt + 1
endif
set slot = slot + 1
exitwhen slot >= bj_MAX_INVENTORY
endloop
set ite = null
return cnt
endfunction
ну и тут идет проверка предмета
function F_Item_Check takes nothing returns nothing
local unit u = GetManipulatingUnit()
local integer id = GetItemTypeId(GetManipulatedItem())
if (id == udg_Item_Init[2]) then
if ( F_GetInventoryIndex(u, udg_Item_Init[2]) > 0 ) then
// если предметов больше 0 и GetItemTypeId = этому предмету то что угодно делать с ним
// в качестве индекса берется переменная типа тип Предмета с массивом
else
call F_Create_Item(u, udg_Item_Init[2])
endif
endif
endfunction
конечно можно использовать и конструкцию типа такого
if ( F_GetInventoryIndex(u, udg_Item_Init[2]) == 2 ) then
call UnitRemoveItem(u, udg_Item_Init[2])
endif
чтобы добавить ограничение для предмета данного типа
Ух какой ужос, меньше используй ГУИ, проверить можно по TypeId берем предмет в слоте и проверяем ид, если оно нужное - то удаляем, далее следующий слот если нужно проверить всё слоты, ну а систем на сборку артефактов на сайте была уйма. Потом если юнит получает предмет - то в триггере ты можешь узнать какой предмет он получил - GetManipulatedItem() его проверяй сразу, а не ищи по слотам.
тут собственно когда юнит приобретает предмет идет проверка если это не Усиливающий предмет
и сохранение HandleId в хэш таблице
и условие
разобрались
тут вызывается
тут идет проверка если герой получил предмет типа Усиливающие
ну и условие
function F_Item_Stack_Cond takes nothing returns boolean
return (GetItemCharges(GetManipulatedItem()) > 0) and (GetItemType(GetManipulatedItem()) == ITEM_TYPE_CHARGED) and (GetManipulatedItem()!=GetItemOfTypeFromUnitBJ(GetManipulatingUnit(),GetItemTypeId(GetManipulatedItem()))) and (UnitHasItemOfTypeBJ(GetManipulatingUnit(),GetItemTypeId(GetManipulatedItem()))==true)
endfunction
можно совершенствовать но это потом
также получаем Id полученного предмета что и нужно
но id будет работать только для Усиливающих предметов
quq_CCCP:
да я этим сейчас и занимаюсь, насчет Type Id воспользуюсь но для проверки заряда предмета
local item i=GetManipulatedItem()
local item gi
local unit u=GetTriggerUnit()
local integer id=GetItemTypeId(i)
call UnitRemoveItem(u,i)
if((GetInventoryIndexOfItemTypeBJ(u,id)>0))then
call SetItemCharges(gi,(GetItemCharges(gi)+GetItemCharges(i)))
call RemoveItem(i)
else
call UnitAddItem(u,i)
endif
событие тоже будет такой при получении предмета,
меня смущает функция
function UnitHasItemOfTypeBJ takes unit whichUnit, integer itemId returns boolean
return GetInventoryIndexOfItemTypeBJ(whichUnit, itemId) > 0
endfunction
проверяет если по типу предмета в инвентаре больше 0
GetInventoryIndexOfItemTypeBJ
function GetInventoryIndexOfItemTypeBJ takes unit whichUnit, integer itemId returns integer
local integer index
local item indexItem
set index = 0
loop
set indexItem = UnitItemInSlot(whichUnit, index)
if (indexItem != null) and (GetItemTypeId(indexItem) == itemId) then
return index + 1
endif
set index = index + 1
exitwhen index >= bj_MAX_INVENTORY
endloop
return 0
endfunction
а если нет то возвращает 0
мне кажется что set index = 0 надо убрать отсюда и поставить другую переменную на +1
Centyrion, каким образом протестировали? Вейт не точен, эти неточности накапливаются за время игры, и в один прекрасный момент чувака десинхает.
пользуюсь такой конструкцией
костыль но работает
тут выбор пал на TriggerSleepAction так как он не использует таймер и к тому же тут использую Ролик созданного юнита, если его не показать всем игрокам он вызывает Десинх тут проблем нету.
Ред. Centyrion
» WarCraft 3 / Как установить сложность компьютера?
он имел в виду
» WarCraft 3 / Как установить сложность компьютера?
» WarCraft 3 / Работа с StringHash
небось скоро начну писать библиотеки» WarCraft 3 / Работа с StringHash
» WarCraft 3 / [GUI] Тригер "отказывает" в запуске карты, или крашит игру.
даю тебе карту где наглядно есть подобный механизм от него и отталкивайся
» WarCraft 3 / [GUI] Тригер "отказывает" в запуске карты, или крашит игру.
» WarCraft 3 / Работа с StringHash
» WarCraft 3 / Работа с StringHash
вот пример где это используется
» WarCraft 3 / Работа с StringHash
))
» WarCraft 3 / Работа с StringHash
меня интересует 2 вещи
создает ли эта нативка утечки или чтото такое
и в мултиплеере как она себя поведет не вызовет десинх или все нормально будет
Ред. Centyrion
» WarCraft 3 / [GUI] Тригер "отказывает" в запуске карты, или крашит игру.
я тебе в 10 раз говорю НИКОГДА не используй вейты в Циклах
» WarCraft 3 / [GUI] Тригер "отказывает" в запуске карты, или крашит игру.
» WarCraft 3 / [GUI] Тригер "отказывает" в запуске карты, или крашит игру.
UPD1: А есть какой-то метод отслеживания ошибок? Где-то логи можно посмотреть?
для этого есть замечательная функция BJDebugMsg, вставляешь и смотришь где она стопорится
» WarCraft 3 / [GUI] Тригер "отказывает" в запуске карты, или крашит игру.
приведу пример как это должно работать
» WarCraft 3 / [GUI] Тригер "отказывает" в запуске карты, или крашит игру.
Ред. Centyrion
» WarCraft 3 / Триггер музыки и загрузка
когда игрок загружает игру, что бы музыка стартовала с рандомного места (ну типа с 10 минуты или с 20 минуты)
переменная Muzic_Theme это Звук
» WarCraft 3 / 20. Оптимизация
Ред. Centyrion
» WarCraft 3 / Проверка Предметов и их удаление
Ред. Centyrion
» WarCraft 3 / Проверка Предметов и их удаление
Ред. Centyrion
» WarCraft 3 / Проверка Предметов и их удаление
да я этим сейчас и занимаюсь, насчет Type Id воспользуюсь но для проверки заряда предмета
меня смущает функция
Ред. Centyrion
» WarCraft 3 / Проверка Предметов и их удаление
» WarCraft 3 / Функция Анимации
» WarCraft 3 / Функция Анимации
или
function PolledWait takes real duration returns nothing
» WarCraft 3 / Функция Анимации
Ред. Centyrion
» WarCraft 3 / Функция Анимации