В теории когда крип юзает способность, то на всех вражеских героев вокруг него должны создаваться дамми юниты, которые пускают артиллерийский снаряд который летит в точку героя. Прикол в том, что все дамми юниты почему-то атакуют область только одного героя. Не могу понять почему.
Код триггера
function SpellGroupForCreepConditionEnemy takes nothing returns boolean
    return (IsPlayerEnemy(GetOwningPlayer(GetTriggerUnit()), GetOwningPlayer(GetFilterUnit()))==true)
endfunction

function SpellGolemFireStone takes nothing returns nothing
    local real f = bj_RADTODEG * Atan2(GetLocationY(GetUnitLoc(GetEnumUnit())) - GetLocationY(GetUnitLoc(GetTriggerUnit())), GetLocationX(GetUnitLoc(GetEnumUnit())) - GetLocationX(GetUnitLoc(GetTriggerUnit())))
    local unit u = CreateUnit(GetOwningPlayer(GetTriggerUnit()), 'e004', GetLocationX(GetUnitLoc(GetTriggerUnit())), GetLocationY(GetUnitLoc(GetTriggerUnit())), f)
    call IssuePointOrderLoc(u, "attackground", GetUnitLoc(GetEnumUnit()))
    call UnitApplyTimedLife (u, 'BTLF', 3)
    set u = null
    set f = 0
endfunction

function CreepSpellActions takes nothing returns nothing
local unit TriggerUnit = GetTriggerUnit()
local location LocationTriggerUnit = GetUnitLoc(GetTriggerUnit())
local real LocationTriggerUnitX = GetLocationX(LocationTriggerUnit)
local real LocationTriggerUnitY = GetLocationY(LocationTriggerUnit)
local group SpellGroup = CreateGroup()
if (GetUnitUserData(GetTriggerUnit()) == 1 and GetSpellAbilityId() == 'A002') then
    call GroupEnumUnitsInRangeOfLoc(SpellGroup, LocationTriggerUnit, 1500, function SpellGolemFireStone)
    call ForGroup(SpellGroup,function SpellGolemFireStone)
    call DestroyBoolExpr(function SpellGroupForCreepConditionEnemy)
endif
set TriggerUnit = null
set LocationTriggerUnit = null
set LocationTriggerUnitX = 0
set LocationTriggerUnitY = 0
set SpellGroup = null
endfunction

//===========================================================================
function InitTrig_CreepSpell takes nothing returns nothing
    set gg_trg_CreepSpell = CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(gg_trg_CreepSpell, Player(10), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    call TriggerAddAction( gg_trg_CreepSpell, function CreepSpellActions )
endfunction

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

Вместо
function InitTrig_CreepSpell takes nothing returns nothing
    set gg_trg_CreepSpell = CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(gg_trg_CreepSpell, Player(1), EVENT_PLAYER_UNIT_SPELL_EFFECT, function CreepSpellFilter) 
    call TriggerAddAction(gg_trg_CreepSpell, function CreepSpellActivation)
endfunction
сделай так:
function InitTrig_CreepSpell takes nothing returns nothing
    set gg_trg_CreepSpell = CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(gg_trg_CreepSpell, Player(1), EVENT_PLAYER_UNIT_SPELL_EFFECT, null) //function CreepSpellFilter
    call TriggerAddCondition(gg_trg_CreepSpell, Condition(function CreepSpellFilter))
    call TriggerAddAction(gg_trg_CreepSpell, function CreepSpellActivation)
endfunction
и вот здесь:
if IsUnitEnemy(GetFilterUnit(), Player(10)) then
        set Dummy = CreateUnit(Player(1), 'e004', CasterX, CasterY, bj_RADTODEG*Atan2(TargetY - CasterY, TargetX - CasterX))
		call IssuePointOrder(Dummy, "attackground", TargetX, TargetY)
        call UnitApplyTimedLife(Dummy, 'BTLF', 3)
        set Dummy = null
    endif
поменяй местами IssuePointOrder и UnitApplyTimedLife, чтобы было вот так:
    if IsUnitEnemy(GetFilterUnit(), Player(10)) then
        set Dummy = CreateUnit(Player(1), 'e004', CasterX, CasterY, bj_RADTODEG*Atan2(TargetY - CasterY, TargetX - CasterX))
        call UnitApplyTimedLife(Dummy, 'BTLF', 3)
        call IssuePointOrder(Dummy, "attackground", TargetX, TargetY)
        set Dummy = null
    endif
Этот комментарий удален
2
12
7 лет назад
2
А там вылетает один или несколько снарядов?
0
13
7 лет назад
0
Толком не понял что ты написал...
Но суть уловил, они у тебя они стреляют в первого добавленого групу героя. Поэтому удаляй героя из группы после выстрела по нему
0
11
7 лет назад
0
Пробовал делать так: создавал цикл, который повторялся ровно столько раз, сколько юнитов в группе. Делал нужные действия для первого юнита в группе, потом удалял его из группы, и так пока все юниты не пройдут. Все равно вылетает в одного.
0
13
7 лет назад
0
Выводи сообщения с именем цели, немного прояснит картину почему так происходит. И на любые подозрения выводи сообщения, имя юнита, цели, число цыклов.... быстрее найтешь ответ чем тут.
Я не заметил в условиях выбор героя, только враги, стоило б проверить.
0
27
7 лет назад
Отредактирован MpW
0
Проверяй дебагом.
раскрыть
Кстати, то что написал в коде работает?
  1. ты в в качестве фильтра написал функцию SpellGolemFireStone, короче вставил в функцию GroupEnumUnitsInRangeOfLoc. Исправь на SpellGroupForCreepConditionEnemy.
  2. Зачем ты ее удаляешь фильтр? во-первых, нужно было в переменную засунуть, и потом удалить. а так бесполезно создаешь. во-вторых, она не утекает, и удалять не нужно.
  3. Используй глобалку вместо GetTriggerUnit() в функции SpellGroupForCreepConditionEnemy (использую для переноса в фильтр, так как надежнее).
  4. ну и точки. неудобно же. взял бы функции GetUnitX и GetUnitY, GroupEnumUnitsInRange, IssuePointOrder

  1. Потом проверяй кол-во пикнутых юнитов в группу. Может быть фильтр не работает и прочее.
  2. Если группа норм выделяет, проверяй SpellGolemFireStone, почему не работает. Там приказы не может юзнуть или что-то еще. Может быть дело в самих даймиках, там радиус у них маленький, и им нужно подбежать ближе, а они не могут так как скорость движения на нуле и др
0
30
7 лет назад
0
Код
function CreepSpellActions takes nothing returns boolean
    local unit Dummy = null
    local real CasterX = GetUnitX(GetTriggerUnit())
    local real CasterY = GetUnitY(GetTriggerUnit())
    local real TargetX = GetUnitX(GetFilterUnit())
    local real TargetY = GetUnitY(GetFilterUnit())
    if IsUnitEnemy(GetFilterUnit(), Player(10)) then
        set Dummy = CreateUnit(Player(10), 'e004', CasterX, CasterY, bj_RADTODEG*Atan2(TargetY - CasterY, TargetX - CasterX))
        call IssuePointOrder(Dummy, "attackground", TargetX, TargetY)
        call UnitApplyTimedLife(Dummy, 'BTLF', 3)
        set Dummy = null
    endif
    return false
endfunction

function CreepSpellActivation takes nothing returns nothing
    local group TempGroup = CreateGroup()
    local real CasterX = GetUnitX(GetTriggerUnit())
    local real CasterY = GetUnitY(GetTriggerUnit())
    call GroupEnumUnitsInRange(TempGroup, CasterX, CasterY, 1500, function CreepSpellActions)
    call DestroyGroup(TempGroup)
    set TempGroup = null
endfunction

function CreepSpellFilter takes nothing returns boolean
    return GetUnitUserData(GetTriggerUnit()) == 1 and GetSpellAbilityId() == 'A002'
endfunction

function InitTrig_CreepSpell takes nothing returns nothing
    set gg_trg_CreepSpell = CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(gg_trg_CreepSpell, Player(10), EVENT_PLAYER_UNIT_SPELL_EFFECT, function CreepSpellFilter)
    call TriggerAddAction(gg_trg_CreepSpell, function CreepSpellActivation)
endfunction
Специально везде разжевал и ввёл переменные с нормальными названиями. Если бы их вводил и нормально называл самостоятельно, вопроса даже не возникло бы.
0
11
7 лет назад
0
Вот карта с твоим триггером. Не работает. Думаю здесь есть мои ошибки.
Загруженные файлы
2
12
7 лет назад
2
Вместо
function InitTrig_CreepSpell takes nothing returns nothing
    set gg_trg_CreepSpell = CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(gg_trg_CreepSpell, Player(1), EVENT_PLAYER_UNIT_SPELL_EFFECT, function CreepSpellFilter) 
    call TriggerAddAction(gg_trg_CreepSpell, function CreepSpellActivation)
endfunction
сделай так:
function InitTrig_CreepSpell takes nothing returns nothing
    set gg_trg_CreepSpell = CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(gg_trg_CreepSpell, Player(1), EVENT_PLAYER_UNIT_SPELL_EFFECT, null) //function CreepSpellFilter
    call TriggerAddCondition(gg_trg_CreepSpell, Condition(function CreepSpellFilter))
    call TriggerAddAction(gg_trg_CreepSpell, function CreepSpellActivation)
endfunction
и вот здесь:
if IsUnitEnemy(GetFilterUnit(), Player(10)) then
        set Dummy = CreateUnit(Player(1), 'e004', CasterX, CasterY, bj_RADTODEG*Atan2(TargetY - CasterY, TargetX - CasterX))
		call IssuePointOrder(Dummy, "attackground", TargetX, TargetY)
        call UnitApplyTimedLife(Dummy, 'BTLF', 3)
        set Dummy = null
    endif
поменяй местами IssuePointOrder и UnitApplyTimedLife, чтобы было вот так:
    if IsUnitEnemy(GetFilterUnit(), Player(10)) then
        set Dummy = CreateUnit(Player(1), 'e004', CasterX, CasterY, bj_RADTODEG*Atan2(TargetY - CasterY, TargetX - CasterX))
        call UnitApplyTimedLife(Dummy, 'BTLF', 3)
        call IssuePointOrder(Dummy, "attackground", TargetX, TargetY)
        set Dummy = null
    endif
Принятый ответ
0
30
7 лет назад
Отредактирован Clamp
0
Player(1)
Таки везде Player(10), он там роль нейтрала выполняет
0
11
7 лет назад
0
Не важна роль игрока. В триггерах игрок номер 10 это номер 9. Потому что по нормальному нумерация начинается с нуля.
Sergarr, я в шоке. Сделал так, как вы посоветовали и все отлично работает. Можете пожалуйста пояснить, ваш совет. Чтобы я понял в собственно была ошибка. Ваш ответ однозначно будет лучшим.
2
12
7 лет назад
Отредактирован Sergarr
2
Dragonear:
Не важна роль игрока. В триггерах игрок номер 10 это номер 9. Потому что по нормальному нумерация начинается с нуля.
Sergarr, я в шоке. Сделал так, как вы посоветовали и все отлично работает. Можете пожалуйста пояснить, ваш совет. Чтобы я понял в собственно была ошибка. Ваш ответ однозначно будет лучшим.
С первой частью - потому что тогда функция фильтра не работает правильно, в ней GetSpellAbilityId() будет всегда 0 выдавать.
Со вторым - UnitApplyTimedLife(Dummy, 'BTLF', 3) сбивает ранее выданные приказы (почему - черт его знает). Дамми юниты палили в одну цель не по приказу из триггера, а из-за своей собственной авто-атаки.
И да, я не очень удивлен что оно все работает, поскольку я примерно полтора часа эту карту дебажил, и решение выдал после того как все у меня начало работать правильно.
0
11
7 лет назад
0
Спасибо вам большое)
Чтобы оставить комментарий, пожалуйста, войдите на сайт.