Сейчас 22:21:42 Суббота, 18 мая, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: PUVer, SirNikolas, Ty3uK  
Форум о Warcraft 3 » Раздел для картостроителей » GUI / Jass » [Вопрос] Группы и boolexpr (:()
[Вопрос] Группы и boolexpr
[SeKtOR]Дата: Суббота, 08 Сентября 2012, 15:50:05 | Сообщение # 1
Группа: Проверенные
Сообщений: 1143
Награды: 0
Репутация: 1168
Блокировки:
Имеется следующий код(писался на скорую руку для примера):
Code
globals
      hashtable udg_Hash = InitHashtable()
endglobals

define
      SPELL_RAWCODE = 'AUan'
      SPELL_LLEVEL = 3
      SPELL_DUMMY = 'ewsp'
enddefine

function Spell_Conditions takes nothing returns boolean
      return GetSpellAbilityId() == SPELL_RAWCODE
endfunction

function Spell_Filter takes nothing returns boolean
      return IsPlayerEnemy(GetOwningPlayer(GetTriggerUnit()), GetOwningPlayer(GetFilterUnit())) and GetWidgetLife(GetFilterUnit()) > 0.405 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING)
endfunction

function Spell_Expired takes nothing returns nothing
      local boolexpr b = Condition(function Spell_Filter)
      local group g = CreateGroup()
      local unit f
      if(LoadInteger(udg_Hash, GetHandleId(GetExpiredTimer()), 2) == 81) then
      call FlushChildHashtable(udg_Hash, GetHandleId(GetExpiredTimer()))
      call DestroyTimer(GetExpiredTimer())
      else
      call SetUnitPosition(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1), 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(g, GetUnitX(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1)), GetUnitY(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1)), 120., b)
      call SaveInteger(udg_Hash, GetHandleId(GetExpiredTimer()), 2, LoadInteger(udg_Hash, GetHandleId(GetExpiredTimer()), 2) + 1)
      loop
      set f = FirstOfGroup(g)
      exitwhen f == null
      call UnitDamageTarget(LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1), f, 500., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)
      call GroupRemoveUnit(g, f)
      endloop
      endif
      call DestroyGroup(g)
      call DestroyBoolExpr(b)
      set b = null
      set f = null
      set g = 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 SaveAgentHandle(udg_Hash, GetHandleId(t), 1, u)
      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 SetUnitAbilityLevel(u, SPELL_RAWCODE, SPELL_LLEVEL)
      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

Собстно сам вопрос как после истечения таймера пикнуть всех вокруг юнита u, учитывая что GetTriggerUnit() в филтре уже не работает
И 2 мини вопрос только у меня уникумный tesh, который не подсвечивает SaveAgentHandle?




Сообщение отредактировал [SeKtOR] - Суббота, 08 Сентября 2012, 15:50:28
 

HexingДата: Суббота, 08 Сентября 2012, 15:57:13 | Сообщение # 2
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Quote (|SeKtOR|)
И 2 мини вопрос только у меня уникумный tesh, который не подсвечивает SaveAgentHandle?

у меня такой функции ваще нет, так что радуйся
по сабжу
сохранить кастера в хеш на таймер, создать глобалку типа юнит, перед фильтром назначить ей значение необходимого юнита, выполнить фильтер, заменив triggeringunit на глобалку, и не забыть проделать тоже самое везде перед вызовом фильтра
однако это плохой костыль, я делаю всё на массивах с 12 ячейками, соответствующими 12ти героям, массив героев, массив урона, массив оставшегося времени и т.д., однако с некоторыми спеллами приходится делать двумерные массивы


 

kapa6acvlkДата: Суббота, 08 Сентября 2012, 15:58:48 | Сообщение # 3
Группа: Проверенные
Сообщений: 612
Награды: 0
Репутация: 361
Блокировки:
[SeKtOR], Перед boolexpr, записывай своего триггерюнита в глобалку, а после boolexpr очисть е на всякий случай. В фильтре ее используй.
Хотя в принципе, ты и так используешь loop, почему не откажешься от фильтра вообще? запихай в свой loop, if()then



Как говориться, не обязательно есть всю кучу говна, чтобы понять, что она однородна.
© Александр Зорич
 

HexingДата: Суббота, 08 Сентября 2012, 16:02:49 | Сообщение # 4
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
[SeKtOR], зачем ты boolexpr создаёшь, Condition(func) насколько я понял не создаёт утечек при множественном использовании, он вернёт указатель на одну и ту же функцию, поэтому просто везде пиши Condition(func)

 

[SeKtOR]Дата: Суббота, 08 Сентября 2012, 16:08:14 | Сообщение # 5
Группа: Проверенные
Сообщений: 1143
Награды: 0
Репутация: 1168
Блокировки:
Quote (kapa6acvlk)
[SeKtOR], Перед boolexpr, записывай своего триггерюнита в глобалку, а после boolexpr очисть е на всякий случай. В фильтре ее используй.
Хотя в принципе, ты и так используешь loop, почему не откажешься от фильтра вообще? запихай в свой loop, if()then

Примерно понял, но лучше пример trollface (желательно на основе моего)
Quote (Hexing)
сохранить кастера в хеш на таймер, создать глобалку типа юнит, перед фильтром назначить ей значение необходимого юнита, выполнить фильтер, заменив triggeringunit на глобалку, и не забыть проделать тоже самое везде перед вызовом фильтра
однако это плохой костыль, я делаю всё на массивах с 12 ячейками, соответствующими 12ти героям, массив героев, массив урона, массив оставшегося времени и т.д., однако с некоторыми спеллами приходится делать двумерные массивы

Как вариант.

Добавлено (08 Сентября 2012, 16:08:14)
---------------------------------------------
А нет понял, щас попробую trollface


 

SirNikolasДата: Суббота, 08 Сентября 2012, 16:15:53 | Сообщение # 6
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (|SeKtOR|)
call SetUnitAbilityLevel(u, SPELL_RAWCODE, SPELL_LLEVEL)
Это требуется только для способности "Техника".


 

[SeKtOR]Дата: Суббота, 08 Сентября 2012, 16:18:47 | Сообщение # 7
Группа: Проверенные
Сообщений: 1143
Награды: 0
Репутация: 1168
Блокировки:
Code
globals
       hashtable udg_Hash = InitHashtable()
endglobals

define
       SPELL_RAWCODE = 'A000'
       SPELL_DUMMY = 'ewsp'
enddefine

function Spell_Conditions takes nothing returns boolean
       return GetSpellAbilityId() == SPELL_RAWCODE
endfunction

function Spell_Expired takes nothing returns nothing
       local group g = CreateGroup()
       local unit f
       local unit u = LoadUnitHandle(udg_Hash, GetHandleId(GetExpiredTimer()), 1)
       if(LoadInteger(udg_Hash, GetHandleId(GetExpiredTimer()), 2) == 81) then
       call FlushChildHashtable(udg_Hash, GetHandleId(GetExpiredTimer()))
       call DestroyTimer(GetExpiredTimer())
       else
       call SetUnitPosition(u, GetUnitX(u) + 10. * Cos(GetUnitFacing(u) * bj_DEGTORAD), GetUnitY(u) + 10. * Sin(GetUnitFacing(u) * bj_DEGTORAD))
       call GroupEnumUnitsInRange(g, GetUnitX(u), GetUnitY(u), 120., null)
       call SaveInteger(udg_Hash, GetHandleId(GetExpiredTimer()), 2, LoadInteger(udg_Hash, GetHandleId(GetExpiredTimer()), 2) + 1)
       loop
       set f = FirstOfGroup(g)
       exitwhen f == null
       if(IsPlayerEnemy(GetOwningPlayer(u), GetOwningPlayer(f)) and GetWidgetLife(f) > 0.405 and not IsUnitType(f, UNIT_TYPE_STRUCTURE) and not IsUnitType(f, UNIT_TYPE_FLYING)) then
       call UnitDamageTarget(u, f, 500., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)
       call GroupRemoveUnit(g, f)
       endif
       endloop
       endif
       call DestroyGroup(g)
       set u = null
       set f = null
       set g = 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 SaveAgentHandle(udg_Hash, GetHandleId(t), 1, u)
       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

Работает! Но и тут напряг, когда оно пикает юнитов вокруг юнита u из-за условия мягко скажем "лагает", есть ли пути решения?




Сообщение отредактировал [SeKtOR] - Суббота, 08 Сентября 2012, 16:19:14
 

HexingДата: Суббота, 08 Сентября 2012, 16:20:08 | Сообщение # 8
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Quote (|SeKtOR|)
 local unit u = CreateUnit(Player(0), SPELL_DUMMY, 0., 0., 0.)
       call UnitAddAbility(u, SPELL_RAWCODE)
       call RemoveUnit(u)
       set u = null

что это такое?


 

[SeKtOR]Дата: Суббота, 08 Сентября 2012, 16:21:28 | Сообщение # 9
Группа: Проверенные
Сообщений: 1143
Награды: 0
Репутация: 1168
Блокировки:
В статье по которой я учился это было написано как "прелоад способности", чтобы не лагало при первом касте



Сообщение отредактировал [SeKtOR] - Суббота, 08 Сентября 2012, 16:21:54
 

HexingДата: Суббота, 08 Сентября 2012, 16:22:09 | Сообщение # 10
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
а ясно, странный способ создания эффекта, в любом случае опиши спелл, хочу повторить, а то понять из кода ничего не могу
а это триггер инициализации, тогда ясно




Сообщение отредактировал Hexing - Суббота, 08 Сентября 2012, 16:22:57
 

SirNikolasДата: Суббота, 08 Сентября 2012, 16:22:24 | Сообщение # 11
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Hexing, preload dummy и способности. Когда в игре впервые появляется юнит нового типа либо добавляется заклинание (триггерно), происходит лаг. Его можно убрать, создав юнита при ините.

 

[SeKtOR]Дата: Суббота, 08 Сентября 2012, 16:22:41 | Сообщение # 12
Группа: Проверенные
Сообщений: 1143
Награды: 0
Репутация: 1168
Блокировки:
Это неудачная попытка создания полностью триггерной Shock Wave(Волны силы)



Сообщение отредактировал [SeKtOR] - Суббота, 08 Сентября 2012, 16:23:10
 

SirNikolasДата: Суббота, 08 Сентября 2012, 16:23:28 | Сообщение # 13
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (|SeKtOR|)
чтобы не лагало при первом касте
При касте лагает от создания эффекта, который тоже желательно прелоадить (native Preload takes string filename returns nothing).


 

HexingДата: Суббота, 08 Сентября 2012, 16:23:35 | Сообщение # 14
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
[SeKtOR], ок, дай 10 минут, щас напишемс, ты в cjass шаришь?

 

[SeKtOR]Дата: Суббота, 08 Сентября 2012, 16:24:12 | Сообщение # 15
Группа: Проверенные
Сообщений: 1143
Награды: 0
Репутация: 1168
Блокировки:
я дефайны только недавно осилил D: хочу JASS2 вариант

 

HexingДата: Суббота, 08 Сентября 2012, 16:25:31 | Сообщение # 16
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Quote (|SeKtOR|)
я дефайны только недавно осилил D: хочу JASS2 вариант

а получишь vjass, jass2 не портабелен, ты уж прости


 

[SeKtOR]Дата: Суббота, 08 Сентября 2012, 16:26:14 | Сообщение # 17
Группа: Проверенные
Сообщений: 1143
Награды: 0
Репутация: 1168
Блокировки:

Пошёл курить мануалы по vJass


 

SirNikolasДата: Суббота, 08 Сентября 2012, 16:29:06 | Сообщение # 18
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (|SeKtOR|)
мягко скажем "лагает"
Quote (|SeKtOR|)
Code
loop
    set f = FirstOfGroup(g)
    exitwhen f == null
    if(IsPlayerEnemy(GetOwningPlayer(u), GetOwningPlayer(f)) and GetWidgetLife(f) > 0.405 and not IsUnitType(f, UNIT_TYPE_STRUCTURE) and not IsUnitType(f, UNIT_TYPE_FLYING)) then
        call UnitDamageTarget(u, f, 500., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)
        call GroupRemoveUnit(g, f)
    endif
endloop
При нахождении невраждебного юнита получается бесконечный цикл, который крутится достаточно долго (заставляя игру подвиснуть), а потом завершается из-за лимита операций в потоке. Если бы не это, игра бы висла намертво.

Добавлено (08 Сентября 2012, 16:29:06)
---------------------------------------------
Кстати, группа должна быть только одна - глобальная. Создание и удаление каждые .05 секунд тоже оказывает вияние на быстродействие.


 

[SeKtOR]Дата: Суббота, 08 Сентября 2012, 16:33:35 | Сообщение # 19
Группа: Проверенные
Сообщений: 1143
Награды: 0
Репутация: 1168
Блокировки:
Ну а как иначе, если учитывать что положение юнита u меняется и нужно брать всех юнитов вокруг него в радиусе 120. и дамажить, пока таймер не закончится нужное кол-во раз?



Сообщение отредактировал [SeKtOR] - Суббота, 08 Сентября 2012, 16:34:20
 

SirNikolasДата: Суббота, 08 Сентября 2012, 16:34:52 | Сообщение # 20
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Вместо того, чтобы создавать локальную группу g, нужно пользоваться глобальной udg_G.

 

[SeKtOR]Дата: Суббота, 08 Сентября 2012, 16:37:21 | Сообщение # 21
Группа: Проверенные
Сообщений: 1143
Награды: 0
Репутация: 1168
Блокировки:
Щас попробуем!

Добавлено (08 Сентября 2012, 16:37:21)
---------------------------------------------
Лагает меньше(кажись), но всё ещё лагает...


 

SirNikolasДата: Суббота, 08 Сентября 2012, 16:43:10 | Сообщение # 22
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Основные лаги из-за первой ошибки - GroupRemoveUnit нужно вынести из блока if. Дополнительную оптимизацию можно провести, рассчитав 10. * Cos(a) и 10. * Sin(a) в момент запуска и сохранив их в хэш.

 

[SeKtOR]Дата: Суббота, 08 Сентября 2012, 16:48:37 | Сообщение # 23
Группа: Проверенные
Сообщений: 1143
Награды: 0
Репутация: 1168
Блокировки:
****** ****!
Сработало11!

Добавлено (08 Сентября 2012, 16:48:37)
---------------------------------------------
Тему можно закрыть

Мат на иностранном языке.




Сообщение отредактировал SirNikolas - Суббота, 08 Сентября 2012, 16:58:55
 

SirNikolasДата: Суббота, 08 Сентября 2012, 16:59:30 | Сообщение # 24
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Подождем решения Hexing... Если, конечно, он собирается писать.

 

HexingДата: Суббота, 08 Сентября 2012, 17:12:12 | Сообщение # 25
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Quote (SirNikolas)
Если, конечно, он собирается писать.



тык

Добавлено (08 Сентября 2012, 17:12:12)
---------------------------------------------

Quote (|SeKtOR|)

7 уровень

Группа: Проверенные
Сообщений: 306
Награды: 0
Репутация: 57  ±
Блокировки:

****** ****!
Сработало11!

Добавлено (08 Сентября 2012, 16:48:37)
---------------------------------------------
Тему можно закрыть

Мат на иностранном языке.

ну и для кого я делал, лол <_<




Сообщение отредактировал Hexing - Суббота, 08 Сентября 2012, 17:06:01
 

Форум о Warcraft 3 » Раздел для картостроителей » GUI / Jass » [Вопрос] Группы и boolexpr (:()
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Copyright © 2006 - 2024 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz