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
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 ночи сижу
Что бы гуишникам было понятнее, и они тоже попытались помочь
Code
Функция таймера GetInfoByPass занимает проход возвращает целое разрешения местных целое я = 0 местного целом к =- 1 цикл exitwhen (я> info_num) , если (info_pass [я] == проходят), то множество К = я ENDIF набор я = я + 1 endloop если (а не (к ==- 1)), то возвращение info_data [к] ENDIF возвращать 0 EndFunction функции SetInfoByPass занимает таймер пройти, целочисленных данных ничего не возвращает набор info_pass [info_num] = проходить набор info_data [info_num] = данные набора info_num = info_num + 1 EndFunction функции B002 ничего не берет ничего не возвращает местный таймер т = GetExpiredTimer () местный объект O = GetInfoByPass (т) называть PauseUnit (габаритная, ложь) называть DestroyEffect (ое) EndFunction структуры объект единицу эффекта электронной endstruct глобальные таймер массив info_pass целое info_num целочисленный массив info_data endglobals функции on_unit_attacked_function ничего не берет ничего не возвращает местная единица и = GetTriggerUnit () местная единица = GetAttacker () местный таймер т = CreateTimer () локальный эффект электронной местных объект O = obj.create () , если ((GetUnitAbilityLevel (и, 'B002 ')> 0) и IsHeroUnitId (GetUnitTypeId (и))), то если (не (GetRandomInt (0100) <= 50)), то возвращение ENDIF вызова DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS) е = AddSpecialEffectTarget ("war3mapImported \ \ MagicDice.mdx", "голова") вызова PauseUnit (а, правда) набор оа = набор ое = е SetInfoByPass называть (г, число (о)) вызов TimerStart (т, 1, ложным, функция B002) / / вызов PolledWait (1) / / вызов DestroyEffect (е) / / вызов PauseUnit (а, ложь) набор т = NULL е = нулевой набор и = нулевой набор = NULL / / установить оа = NULL / / установить ое = NULL / / множество а = NULL ENDIF EndFunction функции main_function ничего не берет ничего не возвращает / / запускает локальный триггер on_unit_attacked = CreateTrigger () вызов TriggerRegisterAnyUnitEventBJ (on_unit_attacked, EVENT_PLAYER_UNIT_ATTACKED) называть TriggerAddAction (on_unit_attacked, функции on_unit_attacked_function ) EndFunction
Может в том что инициализация второго триггера неверна, думаю так будет вернее 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
и убить там таймер, эффект задестройть, и паузу снять с переданного юнита.
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
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
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 сек?
Ещё, 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 секунды.
Соответственно, чем меньше период таймера, тем больше точность.
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 сложно реализован, но если смотреть на эту реализацию, так я не знаю что уж быстрее работает?
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, да и здесь, это активно обсуждается, можно посмотреть в поиске). Основная проблема в том, что она использует процессорное время, что печально сказывается на точности (особенно на маленьких промежутках времени). К тому же есть немаленький шанс, что движок обозначит это ожидание как зависший поток и просто оборвет ход работы функции.
Функция PolledWait использует TriggerSleepAction, а она имеет ряд недостатков (на xgm, да и здесь, это активно обсуждается, можно посмотреть в поиске).
Вот как она выглядит на самом деле:
Code
function PolledWait takes real duration returns nothing local timer t local real timeRemaining
if (duration > 0) then set t = CreateTimer() call TimerStart(t, duration, false, null) loop set timeRemaining = TimerGetRemaining(t) exitwhen timeRemaining <= 0
// If we have a bit of time left, skip past 10% of the remaining // duration instead of checking every interval, to minimize the // polling on long waits. if (timeRemaining > bj_POLLED_WAIT_SKIP_THRESHOLD) then call TriggerSleepAction(0.1 * timeRemaining) else call TriggerSleepAction(bj_POLLED_WAIT_INTERVAL) endif endloop call DestroyTimer(t) endif endfunction
Т.е. юзайте таймеры.
О нас думают плохо лишь те, кто хуже нас, а те кто лучше нас... Им просто не до нас. My Project: Nindogatari MAL