Написал триггер. Должен работать так: юнит, что жмёт способность "A001", наносит 100 урона ближайшему перед собой юниту в регионе, что находится на расстоянии 100 единиц(центр региона) от кастера и радиусом 100 единиц. Обратите внимание на function GetDistanceUnitPoints takes unit 1, real x, real y returns real. Так как я не понял, правильно ли я экспортировал эту функцию. И не понял, как именно это надо было делать.
Ошибок редактор не выдаёт, просто жму эту абилку и урон не наносится... Помогите!
globals

    real X
    real Y
    unit ClosestUnit
    real Distance

endglobals

function GetDistanceUnitPoints takes unit u1, real x, real y returns real
    local real dx = GetUnitX(u1) - x
    local real dy = GetUnitY(u1) - y
    return SquareRoot(dx * dx + dy * dy)
endfunction

function FindClosestToXYCallback takes nothing returns nothing
    local real d = GetDistanceUnitPoints(GetEnumUnit(), X, Y)
    if ( d < Distance ) then
        set Distance = d
        set ClosestUnit = GetEnumUnit()
    endif
    
endfunction


function FindClosestToXY takes group attackingUnits, real attackerX, real attackerY returns unit
    set X = attackerX
    set Y = attackerY
    set ClosestUnit = null
    set Distance = 9999999
    call ForGroup(attackingUnits, function FindClosestToXYCallback)
    return ClosestUnit
endfunction

function Trig_Hit_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A001' 
endfunction

//function FindClosestToXY takes group attackingUnits, real attackerX, real attackerY returns unit
    
//endfunction


function Trig_Hit_Actions takes nothing returns nothing

    local     unit attacker = GetTriggerUnit()
    local     real attackerX = GetUnitX(attacker)
    local     real attackerY = GetUnitY(attacker)
    local     real angle = GetUnitFacing(attacker)*bj_DEGTORAD
    local location LocForSum = Location(attackerX + 100*(Cos(angle)), attackerY + 100*(Sin(angle)))
    local group attackingUnits = GetUnitsInRangeOfLocMatching(100,LocForSum, null)
    
   // call SelectGroupForPlayerBJ( attackingUnits, GetOwningPlayer(attacker))
    local real HP = GetUnitState(ClosestUnit, UNIT_STATE_LIFE)
    call SetUnitState(ClosestUnit, UNIT_STATE_LIFE,  HP - 100.00 )
endfunction

//===========================================================================
function InitTrig_Hit takes nothing returns nothing
    set gg_trg_Hit = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Hit, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Hit, Condition( function Trig_Hit_Conditions ) )
    call TriggerAddAction( gg_trg_Hit, function Trig_Hit_Actions )
    
endfunction

Принятый ответ

function PolarProjectionX takes real x, real dist, real angle returns real
    return x + dist * Cos(angle * bj_DEGTORAD)
endfunction

function PolarProjectionY takes real y, real dist, real angle returns real
    return y + dist * Sin(angle * bj_DEGTORAD)
endfunction

function Trig_Hit_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local real face = GetUnitFacing(caster)
    local real x = PolarProjectionX(GetUnitX(caster), 100., face)
    local real y = PolarProjectionY(GetUnitY(caster), 100., face)
    local group targets = CreateGroup()
    local unit target
    call GroupEnumUnitsInRange(targets, x, y, 100., null)
    set target = FindClosestToXY(targets, x, y)
    if target != null then
        call UnitDamageTargetBJ(caster, target, 100., ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL)
        set target = null
    endif
    set caster = null
    call DestroyGroup(targets)
    set targets = null
endfunction
DopaMine, у тебя нет вызова FindClosestUnitXY.
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
28
5 лет назад
0
Так ты функцию нахождения юнита не вызвал.
Ты не наносишь урон, а отнимаешь здоровье, килл твоему кастеру не засчитается.
0
11
5 лет назад
0
Так ты функцию нахождения юнита не вызвал.
Юнита-кастера? А где её надо вызвать? Я совсем запутался(
PT153:
Ты не наносишь урон, а отнимаешь здоровье, килл твоему кастеру не засчитается.
А как именно урон нанести?(
0
28
5 лет назад
Отредактирован PT153
0
function PolarProjectionX takes real x, real dist, real angle returns real
    return x + dist * Cos(angle * bj_DEGTORAD)
endfunction

function PolarProjectionY takes real y, real dist, real angle returns real
    return y + dist * Sin(angle * bj_DEGTORAD)
endfunction

function Trig_Hit_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local real face = GetUnitFacing(caster)
    local real x = PolarProjectionX(GetUnitX(caster), 100., face)
    local real y = PolarProjectionY(GetUnitY(caster), 100., face)
    local group targets = CreateGroup()
    local unit target
    call GroupEnumUnitsInRange(targets, x, y, 100., null)
    set target = FindClosestToXY(targets, x, y)
    if target != null then
        call UnitDamageTargetBJ(caster, target, 100., ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL)
        set target = null
    endif
    set caster = null
    call DestroyGroup(targets)
    set targets = null
endfunction
DopaMine, у тебя нет вызова FindClosestUnitXY.
Принятый ответ
0
11
5 лет назад
0
function GetDistanceUnitPoints takes unit u1, real x, real y returns real
    local real dx = GetUnitX(u1) - x
    local real dy = GetUnitY(u1) - y
    return SquareRoot(dx * dx + dy * dy)
endfunction
Я хотя бы правильно понял, что такая функция должна получать абстрактные параметры, а не конкретно мои значения?
0
28
5 лет назад
0
DopaMine, конечно. Ты должен их передать.
0
11
5 лет назад
0
PT153:
DopaMine, конечно. Ты должен их передать.
Надо же, не знал, что так можно. Чисто твоё себе вставил - всё заработало... Спасибо! Щас буду разбираться, как это работает.
У меня когда врагов нету, юнит себя бьёт АХАХ, так как радиус с расстоянием совпадает, если я на бегу жму, себя иногда задевает)))))))
0
28
5 лет назад
0
DopaMine, добавь проверку, что target != caster.
    if target != null and target != caster then
        call UnitDamageTargetBJ(caster, target, 100., ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL)
    endif
    set target = null
0
26
5 лет назад
Отредактирован Hate
0
в первую очередь проверяйте так xgm.guru/p/wc3/debugging
сразу придет осознание как что работает
0
11
5 лет назад
0
добавь проверку, что target != caster.
Супер!
1
28
5 лет назад
1
Hate, он не понимает, как вообще функции работают, а ты тут про дебаггинг.
0
32
5 лет назад
0
Лучше уж сразу фильтр в группу, чтобы отделить всех кого дамажить ненужно.
0
28
5 лет назад
Отредактирован PT153
0
quq_CCCP, а вот верно.
globals
...
    unit Caster
endglobals

function TakeUnitsFilter takes nothing returns boolean
    return GetFilterUnit() != Caster and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster))
endfunction

...

    set Caster = caster
    call GroupEnumUnitsInRange(targets, x, y, 100., Filter(function TakeUnitsFilter))
    set target = FindClosestToXY(targets, x, y)
    if target != null then
        call UnitDamageTargetBJ(caster, target, 100., ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL)
        set target = null
    endif
0
24
5 лет назад
0
Не помню надо ли отсеивать скрытых или перебор по области сам их игнорирует, но мертвых же точно надо отсеивать.
1
11
5 лет назад
1
PT153:
Hate, он не понимает, как вообще функции работают, а ты тут про дебаггинг.
Во-первых, я не знал про то, что к функции можно обращаться, как к методам в известных мне языках программирования.
Во-вторых, дебаггинг я делал точно так же, как в инструкции, когда хотел понять, почему у меня выбирается область не перед юнитом. Выводил сообщения на экран, чтоб понять, правильно ли я угол добавляю в синус и косинус. Выяснилось, что тригонометрические операции принимают аргументы в радианах. Я не знал про это.(Обычно я встречался с Cos(90),Sin(45) и т.д.
В-третьих, каждый когда-то не знал всех возможностей работы функций, так что это норма)
PT153:
function TakeUnitsFilter takes nothing returns boolean
return GetFilterUnit() != Caster and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster))
endfunction
Я вижу, фильтр работает для набора юнитов в группу. Я собираюсь одной абилкой доджить этот скилл, поэтому мне нужно, чтоб спрятанных можно было добавить в группу, но нельзя было наносить им урон. По дефолту спрятанные домажатся?
prog:
Не помню надо ли отсеивать скрытых или перебор по области сам их игнорирует, но мертвых же точно надо отсеивать.
Это я сделал, спасибо) и спрятанных не дамажит теперь. Что за прикол с событием "ADD_PLAYER_HERO_SKILL"? В триггерах это - Юнит получает способность. Почему я в условиях не могу обратиться к полученной способности? Даже на Jass'e
То есть, мне надо условие: return полученная способность == 'A002'
DopaMine:
Не помню надо ли отсеивать скрытых или перебор по области сам их игнорирует, но мертвых же точно надо отсеивать.
Сделал не без помощи ребят с этого сайта, конечно))
1
28
5 лет назад
Отредактирован PT153
1
return полученная способность
Это событие относится к героям, когда они увеличивают уровень способности для героев.
Тебе нужна функция GetLearnedSkill().
0
11
5 лет назад
0
Тебе нужна функция GetLearnedSkill().
Не работает... у меня событие:
call TriggerRegisterAnyUnitEventBJ( gg_trg_CastTrigger, EVENT_PLAYER_HERO_SKILL )
Условие
 return GetLearnedSkill() == 'A002'
В другом триггере написано в деиствиях:
call UnitAddAbility(target, 'A002' )
Способность появляется у юнита, но сообщение, которое должно вывестись(debugging), не выводится(
PT153:
Это событие относится к героям, когда они увеличивают уровень способности для героев.
Плюс, если я даю способность не герою, а мечнику, к примеру, ему подойдёт это событие?
0
26
5 лет назад
0
Это событие относится к героям, когда они увеличивают уровень способности для героев.
0
11
5 лет назад
0
Hate:
Это событие относится к героям, когда они увеличивают уровень способности для героев.
А, а как для любого юнита проверить? Дать предмет?
DopaMine:
Hate:
Это событие относится к героям, когда они увеличивают уровень способности для героев.
А, а как для любого юнита проверить? Дать предмет?
Ну и проверять тоже предмет. Не оч удобно
0
26
5 лет назад
Отредактирован Hate
0
DopaMine:
Hate:
Это событие относится к героям, когда они увеличивают уровень способности для героев.
А, а как для любого юнита проверить? Дать предмет?
DopaMine:
Hate:
Это событие относится к героям, когда они увеличивают уровень способности для героев.
А, а как для любого юнита проверить? Дать предмет?
Ну и проверять тоже предмет. Не оч удобно
зачем вам событие. вы же и так знаете когда вручаете абилку
еще раз
Это событие относится к героям, когда они увеличивают уровень способности для героев.
когда в плюсике оно прокачивается.
0
11
5 лет назад
0
когда в плюсике оно прокачивается.
Понял, так сработало...
Мне нужно вот, что: когда юнит атакован этой абилкой, с ним надо что-то сделать, чтоб в другом триггере через событие я мог обратиться к этому юниту. Я хотел дать ему невидимую способность 'A002'(канал - параменты -изображение убрать галочку). И типо в другом триггере тогда нужно событие: юнит получил способность... Условие - уровень способности 'A002' > 0. Или как-то так
А как кроме способности сделать - пока не понял.
0
26
5 лет назад
Отредактирован Hate
0
и чем не подходят ивент "юнит атакован"?
или ивент "приводит способность в действие", где проверяется цель
или делать проверку в том месте где наносится урон
Чтобы оставить комментарий, пожалуйста, войдите на сайт.