Добавлен
Я изучаю jass и попробовал написать простой огненный шар, который летит и наносит всем на пути урон. Шар у меня летит нормально а с нанесением урона у меня возникают трудности. Конкретно с функцией GetEnumUnitsInRange(). Как правильно передавать через нее все локальные переменные?
globals
    group FGroup = CreateGroup()
    location array Point
    unit array temp
endglobals
  
function Trigger_SpellFireball_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()  
    local location point1 = GetUnitLoc(u)
    local location point2 = GetSpellTargetLoc()
    local unit fireball = CreateUnitAtLoc(GetTriggerPlayer(), 'h021', point1, 0)
    local integer cv = GetUnitUserData(fireball) // У меня стоит система Unit Indexer
  
    call SetUnitAnimationByIndex(u, 3)
    set Point[cv] = point2
    set temp[cv] = fireball
    call GroupAddUnit(FGroup, fireball)
  
    set u = null
    set point1 = null
    set point2 = null
    set fireball = null
endfunction

function Trigger_SpellFireball_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A02P'
endfunction
//===========================================================================
function InitTrig_SpellFireball takes nothing returns nothing
    set gg_trg_SpellFireball = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_SpellFireball, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_SpellFireball , Condition(function Trigger_SpellFireball_Conditions))
    call TriggerAddAction( gg_trg_SpellFireball, function Trigger_SpellFireball_Actions )
endfunction
function F_damager takes nothing returns nothing

//call UnitDamageTarget(??, GetFilterUnit(), 50, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)

// как сюда передать кастера и цели? как не надамажить союзных юнитов?

endfunction

function F_Callback takes nothing returns nothing
    local integer cv = GetUnitUserData(GetEnumUnit())
    local group damagegroup = CreateGroup()
    local location point1 = GetUnitLoc(GetEnumUnit())
    local location point2 = Point[cv]
    local real facing = AngleBetweenPoints(point1, point2)
    local real x = GetLocationX(point1) + 20 * Cos(facing * bj_DEGTORAD)
    local real y = GetLocationY(point1) + 20 * Sin(facing * bj_DEGTORAD)
  
  
  
    if DistanceBetweenPoints(point1, point2) > 20 then
    call SetUnitPosition(GetEnumUnit(), x, y)
    call DestroyEffect(AddSpecialEffectLoc("Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl",point1))
    call GroupEnumUnitsInRange(damagegroup, x,y, 250, Filter(function F_damager))
    call GroupClear(damagegroup)
    else
    call KillUnit(GetEnumUnit())
    call GroupRemoveUnit(FGroup, GetEnumUnit())
    call GroupClear(damagegroup)
    endif
  
endfunction

function Trig_SpellFireballMover_Actions takes nothing returns nothing
    call ForGroup(FGroup, function F_Callback)
endfunction

//===========================================================================
function InitTrig_SpellFireballMover takes nothing returns nothing
    set gg_trg_SpellFireballMover = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_SpellFireballMover, 0.03 )
    call TriggerAddAction( gg_trg_SpellFireballMover, function Trig_SpellFireballMover_Actions )
endfunction
 
Как это заставить работать? Может нужно использовать struct'ы? если да то как это должно выглядеть

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

если да то как это должно выглядеть
Посмотрите в этой наработке, там структуры с хэштаблицами а таймерами.
Не используйте точки
local location point1 = GetUnitLoc(u)
local location point2 = GetSpellTargetLoc()
// Где RemoveLocation() ?
Лучше координаты
local real casterX = GetUnitX(caster)
local real casterY = GetUnitY(caster)
local real targetX = GetSpellTargetX()
local real targetY = GetSpellTargetY()

Или переходите на lua, там всё в разы проще))
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
29
5 лет назад
0
если да то как это должно выглядеть
Посмотрите в этой наработке, там структуры с хэштаблицами а таймерами.
Не используйте точки
local location point1 = GetUnitLoc(u)
local location point2 = GetSpellTargetLoc()
// Где RemoveLocation() ?
Лучше координаты
local real casterX = GetUnitX(caster)
local real casterY = GetUnitY(caster)
local real targetX = GetSpellTargetX()
local real targetY = GetSpellTargetY()

Или переходите на lua, там всё в разы проще))
Принятый ответ
0
4
5 лет назад
Отредактирован Roflan
0
Не могу прочесть, сложный для меня код :(
Мне нужно перенести всех юнитов и точки через call GroupEnumUnitsInRange(), но функция к которой он ссылается реагирует только на GetEnumUnit()
в итоге получается ерунда
UnitDamageTarget(??, GetEnumUnit(), 50
0
29
5 лет назад
0
Roflan, без хэштаблиц или структур у вас всёравно MUI не получится, а так можете через глобалки перебросить. Но лучше ненужно.
0
32
5 лет назад
0
Roflan, переходи сразу на луа, пока ещё Jass не затуманил тебе мозг своей кривостью (как мне),
а как перейти?
Качаешь 131 PTR
Качаешь VS code (инфа у меня в профиле)
Смотришь наработки NazarPunk, учишься по ним
3
29
5 лет назад
3
Смотришь наработки NazarPunk, учишься по ним
Фаербол на lua очень просто реализуется, если нужно могу вечером опубликовать.
0
4
5 лет назад
0
Фаербол на lua очень просто реализуется, если нужно могу вечером опубликовать.
Было бы здорово, я посмотрю
0
28
5 лет назад
0
Но лучше ненужно.
Можно, ведь код выполняется линейно, потому проблем не будет. На этом основан весь vJass.
Roflan, передаёшь глобалками просто. В фильтре делаешь проверки, наносишь урон и возвращаешь false, тогда и группу чистить не надо.
0
29
5 лет назад
0
PT153, на каждый фаербол нужно хранить группу, чтоб повторно не дамажить юнитов, как её хранить в глобалках? хэштаблицы конечно идеально подойдут.
0
28
5 лет назад
Отредактирован PT153
0
как её хранить в глобалках?
У него же indexer, глобальный массив групп (как в структурах). Или хештаблицы, как ты уже сказал.
Вообще, я имел в виду, передачу значений в фильтр, то есть вот так.
// В теле функции
set t_Ball = GetEnumUnit()
set t_Owner = GetOwningPlayer(t_Ball)
call GroupEnumUnitsInRange(ProxyGroup, x,y, 250, filter)

// Фильтр
if IsUnitEnemy(GetFilterUnit(), t_Owner) then
    call UnitDamageTarget(t_Ball, GetFilterUnit(), 50, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endif
return false
0
24
5 лет назад
0
PT153, главное не забывать отслеживать случаи когда нанесение урона другое событие вызовет в процессе перебора иначе можно на бесконечный цикл и краш или просто на перезапись глобальных переменных нарваться ...
0
28
5 лет назад
0
prog, безусловно, потому лучше будет даже сделать без фильтра, а в цикле.
0
29
5 лет назад
0
У него же indexer
Два фаербола от одного юнита и привет перезапись переменной. Нужно в хэштаблице на id таймера все данные сохранять.
0
28
5 лет назад
0
привет перезапись переменной
Зависит от того, что индексировать. Как я понял по F_Callback, каждый файербол имеет свой индекс.
0
24
5 лет назад
Отредактирован prog
0
PT153,
Я про перезапись глобалок t_Ball и t_Owner из твоего примера, если они еще где-то используются в месте, которое может быть вызвано через реакцию на нанесение урона. Случай довольно редкий, но случается рано или поздно, если не учитывать такую возможность и бездумно использовать одни и те же глобалки в нескольких системах.

Лучше, конечно, переходить на Lua.
0
4
5 лет назад
Отредактирован Roflan
0
>Два фаербола от одного юнита и привет перезапись переменной. Нужно в хэштаблице на id таймера все данные сохранять.
Как оформить на id таймера кастера и всех целей в группе? как это в хэш таблицу записать
передаёшь глобалками просто. В фильтре делаешь проверки, наносишь урон и возвращаешь false, тогда и группу чистить не надо.
Я пытался передать глобалками, но тогда второй запущенный фаербол запретит первому наносить урон. Триггер же каждые 0.03 секунды обновляет все локалки, а эти локалки уже сохраняют перезаписанные глобалки.
1
28
5 лет назад
1
prog, именно по этому для каждого фильтра у меня свои глобалки (как правило, приватные статичные поля в структуре).
Roflan:
второй запущенный фаербол запретит первому наносить урон
Не совсем понимаю, как. Как я вижу ситуацию: есть группа фаерболов, каждые X секунд я их двигаю. Передвижение и нанесение урона происходит в коллбеке функции ForGroup. Сначала всё сделается для 1-го фаербола, потом для второго и так далее. Таким образом, передвижение и нанесение урона для каждого фаербола не пересекаются, то есть передача глобалками будет работать.
0
4
5 лет назад
0
Да, это я напутал.
Записал кастера в глобалку и сохранил локально в F_damager. Все сработало, спасибо.
0
29
5 лет назад
0
Сделал почти фаербол на lua.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.