Написал я способность цепной молнии, и хочу узнать какие ошибки допустил.
Хотя их там много)
Вот карта - xgm.guru/files/100/338026/ChainLightning.w3x.
А также вопрос: можно ли в вопросах спрашивать вопросы данного типа?)
Код:
scope ChainLightning initializer Init
    globals
        private constant integer SpellId = 'A000'
        private constant real TimerTick = 0.005
        private constant real Distance = 1000
        private constant real Radius = 60
        private constant real RadiusChain = 400
        
        private timer TimerAct = CreateTimer( )
        private group GroupAct = CreateGroup( )
        private group GroupTemp = CreateGroup( )
    endglobals
    
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId( ) == SpellId
    endfunction
    
    private function ActionsTimer takes nothing returns nothing
        local integer id = GetHandleId( TimerAct )
        local unit caster = LU( Hash, id, k_caster )
        local real angle = LR( Hash, id, k_angle )
        local real casterX = LR( Hash, id, k_casterX )
        local real casterY = LR( Hash, id, k_casterY )
        local real casterZ = LR( Hash, id, k_casterZ )
        local real distance = LR( Hash, id, k_distance )
        local real newX = GetPolarOffsetX( casterX, distance, angle )
        local real newY = GetPolarOffsetY( casterY, distance, angle )
        local real newZ = GetPositionZ( newX, newY )
        local lightning light = LL( Hash, id, k_lightning )
        local unit firstUnit = null
        local unit pickedUnit = null
        
        call GroupEnum( GroupAct, Radius, newX, newY, GetBaseSpellFilter( caster ) )
        set firstUnit = FirstOfGroup( GroupAct )
        set distance = distance + 50
        
        if firstUnit == null then
            if distance < Distance then 
                call MoveLightningEx( light, true, casterX, casterY, casterZ, newX, newY, newZ )     
                call SR( Hash, id, k_distance, distance )
            else
                call GroupEnum( GroupAct, RadiusChain, newX, newY, GetBaseSpellFilter( caster ) )
            
                loop
                    set pickedUnit = GroupPickRandomUnit( GroupAct )
                    exitwhen pickedUnit == null
                    
                    if not IsUnitInGroup( pickedUnit, GroupTemp ) then
                        call RemoveLightningTimed( AddLightningEx( "CLSB", true, newX, newY, newZ, GetUnitX( pickedUnit ), GetUnitY( pickedUnit ), GetUnitZ( pickedUnit ) ), 0.2 )
                        call DamageUnit( caster, pickedUnit, 100, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC )
                        call GroupAddUnit( GroupTemp, pickedUnit )
                    endif
                    
                    call GroupRemoveUnit( GroupAct, pickedUnit )
                endloop
                
                call GroupClear( GroupTemp )
                call FlushChildHashtable( Hash, id )
                call RemoveLightningTimed( light, 0.1 )
                call PauseTimer( TimerAct )
            endif
        else
            call MoveLightningEx( light, true, casterX, casterY, casterZ, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetUnitZ( firstUnit ) )
            call PlayEffect( "Abilities\\Weapons\\Bolt\\BoltImpact.mdl", GetUnitX( firstUnit ), GetUnitY( firstUnit ) )
            call DamageUnit( caster, firstUnit, 100, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC )
            call GroupAddUnit( GroupTemp, firstUnit )
            call GroupEnum( GroupAct, RadiusChain, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetBaseSpellFilter( caster ) )
            
            loop
                set pickedUnit = GroupPickRandomUnit( GroupAct )
                exitwhen pickedUnit == null
                
                if not IsUnitInGroup( pickedUnit, GroupTemp ) then
                    call RemoveLightningTimed( AddLightningEx( "CLSB", true, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetUnitZ( firstUnit ), GetUnitX( pickedUnit ), GetUnitY( pickedUnit ), GetUnitZ( pickedUnit ) ), 0.2 )
                    set firstUnit = pickedUnit
                    call DamageUnit( caster, pickedUnit, 100, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC )
                    call GroupAddUnit( GroupTemp, firstUnit )
                endif
                
                call GroupRemoveUnit( GroupAct, pickedUnit )
            endloop
            
            call GroupClear( GroupTemp )
            call FlushChildHashtable( Hash, id )
            call RemoveLightningTimed( light, 0.1 )
            call PauseTimer( TimerAct )
        endif
        
        set caster = null
        set light = null
        set pickedUnit = null
    endfunction
    
    private function Actions takes nothing returns nothing
        local unit caster = GetSpellAbilityUnit( )
        local real castX = GetSpellTargetX( )
        local real castY = GetSpellTargetY( )
        local real angle = GetCastAngle( caster, castX, castY )
        local real casterX = GetPolarOffsetX( GetUnitX( caster ), 25, angle )
        local real casterY = GetPolarOffsetY( GetUnitY( caster ), 25, angle )
        local real casterZ = GetUnitZ( caster )
        local integer id = GetHandleId( TimerAct )
        local lightning light = AddLightningEx( "CLPB", true, casterX, casterY, casterZ, casterX, casterY, casterZ )
        
        call SU( Hash, id, k_caster, caster )
        call SR( Hash, id, k_angle, angle )
        call SR( Hash, id, k_casterX, casterX )
        call SR( Hash, id, k_casterY, casterY )
        call SR( Hash, id, k_casterZ, casterZ )
        call SR( Hash, id, k_distance, 0 )
        call SL( Hash, id, k_lightning, light )
        call TimerStart( TimerAct, TimerTick, true, function ActionsTimer )
        
        set caster = null
        set light = null
    endfunction
    
    private function Init takes nothing returns nothing
        call NewTriggerPlayerUnitEvent( EVENT_PLAYER_UNIT_SPELL_EFFECT, function Conditions, function Actions )
    endfunction
endscope

LastUchiha, код нормальный, я бы только этот момент поправил
			call GroupAddUnit( GroupTemp, firstUnit )
            call GroupEnum( GroupAct, RadiusChain, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetBaseSpellFilter( caster ) )
            
            loop
                set pickedUnit = GroupPickRandomUnit( GroupAct )
                exitwhen pickedUnit == null
                
                if not IsUnitInGroup( pickedUnit, GroupTemp ) then
                    call RemoveLightningTimed( AddLightningEx( "CLSB", true, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetUnitZ( firstUnit ), GetUnitX( pickedUnit ), GetUnitY( pickedUnit ), GetUnitZ( pickedUnit ) ), 0.2 )
                    set firstUnit = pickedUnit
                    call DamageUnit( caster, pickedUnit, 100, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC )
                    call GroupAddUnit( GroupTemp, firstUnit )
                endif
                
                call GroupRemoveUnit( GroupAct, pickedUnit )
            endloop
--->
            call GroupEnum( GroupAct, RadiusChain, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetBaseSpellFilter( caster ) )
            call GroupRemoveUnit( GroupAct, firstUnit )
            
            loop
                set bj_groupRandomConsidered = 0
                set bj_groupRandomCurrentPick = null
                call ForGroup( GroupAct, function GroupPickRandomUnitEnum)
                exitwhen bj_groupRandomCurrentPick == null
                call GroupRemoveUnit( GroupAct, bj_groupRandomCurrentPick )
                
                call RemoveLightningTimed( AddLightningEx( "CLSB", true, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetUnitZ( firstUnit ), GetUnitX( bj_groupRandomCurrentPick ), GetUnitY( bj_groupRandomCurrentPick ), GetUnitZ( bj_groupRandomCurrentPick ) ), 0.2 )
                call DamageUnit( caster, bj_groupRandomCurrentPick, 100, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC )
                
                set firstUnit = bj_groupRandomCurrentPick
            endloop
ну и надеюсь у тебя включена оптимизация кода, иначе очень хреново, что ты юзаешь вспомогательные функции, по сути создал свой арсенал близзардовских бжшек
`
ОЖИДАНИЕ РЕКЛАМЫ...
28
Приложи код к вопросу. Не каждый, кто может помочь, имеет доступ к редактору или желание открывать карту
Ответы (3)
15
rsfghd, Приложил, но там если что юзаются кастомные функции.
23
LastUchiha, он имел ввиду, наверное в текстовом виде, на сайте можно выводить код.
Типо так
15
RvzerBro, Ну я тоже так думал, но мне почему то в голово пришло, что сайт зажуёт код.
32
Ну во первых вовсе нифига не цепная молния, алгоритм даже не близко. Во вторых на кой черт ты и двигаешь молнии и находишь цели с 1 таймером, усложнил код и ниче не работает в итоге.
Отдельный код должен двигать молнию, отдельный искать цели и добавлять между ними разряды молний.
Стандартная молния ищет ближайшего видимого противника, к слову были же системы движения молний на сайте? Не?
Ниже кусок кода продвинутой дотки 6.83, цепная молния 1 в 1 как дефолт:
function Timer_ArcBolt_Expired takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer id = GetHandleId( t )
    local unit cast = LoadUnitHandle( HashData, id, 0 )
    local unit targ = LoadUnitHandle( HashData, id, 1 )
    local integer max = LoadInteger( HashData, id, 4 )
    local integer cur = LoadInteger( HashData, id, 5 )
    local group grp = LoadGroupHandle( HashData, id, ExChainGroup )
    local unit enemy = null

    call UnitDamageTarget( cast, targ, LoadReal( HashData, id, 3 ), false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS )
    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\Bolt\\BoltImpact.mdl", targ, "chest" ) )

    call GroupAddUnit( grp, targ )
    call GroupClear( bj_TempGroup )
    set bj_groupEnumOwningPlayer = GetOwningPlayer( cast )
    set bj_ChainGroup = grp
    call GroupEnumUnitsInRange( bj_TempGroup, GetUnitX( targ ), GetUnitY( targ ), RMaxBJ( LoadReal( HashData, id, 6 ), 200.00 ), Condition( function Only_Visibly_Enemy_No_Immune_NoReply_Unit ) )
    call GroupRemoveUnit( bj_TempGroup, targ )
    set enemy = GroupPickRandomUnit( bj_TempGroup )

    if enemy == null or cur >= max then
        call PauseTimer( t )
        call ReleaseTimer( t )
        call FlushChildHashtable( HashData, id )
        call NSI( grp )
    else
        call SaveInteger( HashData, id, 5, cur + 1 )
        call SaveUnitHandle( HashData, id, 1, enemy )
        call CreateBolt( targ, enemy, "CLSB", 1.50, false )
    endif

    set cast = null
    set targ = null
    set enemy = null
    set grp = null
    set t = null
endfunction

function Trig_ArcLightning_Actions takes nothing returns nothing
    local unit cast = GetSpellAbilityUnit( )
    local unit targ = GetSpellTargetUnit( )
    local integer level = GetUnitAbilityLevel( cast, 'A020' )
    local integer max = 3 + 2 * level
    local timer t = NewTimer( )
    local integer id = GetHandleId( t )

    if level == 4 then
        set max = 15
    endif

    call SaveUnitHandle( HashData, id, 0, cast )
    call SaveUnitHandle( HashData, id, 1, targ )
    call SaveReal( HashData, id, 3, 50.00 + 30.00 * level )
    call SaveInteger( HashData, id, 4, max )
    call SaveInteger( HashData, id, 5, 1 )
    call SaveGroupHandle( HashData, id, ExChainGroup, NTI( ) )
    call SaveReal( HashData, id, 6, 525 )

    call CreateBolt( cast, targ, "CLPB", 1.50, true )

    call TimerStart( t, 0.25, true, function Timer_ArcBolt_Expired )

    set cast = null
    set targ = null
    set t = null
endfunction

function Trig_ArcLightning_Conditions takes nothing returns boolean
    if GetSpellAbilityId( ) == 'A020' and not IsUnitHasNegation( GetSpellTargetUnit( ) ) then
        call Trig_ArcLightning_Actions( )
    endif
    return false
endfunction

//==== Init Trigger NewTrigger ====
function InitTrig_ArcLightning takes nothing returns nothing
    local trigger trg = CreateTrigger( )
    local integer nIndex = 1

    call TriggerAddCondition( trg, Condition( function Trig_ArcLightning_Conditions ) )

    loop
        exitwhen nIndex > 11
        if IsSlotPlayer( Player( nIndex ) ) then
            call TriggerRegisterPlayerUnitEvent( trg, Player( nIndex ), EVENT_PLAYER_UNIT_SPELL_EFFECT, OnlyHero )
        endif
        set nIndex = nIndex + 1
    endloop

    set trg = null
endfunction

пример поиска ближайшего юнита:
function AQ1 takes nothing returns nothing
    local unit enum = GetEnumUnit( )
    local real d = DistBetweenCords( GetUnitX( enum ), GetUnitY( enum ), PJ, QJ )
    if d < RJ then
        set RJ = d
        set TJ = enum
    endif
    set enum = null
endfunction

function AU1 takes group g, real x, real y returns unit
    set RJ = 999999
    set TJ = null
    set PJ = x
    set QJ = y
    call ForGroup( g, function AQ1 )
    return TJ
endfunction

Ну а вот урезанный кусок от системы движения молний, собственно чтобы делать красивые молниии нужно еще знать ImpactZ, это либо бд либо мемхак.
	struct LightningData
    private static constant timer period = CreateTimer( )
    private thistype prev
    private thistype next
    private lightning bolt
    private unit a1
    private unit a2
    private real ax1
    private real ay1
    private real ax2
    private real ay2
    private real alpha
    private real ticks
    private real time
    private boolean flag


    private stub method destroy takes nothing returns nothing

    call SetLightningColor( this.bolt, 0.00, 0.00, 0.00, 0.00 )
    call DestroyLightning( this.bolt )
    set this.a1 = null
    set this.a2 = null
    set this.bolt = null
    set this.alpha = 0.00

    set this.prev.next = this.next
    set this.next.prev = this.prev

    if ( thistype( 0 ).next == 0 ) then
        call PauseTimer( thistype.period )
    endif

    call thistype.deallocate( this )
endmethod
        
private static method iterate takes nothing returns nothing
    local thistype this = thistype( 0 ).next

    loop
        exitwhen ( this == 0 )
                
        if not IsUnitDead( this.a1 ) then
            set this.ax1 = GetUnitX( this.a1 )
            set this.ay1 = GetUnitY( this.a1 )
            if this.flag then
                set this.ax1 = this.ax1 + 25.00
                set this.ay1 = this.ay1 - 25.00
            endif
        endif
                    
        if not IsUnitDead( this.a2 ) then
            set this.ax2 = GetUnitX( this.a2 )
            set this.ay2 = GetUnitY( this.a2 )
        endif
                
        set TempAZ = GetLocationZ( bj_TempPoint ) + GetUnitFlyHeight( this.a1 ) + GetUnitHeight( this.a1 )
        call MoveLocation( bj_TempPoint, this.ax2, this.ay2 )
        set TempBZ = GetLocationZ( bj_TempPoint ) + GetUnitFlyHeight( this.a2 ) + GetUnitHeight( this.a2 )
        call MoveLightningEx( this.bolt, true, this.ax1, this.ay1, TempAZ, this.ax2, this.ay2, TempBZ )
                    
        if GetLightningColorA( this.bolt ) > this.alpha then
            call SetLightningColor( this.bolt, GetLightningColorR( this.bolt ), GetLightningColorG( this.bolt ), GetLightningColorB( this.bolt ), GetLightningColorA( this.bolt ) - this.alpha )
        endif
                    
        set this.ticks = ( this.ticks + 0.03125 ) * 1.00
        if this.ticks > this.time then
            call this.destroy( )
        endif
                    
        set this = this.next
    endloop

endmethod

static method CreateBolt takes unit a, unit b, string CodeName, real timeout, boolean IsCaster returns thistype
    local thistype this = thistype.allocate( )

    set this.next = thistype( 0 )
    set this.prev = thistype( 0 ).prev
    set this.next.prev = this
    set this.prev.next = this
    set this.a1 = a
    set this.a2 = b
    set this.ax1 = GetUnitX( this.a1 )
    set this.ay1 = GetUnitY( this.a1 )
    set this.ax2 = GetUnitX( this.a2 )
    set this.ay2 = GetUnitY( this.a2 )
    set this.alpha = ( 1.00 / ( timeout / 0.03125 ) )
    set this.ticks = 0
    set this.time = timeout
    set this.flag = IsCaster
            
    call MoveLocation( bj_TempPoint, this.ax1, this.ay1 )
    set TempAZ = GetLocationZ( bj_TempPoint ) + GetUnitFlyHeight( this.a1 ) + GetUnitHeight( this.a1 )
    call MoveLocation( bj_TempPoint, this.ax2, this.ay2 )
    set TempBZ = GetLocationZ( bj_TempPoint ) + GetUnitFlyHeight( this.a2 ) + GetUnitHeight( this.a2 )
    if this.flag then
        set this.ax1 = this.ax1 + 25.00
        set this.ay1 = this.ay1 - 25.00
    endif
    set this.bolt = AddLightningEx( CodeName, true, this.ax1, this.ay1, TempAZ, this.ax2, this.ay2, TempBZ )
    if ( this.prev == 0 ) then
        call TimerStart( thistype.period, 0.03125, true, function thistype.iterate )
    endif
    return this
endmethod
endstruct
Ответы (3)
15
quq_CCCP, Ну вообще, я делал что-то на подобии такого.
Из игры Skyrim, а не из доты.
Загруженные файлы
32
LastUchiha, это отменяет твои ошибки? Посыл про разделение отрисовки молний и поиска целей не понятен? И как всё можно сделать проще и удобнее.
15
quq_CCCP, Насчёт поиска, я ведь ищу именно юнита который первый под молнию попадается, молния ведь не таргет. И способность мне нужна в MUI виде, я 2 группы и 1 таймер глобалками для примера сделал.
28
LastUchiha, код нормальный, я бы только этот момент поправил
			call GroupAddUnit( GroupTemp, firstUnit )
            call GroupEnum( GroupAct, RadiusChain, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetBaseSpellFilter( caster ) )
            
            loop
                set pickedUnit = GroupPickRandomUnit( GroupAct )
                exitwhen pickedUnit == null
                
                if not IsUnitInGroup( pickedUnit, GroupTemp ) then
                    call RemoveLightningTimed( AddLightningEx( "CLSB", true, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetUnitZ( firstUnit ), GetUnitX( pickedUnit ), GetUnitY( pickedUnit ), GetUnitZ( pickedUnit ) ), 0.2 )
                    set firstUnit = pickedUnit
                    call DamageUnit( caster, pickedUnit, 100, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC )
                    call GroupAddUnit( GroupTemp, firstUnit )
                endif
                
                call GroupRemoveUnit( GroupAct, pickedUnit )
            endloop
--->
            call GroupEnum( GroupAct, RadiusChain, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetBaseSpellFilter( caster ) )
            call GroupRemoveUnit( GroupAct, firstUnit )
            
            loop
                set bj_groupRandomConsidered = 0
                set bj_groupRandomCurrentPick = null
                call ForGroup( GroupAct, function GroupPickRandomUnitEnum)
                exitwhen bj_groupRandomCurrentPick == null
                call GroupRemoveUnit( GroupAct, bj_groupRandomCurrentPick )
                
                call RemoveLightningTimed( AddLightningEx( "CLSB", true, GetUnitX( firstUnit ), GetUnitY( firstUnit ), GetUnitZ( firstUnit ), GetUnitX( bj_groupRandomCurrentPick ), GetUnitY( bj_groupRandomCurrentPick ), GetUnitZ( bj_groupRandomCurrentPick ) ), 0.2 )
                call DamageUnit( caster, bj_groupRandomCurrentPick, 100, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC )
                
                set firstUnit = bj_groupRandomCurrentPick
            endloop
ну и надеюсь у тебя включена оптимизация кода, иначе очень хреново, что ты юзаешь вспомогательные функции, по сути создал свой арсенал близзардовских бжшек
Принятый ответ
28
решил чисто из спеллмейкерского любопытства заценить и открыть карту, и был разочарован, ты бы хоть удосужился плавное сгасание добавить молниям, дополнительные эффекты от нанесения урона, не по земле молнию волочить, а с оффсетом (выше упомянули ImpactZ, но хотя бы для покрытия половины нужд тыкнуть +50/60 к Z, чтобы оторвать от земли)
Ответы (21)
15
rsfghd, Да я там забыл вроде высоту добавить после GetUnitZ)))
А плавное сгасание делать через понижение непрозрачности?
15
quq_CCCP, Да видел, там на структурах сгасание сделано, я этого не понимаю, обучаться этому не хочу пока что.
Но спасибо за пример!
28
LastUchiha, структуры очень сильно облегчат тебе работу с кодом. Лучше выгрузить структуру и сразу работать со значениями, нежели выгружать каждое значение, изменять его и снова сохранять.
Вот тебе простой пример:
globals
	constant hashtable H = InitHashtable( )
endglobals

struct MyStruct
	unit caster
	
	real x
	real y
	real z
endstruct

function FuncForTimer takes nothing returns nothing
	local MyStruct A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
	
	set A.x = A.x + 5.00
	set A.y = A.y + 5.00
	set A.z = A.z + 5.00

	call SetUnitPositition( A.caster, A.x, A.y )
	
	set A.caster = null
	call A.destroy( ) // удаление структуры

	call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
	call DestroyTimer( GetExpiredTimer( ) )
endfunction

function MyFunc takes nothing returns nothing
	local timer t = CreateTimer( )
	local MyFunc A = MyFunc.create( ) // создание структуры

	set A.caster = GetTriggerUnit( )

	set A.x = GetUnitX( A.caster )
	set A.y = GetUnitY( A.caster )
	set A.z = GetUnitFlyHeight( A.caster )

	call SaveInteger( H, GetHandleId( t ), 0, A ) // структура это целочисленная
	call TimerStart( t, 0.00, false, function FuncForTimer )

	set t = null
endfunction
15
rsfghd, Аа, вот тут понятно щас стало, то есть по сути можно собирать свой набор локалок?
И где их лучше так сказать объявлять? Ну то есть в шапке карты можно создавать вариации структур?
28
LastUchiha, это не локалки, а глобалки. Лучше в личку спрашивать, уведомления сайта не работают
28
LastUchiha, там я MyFunc с MyStruct перепутал. Ибо писал в ручную с телефона, а не на компе
30
Ну то есть в шапке карты можно создавать вариации структур?
Забудь про структуры и не трогай их даже палочкой.
28
LastUchiha, он просто хейтит в то, во что они в коде превращается, и типа если тебе структуру аргументом в функцию передавать не нужно, то и смысла от неё нет, не обращай внимания
15
rsfghd, А оптимизированней ли такой способ написания спеллов, чем на обычных локалках?
И да видел я тоже во что они превращаются, глобальные массивы, а если таких массивом много накопится?
Стоит ли вообще об этом переживать?
30
а если таких массивом много накопится?
Когда накопится 8192 экземпляра структур твоя жопа будет отстрелена.
28
LastUchiha, нет, переживать не стоит. Будет оптимизированней, чем обработка локальных переменных функциями Load/Save и StringHash. Жопа отстроена не будет, если не забудешь уничтожать структуры по их ненужде (окончание спелла, к примеру, ибо вряд-ли у тебя будет 9к кастов одновременно)
15
rsfghd, Раз дело до оптимизации дошло, получается глобалки оптимизированней локалок если в спелле есть частый таймер?
18
LastUchiha, нет, их задача хранить информацию, не отвечают они за оптимизацию. Комп выделяет место под хранение информации, для глобалок на старте, а локалок по ходу их создания. По простому, задача локальних, в нужный период отработать внутри функции и освободить место. Возможно скорость будет чуть ниже, но она на столько мизерная, что не стоит на протяжении всей игры "занимать место".
28
LastUchiha, этот вопрос уже не столь к структурам относится, вирт машина читает быстрее последнюю созданную переменную, т.е. локалки, поэтому доступ к ним происходит быстрее, но это наносекунды и на игру не влияет. Глобалки, в отличии от локалок, обнулять не нужно, поэтому и существуют темповые переменные, чтобы, к примеру, не создавать каждый раз группу при необходимости выбора юнитов
Если возвращаться к структурам, то опять же, сохранять каждое значение под определённым ключем, в частности, если ты юзаешь стрингхэши, а потом ещё и выгрузка всех этих значений с последующим сейвом при их изменении - обойдётся тебе куда дороже, чем выгрузка целочисленной для работы со структурой, я уже молчу о банальном удобстве
28
LastUchiha, просто чтобы ты знал, работа с переменными происходит быстрее, чем с вызовом функций, для остальных интересующих тебя вещей существуют бенчмарки в мемхаке/южапи, балуйся
Чтобы оставить комментарий, пожалуйста, войдите на сайт.