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

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

Ответ
 
Igores
НИИ 4А-Во! Кафедра Джасс.
offline
Опыт: 5,325
Активность:
Проблемка со стомп спеллом.
На сайте есть статья, в которой описывается как создать обычный стомп спелл используя кеш. Я создал такой же стомп спелл, но только не через кеш, а через атачи хэндлов, всё получилось нормально. Потом я решил усовершенствовать этот спелл, сделать так чтобы спелл работал в течение 10 секунд, то есть, чтобы всех кто подойдет к герою в течение 10 секунд откидывало назад, даже когда герой просто ходит, для этого просто добавил в код еще один таймер, где каждые пол секунды создается новый таймер для новой группы юнитов, то есть создается еще 20 таймеров, которые конечно каждую секунду самоуничтожаются. Но после добавления начались глюки. В начале спелл вообще перестал работать, но когда я в функции фильтра заменил условия на тру, спелл заработал, но при этом сам герой тоже начал отлетать. Я думаю, что ошибка изза функции copygroup. Есть какие нибудь предположения как исправить эту ошибку?
Старый 19.02.2009, 01:42
agentex

offline
Опыт: 34,834
Активность:
Скорее всего 20 таймеров это лишнее, в 80% случаев для 1 спела хватает 1 таймера. И группы атачить нет смысла, легче каждый раз набирать юнитов в одну. Вообще нужно видеть код и нормальное описание работы спела чтобы как то помочь
Старый 19.02.2009, 01:49
Igores
НИИ 4А-Во! Кафедра Джасс.
offline
Опыт: 5,325
Активность:
Насчет одного таймера согласен, просто для начала решил упростить задачу:) но в чем же косяк? А есть способ как достать приатаченные хэндлы в другой функции?

Igores добавил:
А как мне добавлять в группу новых юнитов? они ведь перепутаются.
Старый 19.02.2009, 01:59
Vampirrr
O_o
offline
Опыт: 19,286
Активность:
Igores, мб герой тоже отлетает потому что он занесен в группу? А добавляй нужных юнитов через
Код:
function ExcluseCaster takes nothing returns boolean
return GetUnitTypeId(GetFilterUnit()) != 'A001' //не равен ID кастера 
endfunction

function Action takes nothing returns nothing
call EnumUnitsInRange(group, x, y, radius, Condition(function ExcluseCaster))
call GroupAddUnit(group, GetEnumUnit())
endfunction

это мой вариант..может есть че получше, но я хз..
Старый 19.02.2009, 03:16
agentex

offline
Опыт: 34,834
Активность:
Цитата:
А как мне добавлять в группу новых юнитов? они ведь перепутаются.

есть функция GroupClear()
Старый 19.02.2009, 09:28
adic3x

offline
Опыт: 108,439
Активность:
Vampirrr, советую ознакомиться с нативками для работы с группами, сейчас ты написал потенциальный бред

собж, нужно создать что то вроде поля вокруг кастера? дык, пикайте всех, и через имба цикл с группами просто двигайте их (т.е. в функции передаваемой в качестве аргумента функции пика юнитов в радиусе перемещайте пикнутого, и возращайте фалсе, группа будет чиста всегда тогда полностью, это более чем удобно и качественно)
Старый 19.02.2009, 12:25
alexkill

offline
Опыт: 18,872
Активность:
Цитата:
Сообщение от Igores
но при этом сам герой тоже начал отлетать. Я думаю, что ошибка изза функции copygroup.


эта функция там не нужна вообще. герой отлетает, потому как в фильтре наверняка не указал:
Код:
GetFilterUnit()!=GetTriggerUnit()

Цитата:
Код:
return GetUnitTypeId(GetFilterUnit()) != 'A001' //не равен ID кастера

что ж вас тянет на всякого рода извращения? =) а как же универсальность?
Старый 19.02.2009, 12:37
Igores
НИИ 4А-Во! Кафедра Джасс.
offline
Опыт: 5,325
Активность:
agentex, если буду постоянно чистить группу, то у меня предыдущие юниты не будут успевать отлетать до конца, просто остановятся на полпути.
ADOLF, не совсем понял тебя, так ты предлагаешь делать действия не с группой, а каждый раз с одним юнитом?
alexkill, а как мне без copygroup делать? Ну вообщето у меня в фильтре делалась проверка на врага, просто он потом с фильтром перестал работать, поэтому я его отключил.
Старый 19.02.2009, 14:46
agentex

offline
Опыт: 34,834
Активность:
Igores ну тогда не чисть а проверяй расстояние от кастера до всех юнитов в группе, если меньше какогото, двигай, если больше, плавно тормози
Старый 19.02.2009, 14:48
alexkill

offline
Опыт: 18,872
Активность:
Обрабатывай GetEnumUnit()'a. То есть аттач на хэндл таймера каждого пикнутого юнита и производи с ним действие (передвигай и т.п.).
Цитата:
если буду постоянно чистить группу, то у меня предыдущие юниты не будут успевать отлетать до конца

будут
Старый 19.02.2009, 14:59
Igores
НИИ 4А-Во! Кафедра Джасс.
offline
Опыт: 5,325
Активность:
alexkill, как мне тогда этих юнитов останавливать? Таймер ведь не затормозишь.
Старый 19.02.2009, 15:21
alexkill

offline
Опыт: 18,872
Активность:
Igores
Аттач также воина, применившего способность. И в условии проверяй расстояние между кастером и GetEnumUnit()'ом.
Старый 19.02.2009, 15:45
Igores
НИИ 4А-Во! Кафедра Джасс.
offline
Опыт: 5,325
Активность:
Ты предлагаешь мне использовать функцию forgroup, тогда я не совсем понял как использовать в ней хэндлы.
Старый 19.02.2009, 15:57
Vampirrr
O_o
offline
Опыт: 19,286
Активность:
ADOLF, хм, а что не так? Этот потенциальны бред (по крайней мере у меня) успешно работает и проблем не вызывает..
Старый 19.02.2009, 17:22
alexkill

offline
Опыт: 18,872
Активность:
Vampirrr
1. Представь ситуацию: 100 героев обладают этой способностью. Мне надо в фильтре проверять все их айдишники? Для этого достаточно в фильтр-функции проверить, не является ли он GetTriggerUnit()'ом.
2. call GroupAddUnit(group, GetEnumUnit()) - бред, причем даже не потенциальный (я тебе не раз исправлял это в кодах). Ты уже объединил воинов в группу в предыдущей строке. Теперь достаточно лишь обратиться к ним через ForGroup() (в каллбек-функции они уже и будут обрабатываться как GetEnumUnit()).

Отредактировано alexkill, 19.02.2009 в 17:52.
Старый 19.02.2009, 17:32
Vampirrr
O_o
offline
Опыт: 19,286
Активность:
alexkill, понял, спасибо)
Старый 19.02.2009, 23:01
Igores
НИИ 4А-Во! Кафедра Джасс.
offline
Опыт: 5,325
Активность:
alexkill, переделал спелл, сделал без групп, добавил динамический триггер, убрал лишние таймеры, всё работает превосходно:) но я так и не понял как в callback функциях forgroupа вызывать нужные хэндлы объектов?:) скоро выложу этот спелл в своей теме.
Старый 20.02.2009, 00:02
alexkill

offline
Опыт: 18,872
Активность:
Igores, я не знаю всех твоих требований к спеллу, вот что сделал я. Каждую секунду в течении 10 секунд враги отбрасыватся. Триггер на отмену способности добавил. Основа - Канал со значением 10 поля "Следовать в течении времени"
» code

Код:
-------// нестанд. код
globals
  constant integer NumberOfPlayers = 10
  trigger array Trigger
  timer array Timer
  real array Real
  real array Z
  unit array Unit
  unit array Target
  integer array Int
endglobals

function H2I takes handle h returns integer
  return h
  return 0
endfunction

function Angle takes real AX, real AY, real BX, real BY returns real
  return bj_RADTODEG * Atan2(BY - AY, BX - AX)
endfunction

Код:
-------// сама способность

function Gr_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000' 
endfunction

function G_Filt takes nothing returns boolean
    local integer h = H2I(GetExpiredTimer())-0x100000
    return GetUnitState(GetFilterUnit(),ConvertUnitState(0))>0 and GetFilterUnit()!=Unit[h] and IsUnitEnemy(GetFilterUnit(),GetOwningPlayer(Unit[h]))
endfunction

function Gr_Endcast takes nothing returns nothing
    local trigger tr = GetTriggeringTrigger()
    local integer htr = H2I(tr)-0x100000
    local integer h = H2I(Timer[htr])-0x100000
    call DestroyTimer(Timer[htr])
    call DestroyTrigger(tr)
    set Unit[h] = null
    set Timer[htr] = null
    set tr = null
endfunction

function GroupMove takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = H2I(t)-0x100000
      if Real[h]>=0 then
        call SetUnitX(Target[h],GetUnitX(Target[h])-20*Cos(Z[h]*0.0175))
        call SetUnitY(Target[h],GetUnitY(Target[h])-20*Sin(Z[h]*0.0175))
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl",Target[h],"origin"))
        set Real[h] = Real[h]-20
      else
        call DestroyTimer(t)
        call PauseUnit(Target[h],false)
        set Target[h] = null
      endif
    set t = null
endfunction

function GroupEnum takes nothing returns nothing
    local timer te = GetExpiredTimer() 
    local integer he = H2I(te)-0x100000
    local timer t = CreateTimer()
    local integer h = H2I(t)-0x100000
    set Target[h] = GetEnumUnit()
    set Real[h] = 200.
    set Z[h] = Angle(GetUnitX(Target[h]),GetUnitY(Target[h]),GetUnitX(Unit[he]),GetUnitY(Unit[he]))
    call UnitDamageTarget(Unit[he],Target[h], 200, true, false, ConvertAttackType(4), ConvertDamageType(14), ConvertWeaponType(0))
    call PauseUnit(Target[h],true)
    call TimerStart(t,0.04,true, function GroupMove)
    set t = null
endfunction

function G_Actions takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u = GetTriggerUnit()
    local group g = CreateGroup()
    local integer h = H2I(t)-0x100000
    set Int[h] = Int[h] + R2I(TimerGetElapsed(t))
      if Int[h]<10 then
        call GroupEnumUnitsInRange(g,GetUnitX(Unit[h]),GetUnitY(Unit[h]),400,Filter(function G_Filt))
        call ForGroup(g,function GroupEnum)
        call DestroyGroup(g)
        call TimerStart(t,1.,false,function G_Actions)
      else
        call DestroyTimer(t)
        set Unit[h] = null
      endif
    set g = null
    set u = null
    set t = null
endfunction

function Gr_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = H2I(t)-0x100000
    local integer htr = 0
    set Trigger[h] = CreateTrigger()
    set htr = H2I(Trigger[h])-0x100000
    set Timer[htr] = t
    set Int[h] = 0
    set Unit[h] = GetTriggerUnit()
    call TriggerRegisterUnitEvent(Trigger[h], Unit[h], EVENT_UNIT_SPELL_ENDCAST)
    call TriggerAddAction( Trigger[h], function Gr_Endcast )
    call TimerStart(t,0.,false,function G_Actions)
    set t = null
endfunction

//===========================================================================
function InitTrig_Group takes nothing returns nothing
    local integer index = 0
    set gg_trg_Group = CreateTrigger(  )
    
      loop
         call TriggerRegisterPlayerUnitEvent(gg_trg_Group, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
         set index = index + 1
       exitwhen index == NumberOfPlayers
      endloop

    call TriggerAddCondition( gg_trg_Group, Condition( function Gr_Conditions ) )
    call TriggerAddAction( gg_trg_Group, function Gr_Actions )
endfunction

Старый 20.02.2009, 13:09
Igores
НИИ 4А-Во! Кафедра Джасс.
offline
Опыт: 5,325
Активность:
Спасиб:) не знал, что в других функциях можно узнавать истекший таймер:)
Старый 20.02.2009, 14:15
Ответ

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

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

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

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



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