XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
Один из методов OOP, его правильное использоване
Доброго всем времени суток.
Неделю назад в одной из тем jass'а DioD посоветовал использовать вместо стандартного создавания таймера на юните, с последующим удалением его при окончании действия на такой пример:
» CodeFromExample
globals

 integer	HolyLight_AbilityId	= 'A000'
 string		HolyLight_RayModelPath	= "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
 real		HolyLight_AreaOfEffect	= 200.00
 real		HolyLight_RayCollision	= 80.0
 real		HolyLight_WaveInterval	= 1.0

endglobals

function HolyLight_TargetFilter takes unit target returns boolean
    if (IsUnitType(target, UNIT_TYPE_STRUCTURE)) then
        return false
    endif
    if (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)) then
        return false
    endif
    if (IsUnitType(target, UNIT_TYPE_MECHANICAL)) then
        return false
    endif
 return true
endfunction

function HolyLight_RandomPointInCircle takes real centerX, real centerY, real radius returns location
 local real range = GetRandomReal(0.0, radius)
 local real angle = GetRandomReal(0.0, 360.0)
 local real x = centerX + range * Cos(angle * 3.14159/180.0)
 local real y = centerY + range * Sin(angle * 3.14159/180.0)
 return Location(x, y)
endfunction

function HolyLight_RayCount takes integer level returns integer
 return 5

    // Though I do not take advantage of the 'level' variable, I left it in there
    // so that people who may be altering this ability can alter the amount of rays
    // that appear per wave based on the ability's level.
endfunction

function HolyLight_HitpointsCalc takes integer level returns real
 return (15.0 + (15.0 * level))

    // This is the equation I use, returning amounts of 30/45/60. If a user wishes to
    // change the amount healed per ray, he may alter the equation here.
endfunction

struct HolyLight
 unit caster
 real centerX
 real centerY
 integer level
endstruct

function HolyLight_Channel takes nothing returns nothing

    local HolyLight data = 0
    local integer index = 0
    
    local group units = CreateGroup( )
    local unit temp = null
    local location random = null
    local real x = 0.0
    local real y = 0.0
    local real hitpoints = 0.0
    
    loop
        set data = data + 1
        if GetUnitCurrentOrder(data.caster) == OrderId("blizzard") then
                set index = 0
            loop
                set random = HolyLight_RandomPointInCircle(data.centerX, data.centerY, HolyLight_AreaOfEffect)
                set x = GetLocationX(random)
                set y = GetLocationY(random)
                set hitpoints = HolyLight_HitpointsCalc(data.level)
                call RemoveLocation(random)
                call DestroyEffect(AddSpecialEffect(HolyLight_RayModelPath, x, y))
                call GroupEnumUnitsInRange(units, x, y, HolyLight_RayCollision, null)
                loop
                    set temp = FirstOfGroup(units)
                    exitwhen (temp == null)
                    if (HolyLight_TargetFilter(temp)) then
                        if (IsUnitEnemy(temp, GetOwningPlayer(data.caster))) then
                            call UnitDamageTarget(data.caster, temp, hitpoints, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                        elseif (IsUnitAlly(temp, GetOwningPlayer(data.caster))) then
                            call SetUnitState(temp, UNIT_STATE_LIFE, GetUnitState(temp, UNIT_STATE_LIFE) + hitpoints)
                        endif
                    endif
                    call GroupRemoveUnit(units, temp)
                endloop
            
                exitwhen index >= HolyLight_RayCount(data.level)
                set index = index + 1
            endloop
            
        else
            set s__HolyLight_caster[data] = null
            call data.destroy( )
        endif
        exitwhen data == 5
    endloop
endfunction

function HolyLight_Conditions takes nothing returns boolean
    return (GetSpellAbilityId( ) == HolyLight_AbilityId)
endfunction

function HolyLight_Actions takes nothing returns nothing
    local HolyLight data = HolyLight.create( )
    call BJDebugMsg(I2S(data))
    set data.caster  = GetTriggerUnit( )
    set data.centerX = GetSpellTargetX()
    set data.centerY = GetSpellTargetY()
    set data.level   = GetUnitAbilityLevel(data.caster, HolyLight_AbilityId)
endfunction

function InitTrig_HolyLight takes nothing returns nothing
 local trigger spell = CreateTrigger( )
    call TimerStart(CreateTimer(), HolyLight_WaveInterval, true, function HolyLight_Channel)
    call TriggerRegisterAnyUnitEventBJ(spell, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(spell, Condition(function HolyLight_Conditions))
    call TriggerAddAction(spell, function HolyLight_Actions)
endfunction
Пользуясь таким методом диспечер задач показывает небольшое использование памяти, однако при использовании приема в разных спелах приводит к большим лагам
Пояснение предыдущей строки: 1\3 всех триггов я перевел на этот прием, в итоге получил задержку в пол секунды постоянно, она не подымаеться, но и не понижаеться из-за постоянных переборов структур
как пример спел с передвижением юнита
» SpellПытаясьпонятьсутьприема
scope Jump
include "cj_types_priv.j"

define {
private Spell1 = 'A01N'
private Speed = 30.00 }

private struct Data
unit u
real a
real r
real t
endstruct
function ParabolaZ takes real h, real d, real x returns real
return (4 * h / d) * (d - x) * (x / d)
endfunction

private bool Conditions() {
return GetSpellAbilityId() == Spell1 }

private void Move() {
Data D = 0
real x = 0.00
real y = 0.00
real z = 0.00
integer i = 0
loop
D = D + 1
if D.u!=null then
x = GetUnitX(D.u)+Speed*Cos(D.a)
y = GetUnitY(D.u)+Speed*Sin(D.a)
z = GetUnitFlyHeight()
if MapContainsCoords(x,y) and D.t < D.r then
D.t=D.t+Speed
SetUnitX(D.u, x) ; SetUnitY(D.u, y)
SetUnitFlyHeight( D.u, ParabolaZ(D.r/2,D.r,D.t), 0 )
else
D.u=null
D.a=0.00
D.r=0.00
D.destroy()
endif
endif
exitwhen i >= 5
endloop }

private void Actions() {
real xt = GetSpellTargetX()
real yt = GetSpellTargetY()
real x = 0.00
real y = 0.00
Data D = Data.create()
D.u = GetSpellAbilityUnit()
x = GetUnitX(D.u)
y = GetUnitY(D.u)
D.r = SquareRoot((yt-y)*(yt-y)+(xt-x)*(xt-x))
D.t = 0.00
SetUnitAnimationByIndex(D.u, 2)
UnitAddAbility(D.u, 'Arav')
UnitRemoveAbility(D.u, 'Arav')
if GetSpellAbilityId() == Spell1 then
D.a = Atan2(yt-y, xt-x)
else
D.a = Atan2(y-yt, x-xt)
endif }
===========================================================================
function InitTrig_Jump takes nothing returns nothing
timer t = CreateTimer()
TimerStart(t, 0.03, true, function Move)
gg_trg_Jump = CreateTrigger( )
TriggerRegisterPlayerUnitEvent(gg_trg_Jump,Player(0),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
TriggerRegisterPlayerUnitEvent(gg_trg_Jump,Player(1),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
TriggerRegisterPlayerUnitEvent(gg_trg_Jump,Player(2),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
TriggerRegisterPlayerUnitEvent(gg_trg_Jump,Player(3),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
TriggerRegisterPlayerUnitEvent(gg_trg_Jump,Player(4),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
TriggerRegisterPlayerUnitEvent(gg_trg_Jump,Player(5),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
TriggerRegisterPlayerUnitEvent(gg_trg_Jump,Player(6),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
TriggerRegisterPlayerUnitEvent(gg_trg_Jump,Player(7),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
TriggerRegisterPlayerUnitEvent(gg_trg_Jump,Player(8),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
TriggerRegisterPlayerUnitEvent(gg_trg_Jump,Player(9),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
TriggerAddCondition(gg_trg_Jump, Condition( function Conditions ) )
TriggerAddAction(gg_trg_Jump, function Actions)
t=null
endfunction
endscope
""
Обьясните пожалуйста что я упустил, не понял.
Если суть разложил не ясно, напишите, исправлю 1 пост на более внятную речь
Старый 15.06.2010, 23:51
ScorpioT1000
Работаем
offline
Опыт: отключен
ни разу не видел в ооп метода "кривые абилки" ...
Старый 16.06.2010, 00:03
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
пост
ScorpioT1001,
что я упустил, не понял.
не прямой же попуск на код новичка -.-
Старый 16.06.2010, 00:06
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
я не шарю в ооп, +знаний в языках программирования 0
здесь пытаюсь просто понять в чем же рационален тот или иной способ исполнения спелов
и помоему в первом посте это я и не написал, завтра исправлю
Старый 16.06.2010, 00:22
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
тему клоуз
Старый 16.06.2010, 18:47
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 17:48.