Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Jass
Тип:
Алгоритм
Версия Warcraft:
UjAPI v1.1.14.215+

О системе

Относительно краткий пример создания пик системы строго на CSimpleFrame/CSimpleRegion фреймах (за исключением превью героя) используя UjAPI и Frame API.
Главным бонусом UjAPI в данной наработке является handlelist тип, который позволяет нам хранить все созданные фреймы в "листе" и не использовать тучу переменных, без какой-либо нужды. Ну и конечно же HashTable, которая решает в целом проблемы работы с MUI наработками.
Собственно, почему же выбор пал на CSimpleFrame/CSimpleRegion типы фреймов? На деле, главная причина - отсутствие в целом поддержки этих фреймов как на Reforged, так и в DzAPI. Хотя этих фреймов хватает почти на все нужды, если расширить их API.
Данная система конечно же работает в онлайне и не вызывает десинха, иначе это не имело бы смысла.

Код

раскрыть
globals
    hashtable frameHT = InitHashtable( )
    framehandle pickTooltip = null
    framehandle frameTemp = null
    handlelist heroPickButtons = HandleListCreate( )
    constant real frameButtonBaseWidth = .038
    constant real frameButtonBaseHeight = .038
endglobals

function GetFrameBaseWidth takes framehandle frm returns real
    local integer fid = GetHandleId( frm )
    local real width = .0

    if HaveSavedReal( frameHT, fid, 'sizX' ) then
        set width = LoadReal( frameHT, fid, 'sizX' )
    else
        set width = GetFrameWidth( frm )
        call SaveReal( frameHT, fid, 'sizX', width )
    endif

    return width
endfunction

function GetFrameBaseHeight takes framehandle frm returns real
    local integer fid = GetHandleId( frm )
    local real height = .0

    if HaveSavedReal( frameHT, fid, 'sizY' ) then
        set height = LoadReal( frameHT, fid, 'sizY' )
    else
        set height = GetFrameHeight( frm )
        call SaveReal( frameHT, fid, 'sizY', height )
    endif

    return height
endfunction

function GetPickSystemTooltip takes nothing returns framehandle
    local framehandle gameUI = null
    local framehandle consoleUI = null
    local framehandle pickUI = null
    local framehandle texture = null
    local framehandle textFrame = null
    local framehandle spriteFrame = null
    local integer i = 0

    if pickTooltip != null then
        return pickTooltip
    endif

    set consoleUI = GetOriginFrame( ORIGIN_FRAME_CONSOLE_UI, 0 )
    set pickUI = GetCSimpleFrameByName( "HeroSelectionUI", 0 )

    set pickTooltip = CreateFrameByType( "SIMPLEFRAME", "HeroPickToolTip", consoleUI, "", 0 )
    call ClearFrameAllPoints( pickTooltip )
    call SetFrameSize( pickTooltip, .1225, .45 ) // .25
    call SetFrameRelativePoint( pickTooltip, FRAMEPOINT_TOPRIGHT, pickUI, FRAMEPOINT_TOPRIGHT, .12, .0 ) // UI\\Widgets\\ToolTips\\Human\\human-tooltip-background | UI\\Widgets\\ToolTips\\Human\\human-tooltip-border
    call SetFrameTextureEx( pickTooltip, 0, "UI\\Widgets\\EscMenu\\Orc\\orc-options-menu-background", false, "UI\\Widgets\\EscMenu\\Orc\\orc-options-menu-border", BORDER_FLAG_ALL )
    call SetFramePriority( pickTooltip, 4 )

    set texture = CreateFrameByType( "SIMPLETEXTURE", "HeroPickIcon", pickTooltip, "", 0 )
    //call SetFrameTexture( texture, heroIcon, 0, false )
    call ClearFrameAllPoints( texture )
    call SetFrameRelativePoint( texture, FRAMEPOINT_TOPLEFT, pickTooltip, FRAMEPOINT_TOPLEFT, .005, -.0075 )
    call SetFrameSize( texture, .0125, .025 )
    call SetFrameBlendMode( texture, 0, BLEND_MODE_BLEND )
    call ShowFrame( texture, true )

    set textFrame = CreateFrameByType( "SIMPLETEXT", "HeroPickTextHeader", pickTooltip, "", 0 )
    call ClearFrameAllPoints( textFrame )
    call SetFrameRelativePoint( textFrame, FRAMEPOINT_TOPLEFT, texture, FRAMEPOINT_TOPRIGHT, .0, -.0025 )
    call SetFrameBlendMode( textFrame, 0, BLEND_MODE_BLEND )
    call SetFrameFont( textFrame, "Fonts\\FRIZQT__.TTF", .015, 0 )
    call SetFrameTextAlignment( textFrame, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE )
    call SetFrameWidth( textFrame, .1 )
    call SetFrameText( textFrame, " " )
    call ShowFrame( textFrame, true )

    set textFrame = CreateFrameByType( "SIMPLETEXT", "HeroPickTextBody", pickTooltip, "", 0 )
    call ClearFrameAllPoints( textFrame )
    call SetFrameRelativePoint( textFrame, FRAMEPOINT_TOPLEFT, texture, FRAMEPOINT_BOTTOMLEFT, .0, -.005 )
    call SetFrameBlendMode( textFrame, 0, BLEND_MODE_BLEND )
    call SetFrameFont( textFrame, "Fonts\\FRIZQT__.TTF", .011, 0 )
    call SetFrameTextHorizontalAlignment( textFrame, TEXT_JUSTIFY_LEFT )
    call SetFrameWidth( textFrame, .115 )
    call SetFrameText( textFrame, " " )
    call ShowFrame( textFrame, true )

    loop
        exitwhen i > 3

        set texture = CreateFrameByType( "SIMPLETEXTURE", "HeroPickAbilityIcon", pickTooltip, "", i )
        call SetFrameTexture( texture, "ReplaceableTextures\\CommandButtons\\BTNHeroArchMage", 0, false )
        call ClearFrameAllPoints( texture )
        call SetFrameRelativePoint( texture, FRAMEPOINT_TOPLEFT, pickTooltip, FRAMEPOINT_TOPLEFT, .005, -.1 + i * -.03 )
        call SetFrameSize( texture, .0125, .025 )
        call SetFrameBlendMode( texture, 0, BLEND_MODE_BLEND )
        call ShowFrame( texture, true )

        set textFrame = CreateFrameByType( "SIMPLETEXT", "HeroPickAbilityText", pickTooltip, "", i )
        call ClearFrameAllPoints( textFrame )
        call SetFrameRelativePoint( textFrame, FRAMEPOINT_TOPLEFT, texture, FRAMEPOINT_TOPRIGHT, .005, -.0065 )
        call SetFrameBlendMode( textFrame, 0, BLEND_MODE_BLEND )
        call SetFrameFont( textFrame, "Fonts\\FRIZQT__.TTF", .012, 0 )
        call SetFrameTextAlignment( textFrame, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_LEFT )
        call SetFrameText( textFrame, "" )
        call ShowFrame( textFrame, true )

        set i = i + 1
    endloop

    call ShowFrame( pickTooltip, false )
    
    set gameUI = GetOriginFrame( ORIGIN_FRAME_GAME_UI, 0 )
    
    set spriteFrame = CreateFrameByType( "SPRITE", "HeroPickSelector", gameUI, "", 0 )
    call ClearFrameAllPoints( spriteFrame )
    call SetFrameAbsolutePoint( spriteFrame, FRAMEPOINT_CENTER, .2, .2 )
    call SetFrameSize( spriteFrame, .01, .01 )
    call SetFrameSpriteModel( spriteFrame, "UI\\Feedback\\Autocast\\UI-ModalButtonOn.mdl" )
    call SetFrameLayerFlag( spriteFrame, LAYER_STYLE_IGNORE_TRACK_EVENTS, true )
    call ShowFrame( spriteFrame, false )

    set gameUI = null
    set consoleUI = null
    set texture = null
    set textFrame = null
    set spriteFrame = null

    return pickTooltip
endfunction

function OnButtonEnter takes nothing returns nothing
    local player p = GetTriggerPlayer( )
    local framehandle but = GetTriggerFrame( )
    local framehandle cursor = GetOriginFrame( ORIGIN_FRAME_CURSOR_FRAME, 0 )
    local framehandle tooltip = GetPickSystemTooltip( )
    local framehandle frm = null
    local integer index = LoadInteger( frameHT, GetHandleId( but ), 'indx' )
    local integer typeId = LoadInteger( frameHT, GetHandleId( but ), 'tpid' )
    local string texturePath = GetFrameTexture( but, 0 )
    local string modelPath = LoadStr( frameHT, GetHandleId( but ), 'modl' )
    local string name = LoadStr( frameHT, GetHandleId( but ), 'name' )
    local string text = LoadStr( frameHT, GetHandleId( but ), 'text' )
    local string abilList = GetUnitBaseStringFieldById( typeId, UNIT_SF_HERO_ABILITY_LIST )
    local string s = ""
    local integer abilCount = StringCount( abilList, ",", false ) + 1
    local integer i = 0
    local integer abilId = 0
    local integer len = 0
    local string array abilListData

    //call ConsolePrint( "OnButtonEnter\n" )

    if abilCount == 4 then
        if p == GetLocalPlayer( ) then
            set abilList = StringReplace( abilList, ",", "", true )
            set len = StringLength( abilList )
            //call ConsolePrint( "[" + GetTimeStamp( true, 0 ) + "]: OnButtonEnter\n" )
            //call ConsolePrint( "[" + GetTimeStamp( true, 0 ) + "]: OnButtonEnter | abilList = " + abilList + " | count = " + I2S( abilCount ) + "\n" )

            loop
                exitwhen i * 4 >= len
                set s = SubString( abilList, i * 4, i * 4 + 4 )
                
                set abilId = String2Id( s )
                set abilListData[ i ] = GetAbilityBaseStringFieldById( abilId, ABILITY_SF_NAME )
                set abilListData[ 100 + i ] = GetAbilityBaseStringFieldById( abilId, ABILITY_SF_ICON_NORMAL )

                //call ConsolePrint( "[" + GetTimeStamp( true, 0 ) + "]: abilId = " + s + "\n" )
                //call ConsolePrint( "[" + GetTimeStamp( true, 0 ) + "]: name = " + abilListData[ i ] + "\n" )
                //call ConsolePrint( "[" + GetTimeStamp( true, 0 ) + "]: icon = " + abilListData[ 100 + i ] + "\n" )

                set frm = GetCSimpleFontStringByName( "HeroPickAbilityText", i )
                call SetFrameText( frm, abilListData[ i ] )

                set frm = GetCSimpleTextureByName( "HeroPickAbilityIcon", i )
                call SetFrameTexture( frm, abilListData[ 100 + i ], 0, false )

                set i = i + 1
            endloop

            //call ConsolePrint( "[" + GetTimeStamp( true, 0 ) + "]: OnButtonEnter | typeId = " + Id2String( typeId ) + "\n" )
            //call ConsolePrint( "[" + GetTimeStamp( true, 0 ) + "]: OnButtonEnter | abilList = " + abilList + " | count = " + I2S( abilCount ) + "\n" )

            call SetFrameSpriteColour( cursor, 0xFF00FF00 )

            call ShowFrame( tooltip, true )

            set frm = GetCSimpleTextureByName( "HeroPickIcon", 0 )
            call SetFrameTexture( frm, texturePath, 0, false )

            set frm = GetCSimpleFontStringByName( "HeroPickTextHeader", 0 )
            call SetFrameText( frm, name )

            set frm = GetCSimpleFontStringByName( "HeroPickTextBody", 0 )
            call SetFrameText( frm, text )
            
            //call ConsolePrint( "[" + GetTimeStamp( true, 0 ) + "]:================\n" )
        endif
    endif

    set p = null
    set but = null
    set frm = null
    set cursor = null
    set tooltip = null
endfunction

function OnButtonLeave takes nothing returns nothing
    local player p = GetTriggerPlayer( )
    local framehandle but = GetTriggerFrame( )
    local framehandle cursor = GetOriginFrame( ORIGIN_FRAME_CURSOR_FRAME, 0 )

    //call ConsolePrint( "OnButtonLeave\n" )

    if p == GetLocalPlayer( ) then
        call SetFrameSpriteColour( cursor, 0xFFFFFFFF )
        call ShowFrame( pickTooltip, false )
    endif
    
    set p = null
    set but = null
    set cursor = null
endfunction

function OnButtonPress takes nothing returns nothing
    local framehandle but = GetTriggerFrame( )
    local integer bid = GetHandleId( but )
    local player p = GetTriggerPlayer( )
    local real width = GetFrameBaseWidth( but )
    local real height = GetFrameBaseHeight( but )

    if p == GetLocalPlayer( ) then
        if but != null then
            if not LoadBoolean( frameHT, bid, 'prss' ) then
                call SetFrameSize( but, width * .98, height * .98 ) // .024, .0465
                call SaveBoolean( frameHT, bid, 'prss', true )
            endif
        endif
    endif

    set p = null
    set but = null
endfunction

function OnUnPressHandler takes nothing returns nothing
    local integer hid = GetHandleId( GetExpiredTimer( ) )
    local player p = LoadPlayerHandle( frameHT, hid, '+ply' )
    local framehandle but = LoadFrameHandle( frameHT, hid, '+frm' )
    local integer bid = GetHandleId( but )
    local real width = GetFrameBaseWidth( but )
    local real height = GetFrameBaseHeight( but )

    if p == GetLocalPlayer( ) then
        if but != null then
            if LoadBoolean( frameHT, bid, 'prss' ) then
                call SetFrameSize( but, width, height ) // .025, .0475
                call SaveBoolean( frameHT, bid, 'prss', false )
            endif
        endif
    endif

    set p = null
    set but = null
endfunction

function OnButtonUnPress takes nothing returns nothing
    local player p = GetTriggerPlayer( )
    local framehandle but = GetTriggerFrame( )
    local timer tmr = LoadTimerHandle( frameHT, GetHandleId( but ), '+tmr' )

    if tmr == null then
        set tmr = CreateTimer( )
        call SaveTimerHandle( frameHT, GetHandleId( but ), '+tmr', tmr )
        call SavePlayerHandle( frameHT, GetHandleId( tmr ), '+ply', p )
        call SaveFrameHandle( frameHT, GetHandleId( tmr ), '+frm', but )
    endif

    call TimerStart( tmr, .1, false, function OnUnPressHandler )

    set p = null
    set but = null
endfunction

function OnButtonClick takes nothing returns nothing
    local player p = GetTriggerPlayer( )
    local framehandle but = GetTriggerFrame( )
    local framehandle selector = GetCFrameByName( "HeroPickSelector", 0 )
    local framehandle spriteFrame = GetCFrameByName( "HeroPickSprite", 0 )
    local integer butHid = GetHandleId( but )
    local integer pHid = GetHandleId( p )
    local integer index = LoadInteger( frameHT, butHid, 'indx' )
    local integer typeId = LoadInteger( frameHT, butHid, 'tpid' )
    local string modelFile = LoadStr( frameHT, butHid, 'modl' )
    local real startAngle = 90.

    if HaveSavedReal( frameHT, pHid, 'angl' ) then
        set startAngle = LoadReal( frameHT, pHid, 'angl' )
    else
        call SaveReal( frameHT, pHid, 'angl', startAngle )
    endif
    
    call SaveInteger( frameHT, pHid, '+hId', index )
    
    if p == GetLocalPlayer( ) then
        call SetFrameAllPoints( selector, but )
        call SetFrameSpriteMatrixScale( selector, GetFrameBaseWidth( but ) / frameButtonBaseWidth, GetFrameBaseHeight( but ) / frameButtonBaseHeight, 1. )
        call ShowFrame( selector, true )

        call SetFrameSpriteModel( spriteFrame, modelFile )
        call SetFrameSpriteScale( spriteFrame, .001 )
        call SetFrameSpriteOrientation( spriteFrame, 0., startAngle, 90. )
        call SetFrameSpriteAnimationWithRarity( spriteFrame, "stand", RARITY_RARE )
        call ShowFrame( spriteFrame, true )
    endif

    set p = null
    set but = null
    set selector = null
    set spriteFrame = null
endfunction

function OnButtonRotateLeftClick takes nothing returns nothing
    local player p = GetTriggerPlayer( )
    local framehandle but = GetTriggerFrame( )
    local framehandle spriteFrame = GetCFrameByName( "HeroPickSprite", 0 )
    local integer pHid = GetHandleId( p )
    local real startAngle = LoadReal( frameHT, pHid, 'angl' )

    if p == GetLocalPlayer( ) then
        set startAngle = startAngle + 30.
        if startAngle > 360. then
            set startAngle = 30.
        endif
        call SetFrameSpriteOrientation( spriteFrame, 0., startAngle, 90. )
        call SaveReal( frameHT, pHid, 'angl', startAngle )
    endif

    set p = null
    set but = null
    set spriteFrame = null
endfunction

function OnButtonRotateRightClick takes nothing returns nothing
    local player p = GetTriggerPlayer( )
    local framehandle but = GetTriggerFrame( )
    local framehandle spriteFrame = GetCFrameByName( "HeroPickSprite", 0 )
    local integer pHid = GetHandleId( p )
    local real startAngle = LoadReal( frameHT, pHid, 'angl' )

    if p == GetLocalPlayer( ) then
        set startAngle = startAngle - 30.
        if startAngle < 0. then
            set startAngle = 330.
        endif
        call SetFrameSpriteOrientation( spriteFrame, 0., startAngle, 90. )
        call SaveReal( frameHT, pHid, 'angl', startAngle )
    endif
    
    set p = null
    set but = null
    set spriteFrame = null
endfunction

function OnButtonAcceptHero takes nothing returns nothing
    local player p = GetTriggerPlayer( )
    local integer pHid = GetHandleId( p )
    local integer heroId = LoadInteger( frameHT, pHid, '+hId' )
    local framehandle but = HandleListGetFrameByIndex( heroPickButtons, heroId )
    local integer butHid = GetHandleId( but )
    local integer heroTypeId = LoadInteger( frameHT, butHid, 'tpid' )
    local unit u = null

    if not HaveSavedHandle( frameHT, pHid, 'hero' ) and HaveSavedInteger( frameHT, pHid, '+hId' ) then
        set u = CreateUnit( p, heroTypeId, .0, .0, 270. )

        if p == GetLocalPlayer( ) then
            call ShowFrame( GetCFrameByName( "HeroPickSelector", 0 ), false )
            call ShowFrame( GetCFrameByName( "HeroPickSprite", 0 ), false )
            call ShowFrame( GetFrameByName( "HeroSelectionUI", 0 ), false )
            call EditBlackBorders( -.02, .13 ) // -.02, .13 | to return to default 
            call HideOriginFrames( false )
            call SelectUnit( u, true )
            call SaveUnitHandle( frameHT, pHid, 'hero', u )
        endif
    endif

    set u = null
    set p = null
    set but = null
endfunction

function SetSelectionButtonDataEx takes framehandle but, integer index, integer uid, string iconPath, string modelPath, string tip, string ubertip returns nothing
    local integer fid = GetHandleId( but )

    if iconPath == "" then
        set iconPath = GetUnitBaseStringFieldById( uid, UNIT_SF_ICON_NORMAL )
    endif

    if modelPath == "" then
        set modelPath = GetUnitBaseStringFieldById( uid, UNIT_SF_MODEL )
    endif

    if tip == "" then
        set tip = GetUnitBaseStringFieldById( uid, UNIT_SF_TOOLTIP_NORMAL )
    endif

    if ubertip == "" then
        set ubertip = GetUnitBaseStringFieldById( uid, UNIT_SF_TOOLTIP_EXTENDED )
    endif

    call SetFrameTexture( but, iconPath, 0, true )
    call SetFrameTexture( but, iconPath, 1, true )
    call SetFrameTexture( but, iconPath, 2, true )
    call SaveStr( frameHT, fid, 'modl', modelPath )
    call SaveStr( frameHT, fid, 'name', tip )
    call SaveStr( frameHT, fid, 'text', ubertip )
    call SaveInteger( frameHT, fid, 'tpid', uid )
    call SaveInteger( frameHT, fid, 'indx', index )
    //call SetFramePriority( frameTemp, 5 )
    call ShowFrame( but, true )
endfunction

function SetSelectionButtonData takes framehandle but, integer index, integer uid returns nothing
    call SetSelectionButtonDataEx( but, index, uid, "", "", "", "" )
endfunction

function TestFramePickSystem takes nothing returns nothing
    local trigger tOnPress = null
    local trigger tOnUnPress = null
    local trigger tOnClick = null
    local trigger tOnEnter = null
    local trigger tOnLeave = null
    local framehandle gameUI = GetOriginFrame( ORIGIN_FRAME_GAME_UI, 0 )
    local framehandle consoleUI = GetOriginFrame( ORIGIN_FRAME_CONSOLE_UI, 0 )
    local framehandle mainFrame = CreateFrameByType( "SIMPLEFRAME", "HeroSelectionUI", consoleUI, "", 0 )
    local framehandle frameGrid = CreateFrameByType( "SIMPLEGRID", "HeroSelectionGrid", mainFrame, "", 0 )
    local framehandle modelPreviwer = null
    local framehandle simpleButton = null
    local framehandle textFrame = null
    local string s = ""
    local integer i = 0
    local integer j = 0
    local integer k = 0
    local integer row = 0
    local integer column = 0
    local integer rows = 4
    local integer columns = 4
    local real iconWidth = .025
    local real iconHeight = .0475
    local integer array heroIds

    call EditBlackBorders( .0, .0 ) // -.02, .13 | to return to default 
    call HideOriginFrames( true )
    call ClearFrameAllPoints( mainFrame )
    call SetFrameSize( mainFrame, .5, .45 )
    call SetFrameAbsolutePoint( mainFrame, FRAMEPOINT_CENTER, .35, .35 ) // UI\\Widgets\\ToolTips\\Human\\human-tooltip-border
    call SetFrameTextureEx( mainFrame, 0, "UI\\Widgets\\EscMenu\\Orc\\orc-options-menu-background", false, "UI\\Widgets\\EscMenu\\Orc\\orc-options-menu-border", BORDER_FLAG_ALL )
    call SetFramePriority( mainFrame, 4 )
    call ShowFrame( mainFrame, true )

    set tOnEnter = CreateTrigger( )
    set tOnLeave = CreateTrigger( )
    set tOnPress = CreateTrigger( )
    set tOnUnPress = CreateTrigger( )
    set tOnClick = CreateTrigger( )

    call ClearFrameAllPoints( frameGrid )
    call SetFrameGridSize( frameGrid, rows, columns )
    call SetFrameSize( frameGrid, columns * iconWidth + iconWidth, rows * iconHeight + iconHeight )
    call SetFrameRelativePoint( frameGrid, FRAMEPOINT_TOPLEFT, mainFrame, FRAMEPOINT_TOPLEFT, .0075, -.01 )

    set heroIds[0] = 'Hamg'
    set heroIds[1] = 'Hblm'
    set heroIds[2] = 'Hmkg'
    set heroIds[3] = 'Hpal'

    set heroIds[4] = 'Obla'
    set heroIds[5] = 'Ofar'
    set heroIds[6] = 'Oshd'
    set heroIds[7] = 'Otch'

    set heroIds[8] = 'Ucrl'
    set heroIds[9] = 'Udea'
    set heroIds[10] = 'Udre'
    set heroIds[11] = 'Ulic'

    set heroIds[12] = 'Edem'
    set heroIds[13] = 'Ekee'
    set heroIds[14] = 'Emoo'
    set heroIds[15] = 'Ewar'

    set i = 0
    loop
        exitwhen row == rows

        set simpleButton = CreateFrameByType( "SIMPLEBUTTON", "", frameGrid, "", 0 )
        call ClearFrameAllPoints( simpleButton )
        call SetFrameSize( simpleButton, iconWidth, iconHeight )
        call SetSelectionButtonData( simpleButton, i, heroIds[i] )
        call SetFrameGridFrame( frameGrid, row, column, simpleButton )

        call TriggerRegisterFrameEvent( tOnEnter, simpleButton, FRAMEEVENT_MOUSE_ENTER )
        call TriggerRegisterFrameEvent( tOnLeave, simpleButton, FRAMEEVENT_MOUSE_LEAVE )
        call TriggerRegisterFrameEvent( tOnPress, simpleButton, FRAMEEVENT_MOUSE_DOWN )
        call TriggerRegisterFrameEvent( tOnUnPress, simpleButton, FRAMEEVENT_MOUSE_UP )
        call TriggerRegisterFrameEvent( tOnClick, simpleButton, FRAMEEVENT_CONTROL_CLICK )

        call HandleListAddHandle( heroPickButtons, simpleButton )

        set column = column + 1

        if column == columns then
            set row = row + 1
            set column = 0
        endif

        set i = i + 1
    endloop

    call ShowFrame( frameGrid, true )

    call TriggerAddAction( tOnEnter, function OnButtonEnter )
    call TriggerAddAction( tOnLeave, function OnButtonLeave )
    call TriggerAddAction( tOnPress, function OnButtonPress )
    call TriggerAddAction( tOnUnPress, function OnButtonUnPress )
    call TriggerAddAction( tOnClick, function OnButtonClick )
    
    set modelPreviwer = CreateFrameByType( "SPRITE", "HeroPickSprite", gameUI, "", 0 )
    call ClearFrameAllPoints( modelPreviwer )
    call SetFrameRelativePoint( modelPreviwer, FRAMEPOINT_CENTER, mainFrame, FRAMEPOINT_CENTER, .025, -.05 )
    call SetFrameSize( modelPreviwer, .01, .01 )
    call SetFrameLayerFlag( modelPreviwer, LAYER_STYLE_IGNORE_TRACK_EVENTS, true )
    call ShowFrame( modelPreviwer, false )

    set s = "CustomUI\\Selectors\\ArrowLeft" // "ReplaceableTextures\\CommandButtons\\BTNReplay-Speedup"
    set simpleButton = CreateFrameByType( "SIMPLEBUTTON", "HeroPickLeftRotator", mainFrame, "", 0 )
    call ClearFrameAllPoints( simpleButton )
    call SetFrameTexture( simpleButton, s, 0, true )
    call SetFrameTexture( simpleButton, s, 1, true )
    call SetFrameTexture( simpleButton, s, 2, true )
    call SetFrameSize( simpleButton, .025, .0475 )
    call SetFramePriority( simpleButton, 5 )
    call SetFrameParent( simpleButton, mainFrame )
    call ShowFrame( simpleButton, true )
    
    set tOnPress = CreateTrigger( )
    set tOnUnPress = CreateTrigger( )
    set tOnClick = CreateTrigger( )
    
    call TriggerRegisterFrameEvent( tOnPress, simpleButton, FRAMEEVENT_MOUSE_DOWN )
    call TriggerRegisterFrameEvent( tOnUnPress, simpleButton, FRAMEEVENT_MOUSE_UP )
    call TriggerRegisterFrameEvent( tOnClick, simpleButton, FRAMEEVENT_CONTROL_CLICK )

    call TriggerAddAction( tOnPress, function OnButtonPress )
    call TriggerAddAction( tOnUnPress, function OnButtonUnPress )
    call TriggerAddAction( tOnClick, function OnButtonRotateLeftClick )

    set s = "CustomUI\\Selectors\\ArrowRight" // "ReplaceableTextures\\CommandButtons\\BTNReplay-Speeddown"
    set simpleButton = CreateFrameByType( "SIMPLEBUTTON", "HeroPickRightRotator", mainFrame, "", 0 )
    call ClearFrameAllPoints( simpleButton )
    
    call SetFrameTexture( simpleButton, s, 0, true )
    call SetFrameTexture( simpleButton, s, 1, true )
    call SetFrameTexture( simpleButton, s, 2, true )
    call SetFrameSize( simpleButton, .025, .0475 )
    call SetFramePriority( simpleButton, 5 )
    call SetFrameParent( simpleButton, mainFrame )
    call ShowFrame( simpleButton, true )

    set tOnPress = CreateTrigger( )
    set tOnUnPress = CreateTrigger( )
    set tOnClick = CreateTrigger( )
    
    call TriggerRegisterFrameEvent( tOnPress, simpleButton, FRAMEEVENT_MOUSE_DOWN )
    call TriggerRegisterFrameEvent( tOnUnPress, simpleButton, FRAMEEVENT_MOUSE_UP )
    call TriggerRegisterFrameEvent( tOnClick, simpleButton, FRAMEEVENT_CONTROL_CLICK )

    call TriggerAddAction( tOnPress, function OnButtonPress )
    call TriggerAddAction( tOnUnPress, function OnButtonUnPress )
    call TriggerAddAction( tOnClick, function OnButtonRotateRightClick )

    set s = "CustomUI\\Selectors\\ClickableButton" // "UI\\Widgets\\EscMenu\\Human\\checkbox-check"
    set simpleButton = CreateFrameByType( "SIMPLEBUTTON", "HeroPickAcceptButton", mainFrame, "", 0 )
    call ClearFrameAllPoints( simpleButton )
    
    call SetFrameTexture( simpleButton, s, 0, true )
    call SetFrameTexture( simpleButton, s, 1, true )
    call SetFrameTexture( simpleButton, s, 2, true )
    call SetFrameSize( simpleButton, .06, .0475 )
    call SetFramePriority( simpleButton, 5 )
    call SetFrameParent( simpleButton, mainFrame )
    call ShowFrame( simpleButton, true )

    set textFrame = CreateFrameByType( "SIMPLETEXT", "HeroPickAcceptText", simpleButton, "", 0 )
    call ClearFrameAllPoints( textFrame )
    
    call SetFrameBlendMode( textFrame, 0, BLEND_MODE_BLEND )
    call SetFrameFont( textFrame, "Fonts\\FRIZQT__.TTF", .015, 0 )
    call SetFrameTextAlignment( textFrame, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE )
    //call SetFrameWidth( textFrame, .1 )
    call SetFrameTextColour( textFrame, 0xFF806050 ) // 0xFFFF9000
    call SetFrameParent( textFrame, simpleButton )
    call SetFrameText( textFrame, "SELECT" )
    call ShowFrame( textFrame, true )

    set tOnPress = CreateTrigger( )
    set tOnUnPress = CreateTrigger( )
    set tOnClick = CreateTrigger( )

    call TriggerRegisterFrameEvent( tOnPress, simpleButton, FRAMEEVENT_MOUSE_DOWN )
    call TriggerRegisterFrameEvent( tOnUnPress, simpleButton, FRAMEEVENT_MOUSE_UP )
    call TriggerRegisterFrameEvent( tOnClick, simpleButton, FRAMEEVENT_CONTROL_CLICK )

    call TriggerAddAction( tOnPress, function OnButtonPress )
    call TriggerAddAction( tOnUnPress, function OnButtonUnPress )
    call TriggerAddAction( tOnClick, function OnButtonAcceptHero )

    call SetFrameRelativePoint( GetCSimpleFrameByName( "HeroPickLeftRotator", 0 ), FRAMEPOINT_CENTER, mainFrame, FRAMEPOINT_CENTER, -.025, -.1 )
    call SetFrameRelativePoint( GetCSimpleFrameByName( "HeroPickAcceptButton", 0 ), FRAMEPOINT_LEFT, GetCSimpleFrameByName( "HeroPickLeftRotator", 0 ), FRAMEPOINT_CENTER, .01375, .0 )
    call SetFrameRelativePoint( GetCSimpleFrameByName( "HeroPickRightRotator", 0 ), FRAMEPOINT_LEFT, GetCSimpleFrameByName( "HeroPickLeftRotator", 0 ), FRAMEPOINT_CENTER, .0750, .0 )
    call SetFrameRelativePoint( textFrame, FRAMEPOINT_CENTER, GetCSimpleFrameByName( "HeroPickAcceptButton", 0 ), FRAMEPOINT_CENTER, .0, .0 )

    call GetPickSystemTooltip( )

    set gameUI = null
    set consoleUI = null
    set mainFrame = null
    set simpleButton = null
    set textFrame = null
    set tOnEnter = null
    set tOnLeave = null
    set tOnPress = null
    set tOnUnPress = null
    set tOnClick = null
endfunction

//===========================================================================
function InitTrig_FramePickSystem takes nothing returns nothing
    //set gg_trg_FramePickSystem = CreateTrigger(  )
    
    call FogEnable( false )
    call FogMaskEnable( false )
    call PanCameraToTimed( 0., 0., 0. )
    call EnableOperationLimit( false )

    //call BJDebugMsg( "UjAPI Version: " + GetUjAPIVersion( ) )

    call TimerStart( CreateTimer( ), .5, false, function TestFramePickSystem )
    //call ConsoleEnable( false )
endfunction

Скриншоты

Превью

`
ОЖИДАНИЕ РЕКЛАМЫ...
0
12
10 месяцев назад
0
А можно такое для Рефоржета?
0
20
10 месяцев назад
0
А можно такое для Рефоржета?
Не интересуюсь рефоржедом. Да и на чистых симплфреймах там далеко не уедешь, а так - реализуемо. Использовать CBackdropFrame и эмулировать как кнопку и т.д. У меня есть планы на ещё пару примеров, но на деле данный пример показывает больше логику, а подстроиться под неё можно и другими фреймами.
0
20
9 месяцев назад
0
Вышла новая версия!
Карта обновлена под UjAPI v1.0.28.102.
0
23
9 месяцев назад
0
А можно такое для Рефоржета?
В рефе нет такого:
call SetFrameSpriteOrientation( spriteFrame, 0., startAngle, 90. )
То есть, произвольно вращать спрайт не получится, разве что имитировать это костылями каким-нибудь
0
20
9 месяцев назад
Отредактирован Unryze
0
А можно такое для Рефоржета?
В рефе нет такого:
call SetFrameSpriteOrientation( spriteFrame, 0., startAngle, 90. )
То есть, произвольно вращать спрайт не получится, разве что имитировать это костылями каким-нибудь
Можно вращать как угодно, вращение всех осей "вместе" имеет ниже шанс врезаться в Gimbel Lock, но API для кручения определённых осей есть.
SetFrameSpriteFacing
SetFrameSpritePitch
SetFrameSpriteRoll
0
20
7 месяцев назад
0
Вышла новая версия!
Исправлена функция SetFrameSpriteMaterialScale на SetFrameSpriteMatrixScale.
0
31
6 месяцев назад
0
Исправлена функция SetFrameSpriteMaterialScale на SetFrameSpriteMatrixScale.
еще я так понимаю поменялись порядок и количество аргументов в функции SetFrameTextureEx()
0
31
6 месяцев назад
Отредактирован Алексей Андреич
0
Импортировал код в свою карту, подправил изменившиеся функции и потестировал,
видео

если не использовать функцию SetFrameSpriteAnimationWithRarity на спрайте, некоторые модели при появлении на экране начинают заливать его белым светом.
нажатие на кнопку фреймов имеет какую-то задержку. Можно быстро прожать дважды и получить двух героев.
У себя пока что временно поправил проверкой, получал ли данный игрок уже героя или нет.
В самом конце видео можно заметить что герои очень резко переходят от анимации "walk" к "stand", прям явным рывком.
По моим наблюдениям, это появляется после создания спрайта,
и использования функции SetFrameSpriteModelEx/SetFrameSpriteModel(), конкретно при передать корректного пути модели в функцию.
0
20
6 месяцев назад
Отредактирован Unryze
0
Нажатия кнопок - обрабатываются пакетами, я не делал блок пика на 1 персонажа, хотя наверное стоило. Правится достаточно легко.
--По поводу резкой смены анимации, постараюсь исправить, ибо я знаю причину, а если точнее использовани Ex фукнции в обоих случаях было плохим решением.
SetFrameSpriteModel/SetFrameSpriteModelEx реально создают эту странную проблему, буду пытаться решить.-- Исправлено на следующую версию.
По поводу анимаций и освящения, да, такая проблема есть, но как её решить мне не известно. | С освещением проблему особо не решить.
Когда выпущу апдейт ужапи, обновлю тут карту тоже с фиксами пик системы + новым и правильным кодом.
Спасибо за информацию.
0
31
6 месяцев назад
Отредактирован Алексей Андреич
0
Пытаюсь состряпать кастомный интерфейс (ничего необычного, просто поотключать часть кнопок стандартного интерфейса и передвинуть остальную). Вторые сутки мучаюсь с портретом.
Идея была проста:
создать SIMPLEFRAME, с помощью функции SetFrameTextureEx сделать из фрейма рамочку. В нее поместит портрет персонажа.
Как оказалось портрет всегда отображается слоем ниже SIMPLEFRAME.
Функция SetFramePriority не помогает. Она может установить порядок отрисовки двух SIMPLEFRAME, но не Портрета.
Далее я начал пробовать все подряд. Делал портрет дочерним по отношению к SIMPLEFRAME, к другим фреймам - бестолку.
По итогу нашел костыльное решение.
Создать после SIMPLEFRAME, новый фрейм типа BACKDROP - он всегда отображается поверх SIMPLEFRAME, задать ему прозрачную текстуру.
Делаем портрет дочерним по отношению к BACKDROP - и вуаля, теперь портрет сверху нашей рамочки.
code
...
	framehandle UI;
    framehandle Backdrop;

    HideOriginFrames(true);
    
    Backdrop = CreateFrameByType( "SIMPLEFRAME", "PortraitBackdrop", GetOriginFrame( ORIGIN_FRAME_GAME_UI, 0 ), "", 0 );
    ClearFrameAllPoints( Backdrop );
    SetFrameSize( Backdrop, 0.1, 0.1 ); 
    SetFrameAbsolutePoint(Backdrop, FRAMEPOINT_BOTTOMLEFT, 0.0, 0.0);
    SetFrameTextureEx( Backdrop, 0, "UI\\Widgets\\Glues\\GlueScreen-Button1-BackdropBackground-Disabled.blp", false, "UI\\Widgets\\Glues\\GlueScreen-Slider-BackdropBorder.blp",  0 );
    
    Backdrop = CreateFrameByType( "BACKDROP", "DummyFrameAnchorForPortrait", GetOriginFrame( ORIGIN_FRAME_GAME_UI, 0 ), "", 0 );
    ClearFrameAllPoints( Backdrop );
    SetFrameSize( Backdrop, 0.1, 0.1 ); 
    SetFrameAbsolutePoint(Backdrop, FRAMEPOINT_BOTTOMLEFT, 0.0, 0.0);
    SetFrameTexture(Backdrop, "empty.blp", 0, false);
    
    UI = GetOriginFrame( ORIGIN_FRAME_PORTRAIT, 0 );
    ShowFrame(UI, true);
    SetFrameParent(UI, Backdrop);
    ClearFrameAllPoints( UI );
    SetFrameSize( UI, 0.09, 0.09 ); 
    SetFrameAbsolutePoint(UI, FRAMEPOINT_BOTTOMLEFT, 0.005, 0.005);
Но есть проблема... портрет как-то не хочет отображаться нормально, когда под ним есть другой фрейм.
Загруженные файлы
0
20
6 месяцев назад
0
Спрайтфреймы любого вида перекрываются мировым фреймом, потому близзарды и добавили "чёрные полосы" - пока что я не нашёл лечения этой проблемы...
CSimpleTop (то где обитают все симплфреймы и т.д.) имеет приоритет выше, верно.
0
20
6 месяцев назад
0
Вышла новая версия!
Карта обновлена под UjAPI v1.0.37.137.
0
31
6 месяцев назад
Отредактирован Алексей Андреич
0
ковыряюсь дальше с настройкой интерфейса.
Словил крит.
//! zinc
library Main {

function onInit(){
    framehandle UI;
    UI = GetOriginFrame( ORIGIN_FRAME_COMMAND_BUTTON, 5 );
    ShowFrame(UI, true);
    TriggerSleepAction(0.001); //закоментировать данную строку, чтобы словить крит
    CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'hfoo', 0.0, 0.0, 270.0);
    UI = null;
}
    
}
//! endzinc

почему-то именно с ORIGIN_FRAME_COMMAND_BUTTON, с другими фреймами такого не было. Но после смены видимости кнопок команд нужно немного подождать, прежде чем создавать юнитов.
0
31
6 месяцев назад
Отредактирован Алексей Андреич
0
карту пример приложил...
Загруженные файлы
0
20
6 месяцев назад
Отредактирован Unryze
0
Проблема в ShowFrame, изучу и постараюсь поправить. Спасибо.
Редактирование 1: Ошибку нашёл и поправил, легаси код - мать его.
0
20
4 месяца назад
0
Вышла новая версия!
Карта обновлена под UjAPI v1.1.4.167
0
20
2 месяца назад
0
Вышла новая версия!
Карта обновлена под UjAPI v1.1.8.178, система выбора теперь использует SIMPLEGRID для выставления фреймов.
0
20
2 часа назад
Отредактирован Unryze
0
Вышла новая версия!
Карта обновлена под UjAPI v1.1.14.215, система выбора теперь использует SetFrameBlendMode для изменения типа отрисовки.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.