21

» WarCraft 3 / Lua: функции в таблице

prog, А как реализовать таблицу для героев, если герои - это ключи для таблицы Ability?
21

» WarCraft 3 / Lua: функции в таблице

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
Кстати, да. Можно добавить то, что Вы предложили. И использовать один триггер, который отлавливает касты способностей и запускать нужные функции.
21

» WarCraft 3 / Lua: функции в таблице

Нет, я понимаю, что это переменная. Я имел ввиду то, что в ней хранится.
Сейчас уже всё понял. Спасибо.
Написал свой код, но не работает. Почему?
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( )
21

» WarCraft 3 / Lua: функции в таблице

NazarPunk, v - это сам объект, а k - имя?
NazarPunk:
На код внимательно посмотреть))
Я код не запускал, поэтому такой вопрос получился)
21

» WarCraft 3 / Lua: функции в таблице

Предполагаю, что делается через какой-то цикл перебором всех элементов таблицы, если элемент является функцией, то запустить.
21

» WarCraft 3 / Заклинание: Волна Воды

удаляет объекты, на которые нет ссылок
То есть, если в коде просто написать CreateTimer( ), то он сам уничтожится? Как сборщик понимает, что этот таймер уже не нужен?
21

» WarCraft 3 / Заклинание: Волна Воды

TimerStart(CreateTimer(), TIMER_PERIOD, true, function() ...
Является ли безымянная функция утечкой? Каждый раз создаётся новая функция, а как её удалить я не знаю.
21

» WarCraft 3 / Что делает нативка Cheat?

Запускает чит:
Cheat( "whosyourdaddy" )
Cheat( "iseedeadpeople" )
Cheat( "warpten" )
Работает только в одиночной игре.
21

» WarCraft 3 / Как триггерно создать блок. пути на тип местности?

8gabriel8, ну чтобы красную сделать нужно:
SetTerrainPathable( x, y, PATHING_TYPE_BUILDABILITY, true )
SetTerrainPathable( x, y, PATHING_TYPE_WALKABILITY, false )
SetTerrainPathable( x, y, PATHING_TYPE_FLYABILITY, false )
Но будут ли работать все 3, или только последняя.
21

» WarCraft 3 / Как триггерно создать блок. пути на тип местности?

Steal nerves, сейчас не могу проверить, но можно ли одну точку сделать неWALKABILITY, но при этом BUILDABILITY? То есть повесть на одну точку несколько pathingtype одновременно?
21

» WarCraft 3 / Процентный хил

Умножаете максимальное здоровье на 0.1, а полученное значение добавляем к текущему здоровью.. Это и будет 10% хил от максимального хп.
21

» WarCraft 3 / Условие "если технология исследована"

Нет такого условия. Нужно проверять уровень исследования, если он выше 0, то исследование сделано.
21

» WarCraft 3 / Помогите получить значение Order способности

Если нужно именно узнать ордер, то создаёте триггер на отлов приказов (UNIT_ISSUED_ORDER, ISSUED_POINT_ORDER, ISSUED_TARGET_ORDER), а в действии триггера добавляем вывод на экран print( GetIssuedOrderId( ) ). B в игре кастуем эту способность.
21

» WarCraft 3 / Официально стал доступен PTR 1.31

prog, так теперь всегда будет? Или справят?
Если исправят, что зачем вручную кешировать?
21

» WarCraft 3 / Официально стал доступен PTR 1.31

Condition'ы больше не кешируются я так понимаю? Каждый раз показывает разные цифры:
function asd( )
    return false
end

function InitDebugTrigger( )
    local trig = CreateTrigger( )

    BlzTriggerRegisterPlayerKeyEvent( trig, Player( 0 ), OSKEY_ESCAPE, 0, true )
    TriggerAddAction( trig, function( )
        local cond = Condition( asd )

        print( "handle ID:  " .. GetHandleId( cond ) )

    end )
end
21

» WarCraft 3 / Официально стал доступен PTR 1.31

Ребят, что они сделали опять с иллюзиями? Как будто все нативки с ними не работают.
21

» WarCraft 3 / Лагодром № 1.31

Для смены языка нужно:
  1. Найти в папке установленной игры файл Launcher.db
  2. Открыть его через блокнот.
  3. Там будет всего 4 буквы, их нужно заменить на enUS.
  4. Далее открываем Warcraft III Launcher.exe и закрываем.
  5. Всё.
21

» WarCraft 3 / Как закрепить плавающий текст вверху экрана?

NazarPunk, да там у меня всё простенько для конкретной карты:
раскрыть
BUILDING_GRAVE                                                      = FourCC( "h003" )
BUILDING_TAVERN = { 
    [0]                                                             = FourCC( "n000" ),
    [1]                                                             = FourCC( "n001" ),
    [2]                                                             = FourCC( "n002" ),
    [3]                                                             = FourCC( "n00A" ),
    [4]                                                             = FourCC( "n00B" ),
    [5]                                                             = FourCC( "n00C" )
}

function IsUnitTavern( whichUnit )
    return 
        GetUnitTypeId( whichUnit ) == BUILDING_TAVERN[0] or 
        GetUnitTypeId( whichUnit ) == BUILDING_TAVERN[1] or 
        GetUnitTypeId( whichUnit ) == BUILDING_TAVERN[2] or 
        GetUnitTypeId( whichUnit ) == BUILDING_TAVERN[3] or 
        GetUnitTypeId( whichUnit ) == BUILDING_TAVERN[4] or 
        GetUnitTypeId( whichUnit ) == BUILDING_TAVERN[5] 
end

function CreateTaverns( )
    tavern = {
        [0] = CreateUnit( NEUTRAL_PASSIVE_PLAYER, BUILDING_TAVERN[0], 7744.0, - 8256.0, 270.000 ),
        [1] = CreateUnit( NEUTRAL_PASSIVE_PLAYER, BUILDING_TAVERN[1], 8000.0, - 8256.0, 270.000 ),

        [2] = CreateUnit( NEUTRAL_PASSIVE_PLAYER, BUILDING_TAVERN[2], 7488.0, - 8512.0, 270.000 ),
        [3] = CreateUnit( NEUTRAL_PASSIVE_PLAYER, BUILDING_TAVERN[3], 8000.0, - 8000.0, 270.000 ),

        [4] = CreateUnit( NEUTRAL_PASSIVE_PLAYER, BUILDING_TAVERN[4], 8000.0, - 8512.0, 270.000 ),
        [5] = CreateUnit( NEUTRAL_PASSIVE_PLAYER, BUILDING_TAVERN[5], 7744.0, - 8512.0, 270.000 )
    }

    for i = 0, #tavern do
        SetUnitColor( tavern[i], ConvertPlayerColor( i ) )
        SetUnitPathing( tavern[i], false )
        SetUnitVertexColor( tavern[i], 0xFF, 0xFF, 0xFF, 0xA0 )

        ForForce( HEROES_FORCE, function( )
            UnitShareVision( tavern[i], GetEnumPlayer( ), true )
        end )
    end
end

function IsUnitHero( whichUnit )
    local isHero = false
    
    ForForce( HEROES_FORCE, function( )
        local id = GetPlayerId( GetEnumPlayer( ) )

        if hero[id] == whichUnit then
            isHero = true
        end
    end )

    return isHero
end

function IsHeroPicked( unitId )
    local isPicked = false
    
    ForForce( HEROES_FORCE, function( )
        local id = GetPlayerId( GetEnumPlayer( ) )

        if GetUnitTypeId( hero[id] ) == unitId then
            isPicked = true
        end
    end )

    return isPicked
end

function GetHeroStartX( whichPlayer )
--  Only for Player(1), Player(2), Player(3), Player(4), Player(5), Player(6).
    return  5312.0 + 256.0 * Cos( 3.5430 + 0.5585 * GetPlayerId( whichPlayer ) )
end
    
function GetHeroStartY ( whichPlayer )
--  Only for Player(1), Player(2), Player(3), Player(4), Player(5), Player(6).
    return -5568.0 + 256.0 * Sin( 3.5430 + 0.5585 * GetPlayerId( whichPlayer ) )
end
    
function GetHeroStartFacing( whichPlayer )
--  Only for Player(1), Player(2), Player(3), Player(4), Player(5), Player(6).
    return bj_RADTODEG * Atan2( GetUnitY( GetTown( ) ) - GetHeroStartY( whichPlayer ), GetUnitX( GetTown( ) ) - GetHeroStartX( whichPlayer ) )
end

function InitHeroPick( )
    hero = { }

    TriggerRegisterForceUnitEvent( CreateTrigger( ), NEUTRAL_PASSIVE_FORCE, EVENT_PLAYER_UNIT_SELL, nil, function( )
        if IsUnitTavern( GetSellingUnit( ) ) then
            local id = GetPlayerId( GetOwningPlayer( GetSoldUnit( ) ) )

            hero[id] = GetSoldUnit( )

            SetPlayerAlliance( NEUTRAL_PASSIVE_PLAYER, Player( id ), ALLIANCE_SHARED_CONTROL, false )

            ForForce( DEFENSIVE_FORCE, function( )
                SetPlayerTechMaxAllowed( GetEnumPlayer( ), GetUnitTypeId( hero[id] ), 0 )
            end )

            SetUnitX     ( hero[id], GetHeroStartX( Player( id ) ) )
            SetUnitY     ( hero[id], GetHeroStartY( Player( id ) ) )
            SetUnitFacing( hero[id], GetHeroStartFacing( Player( id ) ) )

            UnitAddAbility( hero[id], ABILITY_REINCARNATE )
            UnitAddAbility( hero[id], ABILITY_MOVESPEED_INC )
            UnitAddAbility( hero[id], ABILITY_ADDITIONAL_SKILLZ )
            UnitAddAbility( hero[id], ABILITY_TOWN_PORTAL )
            UnitAddAbility( hero[id], ABILITY_INVENTORY )

            SetUnitState( hero[id], UNIT_STATE_LIFE, GetUnitState( hero[id], UNIT_STATE_MAX_LIFE ) )
            SetUnitState( hero[id], UNIT_STATE_MANA, GetUnitState( hero[id], UNIT_STATE_MAX_MANA ) )

            if GetLocalPlayer( ) == Player( id ) then
                ClearSelection( )
                ClearTextMessages( )
                SelectUnit( hero[id], true )
                SetCameraPosition( GetUnitX( hero[id] ), GetUnitY( hero[id] ) )
            end
        end
    end )

    SuperTextPrinter( GetLocalPlayer( ), 12.0, "|cFFFFFF00P I C K   H E R O|r" )
    DisplayTimedTextToPlayer( GetLocalPlayer( ), 0.0, 0.0, 0.0, " " )
    DisplayTimedTextToPlayer( GetLocalPlayer( ), 0.0, 0.0, 0.0, "|cFF32CD32HINT|r - Choose the right character for your game. To complete the game, your team must have at least one hero from each class. For more information, click on the tavern you are interested in." )
--  DisplayTimedTextToPlayer( GetLocalPlayer( ), 0.0, 0.0, 0.0, "|cFFFED312Ability Power:|r  Ability Power гладиаторы в битве полагаются в основном на урон с заклинаний, при этом сами обладают небольшим количеством брони и здоровья." )
--  DisplayTimedTextToPlayer( GetLocalPlayer( ), 0.0, 0.0, 0.0, "|cFFFED312Attack Damage:|r  oписание находится в разработке." )
--  DisplayTimedTextToPlayer( GetLocalPlayer( ), 0.0, 0.0, 0.0, "|cFFFED312Support:|r  сами Support'ы по себе не сильны, однако очень полезны для команды. Они могут как лечить раненных в бою союзников, так и усиливать огневую мощь атакующих." )
--  DisplayTimedTextToPlayer( GetLocalPlayer( ), 0.0, 0.0, 0.0, "|cFFFED312Tank:|r  гладиаторы класса Tank отвлекают в бою внимание противника на себя, предотвращая нанесение урона слобозащищённым персонажам. Могут также перехватить часть повреждений, нацеленных на союзников. Для выполнения поставленных задач Tank'и имеют хорошую защиту и большой запас здоровья." )
    StartSound( questHintSound )
    SetCameraTargetController( tavern[0], 0.0, 0.0, false )

    ForForce( HEROES_FORCE, function( )
        SetPlayerAlliance( NEUTRAL_PASSIVE_PLAYER, GetEnumPlayer( ), ALLIANCE_SHARED_CONTROL, true )
    end )
end

function InitHeroTriggers( )
    InitHeroPick( )
    InitHeroRevive( )
    InitHeroExperience( )
end