|
|
|
|
Проверьте код
|
|
Smartaros | Дата: Вторник, 07 Августа 2012, 18:14:09 | Сообщение # 1 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| Есть ли утечки, или можно как нибудь оптимизировать. Это как бы мой первый спелл полностью на джасс, хочу узнать, в правильном ли я русле
Code function Trig_assss_Conditions takes nothing returns boolean if ( not ( GetSpellAbilityId() == 'A0F8' ) ) then return false endif return true endfunction
function move takes unit u, real dist, real angle returns nothing local real x1 = GetUnitX(u) local real y1 = GetUnitY(u) local real x2 = x1 + dist * Cos(angle * .0174532) local real y2 = y1 + dist * Sin(angle * .0174532) SetUnitPosition(u, x2, y2) set u = null endfunction
function Trig_assss_Move takes nothing returns nothing local timer t = GetExpiredTimer() local integer hid = GetHandleId(t) local unit u = LoadUnitHandle(udg_Hash, hid, 0) local real a = GetUnitFacing(u) local real x = GetUnitX(u) local real y = GetUnitY(u) local real dx = x - udg_AAAA[0] local real dy = y - udg_AAAA[1] set udg_AAAA[2] = SquareRoot(dx * dx + dy * dy) if(udg_AAAA[2] >= 600.)then call SetUnitPathing( u, true ) call FlushChildHashtable(udg_Hash, hid) call DestroyTimer(t) set t = null set u = null else call move(u, 6.00, a) set u = null endif endfunction
function Trig_assss_Actions takes nothing returns nothing local unit u1 = GetSpellAbilityUnit() local timer t = CreateTimer() local integer hid = GetHandleId(t) set udg_AAAA[0] = GetUnitX(u1) set udg_AAAA[1] = GetUnitY(u1) call SaveAgentHandle(udg_Hash, hid, 0, u1) call TimerStart(t, .01, true, function Trig_assss_Move) call SetUnitPathing( u1, false ) set t = null set u1 = null endfunction
//=========================================================================== function InitTrig_assss takes nothing returns nothing set gg_trg_assss = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_assss, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_assss, Condition( function Trig_assss_Conditions ) ) call TriggerAddAction( gg_trg_assss, function Trig_assss_Actions ) endfunction Добавлено (07 Августа 2012, 18:14:09) --------------------------------------------- при многократном использовании спелла начинает лагать, обьясните где утечка, подправьте код, я только учусь
|
|
|
|
SirNikolas | Дата: Вторник, 07 Августа 2012, 19:05:30 | Сообщение # 2 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Смотрю, у тебя есть JNGP, так что пишу на cJass.Code library_once SafeMove { include "cj_types_priv.j";
private real minX, minY, maxX, maxY;
void SafeMove(unit u, real x, real y) { if x > minX && x < maxX { SetUnitX(u, x); } if y > minY && y < maxY { SetUnitY(u, y); } }
callback onInit() { minX = GetRectMinX(bj_mapInitialPlayableArea); minY = GetRectMinY(bj_mapInitialPlayableArea); maxX = GetRectMaxX(bj_mapInitialPlayableArea); maxY = GetRectMaxY(bj_mapInitialPlayableArea); } } Code include "cj_order.j"
scope ForceStaff { include "cj_types_priv.j";
define { private ABILITY = 'A0F8'; private DISTANCE = 600.; private PERIOD = .05; private DELTA = 30.;//SPEED * PERIOD }
callback onUnitSpellEffect(ABILITY) { unit u = GetTriggerUnit(); timer t = CreateTimer(); int id = GetHandleId(t); real a = GetUnitFacing(u) * .017; SaveAgentHandle(udg_Hash, id, 0, u); SaveReal(udg_Hash, id, 1, DISTANCE); SaveReal(udg_Hash, id, 2, Cos(a) * DELTA); SaveReal(udg_Hash, id, 3, Sin(a) * DELTA); TimerStart(t, PERIOD, true, \ lambda void() { timer t = GetExpiredTimer(); int id = GetHandleId(t); unit u = LoadUnitHandle(udg_Hash, id, 0); real r = LoadReal(udg_Hash, id, 1) - DELTA; SafeMove(u, GetWidgetX(u) + LoadReal(udg_Hash, id, 2), \ GetWidgetY(u) + LoadReal(udg_Hash, id, 3)); if r <= .0 { DestroyTimer(t); FlushChildHashtable(udg_Hash, id); } else { IssueImmediateOrderById(u, order_stop); SaveReal(udg_Hash, id, 1, r); } flush locals; } ); flush locals; } } Добавлено (07 Августа 2012, 19:05:30) --------------------------------------------- А лагало у тебя, потому что ты таймер в if'е обнулял.
|
|
|
|
Smartaros | Дата: Вторник, 07 Августа 2012, 19:15:44 | Сообщение # 3 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| я обычный джасс то толком еще не понимаю, а ты мне cJass.....
таймер надо обнулять после endif? и еще....., можешь написать проверку точки на нахождение за пределами карты на обычном джассе, а то от этих фигурных скобок крыша едет
|
|
|
|
SirNikolas | Дата: Вторник, 07 Августа 2012, 19:40:50 | Сообщение # 4 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Сейчас. Добавлено (07 Августа 2012, 19:40:50) ---------------------------------------------
Code function SafeMove takes unit u, real x, real y returns nothing if x > udg_SafeMove_MinX and x < udg_SafeMove_MaxX then call SetUnitX(u, x) endif if y > udg_SafeMove_MinY and y < udg_SafeMove_MaxY then call SetUnitY(u, y) endif endfunction
//=========================================================================== function InitTrig_SafeMove takes nothing returns nothing set udg_SafeMove_MinX = GetRectMinX(bj_mapInitialPlayableArea) set udg_SafeMove_MaxX = GetRectMaxX(bj_mapInitialPlayableArea) set udg_SafeMove_MinY = GetRectMinY(bj_mapInitialPlayableArea) set udg_SafeMove_MaxY = GetRectMaxY(bj_mapInitialPlayableArea) endfunction Code constant function rz takes string s returns real return .0 endfunction
//=========================================================================== constant function Trig_ForceStaff_Ability takes nothing returns integer return 'A0F8' endfunction
constant function Trig_ForceStaff_Distance takes nothing returns real return 600. endfunction
constant function Trig_ForceStaff_Period takes nothing returns real return .05 endfunction
constant function Trig_ForceStaff_Delta takes nothing returns real return 30.//Speed * Period endfunction
//=========================================================================== function Trig_ForceStaff_Conditions takes nothing returns boolean return GetSpellAbilityId() == Trig_ForceStaff_Ability() endfunction
function Trig_ForceStaff_Timer takes nothing returns nothing local timer t = GetExpiredTimer() local integer id = GetHandleId(t) local unit u = LoadUnitHandle(udg_Hash, id, 0) local real r = LoadReal(udg_Hash, id, 1) - Trig_ForceStaff_Delta() call SafeMove(u, GetWidgetX(u) + LoadReal(udg_Hash, id, 2), rz(" ") + GetWidgetY(u) + LoadReal(udg_Hash, id, 3)) // ^ Разбиение строки средствами JASS2 if r <= .0 then call DestroyTimer(t) call FlushChildHashtable(udg_Hash, id) else call IssueImmediateOrderById(u, 851972)//stop call SaveReal(udg_Hash, id, 1, r) endif set t = null set u = null endfunction
function Trig_ForceStaff_Actions takes nothing returns nothing local unit u = GetTriggerUnit() local timer t = CreateTimer() local integer id = GetHandleId(t) local real a = GetUnitFacing(u) * .017 call SaveAgentHandle(udg_Hash, id, 0, u) call SaveReal(udg_Hash, id, 1, Trig_ForceStaff_Distance()) call SaveReal(udg_Hash, id, 2, Cos(a) * Trig_ForceStaff_Delta()) call SaveReal(udg_Hash, id, 3, Sin(a) * Trig_ForceStaff_Delta()) call TimerStart(t, Trig_ForceStaff_Period(), true, function Trig_ForceStaff_Timer) set u = null set t = null endfunction
//=========================================================================== function InitTrig_ForceStaff takes nothing returns nothing local trigger trig = CreateTrigger() local integer i = 0 loop call TriggerRegisterPlayerUnitEvent(trig, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null) exitwhen i == 11 set i = i + 1 endloop call TriggerAddCondition(trig, Condition(function Trig_ForceStaff_Conditions)) call TriggerAddAction(trig, function Trig_ForceStaff_Actions) set trig = null endfunction
|
|
|
|
Smartaros | Дата: Среда, 08 Августа 2012, 14:41:53 | Сообщение # 5 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| constant function Trig_ForceStaff_Distance takes nothing returns real return 600. endfunction
а как сделать расстояние, зависящее от лвл спелла?
|
|
|
|
SirNikolas | Дата: Среда, 08 Августа 2012, 14:48:12 | Сообщение # 6 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Code constant function Trig_ForceStaff_Distance takes integer level returns real return 500. + 100. * level endfunction Code call SaveReal(udg_Hash, id, 1, Trig_ForceStaff_Distance(GetUnitAbilityLevel(u, Trig_ForceStaff_Ability()))) Добавлено (08 Августа 2012, 14:48:12) --------------------------------------------- /*cJass:*/ define private DISTANCE(level) = 500. + 100. * level
|
|
|
|
lawson | Дата: Среда, 08 Августа 2012, 16:02:52 | Сообщение # 7 |
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
| Почему используешь лок триггер? SirNikolas, Quote (SirNikolas) local trigger trig = CreateTrigger()
Nic nie wiem bo mam chuj. редактирую посты! ВСЕ!
|
|
|
|
Hexing | Дата: Среда, 08 Августа 2012, 16:20:26 | Сообщение # 8 |
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
| lawson, а почему бы и нет? он нигде больше не нужен --- хотя использовать созданный редактором глобальный триггер будет экономичнее, т.к. он объявляется в любом случае
Сообщение отредактировал Hexing - Среда, 08 Августа 2012, 16:21:12 |
|
|
|
kapa6acvlk | Дата: Среда, 08 Августа 2012, 16:31:14 | Сообщение # 9 |
Группа: Проверенные
Сообщений: 612
Награды: 0
Репутация: 361
Блокировки:
| Quote (Hexing) созданный редактором глобальный триггер будет экономичнее Почему? поясни? он меньше места занимает?
Как говориться, не обязательно есть всю кучу говна, чтобы понять, что она однородна. © Александр Зорич
|
|
|
|
Smartaros | Дата: Среда, 08 Августа 2012, 17:09:09 | Сообщение # 10 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| ммм, че то не пашет, юнит просто замирает на месте на время движения
|
|
|
|
Hexing | Дата: Среда, 08 Августа 2012, 17:37:08 | Сообщение # 11 |
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
| Quote (kapa6acvlk) Почему? поясни? он меньше места занимает? каждый раз когда ты создаёшь новый триггер, даже если превратить его в текст и удалить весь текст, в коде карты будет висеть глобальные триггер, никак кроме как руками это не выпилить(распаковывать, изменять код и самому запаковывать)
пруф: создай пустой триггер, преврати в текст, в инициализационной функции будет set gg_trg_ИмяТриггера = CreateTrigger(), а значит где-то она объявлена на самом деле это не так страшно, не так страшно как использование структур
|
|
|
|
lawson | Дата: Среда, 08 Августа 2012, 17:45:00 | Сообщение # 12 |
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
| Quote (kapa6acvlk) Почему? поясни? он меньше места занимает? лок переменную нужно создать, а потом присвоить значение - уже созданный глоб триггер не нуждается в этом, ему можно сразу присваивать значение минуя цикл создания.
Nic nie wiem bo mam chuj. редактирую посты! ВСЕ!
|
|
|
|
Hexing | Дата: Среда, 08 Августа 2012, 17:54:39 | Сообщение # 13 |
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
| lawson, не говори так не зная реализации движка варика, может там уже выделены стеки памяти под переменные и она присваивается очень быстро, однако это же инициализация и тут такие моменты абсолютно не важны
|
|
|
|
kapa6acvlk | Дата: Среда, 08 Августа 2012, 18:00:45 | Сообщение # 14 |
Группа: Проверенные
Сообщений: 612
Награды: 0
Репутация: 361
Блокировки:
| Quote (Hexing) set gg_trg_ИмяТриггера = CreateTrigger() Не уверен, но мне кажется, что GG переменные самовыпиливаются, если нигде не используются, иначе раздел с объявлением глобалок превращался бы в помойку со временем. Плюс вижу только в том, что он создается во время загрузки карты, а не во время игры.
Как говориться, не обязательно есть всю кучу говна, чтобы понять, что она однородна. © Александр Зорич
|
|
|
|
lawson | Дата: Среда, 08 Августа 2012, 18:01:39 | Сообщение # 15 |
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
| я пытался просто как можно проще и понятней объяснить Hexing,
Nic nie wiem bo mam chuj. редактирую посты! ВСЕ!
|
|
|
|
SirNikolas | Дата: Среда, 08 Августа 2012, 18:16:06 | Сообщение # 16 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Да, вы правы. Переменная триггера остается висеть в блоке globals. В cJass-версию надо вписать: define <trigger gg_trg_ForceStaff = null>
|
|
|
|
Hexing | Дата: Среда, 08 Августа 2012, 18:20:44 | Сообщение # 17 |
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
| Quote (SirNikolas) В cJass-версию надо вписать: define <trigger gg_trg_ForceStaff = null> ух ты, спасибо за совет.
|
|
|
|
SirNikolas | Дата: Среда, 08 Августа 2012, 18:25:10 | Сообщение # 18 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Quote (Smartaros) че-то не пашет, юнит просто замирает на месте на время движения Возможно, у тебя не заданы переменные, отвечающие за границы карты. Нужно создать триггер SafeMove, скопировать туда функцию InitTrig_SafeMove, а саму SafeMove - в нестандартный код.
|
|
|
|
Smartaros | Дата: Среда, 08 Августа 2012, 20:45:02 | Сообщение # 19 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| ясно, а то я обе функции в нестандартный код скопировал
|
|
|
|
bubliq | Дата: Четверг, 09 Августа 2012, 13:46:57 | Сообщение # 20 |
2 уровень
Группа: Пользователи
Сообщений: 24
Награды: 0
Репутация: -12
Блокировки:
| У тебя во второй функции не обнуляется таймер. Но в последствии ты его удаляешь. На него остаётся переменная. В общем, вот мой, оптимизированный вариант твоего спелла. Именно код. Code function move takes unit u, real dist, real angle returns nothing call SetUnitX(u,GetUnitX(u)+dist*Cos(angle*.0174532)) call SetUnitY(u,GetUnitY(u)+dist*Sin(angle*.0174532)) endfunction
function Trig_assss_Move takes nothing returns nothing local timer t = GetExpiredTimer() local unit u = LoadUnitHandle(udg_Hash,GetHandleId(t),0) if(((GetUnitX(u)-udg_AAAA[0])*(GetUnitX(u)-udg_AAAA[0])+((GetUnitY(u)-udg_AAAA[1])*(GetUnitY(u)-udg_AAAA[1])))>=600.)then call SetUnitPathing(u,true) call FlushChildHashtable(udg_Hash,GetHandleId(t)) call PauseTimer(t) call DestroyTimer(t) else call move(u,6.00,GetUnitFacing(u)) endif set t = null set u = null endfunction
function Trig_Cond takes nothing returns boolean local unit u = null local timer t = null if GetSpellAbilityId() == 'A0F8' then set u = GetSpellAbilityUnit() set t = CreateTimer() set udg_AAAA[0] = GetUnitX(u1) set udg_AAAA[1] = GetUnitY(u1) call SaveUnitHandle(udg_Hash,GetHandleId(t),0,u) call TimerStart(t,.0225,true,function Trig_assss_Move) call SetUnitPathing(u,false ) set t = null set u = null endif return false endfunction
function InitTrig_assss takes nothing returns nothing set gg_trg_assss = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_assss, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_assss, Condition( function Trig_Cond ) ) endfunction
Что ты должен уразуметь. 1. Не спами лишний раз локальными переменными. Ты используешь тот же integer hid - один раз всего в коде, но ты уверен что ты выиграешь в производительности объявив его локалкой. Нет. Можно проще в коде юзать. 2. Сохранять хендл агента - неверно в корне. Юзай лучше на прямую. 3. Ты не обнулял, но уничтожал таймер. Понимаю если бы это был Recycle. Там бы это не пригодилось.
В принципе мой вариант, выжимает из твоей функции практически максимальную производительность
|
|
|
|
Hexing | Дата: Четверг, 09 Августа 2012, 13:57:10 | Сообщение # 21 |
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
| Quote (bubliq) Condition( function Trig_Cond ) утечка, не?
|
|
|
|
bubliq | Дата: Четверг, 09 Августа 2012, 15:20:19 | Сообщение # 22 |
2 уровень
Группа: Пользователи
Сообщений: 24
Награды: 0
Репутация: -12
Блокировки:
| Quote (Hexing) утечка, не? 1. Близзарды это исправили 2. Нет, используется единожды, а не в таймере (при этом, это данное полностью статично), без учета пункта один, утечки - нет.Добавлено (09 Августа 2012, 15:20:19) ---------------------------------------------
Quote (Hexing) ух ты, спасибо за совет. Этого писать не надо, автоматически отключается cJass оптимизатором (офк должна стоять галочка). Так что самое бредовое что я слышал, обнулять итак несуществующий (// закоменченный) триггер
|
|
|
|
Hexing | Дата: Четверг, 09 Августа 2012, 15:27:35 | Сообщение # 23 |
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
| Quote (bubliq) Этого писать не надо, автоматически отключается cJass оптимизатором (офк должна стоять галочка). Так что самое бредовое что я слышал, обнулять итак несуществующий (// закоменченный) триггер не говори чего не знаешь, я читал про это, это не реализовали, но на форуме уже есть соответствующие просьбы Quote (bubliq) 2. Нет, используется единожды, а не в таймере (при этом, это данное полностью статично), без учета пункта один, утечки - нет. угу, уже вспомнил
|
|
|
|
Smartaros | Дата: Четверг, 09 Августа 2012, 15:37:03 | Сообщение # 24 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| да я и не пытался скорость выжать, я нуб, просто статьи читал, первый код, я понятия не имею как быстрее и лучше
|
|
|
|
bubliq | Дата: Среда, 15 Августа 2012, 17:25:17 | Сообщение # 25 |
2 уровень
Группа: Пользователи
Сообщений: 24
Награды: 0
Репутация: -12
Блокировки:
| Quote (Hexing) не говори чего не знаешь, я читал про это, это не реализовали, но на форуме уже есть соответствующие просьбы Я говорю то что я знаю. Это вырезается как не используемая переменная, любым существующим оптимизатором. Но офк, мне все равно, пускай вы мараете руки об это, вам писать код дольше.
|
|
|
|
|
|
|
|
|
|
|