Сейчас 10:01:05 Пятница, 3 мая, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: PUVer, SirNikolas, Ty3uK  
Форум о Warcraft 3 » Раздел для картостроителей » GUI / Jass » Проверьте код
Проверьте код
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>

ух ты, спасибо за совет. ok


 

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)
не говори чего не знаешь, я читал про это, это не реализовали, но на форуме уже есть соответствующие просьбы

Я говорю то что я знаю. Это вырезается как не используемая переменная, любым существующим оптимизатором. Но офк, мне все равно, пускай вы мараете руки об это, вам писать код дольше.
 

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

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