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


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: PUVer, SirNikolas, Ty3uK  
Форум о Warcraft 3 » Раздел для картостроителей » GUI / Jass » Помогите разобраться с кодом (Jass =()
Помогите разобраться с кодом
HexingДата: Пятница, 15 Июля 2011, 21:58:18 | Сообщение # 1
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Code
function Trig_callMain_Actions takes nothing returns nothing
     call main_function()
endfunction

//===========================================================================
function InitTrig_callMain takes nothing returns nothing
     set gg_trg_callMain = CreateTrigger(  )
     call TriggerRegisterTimerEvent(gg_trg_callMain,0.10,false)
     call TriggerAddAction( gg_trg_callMain, function Trig_callMain_Actions )
endfunction



это инит функция, работает 100%
в коде карты написано следующее:
Code
function GetInfoByPass takes timer pass returns integer res
    local integer i=0
    local integer k=-1
    loop
     exitwhen(i>info_num)
     if(info_pass[i] == pass) then
      set k = i
     endif  
     set i = i + 1
    endloop
    if(not(k==-1)) then
     return info_data[k]
    endif  
    return 0
endfunction

function SetInfoByPass takes timer pass,integer data returns nothing
    set info_pass[info_num] = pass
    set info_data[info_num] = data
    set info_num = info_num + 1
endfunction

function B002 takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local obj o=GetInfoByPass(t)
    call PauseUnit(o.a,false)
    call DestroyEffect(o.e)
endfunction

struct obj
unit a
effect e
endstruct

globals
   timer array info_pass
   integer info_num
   integer array info_data
endglobals

function on_unit_attacked_function takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit a = GetAttacker()
    local timer t = CreateTimer()
    local effect e
    local obj o=obj.create()
    if((GetUnitAbilityLevel(u, 'B002') > 0) and IsHeroUnitId(GetUnitTypeId(u))) then
     if(not(GetRandomInt(0,100) <= 50)) then
      return
     endif  
     call UnitDamageTarget(u,a,(GetHeroStr(u,true)+GetHeroAgi(u,true)+GetHeroInt(u,true)),true,false,ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD,WEAPON_TYPE_WHOKNOWS)
     set e = AddSpecialEffectTarget("war3mapImported\\MagicDice.mdx",a,"head")
     call PauseUnit(a,true)
     set o.a = a
     set o.e = e
     call SetInfoByPass(t,integer(o))
     call TimerStart(t,1,false,function B002)
     //call PolledWait(1)
    // call DestroyEffect(e)
    // call PauseUnit(a,false)
    set t = null
    set e = null
    set u = null
    set a = null
    //set o.a = null
    //set o.e = null
    //set o = null
    endif
endfunction

function main_function takes nothing returns nothing
    //triggers
    local trigger on_unit_attacked = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(on_unit_attacked,EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddAction(on_unit_attacked,function on_unit_attacked_function)
endfunction

Результат: При запуске карты, выходит обратно в меню... Не робит, помогите разобраться, до 2 ночи сижу ^_^


 

TitansДата: Пятница, 15 Июля 2011, 22:28:46 | Сообщение # 2
6 уровень
Группа: Проверенные
Сообщений: 167
Награды: 0
Репутация: 77
Блокировки:
Может в том что инициализация второго триггера неверна, думаю так будет вернее set on_unit_attacked = CreateTrigger()
 

lawsonДата: Пятница, 15 Июля 2011, 22:30:01 | Сообщение # 3
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Quote (Hexing)
     call TriggerRegisterTimerEvent(gg_trg_callMain,0.10,false)

call ExecuteFunc() и все дела!


Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!
 

BlyadickДата: Пятница, 15 Июля 2011, 23:07:26 | Сообщение # 4
2 уровень
Группа: Пользователи
Сообщений: 29
Награды: 0
Репутация: -6
Блокировки:
Что бы гуишникам было понятнее, и они тоже попытались помочь


- Лови топор
- Поймал?
- Чё молчишь?
 

HexingДата: Суббота, 16 Июля 2011, 07:08:22 | Сообщение # 5
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
спс за ответы, щас гляну

Добавлено (16-07-2011, 07:08)
---------------------------------------------

Quote (Titans)
Может в том что инициализация второго триггера неверна, думаю так будет вернее set on_unit_attacked = CreateTrigger()

Имхо это одно и тоже, разницы нет
Quote (lawson)
call ExecuteFunc() и все дела!

Ваще не по теме... А на счет ваших эксекут и инитов, если по мап инициализейтион вызывать, много багов бывает я читал.
Вчера ночью не было времени расписывать код, так вот в чем суть: Мне надо передать в другую функцию две переменных,и я пытаюсь запихать структуру как integer в массив интегеров, а потом по сравнению таймеров найти её в другой функции... результат всего этого - мапа не запускается... Вообще до этого у меня всё прекрасно работало с PolledWait(1), но я много читал что нужно делать это через таймер и передовать какимито XAT или MAT и другими системами... Кэш или Ъэш как там его я стараюсь не использовать по убеждению ADULT-а в своей статье... Так как передать переменные из:
Code
function on_unit_attacked_function takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local unit a = GetAttacker()
    local timer t = CreateTimer()
    local effect e
    local obj o=obj.create()
    if((GetUnitAbilityLevel(u, 'B002') > 0) and IsHeroUnitId(GetUnitTypeId(u))) then
     if(not(GetRandomInt(0,100) <= 50)) then
      return
     endif  
     call UnitDamageTarget(u,a,(GetHeroStr(u,true)+GetHeroAgi(u,true)+GetHeroInt(u,true)),true,false,ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD,WEAPON_TYPE_WHOKNOWS)
     set e = AddSpecialEffectTarget("war3mapImported\\MagicDice.mdx",a,"head")
     call PauseUnit(a,true)
     set o.a = a
     set o.e = e
     call SetInfoByPass(t,integer(o))
     call TimerStart(t,1,false,function B002)
     //call PolledWait(1)
    // call DestroyEffect(e)
    // call PauseUnit(a,false)
    set t = null
    set e = null
    set u = null
    set a = null
    //set o.a = null
    //set o.e = null
    //set o = null
    endif
endfunction

мне надо передать (a,e) в функцию
Code
function B002 takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local obj o=GetInfoByPass(t)
    call PauseUnit(o.a,false)
    call DestroyEffect(o.e)
endfunction

и убить там таймер, эффект задестройть, и паузу снять с переданного юнита.

Заранее спс, hexing


 

lawsonДата: Суббота, 16 Июля 2011, 09:50:49 | Сообщение # 6
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:


Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!


Сообщение отредактировал lawson - Суббота, 16 Июля 2011, 10:02:52
 

AjaccioДата: Суббота, 16 Июля 2011, 10:00:25 | Сообщение # 7
7 уровень
Группа: Проверенные
Сообщений: 299
Награды: 1
Репутация: 239
Блокировки:
Code
library EDIT initializer MainFunction

     globals
         timer array info_pass
         integer info_num = 0
         integer array info_data  
     endglobals

     private function GetInfoByPass takes timer pass returns integer
         local integer i = 0  
         loop
             exitwhen(i > info_num)
             if (info_pass[i] == pass) then
                 return info_data[i]
             endif
             set i = i + 1
         endloop
         return 0  
     endfunction  

     private function SetInfoByPass takes timer pass, integer data returns nothing  
         set info_pass[info_num] = pass
         set info_data[info_num] = data
         set info_num = info_num + 1
     endfunction
      
     private struct object
         unit source  
         effect sprite
     endstruct

     private function FNC_B002 takes nothing returns nothing  
         local timer exp = GetExpiredTimer()  
         local object use = GetInfoByPass(exp)
         call BJDebugMsg(I2S(GetInfoByPass(exp)))
         call PauseUnit(use.source, false)  
         call DestroyEffect(use.sprite)
         set use.source = null
         set use.sprite = null
         set exp = null
         call use.destroy()
     endfunction

     private function RunOnAttackEvent takes nothing returns nothing  
         local unit source = GetAttacker()
         local unit target = GetTriggerUnit()
         local real damage = GetHeroStr(target, true) + GetHeroAgi(target, true) + GetHeroInt(target, true)
         local timer on_time = CreateTimer()  
         local effect addeffect
         local object new = object.create()  
         if (/*GetUnitAbilityLevel(target, 'B002') > 0 and*/ GetUnitAbilityLevel(target, 'AHer') > 0) then  
             if (GetRandomInt(0, 100) > 50) then  
                 return
             endif
              call UnitDamageTarget(target, source, damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, null)  
              //set addeffect = AddSpecialEffectTarget("war3mapImported\\MagicDice.mdx", source, "head")
              set addeffect = AddSpecialEffectTarget("Abilities\\Spells\\Human\\StormBolt\\StormBoltTarget.mdl", source, "overhead")
              call PauseUnit(source, true)
              set new.source = source
              set new.sprite = addeffect
              call SetInfoByPass(on_time, new)  
              call TimerStart(on_time, 1, false, function FNC_B002)  
         endif  
         set target = null
         set source = null
         set addeffect = null
         set on_time = null
     endfunction  

     private function MainFunction takes nothing returns nothing  
         local trigger on_unit_attacked = CreateTrigger()
         call TriggerRegisterAnyUnitEventBJ(on_unit_attacked, EVENT_PLAYER_UNIT_ATTACKED)
         call TriggerAddAction(on_unit_attacked, function RunOnAttackEvent)
     endfunction

endlibrary


Хотя я бы сделал примерно так:

Code
library EDIT initializer MainFunction
      
     private struct object
         static integer index = 1
         static integer count = 0
          
         unit source
         real expire
         effect sprite
          
         method doaction takes nothing returns nothing
             set .expire = .expire - 0.05
             if not (.expire > 0.0) then
                 call PauseUnit(.source, false)
                 call DestroyEffect(.sprite)
                 set .source = null
                 set .sprite = null
                 call .destroy()
             endif
         endmethod
          
         static method update takes nothing returns nothing
             local object use
             loop
                 exitwhen (object.index > object.count)
                 set use = object.index
                 call use.doaction()
                 set object.index = object.index + 1
             endloop
             set object.index = 1
         endmethod
     endstruct

     private function RunOnAttackEvent takes nothing returns nothing  
         local unit source = GetAttacker()
         local unit target = GetTriggerUnit()
         local real damage = GetHeroStr(target, true) + GetHeroAgi(target, true) + GetHeroInt(target, true)
         local timer on_time = CreateTimer()  
         local effect addeffect
         local object new = object.create()
         if (/*GetUnitAbilityLevel(target, 'B002') > 0 and*/ GetUnitAbilityLevel(target, 'AHer') > 0) then  
             if (GetRandomInt(0, 100) > 50) then  
                 return
             endif
              call UnitDamageTarget(target, source, damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, null)  
              //set addeffect = AddSpecialEffectTarget("war3mapImported\\MagicDice.mdx", source, "head")
              set addeffect = AddSpecialEffectTarget("Abilities\\Spells\\Human\\StormBolt\\StormBoltTarget.mdl", source, "overhead")
              call PauseUnit(source, true)
              set new.source = source
              set new.sprite = addeffect
              set new.expire = 1.0
              if (integer(new) > object.count) then
                 set object.count = integer(new)
              endif
         endif  
         set target = null
         set source = null
         set addeffect = null
         set on_time = null
     endfunction  

     private function MainFunction takes nothing returns nothing  
         local trigger on_unit_attacked = CreateTrigger()
         call TimerStart(CreateTimer(), 0.05, true, function object.update)
         call TriggerRegisterAnyUnitEventBJ(on_unit_attacked, EVENT_PLAYER_UNIT_ATTACKED)
         call TriggerAddAction(on_unit_attacked, function RunOnAttackEvent)
     endfunction

endlibrary


XOR EAX, EAX
MOV EAX, 00H ;; NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.
 

HexingДата: Суббота, 16 Июля 2011, 11:34:29 | Сообщение # 8
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Ajaccio, круть! =) так элегантно сделано, вряд ли я когда нибудь смог бы реализовать такое) Спасибо огромное! Скажите пожалуйста,
Code
call TimerStart(CreateTimer(), 0.05, true, function object.update)
это означает что каждые 1/20 секунды мы пробегаемся по массиву и смотрим нужно ли убрать тот или иной объект... Но в коде нет не одного массива. Если можно, объясните принцип действия или накиньте статейку про это. Читал на хгм про jass всё что нашёл. И что это за library и как он запускается, почему метод а не функция и что за static, точнее какое влияние оно оказывает?

Добавлено (16-07-2011, 11:34)
---------------------------------------------
Всё кажется разобрался, библиотека удобна, что у нее авто инициализация, а вместо массивов структуры с встроенными функциями - методами, таймер запускает течение внутри структуры, которое остановится когда надо. Скажите а почему не сделать период таймера 0.5 или 1.0, зачем такой маленький - 0.05, когда мы знаем что нам нужно 1.00 сек?


 

AjaccioДата: Суббота, 16 Июля 2011, 12:04:01 | Сообщение # 9
7 уровень
Группа: Проверенные
Сообщений: 299
Награды: 1
Репутация: 239
Блокировки:
Ещё, static на vJass обозначает принадлежность функции\переменной к определенной структуре.
Иначе говоря object.count - обычная переменная, но обращаться к ней нужно по правилу object.<ИМЯ ПЕРЕМЕННОЙ>\<ИМЯ ФУНКЦИИ>.

А вообще ВОТ отличный мануал на русском, там все рассказано и показано.

Quote (Hexing)
Скажите а почему не сделать период таймера 0.5 или 1.0, зачем такой маленький - 0.05, когда мы знаем что нам нужно 1.00 сек?

Заклинания срабатывают в случайный момент времени, при этом таймер, в этот момент, может иметь значение 0.99 или 0.01, да какое угодно.
Поэтому, если проследить за ходом работы таймера с периодом в 1 секунду, можно получить такое:

1) Таймер сработает через 0.2 секунды.
2) ВНЕЗАПНО сработало заклинание, поэтому expire = 1.0.
3) Таймер срабатывает, переменная expire становиться равной 0.
4) Заклинание прекращает свое действие, хотя прошло только 0.2 секунды.

Соответственно, чем меньше период таймера, тем больше точность.


XOR EAX, EAX
MOV EAX, 00H ;; NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.
 

HexingДата: Суббота, 16 Июля 2011, 12:35:21 | Сообщение # 10
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Спасибо огромное, будем учиться =)

Добавлено (16-07-2011, 12:35)
---------------------------------------------

Code
if (integer(new) > object.count) then
                  set object.count = integer(new)

А что это означает?
Code
local object new = object.create()

и разве не стоит делать object.create() после проверки шанса на random > 50?
и намного-ли лучше вся эта сложная конструкция, заменой всего это на 3 строки - PolledWait, remove effect, unpause... Я начал переделку именно из-за того что PolledWait сложно реализован, но если смотреть на эту реализацию, так я не знаю что уж быстрее работает?


 

AjaccioДата: Суббота, 16 Июля 2011, 12:51:05 | Сообщение # 11
7 уровень
Группа: Проверенные
Сообщений: 299
Награды: 1
Репутация: 239
Блокировки:
Code
if (integer(new) > object.count) then  
     set object.count = integer(new)  
endif


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

Quote (Hexing)
и разве не стоит делать object.create() после проверки шанса на random > 50?

Правильно, недоглядел.

Quote (Hexing)
заменой всего это на 3 строки - PolledWait

Функция PolledWait использует TriggerSleepAction, а она имеет ряд недостатков (на xgm, да и здесь, это активно обсуждается, можно посмотреть в поиске).
Основная проблема в том, что она использует процессорное время, что печально сказывается на точности (особенно на маленьких промежутках времени).
К тому же есть немаленький шанс, что движок обозначит это ожидание как зависший поток и просто оборвет ход работы функции.


XOR EAX, EAX
MOV EAX, 00H ;; NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.
 

FaionДата: Суббота, 16 Июля 2011, 13:02:56 | Сообщение # 12
10 уровень
Группа: Проверенные
Сообщений: 1894
Награды: 0
Репутация: 430
Блокировки:
Quote (Ajaccio)
Функция PolledWait использует TriggerSleepAction, а она имеет ряд недостатков (на xgm, да и здесь, это активно обсуждается, можно посмотреть в поиске).


Вот как она выглядит на самом деле:



Т.е. юзайте таймеры.


О нас думают плохо лишь те, кто хуже нас, а те кто лучше нас... Им просто не до нас.
My Project: Nindogatari
MAL
 

HexingДата: Суббота, 16 Июля 2011, 13:11:05 | Сообщение # 13
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Okey boss...

 

Форум о Warcraft 3 » Раздел для картостроителей » GUI / Jass » Помогите разобраться с кодом (Jass =()
  • Страница 1 из 1
  • 1
Поиск:

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