Не получается сделать способность, действующую по линии. Пытаюсь сделать MUI, используя hash. Проблема в функциях условия для GetUnitsInRangeOfLocMatching, где нужно выбрать юнита, являющегося врагом кастера и т.п. Нашел пару ссылок с примерами, но там везде "Файл удален". Может кто-нибудь разместить рабочую ссылку с примером? Спасибо.
На ГУИ я и сам могу. Но тогда будет не мультиспелл.
Добавлено (12 Сентября 2012, 11:43:54) --------------------------------------------- А так мне нужно, чтобы просто урон наносился так же, как и в способности "Волна силы".
Добавлено (12 Сентября 2012, 11:44:28) --------------------------------------------- С остальным там уже проще будет, думаю, что сам разберусь.
пфф. с чего это стиль написания (ГУИ/Джасс) влияет на то МУИ или не МУИ заклинание???
Не влияет, я имею в виду, что не смогу на GUI сделать все компактно без кучи глобальных переменных и без использования массивов. Я предполагаю, что Jass - более короткий способ (может это и не так). А так как последнее время потихоньку учу Jass, мне нужно знать как это будет выглядеть именно на Jass.
Сообщение отредактировал RaiN_S - Среда, 12 Сентября 2012, 16:01:58
мне нужно знать как это будет выглядеть именно на Jass.
Если я понял что тыхочешь, то даешь даммику эффект волны силы, запускаешь его от героя, пикаешь всех юнитов рядом от даммика и наносишь урон, потом после н'ых секунд удаляешь даммика.
function Spell_Expired takes nothing returns nothing local unit f if(LoadInteger(udg_Hash, GetHandleId(GetExpiredTimer()), 3) == SPELL_JUMPS) then call DestroyGroup(LoadGroupHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 2)) call FlushChildHashtable(udg_Hash, GetHandleId(GetExpiredTimer())) call DestroyTimer(GetExpiredTimer()) else call SetUnitPosition(u, GetUnitX(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1)) + 10. * Cos(GetUnitFacing(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1)) * bj_DEGTORAD), GetUnitY(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1)) + 10. * Sin(GetUnitFacing(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1)) * bj_DEGTORAD)) call GroupEnumUnitsInRange(LoadGroupHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 2), GetUnitX(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1)), GetUnitY(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1)), 120., null) call SaveInteger(udg_Hash, GetHandleId(GetExpiredTimer()), 3, LoadInteger(udg_Hash, GetHandleId(GetExpiredTimer()), 3) + 1) loop set f = FirstOfGroup(g) exitwhen f == null if(IsPlayerEnemy(GetOwningPlayer(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1)), GetOwningPlayer(f)) and GetWidgetLife(f) > 0.405 and not IsUnitType(f, UNIT_TYPE_STRUCTURE) and not IsUnitType(f, UNIT_TYPE_FLYING)) then call UnitDamageTarget(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1), f, 500., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null) endif call GroupRemoveUnit(LoadGroupHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 2), f) endloop endif set f = null endfunction
function Spell_Actions takes nothing returns nothing local unit u = CreateUnit(GetOwningPlayer(GetTriggerUnit()), SPELL_DUMMY, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 0.) local timer t = CreateTimer() call SetUnitPathing(u, false) call SetUnitFacing(u, GetUnitFacing(GetTriggerUnit())) call TimerStart(t, .05, true, function Spell_Expired) call SaveUnitHandle(udg_Hash, GetHandleId(t), 1, u) call SaveGroupHandle(udg_Hash, GetHandleId(t), 2, CreateGroup()) set t = null set u = null endfunction
//=========================================================================== function InitTrig_Spell takes nothing returns nothing local unit u = CreateUnit(Player(0), SPELL_DUMMY, 0., 0., 0.) call UnitAddAbility(u, SPELL_RAWCODE) call RemoveUnit(u) set u = null set gg_trg_Spell = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_Spell, Condition(function Spell_Conditions)) call TriggerAddAction(gg_trg_Spell, function Spell_Actions) endfunction
Писалось на скорую руку, vJass вариант от Hexing P.S. Нужен JNGP P.S.S. Не используй точки, если ты не используеш Z координату это уменьшит нагрузку и повысит быстродействие кода...
Что значит GetWidgetLife(u) > 0.405 ? Я так понял здесь проверяется жив юнит или нет, но что за число 0.405 ? В чем преимущество точек с координатами (x, y) от точек с полярным смещением? В остальном вроде разобрался, только я не через дамми делаю. Сейчас буду пробовать.
Добавлено (12 Сентября 2012, 15:58:50) --------------------------------------------- Еще вопрос: bj_DEGTORAD что это?
количество жизни юнита. Если меньше - значит мёртв.
Добавлено (12 Сентября 2012, 16:00:52) ---------------------------------------------
Quote (RaiN_S)
bj_DEGTORAD что это
degrees to radian
Добавлено (12 Сентября 2012, 16:01:14) --------------------------------------------- градусы
Добавлено (12 Сентября 2012, 16:02:42) --------------------------------------------- преобразование угла в число или числа в угол. Не берусь утверждать.
константа типа real, при умножении на которое, можно преобразовать значение из градусов в радианы. градусы варьируются от 0 до 360, а радианы от 0 до 2Pi(~6.28), SetUnitFacing() берёт градусы как угол, а Sin и Cos - радианы, чем думали это близзарды, один бог ведает
Quote (RaiN_S)
Что значит GetWidgetLife(u) > 0.405 ?
так уж устроен движок, что юнит умирает, когда его здоровье меньше или равно 0.405, а не 0, GetUnitState вернёт 0, но GetWidgetLife работает быстрее
Quote (RaiN_S)
В остальном вроде разобрался, только я не через дамми делаю. Сейчас буду пробовать.
без дамми никак, ты эффект не повернёшь
Добавлено (12 Сентября 2012, 16:11:28) --------------------------------------------- на счёт полярок - там куча утечек(игра начнёт лагать через время), да и это в ряде случае медленнее, хотя в сложных задачах полярки легче для восприятия(разумеется не BJ-шные, а самописные безутечные) ну и тут быстрее использовать 2 реальных, так как угол не меняется(посчитать скорость один раз)
Добавлено (12 Сентября 2012, 16:11:57) --------------------------------------------- [SeKtOR], статусоплагиат
Quote (Hexing)
ну и тут быстрее использовать 2 реальных, так как угол не меняется(посчитать скорость один раз)
Блин. Вроде все нормально сделал, но почему-то урон наносится многократно:
Code
function Trig_A01_Timer takes nothing returns nothing local timer t = GetExpiredTimer() local integer id = GetHandleId(t) local unit caster = LoadUnitHandle( udg_hash, id, 0) local location tarp = LoadLocationHandle( udg_hash, id, 1) local location casp = LoadLocationHandle( udg_hash, id, 2) local location p = tarp local effect e = LoadEffectHandle( udg_hash, id, 3) local integer n = LoadInteger( udg_hash, id, 4) local group gr1 local group gr2 = LoadGroupHandle( udg_hash, id, 5) local unit u call DestroyEffect( e ) if n < 25 then set gr1 = GetUnitsInRangeOfLocAll( 150., tarp) loop set u = FirstOfGroup(gr1) exitwhen(u == null) if(IsUnitEnemy(u, GetOwningPlayer(caster)) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and GetWidgetLife(u) > 0.405 and not IsUnitInGroup(u, gr2)) then call GroupAddUnit(gr2, u) call UnitDamageTargetBJ( caster, u, ( 40.00 + udg_M ), ATTACK_TYPE_HERO, DAMAGE_TYPE_FIRE ) endif call GroupRemoveUnit(gr1, u) endloop call SaveGroupHandle( udg_hash, id, 5, gr2) call AddSpecialEffectLocBJ( tarp, "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl" ) call DestroyEffect( GetLastCreatedEffectBJ() ) set n = n+1 call SaveInteger( udg_hash, id, 4, n) set tarp = PolarProjectionBJ( p, 20.00, AngleBetweenPoints( tarp, casp)) call SaveLocationHandle( udg_hash, id, 1, tarp) call RemoveLocation(p) else call PauseTimer(t) call DestroyTimer(t) call FlushChildHashtable( udg_hash, id) call RemoveLocation(tarp) call RemoveLocation(casp) call GroupClear(gr2 ) endif set t = null set tarp = null set casp = null set caster = null endfunction
Не судите строго, я совсем недавно начал разбираться с Jass.
Сообщение отредактировал RaiN_S - Среда, 12 Сентября 2012, 17:00:42
RaiN_S, используй одну из уже названных наработок, или тебе важно сделать самому? локации(точки) очень медленные, используй x/y, на счёт многократного урона - поменяй условие на n > 25, я вообще не понимаю как твой код работает
локации - зло, за исключением случая когда нужно найти координату Z конкретной точки, используйте координаты насколько я понял часть кода скопирована, часть самодельная-сконвертированная с гуи прочитайте про BJ функции ну и перебор группы циклом - это, конечно, пушка
либо это ирония, либо бесполезное замечание, так как все знают что это лучше так как не нужно лишнее условие, из минусов - возможность переполнения стека
Добавлено (12 Сентября 2012, 17:30:31) --------------------------------------------- RaiN_S, на счёт n я погорячился, и всётаки пиши на основе норм наработки, или уж сам с нуля, ты же даже не понимаешь что тут происходит, не так ли?
локации - зло, за исключением случая когда нужно найти координату Z конкретной точки, используйте координаты
С этим позже разберусь. Сейчас главное, чтобы работало.
Quote (DragoN)
насколько я понял часть кода скопирована
Quote (DragoN)
ну и перебор группы циклом - это, конечно, пушка
Как раз перебор группы циклом и скопировано, а остальное сам лепил.
Quote (DragoN)
часть самодельная-сконвертированная с гуи
Ну отдельными функциями как-бы. Во всех статьях про Jass, которые я читал, написано:"Не знаете как выглядит нужная вам функция на Jass? Делайте в ГУИ и конвертируйте в текст."
Quote (DragoN)
прочитайте про BJ функции
Ок. Разберусь.
Quote (Hexing)
поменяй условие на n > 25
Он так сразу таймер останавливает.
Quote (Hexing)
я вообще не понимаю как твой код работает
Работает, проблема только в том, что урон наносится многократно, хотя юнита из gr1, прошедшего проверку и получившего урон я заношу в gr2 , при этом условие not IsUnitInGroup(u, gr2) прописано. Как это исправить? С остальным потом разберусь.
Добавлено (12 Сентября 2012, 17:42:20) ---------------------------------------------
Quote (Hexing)
даже не понимаешь что тут происходит, не так ли?
Если бы не понимал, не задавал бы конкретный вопрос. Я пытаюсь разобраться в своих ошибках, рано или поздно научусь. Сказал же, не судите строго, я только начал Jass разбирать. Вот весь триггер, если что:
function Trig_A01_Timer takes nothing returns nothing local timer t = GetExpiredTimer() local integer id = GetHandleId(t) local unit caster = LoadUnitHandle( udg_hash, id, 0) local location tarp = LoadLocationHandle( udg_hash, id, 1) local location casp = LoadLocationHandle( udg_hash, id, 2) local location p = tarp local effect e = LoadEffectHandle( udg_hash, id, 3) local integer n = LoadInteger( udg_hash, id, 4) local group gr1 local group gr2 = LoadGroupHandle( udg_hash, id, 5) local unit u call DestroyEffect( e ) if n < 25 then set gr1 = GetUnitsInRangeOfLocAll( 150., tarp) loop set u = FirstOfGroup(gr1) exitwhen(u == null) if(IsUnitEnemy(u, GetOwningPlayer(caster)) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and GetWidgetLife(u) > 0.405 and not IsUnitInGroup(u, gr2)) then call GroupAddUnit(gr2, u) call UnitDamageTargetBJ( caster, u, ( 40.00 + udg_M ), ATTACK_TYPE_HERO, DAMAGE_TYPE_FIRE ) endif call GroupRemoveUnit(gr1, u) endloop call SaveGroupHandle( udg_hash, id, 5, gr2) call AddSpecialEffectLocBJ( tarp, "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl" ) call DestroyEffect( GetLastCreatedEffectBJ() ) set n = n+1 call SaveInteger( udg_hash, id, 4, n) set tarp = PolarProjectionBJ( p, 20.00, AngleBetweenPoints( tarp, casp)) call SaveLocationHandle( udg_hash, id, 1, tarp) call RemoveLocation(p) else call PauseTimer(t) call DestroyTimer(t) call FlushChildHashtable( udg_hash, id) call RemoveLocation(tarp) call RemoveLocation(casp) call GroupClear(gr2 ) endif set t = null set tarp = null set casp = null set caster = null endfunction
function Trig_A01_Actions takes nothing returns nothing local unit caster = GetSpellAbilityUnit() local location p = GetSpellTargetLoc() local location casp = GetUnitLoc(caster) local location tarp = PolarProjectionBJ( casp, 500.00, AngleBetweenPoints( casp, p)) local timer t = CreateTimer() local integer id = GetHandleId(t) local effect e call AddSpecialEffectLocBJ( tarp, "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl" ) call DestroyEffect( GetLastCreatedEffectBJ() ) call AddSpecialEffectLocBJ( tarp, "Doodads\\Cinematic\\Lightningbolt\\Lightningbolt.mdl" ) set e = GetLastCreatedEffectBJ() call SaveUnitHandle( udg_hash, id, 0, caster) call SaveLocationHandle( udg_hash, id, 1, tarp) call SaveLocationHandle( udg_hash, id, 2, casp) call SaveEffectHandle( udg_hash, id, 3, e) call TimerStart(t, 0.04, true, function Trig_A01_Timer) set p = null set casp = null set tarp = null set caster = null call RemoveLocation(p) call RemoveLocation(tarp) call RemoveLocation(casp) endfunction
//=========================================================================== function InitTrig_A01 takes nothing returns nothing set gg_trg_A01 = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_A01, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_A01, Condition( function Trig_A01_Conditions ) ) call TriggerAddAction( gg_trg_A01, function Trig_A01_Actions ) endfunction
Сообщение отредактировал RaiN_S - Среда, 12 Сентября 2012, 17:58:03
либо это ирония, либо бесполезное замечание, так как все знают что это лучше так как не нужно лишнее условие, из минусов - возможность переполнения стека
что из этого получится если накатать аналогичное в гуи??
Добавлено (12 Сентября 2012, 18:39:32) --------------------------------------------- ок, конкретизирую адресата вопроса - SirNikolas, отвечайте. То что гуи медленне это ясно, что именно из перечисленного в теме получится при конвертации гуишного кода? И насколько медленно? Желательно словами описать как проверять зрительно скорость обработки.