XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
denonlink

offline
Опыт: 1,112
Активность:
Ошибка в функции
Всем привет. Задавал вопрос по функциям - вроде разобрался. Попробовал - все вышло, кроме одной "мелочи"(читал статьи, но так и не понял где ошибка - все по идее прпавильно, но варик-едитор(и JassCraft) выдают ошибку).

Вот код триггера:
Код:
function Trig_Templar_Knight___Inversion_JASS_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A021' ) ) then
        return false
    endif
    return true
endfunction

function Inversion_DCast takes unit c, unit u returns boolean
    return ( IsPlayerAlly(GetTriggerPlayer(), Player(0)) == true )
endfunction

function Inversion_Damage takes unit c, unit u, real d returns nothing
    if IsUnitType(u, UNIT_TYPE_STRUCTURE ) == true then
    else
      if Inversion_DCast( c , u ) then
      else
        call UnitDamageTargetBJ( c, u, ( d * ( GetUnitStateSwap(UNIT_STATE_MAX_LIFE, u) * 1.50 ) ) , ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL )
        call AddSpecialEffectTargetUnitBJ( "overhead", u, "Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdl" )
      endif
    endif
endfunction

function Trig_Templar_Knight___Inversion_JASS_Actions takes nothing returns nothing
    local unit caster
    local real damagefactor
    local integer abl
    local boolean alive = true
    local integer strike = 0
    set caster = GetSpellTargetUnit()
    set abl = GetUnitAbilityLevelSwapped('A021', caster)
    set damagefactor = (R2I(abl) + 4)*0.01
    call PolledWait( 0.50 )
    loop
      call AddSpecialEffectTargetUnitBJ( "overhead", caster, "Abilities\\Spells\\Orc\\Disenchant\\DisenchantSpecialArt.mdl" )
      call ForGroupBJ( GetUnitsInRangeOfLocAll(512, GetUnitLoc(caster)), function Inversion_Damage(caster, GetEnumUnit(), damagefactor)))
      if IsUnitAliveBJ ( caster ) == false then
      set alive = false
      endif
      call PolledWait( 1.00)
      set strike = strike + 1
      exitwhen alive == false
      exitwhen strike == 10
    endloop
endfunction

//===========================================================================
function InitTrig_Templar_Knight___Inversion_JASS takes nothing returns nothing
    set gg_trg_Templar_Knight___Inversion_JASS = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Templar_Knight___Inversion_JASS, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Templar_Knight___Inversion_JASS, Condition( function Trig_Templar_Knight___Inversion_JASS_Conditions ) )
    call TriggerAddAction( gg_trg_Templar_Knight___Inversion_JASS, function Trig_Templar_Knight___Inversion_JASS_Actions )
endfunction


Ошибка в подчеркнутой строке - почему - понять не могу.
Если я ее меняю на:
Код:
call ForGroupBJ( GetUnitsInRangeOfLocAll(512, GetUnitLoc(caster)), function Inversion_Damage)

то есть после функции function Inversion_Damage ничего не ставлю, то ошибок нету, но мое заклинание работать нормально не может. Что делать? Подскажите пожалуйста.
А пытался ставить call вместо function - ошибка тоже.
Старый 29.02.2008, 10:42
Freezen
Тут должен быть бред
offline
Опыт: 2,517
Активность:
Избавляемся от переменных, GetEnumUnit используется внутри функции которую ты вызываешь с ForGroup, для остальных юзай либо глобалки либо буфер, а твоя функция Inversion_Damage должна ничего не принимать в качестве параметров. Попробуй через LHV так будет удобнее и ещё твой код нуждается в оптимизации
Старый 29.02.2008, 14:11
denonlink

offline
Опыт: 1,112
Активность:
А все таки сделать, что эта функция принимала параметры?
Насчет кэша - почитаю мануалы, если что - напишу, а вообще я предаочитаю использовать именно функции.
Старый 29.02.2008, 14:20
adic3x

offline
Опыт: 108,439
Активность:
Код:
function Trig_Templar_Knight___Inversion_JASS_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A021' ) ) then
        return false
    endif
    return true
endfunction

false

Код:
function Trig_Templar_Knight___Inversion_JASS_Conditions takes nothing returns boolean
 return GetSpellAbilityId()==0x41003231
endfunction

true

//=====
тут стока ошибак, что даже незнаю с чего начать, ща попробую вывести что то самое важное)

ADOLF добавил:
call PolledWait - забудь о ней раз и навсегда...
Старый 29.02.2008, 14:30
Freezen
Тут должен быть бред
offline
Опыт: 2,517
Активность:
Код:
return ( IsPlayerAlly(GetTriggerPlayer(), Player(0)) == true )


P.S. меня терзают смутные сомнения, почему не напрямую подставлять в функцию, и не потеряется ли GetTriggerPlayer() т.к. юзается PolledWait
Старый 29.02.2008, 14:34
denonlink

offline
Опыт: 1,112
Активность:
Вот и хорошо :)
Это первое заклинание которое я на джассе сам делаю :)
Игрока запишу в локалку, а вы решите проблему с функцией.
И всем спасибо за подсказки - на ошибках учатся ведь...

Отредактировано denonlink, 29.02.2008 в 15:06.
Старый 29.02.2008, 14:47
J
expert
offline
Опыт: 48,447
Активность:
логика мышления должна быть у тебя такая...
Код:
function Trig_Templar_Knight___Inversion_JASS_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A021'
endfunction

function Trig_Templar_Knight___Inversion_JASS_Actions takes nothing returns nothing
    local unit caster = GetSpellAbilityUnit()
    local player p = GetOwningPlayer(caster)
    local integer abl = GetUnitAbilityLevel(caster, 'A021')
    local real damagefactor = (abl + 4) * 0.01   
    local integer strike = 10
    local group gr = CreateGroup()
    local unit u   
    call TriggerSleepAction(0.5)
    loop
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\Disenchant\\DisenchantSpecialArt.mdl", caster, "overhead"))
        call GroupEnumUnitsInRange (gr, GetUnitX(caster), GetUnitY(caster), 512, null )
        loop
            set u = FirstOfGroup(gr)
            exitwhen u == null    
            if IsUnitEnemy(u, p) and not IsUnitType(u, UNIT_TYPE_STRUCTURE) then 
                call UnitDamageTargetBJ( caster, u, damagefactor * 1.5 * GetUnitState(u, UNIT_STATE_MAX_LIFE), ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL)
                call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdl", u, "overhead"))
            endif
            call GroupRemoveUnit (gr, u)
        endloop
        call TriggerSleepAction(1)
        set strike = strike - 1
        exitwhen strike <= 0 or GetUnitState(caster, UNIT_STATE_LIFE) <= 0
    endloop
    call DestroyGroup(gr)
    set gr = null
endfunction

function InitTrig_Templar_Knight___Inversion_JASS takes nothing returns nothing
    set gg_trg_Templar_Knight___Inversion_JASS = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Templar_Knight___Inversion_JASS, EVENT_PLAYER_UNIT_SPELL_CAST                                       )
    call TriggerAddCondition          ( gg_trg_Templar_Knight___Inversion_JASS, Condition(function Trig_Templar_Knight___Inversion_JASS_Conditions))
    call TriggerAddAction             ( gg_trg_Templar_Knight___Inversion_JASS,           function Trig_Templar_Knight___Inversion_JASS_Actions    )
endfunction

Отредактировано Jon, 29.02.2008 в 15:48.
Старый 29.02.2008, 15:17
denonlink

offline
Опыт: 1,112
Активность:
Jon
Спасибо, буду юзать :)
Если есть у кого еще комментарии - пишите. Вниму и буду учиться :)
Старый 29.02.2008, 15:18
J
expert
offline
Опыт: 48,447
Активность:
я правдо не совсем помню как ведет себя специфект-аттач при тутжем удалении, для обычных спецэффектов он еще остается, если эффекта не будет, то убери удаление, и удаляй в конце интерации.

p.s.
код на содержание ошибок не проверял, писал просто в блокноте, но алгоритм ты должен понять сам

Jon добавил:
советую сравнить каждую функцию в моем и твоем коде, и понять почему надо так...
Старый 29.02.2008, 15:20
adic3x

offline
Опыт: 108,439
Активность:
call TriggerSleepAction(0.5) - об этом тоже жедательно забыть...
Jon, код крайне небезопастный, с большим колвом багов, недумаю что его стоит юзать всерьез

ща попробую таки обьяснить как надо)
Старый 29.02.2008, 15:22
denonlink

offline
Опыт: 1,112
Активность:
Объясняйте :)
Принципы я пойму - я раньше программировал, так что можете объяснять "по научному" :)
Старый 29.02.2008, 15:24
J
expert
offline
Опыт: 48,447
Активность:
Цитата:
call TriggerSleepAction(0.5) - об этом тоже жедательно забыть...

если ты хочеш заменить это таймером и обьеснить автору как это работает милости прошу, у меня же время не резиновое

Jon добавил:
Цитата:
Jon, код крайне небезопастный, с большим колвом багов, недумаю что его стоит юзать всерьез

мысли в слух?
алгоритм кода нормальный, единственое что можно сделать это убрать слип, сделать общую глобальную группу и заменить 'A021' на 0x41003231 ^^

нет, действительно, я не понимаю что ты нашел в нем не безопасного? если ты имел ввиду только слип, то я вполне уверен что в рамках даного вопроса слип допустим.

Jon добавил:
p.s.
если ты выложиш код для ген пака с кучей глабалками и лишней оптимизацией то сразу говорю, лучше не делай этого, а то поднимеш мне настроение)

Jon добавил:
denonlink но ты всеже бы протестил код, если там есть какието ошибки говори, единственое что в коде правельно 100% это только алгоритм, потому я неуверен скомпилится ли он или нет...

Отредактировано Jon, 29.02.2008 в 15:33.
Старый 29.02.2008, 15:40
adic3x

offline
Опыт: 108,439
Активность:
действительно слип - совершенно непоходящая функция

http://xgm.guru/articles.php?section=wc3&name=rates_on_spellmaking

тут описанна работа с таймером... конечно достаточно корява, однако)

для написания спела мной, я должен использовать кучу систем, хотя бы тот же механизм запуска, массивы для хранения инфы и ХАТ для аттачей)

теперь что до кода:
1) цикл и слип - не решение проблемы
2) с группами афтор работать неумеет вообще (правильно создать одну группу на карту и фильтром все делать)
3) афтор не обнуляет локальные переменные, что же, поздравим его с кучей утечек

ADOLF добавил:
многие локалки - абуз, к примеру уровень абилы используеться только в одном месте, зачем?
Старый 29.02.2008, 15:50
J
expert
offline
Опыт: 48,447
Активность:
  1. ну это и правдо, denonlink попрактикуйся с группами, а также с фильтрами, почитай про них статьи, т.к. ты используеш их опсолютно неправельно, ну и насчет глобальной группы я тоже сказал...
  2. поправка, у него только одна хендл локалка, это кастер, ее обнулять не нужно, проблема у другом, то что обьекты не удаляются...
Насчет многих локалох это ладно... но как замечание пойдет, даже я не удалил, както не заметил, но это ладно...

Отредактировано Jon, 29.02.2008 в 16:45.
Старый 29.02.2008, 15:56
adic3x

offline
Опыт: 108,439
Активность:
Цитата:
ее обнулять не нужно

надо... с чего ты вдруг такое решил? грубо говоря у вара есть особый счетчик, в скольки переменных содержиться юнит (в нашем случае) и когда таких ссылок 0 и юнит реально удален хендл высвобождаеться. ясно что если локалки не обнулять ты этот счетчик будет абузиться

Отредактировано ADOLF, 29.02.2008 в 16:39.
Старый 29.02.2008, 16:19
df Hunter
Нападатель
offline
Опыт: 5,749
Активность:
Цитата:
он вредит тогда когда карта делается полностью на джазе, с использованием кучи систем и кучи извращений, в которых лишний слип это уже котастрофа...

стена
вообще посоветую автору поменьше слушать Jon'a
излишний идиотизм и срач удалил
для ожидания юзать таймер однозначно, хотя бы потому, что TriggerSleepAction aka wait ждёт не то время, которое ты указываешь, ну а на самом деле вейт не совсем ждёт
Старый 29.02.2008, 16:29
J
expert
offline
Опыт: 48,447
Активность:
я это уже проверял, если обнулять хендл локалки в которых просто обьект осуществляет промежуточную стадию (не удаляется не создается а просто посредством) то их обнулять не обезательно, если опровергнеш это то пошли мне карту в приват я посмотрю... вообщем ладно.. вопрос по мне не очень значителен... я не ошибусь если предположу что у автора темы в его карте доуя утечек и в других функцих, если в этой используем слип или лишню локалку не обнулим то большой котострофы не будет... в любом случае на вопрос уже ответили, denonlink ты как? скажеш норм получилось или нет?

Отредактировано Jon, 29.02.2008 в 16:59.
Старый 29.02.2008, 16:31
denonlink

offline
Опыт: 1,112
Активность:
я на работе - варик дома. буду дома проверять - я темя сохраняю. и на флешке домой везу.
это скилл - суть: когда герой его юзает - все вокруг в течении 10 секунд каждую секунду демажатся на процент от их максимальной жизни, причем естественно что с каждым уровнем на больший.
в понедельник отпишусь о результатах.
эта карта для моего проекта, который я задумал очень серьезным, но до сих пор все делал на триггерах. джасс только начал изучать так что не бейте - это первая серьезная попытка вообще что либо на джассе сделать, я и не думал что с первого раза все так получится.
Старый 29.02.2008, 17:46
denonlink

offline
Опыт: 1,112
Активность:
скрипт Jon'a заработал отлично :)
Старый 01.03.2008, 16:42
adic3x

offline
Опыт: 108,439
Активность:
Цитата:
скрипт Jon'a заработал отлично :)

false
поставь для начала игру на паузу после каста...
+
я давал линк на статью где рассказывается как юзать таймеры
Старый 02.03.2008, 17:13
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 02:06.