Есть ли в Lua способ запустить все функции указанной таблицы?
test = { }

test.a = 123
test.b = true

function test.func0( )
end

function test.func1( )
end

function test.qab( )
end
Нужно сделать так, чтобы все функции test.func0( ), test.func1( ), test.qab( ) были запущены. При этом заранее не известно количество функций.

Принятый ответ

ScopteRectuS:
Предполагаю, что делается через какой-то цикл перебором всех элементов таблицы, если элемент является функцией, то запустить.
Правильно предполагаете, но мануалы же никому неинтересны, проже же вопрос задать.
test   = { }
test.a = 123
test.b = true
function test.func0()
	print(0)
end
function test.func1()
	print(1)
end
function test.qab()
	print(2)
end

for k, v in pairs(test) do
	if type(v) == 'function' then
		print(k, ':')
		v()
	end
end
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
21
5 лет назад
0
Предполагаю, что делается через какой-то цикл перебором всех элементов таблицы, если элемент является функцией, то запустить.
1
29
5 лет назад
1
ScopteRectuS:
Предполагаю, что делается через какой-то цикл перебором всех элементов таблицы, если элемент является функцией, то запустить.
Правильно предполагаете, но мануалы же никому неинтересны, проже же вопрос задать.
test   = { }
test.a = 123
test.b = true
function test.func0()
	print(0)
end
function test.func1()
	print(1)
end
function test.qab()
	print(2)
end

for k, v in pairs(test) do
	if type(v) == 'function' then
		print(k, ':')
		v()
	end
end
Принятый ответ
0
21
5 лет назад
0
NazarPunk, простите за наглость. А как еще получить название функции?
1
29
5 лет назад
1
А как еще получить название функции?
На код внимательно посмотреть))
Загруженные файлы
0
21
5 лет назад
0
NazarPunk, v - это сам объект, а k - имя?
NazarPunk:
На код внимательно посмотреть))
Я код не запускал, поэтому такой вопрос получился)
0
29
5 лет назад
0
v - это сам объект, а k - имя?
Это сокращённо от key, value.
3
24
5 лет назад
3
ScopteRectuS, в k в этом коде попадает ключ по которому что-то лежит в таблице. В общем случае - ключ не обязательно строка.
0
21
5 лет назад
0
Нет, я понимаю, что это переменная. Я имел ввиду то, что в ней хранится.
Сейчас уже всё понял. Спасибо.
Написал свой код, но не работает. Почему?
Ability = { }
Ability.DeathCoil = { }

function Ability.DeathCoil.init( )
    print( 321 )
end

function InitAllAbilities( )
    for parentKey, parentValue in pairs( Ability ) do

        if type( parentValue ) == "table" then

            for childKey, chilValue in pairs( parentValue ) do
                if type( childValue ) == "function" and childKey == "init" then
                    childValue( )
                end
            end

        end
    end
end

InitAllAbilities( )
3
24
5 лет назад
Отредактирован prog
3
ScopteRectuS, Зачем так сложно то?

Ability = { }
Ability.DeathCoil = { }

function Ability.DeathCoil.init( )
    print( 321 )
end

function InitAllAbilities( )
    for parentKey, parentValue in pairs( Ability ) do
        if (type( parentValue ) == "table") then
			if(parentValue.init and type( parentValue.init ) == "function" ) then
				parentValue.init()
			end
       end
    end
end

InitAllAbilities( ) -- Этот вызов лучше бы перенести куда-то после инициализации карты, иначе будут проблемы.
Более того, я бы и от проверок на table и function избавился бы, условившись с самим собой что в таблице Ability могут лежать только таблицы спелов, а в таблицах спелов init либо функция либо его нет.
Ну и самое важное - я бы ключами в таблице Ability взял равкоды абилок, чтобы по равкоду абилки можно было сразу получить доступ к связанной с этим равкодом таблице.
Как-то так
	Ability = {}
	local DeathCoil = {}
	Ability[FourCC('A000')] = DeathCoil

	function DeathCoil.init( )
	...
	end
	
	function DeathCoil.cast( )
	...
	end
	...
	
function SomeTriggerAction()
	local spellId = GetSpellAbilityId()
	if(	Ability[spellId]) then
		if(Ability[spellId].cast)then
			Ability[spellId].cast()
		end
	end
end
...
А при желании можно еще и параметры в cast передавать.
0
21
5 лет назад
Отредактирован scopterectus
0
prog, да, без второго цикла действительно лучше!
Таблицы у меня так реализованы:
-----------------------------------------------------------------------------
--  H E R O E S                                                            --
-----------------------------------------------------------------------------
HERO_BLADEMASTER                                                    = FourCC( "Her0" )
HERO_DEATH_KNIGHT                                                   = FourCC( "Her2" )

-----------------------------------------------------------------------------
--  A B I L I T I E S                                                      --
-----------------------------------------------------------------------------
Q                                                                   = 0x000001
W                                                                   = 0x000002
E                                                                   = 0x000003
R                                                                   = 0x000004

Ability = {
    [ HERO_BLADEMASTER ] = { 
        [ Q ]                                                       = FourCC( "A006" ),
        [ W ]                                                       = FourCC( "A001" ),
        [ E ]                                                       = FourCC( "A000" ),
        [ R ]                                                       = FourCC( "A007" )
    },
    [ HERO_DEATH_KNIGHT ] = { 
        [ Q ]                                                       = FourCC( "A00I" ),
        [ W ]                                                       = 0,
        [ E ]                                                       = 0,
        [ R ]                                                       = 0
    },
    [ HERO_CRYPT_LORD ] = { 
        [ Q ]                                                       = FourCC( "A00B" ),
        [ W ]                                                       = 0,
        [ E ]                                                       = 0,
        [ R ]                                                       = 0
    },
    [ HERO_PALADIN ] = {
        [ Q ]                                                       = FourCC( "A004" ),
        [ W ]                                                       = 0,
        [ E ]                                                       = 0,
        [ R ]                                                       = 0
    }
}
И собственно сама способность:
-----------------------------------------------------------------------------
--  D E A T H   K N I G H T :   D E A T H   C O I L ,   ( Q )              --
-----------------------------------------------------------------------------

do
    Ability.DeathCoil = { }
    
    function Ability.DeathCoil.init( )
        RegisterAnyUnitEvent( EVENT_PLAYER_UNIT_SPELL_EFFECT, nil,
            function( )
                if GetSpellAbilityId( ) ~= Ability[ HERO_DEATH_KNIGHT ][ Q ] then return end

                local caster    = GetSpellAbilityUnit( )
                local player    = GetOwningPlayer( caster )
                local coilX     = GetUnitX( caster )
                local coilY     = GetUnitY( caster )
                local angle     = Atan2( GetSpellTargetY( ) - coilY, GetSpellTargetX( ) - coilX )
                local targetX   = Cos( angle ) * 800.0 + coilX
                local targetY   = Sin( angle ) * 800.0 + coilY
                local coil      = AddSpecialEffect( "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilMissile.mdl", coilX, coilY )
                local stock     = CreateGroup( )
                local enumGroup = CreateGroup( )

                local level     = GetUnitAbilityLevel( caster, GetSpellAbilityId( ) )
                local damage    = 75.0 * level
                local aoe       = 150.0

                BlzSetSpecialEffectYaw( coil, Atan2( targetY - coilY, targetX - coilX ) )
                    
                TimerStart( CreateTimer( ), 0.03125, true, 
                    function( )
                        local dx   = targetX - coilX
                        local dy   = targetY - coilY
                        local dist = math.sqrt( dx ^ 2 + dy ^ 2 )
                            
                        if dist > 32.8125 then
                            coilX = coilX + 32.8125 * ( dx / dist )
                            coilY = coilY + 32.8125 * ( dy / dist )

                            BlzSetSpecialEffectX( coil, coilX )
                            BlzSetSpecialEffectY( coil, coilY )

                            GroupEnumUnitsInRange( enumGroup, coilX, coilY, aoe + MAX_COLLISION_SIZE, nil ) 
                            while true do
                                local enumUnit = FirstOfGroup( enumGroup ) 
                                    
                                if enumUnit == nil then break else GroupRemoveUnit( enumGroup, enumUnit ) end

                                if 
                                    UnitAlive( enumUnit ) 
                                    and not IsUnitInGroup( enumUnit, stock ) 
                                    and not IsUnitBuilding( enumUnit ) 
                                    and enumUnit ~= caster 
                                    and IsUnitInRangeXY( enumUnit, coilX, coilY, aoe ) 
                                then
                                    DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl", enumUnit, "origin" ) )
                                    GroupAddUnit( stock, enumUnit )
                                    GroupRemoveUnit( enumGroup, enumUnit )

                                    if IsUnitEnemy( enumUnit, player ) then
                                        UnitDamageTarget( caster, enumUnit, damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, nil )

                                    elseif IsUnitAlly( enumUnit, player ) then
                                        UnitHealTarget( caster, enumUnit, damage )
                                    end
                                end
                            end
                                    
                        else
                            DestroyEffect( coil )
                            DestroyTimer( GetExpiredTimer( ) )
                            DestroyGroup( stock )
                            DestroyGroup( enumGroup )
                        end
                    end 
                )
            end 
        )
    end

end
Кстати, да. Можно добавить то, что Вы предложили. И использовать один триггер, который отлавливает касты способностей и запускать нужные функции.
1
24
5 лет назад
1
Я бы еще рекомендовал хранить в разных таблицах сами способности и привязку способностей к героям.
Грубо говоря, герои в таблице Heroes, способности в таблице Abilities. Позволит ускорить перебор и избежать ненужных проверок.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.