Написал триггер. Должен работать так: юнит, что жмёт способность "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
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().
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.