XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Закрытая тема
 
Zahanc

offline
Опыт: 23,017
Активность:
Проблема с реализацией заклинания, сбивающего врагов с ног.
Код:
function Trig_Charge_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'AAnp'
endfunction

function Charge_Stun_Check takes nothing returns boolean
    if GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.425 and IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) == true and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitIdType(GetUnitTypeId(GetTriggerUnit()), UNIT_TYPE_STUNNED) == false and IsUnitType(GetFilterUnit(), UNIT_TYPE_STUNNED) == false and GetUnitAbilityLevel(GetFilterUnit(), 'A00Z') <= 0 and GetUnitAbilityLevel(GetFilterUnit(), 'BPSE') <= 0 and GetUnitAbilityLevel(GetFilterUnit(), 'BSTN') <= 0 and GetUnitAbilityLevel(GetFilterUnit(), 'Aloc') <= 0 then
        return true
    else
        return false
    endif
endfunction

function Charge_Move takes nothing returns nothing
        //Объявление локальных переменных.
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
            //Данные для движения.
    local unit a = LoadUnitHandle(udg_hash, id, StringHash("ChargeCaster"))
    local real x = LoadReal(udg_hash, id, StringHash("ChargeCenterX"))
    local real y = LoadReal(udg_hash, id, StringHash("ChargeCenterY"))
    local real dist = LoadReal(udg_hash, id, StringHash("ChargeDistance"))
    local real tx
    local real ty
    local real angle
            //Остальное.
    local unit d
    local group g = CreateGroup()
    local group n
    local boolexpr b = Filter(function Charge_Stun_Check)
    local unit f
    local timer s = CreateTimer()
    local integer sid
        //Непосредственно движение.
    if dist > 0. then 
        set tx = GetUnitX(a)
        set ty = GetUnitY(a)
        set angle = Atan2(ty-y, tx-x)
        if GetUnitState(a, UNIT_STATE_LIFE) > 0.425 then
            call SetUnitPosition(a, tx-30.*Cos(angle), ty-30.*Sin(angle))
            call SaveReal(udg_hash, id, StringHash("ChargeDistance"), dist-30.)
            //call SetUnitX(a,tx-30.*Cos(angle))  //Оставил на всякий пожарный как альтернативу.
            //call SetUnitY(a,ty-30.*Sin(angle))
                //Произведение действий с группой юнитов, которая попадается на пути у кастера.
            call GroupEnumUnitsInRange(g,GetUnitX(a),GetUnitY(a),300.,b)
            call GroupRemoveUnit(g, a)
            set n = Copy_Group(g)
            loop
                set f = FirstOfGroup(n)
                exitwhen f == null
                call DisplayTextToForce( GetPlayersAll(), GetUnitName(f) ) //Проверка, чтобы я мог узнать в игре кто прошел фильтр.
                set d = CreateUnit(GetOwningPlayer(a), 'udum', GetUnitX(a), GetUnitY(a), 0.)
                call UnitAddAbility(d, 'A00Y')
                //call UnitAddAbility(f, 'A00Z')
                call SetUnitAbilityLevel(d, 'A00Y', GetUnitAbilityLevel(a, 'AAnp'))
                call IssueTargetOrder( d, "creepthunderbolt", f )
                call UnitApplyTimedLife(d,'BTLF',1.0)
                call UnitDamageTargetBJ( a, f, 50.00+50.00*GetUnitAbilityLevel(a, 'AAnp'), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
                call SetUnitPathing( f, false )
                //call PauseUnit(f, true)
                call SetUnitAnimation( f, "death" )
                call GroupRemoveUnit(n, f)
            endloop
        endif
    else
            //Если движение окончено, очищаем не нужные данные и приводим кастера в нормальное состояние.
        call PauseUnit(a, false)
        call SetUnitAnimation(a, "stand")
        call DestroyTimer(t)
        call FlushChildHashtable(udg_hash, id)
    endif
        //Обнуление локальных переменных и других даных.
    call GroupClear(g)
    call DestroyGroup(n)
    call DestroyGroup(g)
    call DestroyBoolExpr(b)
    set t = null
    set f = null
    set a = null
    set g = null
    set n = null
    set b = null
    set s = null
    set d = null
endfunction

function Trig_Charge_Actions takes nothing returns nothing
    local unit a = GetSpellAbilityUnit()
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)
    local real x = GetLocationX(GetSpellTargetLoc())
    local real y = GetLocationY(GetSpellTargetLoc())
    local real dist = DistanceBetweenPoints(Location(GetUnitX(a), GetUnitY(a)), GetSpellTargetLoc())
        //Занесение необходимых для движения данных в хэщ и запуск таймера.
    call SaveReal(udg_hash, id, StringHash("ChargeCenterX"), x)
    call SaveReal(udg_hash, id, StringHash("ChargeCenterY"), y)
    call SaveUnitHandle(udg_hash, id, StringHash("ChargeCaster"), a)
    call SaveReal(udg_hash, id, StringHash("ChargeDistance"), dist)
    call IssueImmediateOrder(a, "stop")
    call PauseUnit(a, true)
    call SetUnitAnimationByIndex(a, 6)
    call TimerStart(t, 0.04, true, function Charge_Move)
        //Обнуление локальных переменных.
    set a = null
    set t = null
endfunction

//===========================================================================
function InitTrig_Charge takes nothing returns nothing
    set gg_trg_Charge = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Charge, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Charge, Condition( function Trig_Charge_Conditions ) )
    call TriggerAddAction( gg_trg_Charge, function Trig_Charge_Actions )
endfunction


По идее кастер должен пермещатся по юнитам, у которых отключен пафинг, но он этого не делает. Однако, юниты проигрывают нужную анимацию, т. е. действия совершаются. Я пробовал сделать такой же спелл, но без движения - тогда все работает.

Отредактировано bladget, 30.04.2012 в 12:08.
Старый 30.04.2012, 07:20
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
3 - задавай Custom Value юниту на 1 , и проверяй на GetUnitUserData(юнит) != 1
4 - SetUnitAnimationByIndex takes unit whichUnit, integer whichAnimation returns nothing
Hatsume_Hate добавил:
и в чем проблема 2 ?
Hatsume_Hate добавил:
//Запуск таймера, который должен будет снять паузу с юнита и вернуть ему физический размер.
                    //Кстати он почему-то не срабатывает.
                call SaveUnitHandle(udg_hash, sid, StringHash("NotLucker"), f)
                call TimerStart(s, 5., false, function Charge_Stun_OFF)
                set sid = GetHandleId(s)
                call GroupRemoveUnit(n, f)
мб надо так?
//Запуск таймера, который должен будет снять паузу с юнита и вернуть ему физический размер.
                    //Кстати он почему-то не срабатывает.
	set sid = GetHandleId(s)  //<-----
                call SaveUnitHandle(udg_hash, sid, StringHash("NotLucker"), f)
                call TimerStart(s, 5., false, function Charge_Stun_OFF)
                call GroupRemoveUnit(n, f)
Hatsume_Hate добавил:
	call PauseTimer(t)
	call DestroyTimer(t)
зачем сначала паузить его а затем удалять? сразу удаляй
Hatsume_Hate добавил:
и в функции Charge_Stun_OFF удали и обнули таймер t
Старый 30.04.2012, 08:53
Zahanc

offline
Опыт: 23,017
Активность:
Так, код обновил.
Hatsume_Hate:
и в чем проблема 2 ?
Как это обойти? Координаты работают заметно быстрее, но тогда герой ведет себя не адекватно. Пробовал паузить героя, но по окончанию каста он начинает кастовать снова.
Hatsume_Hate:
4 - SetUnitAnimationByIndex takes unit whichUnit, integer whichAnimation returns nothing
Выходит тут нужно знать код анимации, или я что-то не понял.
Hatsume_Hate:
3 - задавай Custom Value юниту на 1 , и проверяй на GetUnitUserData(юнит) != 1
Что это и как это работает? И для чего по идее предназначено?
Старый 30.04.2012, 09:26
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
bladget:
Так, код обновил.
Hatsume_Hate:
и в чем проблема 2 ?
Как это обойти? Координаты работают заметно быстрее, но тогда герой ведет себя не адекватно. Пробовал паузить героя, но по окончанию каста он начинает кастовать снова.
что обойти? скажи как должно быть и как сейчас работает.
Hatsume_Hate:
4 - SetUnitAnimationByIndex takes unit whichUnit, integer whichAnimation returns nothing
Выходит тут нужно знать код анимации, или я что-то не понял.
индекс анимации. Индексы анимаций идут по кадрам. Например у анимации с кадрами 100-500 будет индекс 1 если перед ней не будет никаких больше анимаций (глобальные не в счет(или как их там)) 550-700 = 2, 770-860 = 3...
Hatsume_Hate:
3 - задавай Custom Value юниту на 1 , и проверяй на GetUnitUserData(юнит) != 1
Что это и как это работает? И для чего по идее предназначено?
это специальное число юнита. Можно использовать как хочешь, нигде не используется по моим наблюдениям. в своей карте я использовал UnitUserData как значение сколько осталось урона которое будет поглощено барьером
call SetUnitUserData( uTarg, GetUnitUserData(uTarg) - FinalDmg )
Hatsume_Hate добавил:
вот в гуи
Миниатюры
Кликните на картинку для увеличения
Название:  35353535.JPG
Просмотров: 16
Размер:  22.3 Кбайт  
Старый 30.04.2012, 09:37
Zahanc

offline
Опыт: 23,017
Активность:
Hatsume_Hate:
что обойти? скажи как должно быть и как сейчас работает.
Если я пытаюсь перемещать кастера через координаты (SetUnitX/Y), то по окончанию каста он начинает кастовать снова.
Hatsume_Hate:
индекс анимации. Индексы анимаций идут по кадрам. Например у анимации с кадрами 100-500 будет индекс 1 если перед ней не будет никаких больше анимаций (глобальные не в счет(или как их там)) 550-700 = 2, 770-860 = 3...
Я понял, сейчас попробую.
Hatsume_Hate:
это специальное число юнита. Можно использовать как хочешь, нигде не используется по моим наблюдениям. в своей карте я использовал UnitUserData как значение сколько осталось урона которое будет поглощено барьером
А если будет несколько юнитов с одним значением? Кстати на счет барьера интересная идея
Старый 30.04.2012, 09:41
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
и да, если паузить, то он будет повторять каст снова и снова, можно перед паузой отдавать приказ стоп что бы сбросить использование, тогда все будет ок
Hatsume_Hate добавил:
bladget:
Hatsume_Hate:
это специальное число юнита. Можно использовать как хочешь, нигде не используется по моим наблюдениям. в своей карте я использовал UnitUserData как значение сколько осталось урона которое будет поглощено барьером
А если будет несколько юнитов с одним значением? Кстати на счет барьера интересная идея
спасибо =3 это уже как ты захочешь, это целочисленная будет лишь у того юнита которому ты ее дал. Типа персональной переменной)
Старый 30.04.2012, 09:45
Zahanc

offline
Опыт: 23,017
Активность:
Hatsume_Hate:
это уже как ты захочешь, это целочисленная будет лишь у того юнита которому ты ее дал. Типа персональной переменной)
т.е. конфликтов не возникнет если допустим будет несколько героев с таким заклинанием одновременно?
Старый 30.04.2012, 09:49
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
bladget:
Hatsume_Hate:
это уже как ты захочешь, это целочисленная будет лишь у того юнита которому ты ее дал. Типа персональной переменной)
т.е. конфликтов не возникнет если допустим будет несколько героев с таким заклинанием одновременно?
не ну если каждому дать единичку, то они будут игнорить единичку.
Hatsume_Hate добавил:
лучше сохрани юнита в хэш и проверяй на него
Hatsume_Hate добавил:
на таймер вешай)
Hatsume_Hate добавил:
мм, можно убирать кастера из группы сразу после енума, если он там внезапно оказался.
Старый 30.04.2012, 10:00
Zahanc

offline
Опыт: 23,017
Активность:
Так-с, код снова обновил, но проблема номер раз осталась не решенной.
bladget:
По идее кастер должен пермещатся по юнитам, у которых отключен пафинг, но он этого не делает. Однако, юниты проигрывают нужную анимацию, т. е. действия совершаются. Я пробовал сделать такой же спелл, но без движения - тогда все работает.
bladget добавил:
Hatsume_Hate:
мм, можно убирать кастера из группы сразу после енума, если он там внезапно оказался.
Да, так и сделал - работает. Блин, а до этого мне самому следовало догадаться.
Старый 30.04.2012, 10:04
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
мм, попробуй
local boolexpr b = Condition(function Charge_Stun_Check)
заменить на
local boolexpr b = Filter(function Charge_Stun_Check)
мб поможет с фильтром
Старый 30.04.2012, 10:05
Zahanc

offline
Опыт: 23,017
Активность:
Поменял, ничего не изменилось. Кстати - у меня в фильтре стоит проверка на наличие эффекта стана на юните, но её проходят даже те, на кого стан наложен. Поэтому, кстати, я и стал паузить юнитов и ввел проверку на паузу в фильтр, ибо она работает корректно. Почему так?
Старый 30.04.2012, 10:25
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
мб не то оглушение?
Hatsume_Hate добавил:
сделай лучше отдельный фильтр мб
типа
function MyFilter takes nothing returns boolean
if ...
return true
else
return false
endif
endfunction

...
call GroupEnumUnitsInRange(g,GetUnitX(a),GetUnitY(a),300.,Filter(function  MyFilter))
...
Старый 30.04.2012, 10:29
Zahanc

offline
Опыт: 23,017
Активность:
Hatsume_Hate:
мб не то оглушение?
Вряд-ли, я все оглушения добавил которые только есть.
Hatsume_Hate:
сделай лучше отдельный фильтр мб
А чем это поможет?
Старый 30.04.2012, 10:31
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
bladget:
Hatsume_Hate:
мб не то оглушение?
Вряд-ли, я все оглушения добавил которые только есть.
Hatsume_Hate:
сделай лучше отдельный фильтр мб
А чем это поможет?
малоли (с)
Hatsume_Hate добавил:
кстати, я делал так, что бы не проверять москитов (типа даммик это или нет) я как раз давал им юнит юсер дата на 1 или 2, и если юсер дата != 0 то это даммик
Старый 30.04.2012, 10:34
Zahanc

offline
Опыт: 23,017
Активность:
Вообще что-то мистическое с этим пафингом. В цикле не работает, в ForGroup тоже, только если давать напрямую.
Старый 30.04.2012, 12:08
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
всмысле? каким пафингом? как делаешь? тыкни носом)
Старый 30.04.2012, 12:14
Zahanc

offline
Опыт: 23,017
Активность:
call SetUnitPathing( unit, false ) - запустив эту функцию, сквозь unit можна будет проходить и он сам сможет проходить сзвозь юнитов и деревья. Мне это нужно, чтобы сквозь застаненных юнитов можно было проходить. Но это не работает в циклах и в фор груп. (если поставить true, то пафинг будет включен)
Старый 30.04.2012, 12:21
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
bladget:
call SetUnitPathing( unit, false ) - запустив эту функцию, сквозь unit можна будет проходить и он сам сможет проходить сзвозь юнитов и деревья. Мне это нужно, чтобы сквозь застаненных юнитов можно было проходить. Но это не работает в циклах и в фор груп. (если поставить true, то пафинг будет включен)
...
endloop
call SetUnitPathing(unit, false)
...
мб?...
Hatsume_Hate добавил:
мм, а если вызывать функцию которая будет давать пафинг?
соответвенно сохранять юнита в хэш
Старый 30.04.2012, 12:26
Zahanc

offline
Опыт: 23,017
Активность:
так мне нужно юнитов в группе перебирать.
bladget добавил:
Hatsume_Hate:
мм, а если вызывать функцию которая будет давать пафинг?
соответвенно сохранять юнита в хэш
гемор, но если другого выхода не будет то...
Старый 30.04.2012, 12:27
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
да вроде не особо гемор то)
Hatsume_Hate добавил:
тьфу, зачем в хэш его сохранять, XD
function GivePathing takes unit u, boolean A returns nothing
	call SetUnitPathing(u, A)
endfunction

...
call GivePathing(unit, false)
...
Старый 30.04.2012, 12:30
Закрытая тема

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 17:41.