Добавлен , опубликован
Есть в разработках наработка полноэкранных менюшек
как это примерно выглядит визуально

Присутствующие возможности:
  • отрисовка интерфейса на выбор из 4, стиль по расам
  • динамическое создание и удаление деталей интерфейса
  • добавление функциональных кнопок, возможность отображения цифр у них
  • эффект выделения на кнопках, воспроизведения звуков клика
  • отслеживание двойного клика
  • добавление всплывающих подсказок к кнопкам, показывающим какую либо информацию
  • мультиплеер
WIP возможности
  • слайдеры, с помощью них можно сделать "листание" элементов интерфейса
  • анимация нажатия на кнопку
С помощью наработки можно делать в теории (я немножко экспериментировал с этим)
  • полноэкранные книги, их чтение как например в серии TES

Наработка сделана полностью на трекейблах и разрушаемых декорациях.

Хотелось бы увидеть в комментах какие возможности хотели бы еще, и фидбек в целом.
библиотека GUI
library GUI initializer Init requires MISC, Main 

define {
    private PLAYERS = 9
    
    HUMAN_UI = 1
    ORC_UI = 2
    ELF_UI = 3
    UNDEAD_UI = 4
    
    GUI_X(x) = ((Left_X + x * 64) + 32.)
    GUI_Y(y) = ((Left_Y + y * 64) + 32.)
    
    private BASE_ID = 'B00L'
    private BACKGROUND_HUMAN_ID = 'B00O'
    private BACKGROUND_ELF_ID = 'B015'
    private BACKGROUND_ORC_ID = 'B016'
    private BACKGROUND_UNDEAD_ID = 'B017'
    private BACKGROUND_BLACK_ID = 'B00M'
    
    private BORDER_ELF_DOWN = 'B00E'
    private BORDER_ELF_UP = 'B00H'
    private BORDER_ELF_LEFT = 'B00F'
    private BORDER_ELF_RIGHT = 'B00G'
    private BORDER_ELF_DOWN_LEFT = 'B00M'
    private BORDER_ELF_DOWN_RIGHT = 'B00N'
    private BORDER_ELF_UP_LEFT = 'B00O'
    private BORDER_ELF_UP_RIGHT = 'B00P'
    
    private BORDER_HUMAN_DOWN = 'B00P'
    private BORDER_HUMAN_UP = 'B00U'
    private BORDER_HUMAN_LEFT = 'B00S'
    private BORDER_HUMAN_RIGHT = 'B00T'
    private BORDER_HUMAN_DOWN_LEFT = 'B00Q'
    private BORDER_HUMAN_DOWN_RIGHT = 'B00R'
    private BORDER_HUMAN_UP_LEFT = 'B00V'
    private BORDER_HUMAN_UP_RIGHT = 'B00W'
    
    private BORDER_ORC_DOWN = 'B00A'
    private BORDER_ORC_UP = 'B00D'
    private BORDER_ORC_LEFT = 'B00B'
    private BORDER_ORC_RIGHT = 'B00C'
    private BORDER_ORC_DOWN_LEFT = 'B00Q'
    private BORDER_ORC_DOWN_RIGHT = 'B00R'
    private BORDER_ORC_UP_LEFT = 'B00S'
    private BORDER_ORC_UP_RIGHT = 'B00T'
    
    private BORDER_UNDEAD_DOWN = 'B006'
    private BORDER_UNDEAD_UP = 'B009'
    private BORDER_UNDEAD_LEFT = 'B007'
    private BORDER_UNDEAD_RIGHT = 'B008'
    private BORDER_UNDEAD_DOWN_LEFT = 'B00U'
    private BORDER_UNDEAD_DOWN_RIGHT = 'B00V'
    private BORDER_UNDEAD_UP_LEFT = 'B00X'
    private BORDER_UNDEAD_UP_RIGHT = 'B00W'
    
    private Hide(d) = { ShowDestructable(d, GetLocalPlayer() == Player(p)) }
}

//    0   1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 10|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 10
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 9 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 9
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 8 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 8 
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 7 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 7
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 6 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 6
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 5 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 5 
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 4 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 4
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 3 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 3 
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 2 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 2 
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 1 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 1
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 0 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | 0
//    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
//    0   1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22





// globals
    public rect AreaRect
    public fogmodifier Visibility[PLAYERS]
    private destructable BASE[PLAYERS], BACKGROUND[PLAYERS]
    private destructable UP_RIGHT[PLAYERS], UP_LEFT[PLAYERS], DOWN_RIGHT[PLAYERS], DOWN_LEFT[PLAYERS]
    private destructable UP[22][PLAYERS], DOWN[22][PLAYERS], LEFT[10][PLAYERS], RIGHT[10][PLAYERS]
    private destructable MiscDestructables[300][PLAYERS], MiscBackgrounds[125][PLAYERS]
    private texttag MiscText[100][PLAYERS]
    private int DestrCount[PLAYERS], TextsCount[PLAYERS], BackgroundsCount[PLAYERS]
    real Left_X, Left_Y
    public sound ClickSound, ActivateSound
    public bool IsShowed[PLAYERS]
    public timer CameraLockTimer[PLAYERS]
    real BASE_X = -2368., BASE_Y = 2368.
    
    
    public void ResetCamera(int p){
        PT(CameraLockTimer[p])
        if GetLocalPlayer() == Player(p) { ResetToGameCamera(0.) }
    }
    
    public void CameraProcess(){
        int p = GetTimerAttach(GetExpiredTimer())
            if GetLocalPlayer() == Player(p) {
                SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 1645., 0.)
                SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 270., 0.)
                SetCameraField(CAMERA_FIELD_ROTATION, 90., 0.)
                PanCameraToTimed(BASE_X - 8., BASE_Y + 15., 0.)
            }
        TimerStart(CameraLockTimer[p], 0.01, false, function CameraProcess)
    }
    
    public void TurnOnCamera(int p){
        if GetLocalPlayer() == Player(p) {
            SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 270., 0.)
            SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 1645., 0.)
            SetCameraField(CAMERA_FIELD_ROTATION, 90., 0.)
            SetCameraBounds(GetRectMinX(AreaRect), GetRectMinY(AreaRect), GetRectMinX(AreaRect), GetRectMaxY(AreaRect), GetRectMaxX(AreaRect), GetRectMaxY(AreaRect), GetRectMaxX(AreaRect), GetRectMinY(AreaRect))
        }
        TimerStartEx(CameraLockTimer[p], 0.01, function CameraProcess, p)
        //SetCameraBoundsToRect(AreaRect)
    }
    
    public void ClearText(int p){
        while(TextsCount[p] != 0){ DestroyTextTag(MiscText[TextsCount[p]][p]); TextsCount[p]-- }
    }
    
    public void ClearWindow(int p){
        while(DestrCount[p] != 0){ RemoveDestructable(MiscDestructables[DestrCount[p]][p]); DestrCount[p]-- }
        while(TextsCount[p] != 0){ DestroyTextTag(MiscText[TextsCount[p]][p]); TextsCount[p]-- }
        while(BackgroundsCount[p] != 0){ RemoveDestructable(MiscBackgrounds[BackgroundsCount[p]][p]); BackgroundsCount[p]-- }
    }
    
    public void DestroyInterface(int p){
        int c = 22
            IsShowed[p] = false
            RemoveDestructable(BASE[p])
            RemoveDestructable(BACKGROUND[p])
            FogModifierStop(Visibility[p])
            PT(CameraLockTimer[p])
            // UP
                while(c != 0) { RemoveDestructable(UP[c][p]); c-- }
            // DOWN
            c = 22
                while(c != 0) { RemoveDestructable(DOWN[c][p]); c-- }
            // RIGHT
            c = 10
                while(c != 0) { RemoveDestructable(RIGHT[c][p]); c-- }
            // LEFT
            c = 10
                while(c != 0) { RemoveDestructable(LEFT[c][p]); c-- }
            RemoveDestructable(UP_LEFT[p])
            RemoveDestructable(UP_RIGHT[p])
            RemoveDestructable(DOWN_LEFT[p])
            RemoveDestructable(DOWN_RIGHT[p])
                while(DestrCount[p] != 0){ RemoveDestructable(MiscDestructables[DestrCount[p]][p]); DestrCount[p]-- }
                while(TextsCount[p] != 0){ DestroyTextTag(MiscText[TextsCount[p]][p]); TextsCount[p]-- }
                while(BackgroundsCount[p] != 0){ RemoveDestructable(MiscBackgrounds[BackgroundsCount[p]][p]); BackgroundsCount[p]-- }
    }
    
    public void AddTextEx(real x, real y, string s, real size, int p){
        TextsCount[p]++
        MiscText[TextsCount[p]][p] = CreateTextTag()
        if GetLocalPlayer() != Player(p) { s = "" }
        SetTextTagText(MiscText[TextsCount[p]][p], s, (size * 0.023) / 10.)
        SetTextTagPos(MiscText[TextsCount[p]][p], x, y, 5.)
        SetTextTagColor(MiscText[TextsCount[p]][p], 255, 255, 255, 0)
            //SetTextTagColor(MiscText[TextsCount], PercentToInt(1, 255), PercentToInt(g, 255), PercentToInt(b,255), 0)
    }
    
    public void AddText(int cell_x, int cell_y, string s, real r, real g, real b, real size, int p){
        real true_x = (Left_X + cell_x * 64) + 32., true_y = (Left_Y + cell_y * 64) + 32.
            TextsCount[p]++
            MiscText[TextsCount[p]][p] = CreateTextTag()
                if GetLocalPlayer() != Player(p) { s = "" }
            SetTextTagText(MiscText[TextsCount[p]][p], s, (size * 0.023) / 10.)
            SetTextTagPos(MiscText[TextsCount[p]][p], true_x, true_y, 5.)
            SetTextTagColor(MiscText[TextsCount[p]][p], PercentToInt(r, 255), PercentToInt(g, 255), PercentToInt(b,255), 0)
    }
    
    public void AddBackground(int cell_x, int cell_y, int p){
        real true_x = (Left_X + cell_x * 64) + 32., true_y = (Left_Y + cell_y * 64) + 32.
            BackgroundsCount[p]++
            MiscBackgrounds[BackgroundsCount[p]][p] = CreateDestructable(BACKGROUND_BLACK_ID, true_x, true_y, 0., 1.1, 0)
            Hide(MiscDestructables[BackgroundsCount[p]][p])
    }
    
    public void CreateBackground(int cell_x, int cell_y, int lenght, int width, int p){
        real true_x = (Left_X + (cell_x - 1) * 64) + 32., true_y = (Left_Y + cell_y * 64) + 32.
        int l, x
            cell_x = cell_x - 1
            if (lenght == 1 and width == 1){
                BackgroundsCount[p]++
                MiscBackgrounds[BackgroundsCount[p]][p] = CreateDestructable(BACKGROUND_BLACK_ID, true_x, true_y, 0., 1.1, 0)
                Hide(MiscDestructables[BackgroundsCount[p]][p])
            }
            elseif (lenght == 1 and width > 1){
                BackgroundsCount[p]++
                MiscBackgrounds[BackgroundsCount[p]][p] = CreateDestructable(BACKGROUND_BLACK_ID, true_x, true_y, 0., 1.1, 0)
                Hide(MiscDestructables[BackgroundsCount[p]][p])
                    while(width >= 1){
                        cell_y--
                        true_y = (Left_Y + cell_y * 64) + 32.
                        BackgroundsCount[p]++
                        MiscBackgrounds[BackgroundsCount[p]][p] = CreateDestructable(BACKGROUND_BLACK_ID, true_x, true_y, 0., 1.1, 0)
                        Hide(MiscDestructables[BackgroundsCount[p]][p])
                        width--
                    }
            }
            elseif (lenght > 1 and width == 1){
                BackgroundsCount[p]++
                MiscBackgrounds[BackgroundsCount[p]][p] = CreateDestructable(BACKGROUND_BLACK_ID, true_x, true_y, 0., 1.1, 0)
                    while(lenght >= 0){
                        cell_x++
                        true_x = (Left_X + cell_x * 64) + 32.   
                        BackgroundsCount[p]++
                        MiscBackgrounds[BackgroundsCount[p]][p] = CreateDestructable(BACKGROUND_BLACK_ID, true_x, true_y, 0., 1.1, 0)
                        Hide(MiscDestructables[BackgroundsCount[p]][p])
                        lenght--
                    }
            }
            elseif (lenght > 1 and width > 1){
                l = lenght
                x = cell_x
                    while(width >= 1){
                        lenght = l
                        cell_x = x
                            while(lenght >= 0){
                                cell_x++
                                true_x = (Left_X + cell_x * 64) + 32.   
                                BackgroundsCount[p]++
                                MiscBackgrounds[BackgroundsCount[p]][p] = CreateDestructable(BACKGROUND_BLACK_ID, true_x, true_y, 0., 1.1, 0)
                                Hide(MiscDestructables[BackgroundsCount[p]][p])
                                lenght--
                            }
                        width--
                        cell_y--
                        true_y = (Left_Y + cell_y * 64) + 32.
                    }
            }
    }
    
    public void CreatePanel(int cell_x, int cell_y, int lenght, int width, int variation, int p){
        int down_right, down_left, up_right, up_left, up, down, left, right
        //real start_x = BASE_X + Rx(715.547, -153.435), start_y = BASE_Y + Ry(715.547, -153.435)
        real true_x = (Left_X + cell_x * 64) + 32., true_y = (Left_Y + cell_y * 64) + 32.
        int l, w, c_x, c_y
            if (lenght == 0 or width == 0) { return }
        
                if variation == 1 {
                    down_right = BORDER_HUMAN_DOWN_RIGHT
                    down_left = BORDER_HUMAN_DOWN_LEFT
                    up_right = BORDER_HUMAN_UP_RIGHT
                    up_left = BORDER_HUMAN_UP_LEFT
                    up = BORDER_HUMAN_UP
                    down = BORDER_HUMAN_DOWN
                    left = BORDER_HUMAN_LEFT
                    right = BORDER_HUMAN_RIGHT
                }
                elseif variation == 2 {
                    down_right = BORDER_ORC_DOWN_RIGHT
                    down_left = BORDER_ORC_DOWN_LEFT
                    up_right = BORDER_ORC_UP_RIGHT
                    up_left = BORDER_ORC_UP_LEFT
                    up = BORDER_ORC_UP
                    down = BORDER_ORC_DOWN
                    left = BORDER_ORC_LEFT
                    right = BORDER_ORC_RIGHT
                }
                elseif variation == 3 {
                    down_right = BORDER_ELF_DOWN_RIGHT
                    down_left = BORDER_ELF_DOWN_LEFT
                    up_right = BORDER_ELF_UP_RIGHT
                    up_left = BORDER_ELF_UP_LEFT
                    up = BORDER_ELF_UP
                    down = BORDER_ELF_DOWN
                    left = BORDER_ELF_LEFT
                    right = BORDER_ELF_RIGHT
                }
                elseif variation == 4 {
                    down_right = BORDER_UNDEAD_DOWN_RIGHT
                    down_left = BORDER_UNDEAD_DOWN_LEFT
                    up_right = BORDER_UNDEAD_UP_RIGHT
                    up_left = BORDER_UNDEAD_UP_LEFT
                    up = BORDER_UNDEAD_UP
                    down = BORDER_UNDEAD_DOWN
                    left = BORDER_UNDEAD_LEFT
                    right = BORDER_UNDEAD_RIGHT
                }
                
            if (lenght == 1 and width == 1){
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(down_left, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(down_right, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(up_left, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(up_right, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
            }
            elseif (lenght == 1 and width > 1){
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(up_left, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(up_right, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                    while(width > 1){
                        cell_y--
                        true_y = (Left_Y + cell_y * 64) + 32.
                        DestrCount[p]++
                        MiscDestructables[DestrCount[p]][p] = CreateDestructable(left, true_x, true_y, 0., 0.65, 0)
                        Hide(MiscDestructables[DestrCount[p]][p])
                        DestrCount[p]++
                        MiscDestructables[DestrCount[p]][p] = CreateDestructable(right, true_x, true_y, 0., 0.65, 0)
                        Hide(MiscDestructables[DestrCount[p]][p])
                        width--
                    }
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(down_left, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(down_right, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
            }
            elseif (lenght > 1 and width == 1){
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(up_left, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(down_left, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                    while(lenght > 1){
                        cell_x++
                        true_x = (Left_X + cell_x * 64) + 32.   
                        DestrCount[p]++
                        MiscDestructables[DestrCount[p]][p] = CreateDestructable(up, true_x, true_y, 0., 0.65, 0)
                        Hide(MiscDestructables[DestrCount[p]][p])
                        DestrCount[p]++
                        MiscDestructables[DestrCount[p]][p] = CreateDestructable(down, true_x, true_y, 0., 0.65, 0)
                        Hide(MiscDestructables[DestrCount[p]][p])
                        lenght--
                    }
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(up_right, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(down_right, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
            }
            elseif (lenght > 1 and width > 1){
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(up_left, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                // + velocity in right
                l = lenght; c_x = cell_x
                    while(l > 1){
                        c_x++
                        true_x = (Left_X + c_x * 64) + 32.
                        DestrCount[p]++
                        MiscDestructables[DestrCount[p]][p] = CreateDestructable(up, true_x, true_y, 0., 0.65, 0)
                        Hide(MiscDestructables[DestrCount[p]][p])
                        l--
                    }
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(up_right, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                //========================================================================
                // + velocity in down
                w = width; c_y = cell_y
                    while(w > 1){
                        c_y--
                        true_y = (Left_Y + c_y * 64) + 32.
                        DestrCount[p]++
                        MiscDestructables[DestrCount[p]][p] = CreateDestructable(right, true_x, true_y, 0., 0.65, 0)
                        Hide(MiscDestructables[DestrCount[p]][p])
                        w--
                    }
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(down_right, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                //========================================================================
                // - velocity in down
                true_x = (Left_X + cell_x * 64) + 32.
                w = width; c_y = cell_y
                    while(w > 1){
                        c_y--
                        true_y = (Left_Y + c_y * 64) + 32.
                        DestrCount[p]++
                        MiscDestructables[DestrCount[p]][p] = CreateDestructable(left, true_x, true_y, 0., 0.65, 0)
                        Hide(MiscDestructables[DestrCount[p]][p])
                        w--
                    }
                DestrCount[p]++
                MiscDestructables[DestrCount[p]][p] = CreateDestructable(down_left, true_x, true_y, 0., 0.65, 0)
                Hide(MiscDestructables[DestrCount[p]][p])
                //========================================================================
                // - velocity in right
                true_x = (Left_X + cell_x * 64) + 32.
                l = lenght; c_x = cell_x
                    while(l > 1){
                        c_x++
                        true_x = (Left_X + c_x * 64) + 32.
                        DestrCount[p]++
                        MiscDestructables[DestrCount[p]][p] = CreateDestructable(down, true_x, true_y, 0., 0.65, 0)
                        Hide(MiscDestructables[DestrCount[p]][p])
                        l--
                    }
            }
            //CreateDestructable('B000', (start_x + cell_x * 64) + 32.,(start_y + cell_y * 64) + 32., 0., 1.1, 0)
    }
    
    public void BuildInterface(int variation, int p){
        int background, down_right, down_left, up_right, up_left, up, down, left, right
        int c = 22
        real x, y, a, dist = 64.
                if IsShowed[p] { return }
                else { IsShowed[p] = true }
                
                TurnOnCamera(p)
                if variation == 1 {
                    background = BACKGROUND_HUMAN_ID
                    down_right = BORDER_HUMAN_DOWN_RIGHT
                    down_left = BORDER_HUMAN_DOWN_LEFT
                    up_right = BORDER_HUMAN_UP_RIGHT
                    up_left = BORDER_HUMAN_UP_LEFT
                    up = BORDER_HUMAN_UP
                    down = BORDER_HUMAN_DOWN
                    left = BORDER_HUMAN_LEFT
                    right = BORDER_HUMAN_RIGHT
                }
                elseif variation == 2 {
                    background = BACKGROUND_ORC_ID
                    down_right = BORDER_ORC_DOWN_RIGHT
                    down_left = BORDER_ORC_DOWN_LEFT
                    up_right = BORDER_ORC_UP_RIGHT
                    up_left = BORDER_ORC_UP_LEFT
                    up = BORDER_ORC_UP
                    down = BORDER_ORC_DOWN
                    left = BORDER_ORC_LEFT
                    right = BORDER_ORC_RIGHT
                }
                elseif variation == 3 {
                    background = BACKGROUND_ELF_ID
                    down_right = BORDER_ELF_DOWN_RIGHT
                    down_left = BORDER_ELF_DOWN_LEFT
                    up_right = BORDER_ELF_UP_RIGHT
                    up_left = BORDER_ELF_UP_LEFT
                    up = BORDER_ELF_UP
                    down = BORDER_ELF_DOWN
                    left = BORDER_ELF_LEFT
                    right = BORDER_ELF_RIGHT
                }
                elseif variation == 4 {
                    background = BACKGROUND_UNDEAD_ID
                    down_right = BORDER_UNDEAD_DOWN_RIGHT
                    down_left = BORDER_UNDEAD_DOWN_LEFT
                    up_right = BORDER_UNDEAD_UP_RIGHT
                    up_left = BORDER_UNDEAD_UP_LEFT
                    up = BORDER_UNDEAD_UP
                    down = BORDER_UNDEAD_DOWN
                    left = BORDER_UNDEAD_LEFT
                    right = BORDER_UNDEAD_RIGHT
                }
            BASE[p] = CreateDestructable(BASE_ID, BASE_X, BASE_Y, 90., 6.5, 0)
            Hide(BASE[p])
            BACKGROUND[p] = CreateDestructable(background, BASE_X + 32., BASE_Y, 0., 2., 0)
            Hide(BACKGROUND[p])
            FogModifierStart(Visibility[p])
            // UP
            // x = BASE_X + Rx(746.374, 149.036); y = BASE_Y + Ry(746.374, 149.036)
            x = BASE_X + Rx(801.921, 151.390); y = BASE_Y + Ry(801.921, 151.390)
                while(c != 0) {
                    UP[c][p] = CreateDestructable(up, x + Rx(dist, 0.), y + Ry(dist, 0.), 0., 0.65, 0)
                    Hide(UP[c][p])
                    dist += 64.
                    c--
                }
            // DOWN
            // x = BASE_X + Rx(715.547, -153.435); y = BASE_Y + Ry(715.547, -153.435)
            x = BASE_X + Rx(773.327, -155.556); y = BASE_Y + Ry(773.327, -155.556)
            c = 22; dist = 64.
                while(c != 0) {
                    DOWN[c][p] = CreateDestructable(down, x + Rx(dist, 0.), y + Ry(dist, 0.), 0., 0.65, 0)
                    Hide(DOWN[c][p])
                    dist += 64.
                    c--
                }
            // RIGHT
            x = BASE_X + Rx(858.656, 26.565); y = BASE_Y + Ry(858.656, 26.565)
            c = 10; dist = 64.
                while(c != 0) {
                    RIGHT[c][p] = CreateDestructable(right, x + Rx(dist, -90.), y + Ry(dist, -90.), 0., 0.65, 0)
                    Hide(RIGHT[c][p])
                    dist += 64.
                    c--
                }
            // LEFT
            x = BASE_X + Rx(801.921, 151.390); y = BASE_Y + Ry(801.921, 151.390)
            c = 10; dist = 64.
                while(c != 0) {
                    LEFT[c][p] = CreateDestructable(left, x + Rx(dist, -90.), y + Ry(dist, -90.), 0., 0.65, 0)
                    Hide(LEFT[c][p])
                    dist += 64.
                    c--
                }
        UP_LEFT[p] = CreateDestructable(up_left, BASE_X + Rx(801.921, 151.390), BASE_Y + Ry(801.921, 151.390), 0., 0.65, 0)
        Hide(UP_LEFT[p])
        UP_RIGHT[p] = CreateDestructable(up_right, BASE_X + Rx(858.656, 26.565), BASE_Y + Ry(858.656, 26.565), 0., 0.65, 0)
        Hide(UP_RIGHT[p])
        DOWN_LEFT[p] = CreateDestructable(down_left, BASE_X + Rx(773.327, -155.556), BASE_Y + Ry(773.327, -155.556), 0., 0.65, 0)
        Hide(DOWN_LEFT[p])
        DOWN_RIGHT[p] = CreateDestructable(down_right, BASE_X + Rx(832.015, -22.620), BASE_Y + Ry(832.015, -22.620), 0., 0.65, 0)
        Hide(DOWN_RIGHT[p])   
    }
    
    private void InitBasePos(){
        if GetDestructableTypeId(GetEnumDestructable()) == BASE_ID {
            BASE_X = GetDestructableX(GetEnumDestructable())
            BASE_Y = GetDestructableY(GetEnumDestructable())
            RemoveDestructable(GetEnumDestructable())
        }
    }
    
    private void DelayedInit(){
        int i = -1
        Left_X = BASE_X + Rx(773.327, -155.556); Left_Y = BASE_Y + Ry(773.327, -155.556)
        ClickSound = CreateSound("Sound\\Interface\\MouseClick1.wav", false, false, false , 10, 10, "CombatSoundsEAX")
        ActivateSound = CreateSound("Sound\\Interface\\AutoCastButtonClick1.wav", false, false, false, 10, 10, "CombatSoundsEAX")
        AreaRect = Rect(BASE_X - 768., BASE_Y - 512., BASE_X + 952., BASE_Y + 512.)
        while(i++ < PLAYERS){
            Visibility[i] = CreateFogModifierRect(Player(i), FOG_OF_WAR_VISIBLE, AreaRect, true, false)
            FogModifierStop(Visibility[i])
        }
        DT(GetExpiredTimer())
    }
    
    private void Init(){
        int i = -1
            while(i++ < PLAYERS){
                DestrCount[i] = 0
                TextsCount[i] = 0
                BackgroundsCount[i] = 0
                IsShowed[i] = false
                CameraLockTimer[i] = CT
            }
        EnumDestructablesInRect(bj_mapInitialPlayableArea, null, function InitBasePos)
        TimerStart(CT, 0.1, false, function DelayedInit)
    }

endlibrary
библиотека Buttons
library Buttons initializer Init requires GUI

define {
    private PLAYERS = 9
    private MAX_BUTTONS = 220
    Buttons_SELECTION_ID_1 = 'B00X'
    Buttons_SELECTION_ID_2 = 'B00Y'
    Buttons_SELECTION_ID_3 = 'B00Z'
    Buttons_SELECTION_ID_4 = 'B010'
    Buttons_SELECTION_ID_5 = 'B011'
    Buttons_SLIDER_ID = 'B01K'
    Buttons_CHARGES_ID = 'B01Y'
    
    
    Buttons_RemoveSelectionEffect(b, p) = RemoveDestructable(Button_Selection[b][p])
    private Hide(d) = ShowDestructable(d, GetLocalPlayer() == Player(p))
}

// globals
    int ButtonCount = 0
    int Button[MAX_BUTTONS][PLAYERS]
    trackable Button_Trackable[MAX_BUTTONS][PLAYERS]
    destructable Button_ChargeBorder[MAX_BUTTONS][PLAYERS]
    destructable Button_Icon[MAX_BUTTONS][PLAYERS]
    destructable Button_Selection[MAX_BUTTONS][PLAYERS]
    texttag Button_Text[MAX_BUTTONS]
    int Button_Charges[MAX_BUTTONS][PLAYERS]
    texttag Button_ChargesText[MAX_BUTTONS][PLAYERS]
    int Button_Coords[MAX_BUTTONS][2]
    
    public bool DoubleClick[PLAYERS]
    private int LastClicked[PLAYERS]
    private timer DoubleClickTimer[PLAYERS]
    private trigger DoubleClickTrigger = CreateTrigger()
    
    
//=============================================
    public int GetByTrackable(trackable clicked_trackable){
        int current_button = 1
        int i
            while(current_button <= ButtonCount) { 
                //msg("current scan button "+I2S(current_button))
                i = 0
                    while(i < 9){
                        if Button_Trackable[current_button][i] == clicked_trackable 
                        { return current_button }
                        i++
                    }
                current_button++
            }
        return 0
    }
    
    public int GetPlayer(int b, trackable t){
        int i = 0
            while (i < PLAYERS) {
                //msg("index "+I2S(i))
                if Button_Trackable[b][i] == t { return i } 
                i++
            }
        return -69
    }
    
    public int GetFree(int p){
        int current_button = 0
            while (current_button++ < ButtonCount) { if Button[current_button][p] == 0 { return Button[current_button][p] } }
        return 0
    }
    
    public int GetByData(int cell, int p){
        int current_button = 0
            while (current_button++ < ButtonCount) { if Button[current_button][p] == cell { return current_button } }
        return 0
    }
    
    public int GetByCoords(int x, int y){
        int current_button = 0
            while (current_button++ < ButtonCount){
                if (Button_Coords[current_button][1] == x and Button_Coords[current_button][2] == y) { return current_button } }
        return 0
    }
    
//=============================================
    public void Remove(int id, int p){
        Button[id][p] = 0
        RemoveDestructable(Button_Icon[id][p])
        RemoveDestructable(Button_Selection[id][p])
        RemoveDestructable(Button_ChargeBorder[id][p])
        DestroyTextTag(Button_Text[id])
        DestroyTextTag(Button_ChargesText[id][p])
    }
    
    public void RemoveAll(int p){
        int current_button = 0
            while (current_button++ < ButtonCount){
                Button[current_button][p] = 0
                RemoveDestructable(Button_Icon[current_button][p])
                RemoveDestructable(Button_Selection[current_button][p]) 
                RemoveDestructable(Button_ChargeBorder[current_button][p])
                DestroyTextTag(Button_Text[current_button])
                DestroyTextTag(Button_ChargesText[current_button][p])
            }
    }
    
//=============================================
    public void RemoveCharges(int id, int p){
        RemoveDestructable(Button_ChargeBorder[id][p])
        Button_ChargeBorder[id][p] = null
        DestroyTextTag(Button_ChargesText[id][p])
    }
    
    public void UpdateCharges(int id, int p){
        SetTextTagText(Button_ChargesText[id][p], I2S(Button_Charges[id][p]), (7.8 * 0.023) / 10.)
    }
    
    public void SetCharges(int id, int value, int p){
        Button_Charges[id][p] = value
        SetTextTagText(Button_ChargesText[id][p], I2S(value), (7.8 * 0.023) / 10.)
    }
    
    public void AddCharges(int id, int value, int p){
        string s = ""
            if Button_ChargeBorder[id][p] != null {
                RemoveDestructable(Button_ChargeBorder[id][p])
                DestroyTextTag(Button_ChargesText[id][p])
            }
        Button_ChargeBorder[id][p] = CreateDestructable(Buttons_CHARGES_ID, \\
        GUI_X(Button_Coords[id][1]) + 32., GUI_Y(Button_Coords[id][2]) - 32., 0., 1.15, 0)
        Button_ChargesText[id][p] = CreateTextTag()
        SetTextTagPos(Button_ChargesText[id][p], GUI_X(Button_Coords[id][1]) + 30., \\
        GUI_Y(Button_Coords[id][2]) - 42., 40.)
        Button_Charges[id][p] = value
            if GetLocalPlayer() == Player(p) { s = I2S(value) }
        SetTextTagText(Button_ChargesText[id][p], s, (7.8 * 0.023) / 10.)
        SetTextTagColor(Button_ChargesText[id][p], 255, 255, 255, 255)
        ShowDestructable(Button_ChargeBorder[id][p], GetLocalPlayer() == Player(p))
    }
    
//============================================

    private void DCreset(){
        int p = GetTimerAttach(GetExpiredTimer())
            DoubleClick[p] = false
            LastClicked[p] = 0
    }

    private void DoubleClickAct(){
        int b = GetByTrackable(GetTriggeringTrackable())
        int p = GetPlayer(b, GetTriggeringTrackable())
            TimerStartEx(DoubleClickTimer[p], 0.25, function DCreset, p)
                if LastClicked[p] == 0 { LastClicked[p] = b }
                elseif LastClicked[p] == b { DoubleClick[p] = true }
    }
    
//============================================
    public bool AddSelectionEffect(int button_id, int variation, int p){
        real true_x = (Left_X + Button_Coords[button_id][1] * 64) + 32., true_y = (Left_Y + Button_Coords[button_id][2] * 64) + 32.
        int selection_id
            if variation == 1 { selection_id = Buttons_SELECTION_ID_1 }
            elseif variation == 2 { selection_id = Buttons_SELECTION_ID_2 }
            elseif variation == 3 { selection_id = Buttons_SELECTION_ID_3 }
            elseif variation == 4 { selection_id = Buttons_SELECTION_ID_4 }
            elseif variation == 5{ selection_id = Buttons_SELECTION_ID_5 }
                if not (GetDestructableLife(Button_Selection[button_id][p]) > 0.045) {
                    Button_Selection[button_id][p] = CreateDestructable(selection_id, true_x, true_y, 0., 1., 0)
                    Hide(Button_Selection[button_id][p])
                    return true
                }
        return false
    }
    
    // add a text for button
    public void SetText(string txt, real size, real offset_x, real offset_y, int button_id, int p){
        real true_x = ((Left_X + Button_Coords[button_id][1] * 64) + 32.) + offset_x, true_y = ((Left_Y + Button_Coords[button_id][2] * 64) + 32.) + offset_y
            Button_Text[button_id] = CreateTextTag()
            if GetLocalPlayer() != Player(p) { txt = "" }
            SetTextTagText(Button_Text[button_id], txt, (size * 0.023) / 10.)
            SetTextTagPos(Button_Text[button_id], true_x, true_y, 40.)
    }
    
    public void SetAttachEx(int button_id, int db_id, int icon_id, int p){
        real true_x , true_y
            if (db_id == 0 or Button[button_id][p] != 0) { return }
            true_x = (Left_X + Button_Coords[button_id][1] * 64) + 32.; true_y = (Left_Y + Button_Coords[button_id][2] * 64) + 32.
            Button[button_id][p] = db_id
                // if button has icon
                if icon_id > 0 {
                    Button_Icon[button_id][p] = CreateDestructable(icon_id, true_x, true_y, 0., 1.1, 0)
                    Hide(Button_Icon[button_id][p])
                }
    }
    
    // that attach database data at button
    public int SetAttach(int id, int icon_id, int x, int y, int p){
        int free_button, potential_button
        real true_x , true_y
                if id == 0 { return 0 }
                if (x == -1 or y == -1) { free_button = GetFree(p) }
                else {
                    potential_button = GetByCoords(x, y)
                        if potential_button != 0 { free_button = potential_button }
                        else { free_button = GetFree(p) }
                }
            true_x = (Left_X + Button_Coords[free_button][1] * 64) + 32.; true_y = (Left_Y + Button_Coords[free_button][2] * 64) + 32.
            Button[free_button][p] = id
                // if button has icon
                if icon_id > 0 {
                    Button_Icon[free_button][p] = CreateDestructable(icon_id, true_x, true_y, 0., 1.1, 0)
                    Hide(Button_Icon[free_button][p])
                }
        return free_button
    }
    
    public int Add(int cell_x, int cell_y, trigger click_react){
        int button_id
        string s
        real true_x = (Left_X + cell_x * 64) + 32., true_y = (Left_Y + cell_y * 64) + 32.
        trackable new_trackable
            button_id = GetByCoords(cell_x, cell_y)
            if Button_Trackable[button_id][0] != null  { 
                bj_forLoopAIndex = -1
                while(bj_forLoopAIndex++ < PLAYERS){
                    TriggerRegisterTrackableHitEvent(click_react, Button_Trackable[button_id][bj_forLoopAIndex])
                    TriggerRegisterTrackableHitEvent(DoubleClickTrigger, Button_Trackable[button_id][bj_forLoopAIndex])
                }
                return button_id
            }
            else {
                ButtonCount++
                //msg("button count "+ I2S(ButtonCount))
                bj_forLoopAIndex = -1
                    while(bj_forLoopAIndex++ < PLAYERS){
                        Button[ButtonCount][bj_forLoopAIndex] = 0
                        if GetLocalPlayer() == Player(bj_forLoopAIndex) 
                        { s = "war3mapImported\\GUI_Icon_Base_Trackable.mdx" }
                        else { s = "dummy.mdx" }
                        //new_trackable = CreateTrackable(s, true_x, true_y, 0.)
                        Button_Trackable[ButtonCount][bj_forLoopAIndex] = CreateTrackable(s, true_x, true_y, 0.)
                        TriggerRegisterTrackableHitEvent(click_react, Button_Trackable[ButtonCount][bj_forLoopAIndex])
                        TriggerRegisterTrackableHitEvent(DoubleClickTrigger, Button_Trackable[ButtonCount][bj_forLoopAIndex])
                        //msg("created for  "+ I2S(bj_forLoopAIndex))
                    }
                Button_Coords[ButtonCount][1] = cell_x
                Button_Coords[ButtonCount][2] = cell_y
                Button_Text[ButtonCount] = null
            }
        new_trackable = null
        return ButtonCount
    }
    
    private void Init(){
        int c = -1
            while(c++ < PLAYERS){
                DoubleClick[c] = false
                LastClicked[c] = 0
                DoubleClickTimer[c] = CT
            }
    }
    
endlibrary
библиотека Hints
library Hints initializer Init requires Buttons, GUI 


    define {
        private Z = 100.
        private MAX_ROWS = 14
        private PLAYERS = 9
        private TIMEOUT = 10. // время тултипа
        Hints_DESC_CORNER_ID = 'B01Z'
        Hints_DESC_BORDER_ID = 'B021'
        Hints_DESC_BG_ID = 'B020'
        //============================================
        //================= используйте знак @ (собака) что бы перенести строку
        //================= $ что бы создать пустую строку
        private X_OFFSET = 40.
        private Y_OFFSET = 40.
        private ROW_OFFSET = 23.5
        private CELL_SCALE = 45.5 // <= не трогать если не знаете что делаете
        private text_x_offset = 1.6 // <= не трогать если не знаете что делаете
        private SCALE = 0.6
        private MAX_HINTS = 150
        private Hide(d) = ShowDestructable(d, GetLocalPlayer() == Player(p))
    }

    // globals
    int CurrentHints = 0
    int Hints[MAX_HINTS][PLAYERS]
    int HintButton[MAX_HINTS]
    bool Hint_Enabled[MAX_HINTS][PLAYERS]
    destructable Hint_D[75][PLAYERS]
    trackable Hint_TrackableTrack[MAX_HINTS][PLAYERS]
    trackable Hint_Trackable[MAX_HINTS][PLAYERS]
    string Hint_Content[MAX_HINTS][PLAYERS]
    string Hint_Text[MAX_ROWS][10]
    texttag Hint_Texttag[MAX_ROWS][10]
    int Hint_Length[MAX_HINTS], Hint_Width[MAX_HINTS]
    real Hint_Text_X[PLAYERS], Hint_Text_Y[PLAYERS]
    public bool Cleared[PLAYERS]
    private timer DelayedClear[PLAYERS]
    private trigger HintRemoval = CreateTrigger()
    private trigger HintActivation = CreateTrigger()
    private trigger HintEsc = CreateTrigger()
    
    
    real Tooltip_X(int x, int p) {
        return (Hint_Text_X[p] + x * CELL_SCALE) + (CELL_SCALE / 2)
    }
    
    real Tooltip_Y(int y, int p) {
        return (Hint_Text_Y[p] - y * CELL_SCALE) + (CELL_SCALE / 2)
    }
    

    public int GetByA_Trackable(trackable clicked_trackable){
        int current = 1
        int i
            while(current <= CurrentHints) { 
                i = 0
                    while(i < PLAYERS){
                        if (Hint_TrackableTrack[current][i] == clicked_trackable and Hint_Enabled[current][i])
                        { return current }
                        i++
                    }
                current++
            }
        return 0
    }
    
    public int GetByD_Trackable(trackable clicked_trackable){
        int current = 1
        int i
            while(current <= CurrentHints) { 
                i = 0
                    while(i < PLAYERS){
                        if (Hint_Trackable[current][i] == clicked_trackable and Hint_Enabled[current][i])
                        { return current }
                        i++
                    }
                current++
            }
        return 0
    }
    
    public int GetPlayerD(int h, trackable t){
        int i = 0
            while (i < PLAYERS) {
                if Hint_Trackable[h][i] == t { return i } 
                i++
            }
        return -69
    }
    
    public int GetPlayerA(int h, trackable t){
        int i = 0
            while (i < PLAYERS) {
                if Hint_TrackableTrack[h][i] == t { return i } 
                i++
            }
        return -69
    }
    
    public int ButtonMatch(int button_id){
        int c = 0
            while(c++ < CurrentHints){
                if HintButton[c] == button_id { return c }
            }
        return 0
    }
    
    
    public trackable GetButtonTrack(int button_id, int p){
        int c = 0
            while(c++ < CurrentHints){
                if HintButton[c] == button_id { return Hint_Trackable[c][p] }
            }
        return null
    }
    
    public int GetHintButton(int h){
        return HintButton[h]
    }
    
    public void DisableAll(int p){
        int c = 0
            while(c++ < MAX_HINTS){
                Hint_Enabled[c][p] = false
            }
    }
    
    
    private void C2S(int h, int p){
        int row = 1, to = 0, full, from = 0
        string s = Hint_Content[h][p]
        full = StringLength(s)
        
            while(to++ < MAX_ROWS) {
                Hint_Text[to][p] = ""
            }
            
            to = 0
            while(to <= full) {
                if SubString(s, to, to+1) == "$" { 
                    Hint_Text[row][p] = SubString(s, from, to)
                    row++
                    Hint_Text[row][p] = " "
                    row++
                    to += 1
                    from = to
                }
                elseif SubString(s, to, to+1) == "@" {
                    Hint_Text[row][p] = SubString(s, from, to)
                    row++
                    from = to + 1
                }
                elseif to == full {
                    Hint_Text[row][p] = SubString(s, from, to)
                    break
                }
                to++
            }
    }
    
    
    
    public void ShowText(int h, int p){
        int row = 1
        real start_x = Hint_Text_X[p]  - 6., start_y = Hint_Text_Y[p] - 6.
        string s = ""
            C2S(h, p)
            bj_forLoopBIndexEnd = 0
            while(bj_forLoopBIndexEnd++ < MAX_ROWS){ DestroyTextTag(Hint_Texttag[bj_forLoopBIndexEnd][p]) }
                while(row <= MAX_ROWS){
                    if StringLength(Hint_Text[row][p]) > 0 {
                        Hint_Texttag[row][p] = CreateTextTag()
                        SetTextTagPos(Hint_Texttag[row][p], start_x, start_y - ((row - 1) * ROW_OFFSET), Z) //start_y - (row * ROW_OFFSET), 40.)
                            if GetLocalPlayer() == Player(p) { s = Hint_Text[row][p] }
                        SetTextTagText(Hint_Texttag[row][p], s, (7.9 * 0.023) / 10.)
                    }
                    row++
                }
    }
                             
    
    
    public int Add(int button_id, string s, int l, int w, trigger hover_react){
        int i = -1
        int hint = ButtonMatch(button_id)
        string tr
            if hint > 0 {
                CurrentHints++
                HintButton[CurrentHints] = button_id
                    while(i++ < PLAYERS){
                        Hint_Content[CurrentHints][i] = s
                        //C2S(CurrentHints, i)
                        Hint_TrackableTrack[CurrentHints][i] = Button_Trackable[button_id][i]
                        Hint_Trackable[CurrentHints][i] = GetButtonTrack(button_id, i)
                        Hint_Enabled[CurrentHints][i] = false
                    }
                    Hint_Length[CurrentHints] = l
                    Hint_Width[CurrentHints] = w
            }
            else {
                CurrentHints++
                HintButton[CurrentHints] = button_id
                    while(i++ < PLAYERS){
                        if GetLocalPlayer() == Player(i) { tr = "war3mapImported\\GUI_Description_Trackable.mdx" }
                        else { tr = "dummy.mdx" }
                        Hint_TrackableTrack[CurrentHints][i] = Button_Trackable[button_id][i]
                        Hint_Trackable[CurrentHints][i] = CreateTrackable(tr, GUI_X(Button_Coords[button_id][1]), GUI_Y(Button_Coords[button_id][2]), 0.)
                        Hint_Content[CurrentHints][i] = s
                        //C2S(CurrentHints, i)
                        TriggerRegisterTrackableTrackEvent(HintActivation ,Button_Trackable[button_id][i])
                        TriggerRegisterTrackableTrackEvent(hover_react ,Button_Trackable[button_id][i])
                        TriggerRegisterTrackableTrackEvent(HintRemoval ,Hint_Trackable[CurrentHints][i])
                        Hint_Enabled[CurrentHints][i] = false
                    }
                    Hint_Length[CurrentHints] = l
                    Hint_Width[CurrentHints] = w
            }
        return CurrentHints
    }

    private void ClearHints(){
        int p = GetTimerAttach(GetExpiredTimer())
        int c = 0
            while(c++ < 75) { RemoveDestructable(Hint_D[c][p]) }
            c = 0
            while(c++ < MAX_ROWS){ DestroyTextTag(Hint_Texttag[c][p]) }
        Cleared[p] = true
    }
    
     private void HintEsc_Act(){
        int p = GetPlayerId(GetTriggerPlayer()), c = 0
            while(c++ < 75){ RemoveDestructable(Hint_D[c][p]) }
            c = 0
            while(c++ < MAX_ROWS){ DestroyTextTag(Hint_Texttag[c][p]) }
        Cleared[p] = true
    }
    
    
    
    private void Build(int h, int b, int p){
        int c = 0, l, w, cell
        real x, y, offset = 0.
        int i
            while(c++ < 75){ RemoveDestructable(Hint_D[c][p]) }
            c = 0
            while(c++ < MAX_ROWS){ DestroyTextTag(Hint_Texttag[c][p]) }
            
            // idiot proof
            if Hint_Length[h] > 22 { Hint_Length[h] = 22 }
            if Hint_Width[h] > 10 { Hint_Width[h] = 10 }
            
            
                if Button_Coords[b][1] > 14 {
                    offset = 15. + (2. * (22 - Button_Coords[b][1]))
                }
                elseif Button_Coords[b][1] < 8 {
                    offset = offset - (15. + (2. * (11 - Button_Coords[b][1])))
                }
            
            x = (GUI_X(Button_Coords[b][1]) - offset) + (X_OFFSET)
            y = GUI_Y(Button_Coords[b][2]) - (Y_OFFSET)
            
            
            Hint_Text_X[p] = x
            Hint_Text_Y[p] = y
            
            if Button_Coords[b][1] > 14 {
                Hint_Text_X[p] = Hint_Text_X[p] + (text_x_offset * (22 - Button_Coords[b][1]))
            }
            elseif Button_Coords[b][1] < 8 {
                Hint_Text_X[p] = Hint_Text_X[p] - (text_x_offset * (11 - Button_Coords[b][1]))
            }
            
            
            if Hint_Length[h] + Button_Coords[b][1] > 23 {
                i = 22 - (Hint_Length[h] + Button_Coords[b][1])
                x = GUI_X((Button_Coords[b][1] + i)) + (X_OFFSET)
                Hint_Text_X[p] = x
                    if i > 14 {
                        Hint_Text_X[p] = Hint_Text_X[p] + (text_x_offset * (22 - i)) 
                    }
            }
            elseif Button_Coords[b][2] - Hint_Width[h] < -1 {
                i = Hint_Width[h] - Button_Coords[b][2]
                y = GUI_Y((Button_Coords[b][2] + i)) - (Y_OFFSET)
                Hint_Text_Y[p] = y 
            }
            
                // square
                if Hint_Length[h] == 1 and Hint_Width[h] == 1 {
                    // |_
                    Hint_D[1][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x, y - CELL_SCALE, Z, 90., SCALE, 0)
                    //  _
                    // |
                    Hint_D[2][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x, y, Z, 0., SCALE, 0)
                    // _
                    //  |
                    Hint_D[3][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x + CELL_SCALE, y, Z, 270., SCALE, 0)
                    // _|
                    Hint_D[4][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x + CELL_SCALE, y - CELL_SCALE, Z, 180., SCALE, 0)
                    
                    Hint_D[5][p] = CreateDestructableZ(Hints_DESC_BG_ID, x, y, Z, 0, SCALE, 0)
                    Hint_D[6][p] = CreateDestructableZ(Hints_DESC_BG_ID, x, y - CELL_SCALE, Z- 0.1, 0., SCALE, 0)
                    Hint_D[7][p] = CreateDestructableZ(Hints_DESC_BG_ID, x + CELL_SCALE, y - CELL_SCALE, Z- 0.1, 0., SCALE, 0)
                    Hint_D[8][p] = CreateDestructableZ(Hints_DESC_BG_ID, x + CELL_SCALE, y, Z- 0.1, 0, SCALE, 0)
                    Hide(Hint_D[1][p]); Hide(Hint_D[2][p]); Hide(Hint_D[3][p]); Hide(Hint_D[4][p])
                    Hide(Hint_D[5][p]); Hide(Hint_D[6][p]); Hide(Hint_D[7][p]); Hide(Hint_D[8][p])
                }
                // by Y ^^^
                elseif (Hint_Length[h] == 1 and Hint_Width[h] > 1) {
                    Hint_D[1][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x, y, Z, 0., SCALE, 0)
                    Hint_D[2][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x, y, Z, 270., SCALE, 0)
                    Hint_D[3][p] = CreateDestructableZ(Hints_DESC_BG_ID, x, y, Z - 0.1, 0, SCALE, 0)
                    Hide(Hint_D[1][p]); Hide(Hint_D[2][p]); Hide(Hint_D[3][p]);
                    w = 1; c = 4; cell = Hint_Width[h] - 1
                        while(w < cell) {
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BORDER_ID, x, y - (w * CELL_SCALE), Z, 90., SCALE, 0)
                            Hide(Hint_D[c][p]); c++
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BORDER_ID, x, y - (w * CELL_SCALE), Z, 270., SCALE, 0)
                            Hide(Hint_D[c][p]); c++
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BG_ID, x, y - (w * CELL_SCALE), Z, 0., SCALE, 0)
                            Hide(Hint_D[c][p]); c++; w++
                        }
                    Hint_D[c][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x, y - (w * CELL_SCALE), 15, 90., SCALE, 0)
                    Hint_D[c+1][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x, y - (w * CELL_SCALE), Z,  180., SCALE, 0)
                    Hint_D[c+2][p] = CreateDestructableZ(Hints_DESC_BG_ID, x, y - (w * CELL_SCALE), Z, 0., SCALE, 0)
                    Hide(Hint_D[c][p]); Hide(Hint_D[c+1][p]); Hide(Hint_D[c+2][p]);
                }
                // by X =>>>
                elseif (Hint_Length[h] > 1 and Hint_Width[h] == 1) {
                    Hint_D[1][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x, y, Z, 90., SCALE, 0)
                    Hint_D[2][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x, y, Z, 0., SCALE, 0)
                    Hint_D[3][p] = CreateDestructableZ(Hints_DESC_BG_ID, x, y, Z- 0.1, 0, SCALE, 0)
                    Hide(Hint_D[1][p]); Hide(Hint_D[2][p]); Hide(Hint_D[3][p]);
                    l = 1; c = 4; cell = Hint_Length[h] - 1
                        while(l < cell) {
                                Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BORDER_ID, x + (l * CELL_SCALE), y, Z, 180., SCALE, 0)
                            Hide(Hint_D[c][p]); c++
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BORDER_ID, x + (l * CELL_SCALE), y, Z, 0., SCALE, 0)
                            Hide(Hint_D[c][p]); c++
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BG_ID, x+ (l * CELL_SCALE), y, Z- 0.1, 0., SCALE, 0)
                            Hide(Hint_D[c][p]); c++; l++
                        }
                    Hint_D[c][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x+ (l * CELL_SCALE), y, Z, 180., SCALE, 0)
                    Hint_D[c+1][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x+ (l * CELL_SCALE), y, Z, 270., SCALE, 0)
                    Hint_D[c+2][p] = CreateDestructableZ(Hints_DESC_BG_ID, x+ (l * CELL_SCALE), y, Z- 0.1, 0., SCALE, 0)
                    Hide(Hint_D[c][p]); Hide(Hint_D[c+1][p]); Hide(Hint_D[c+2][p]);
                }
                // custom
                elseif (Hint_Length[h] > 1 and Hint_Width[h] > 1) {
                    l = 0; c = 1
                    cell = Hint_Width[h] - 1
                    while(l <= Hint_Length[h]) {
                        // bottom x =>
                        // start corner by x
                        if l == 0 {
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x, y, Z, 0., SCALE, 0)
                            Hide(Hint_D[c][p]); c++
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BG_ID, x, y, Z- 0.1, 0., SCALE, 0)
                            Hide(Hint_D[c][p]); c++
                        }
                        // end corner by x
                        elseif l == Hint_Length[h] {
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x + (l * CELL_SCALE), y, Z, 270., SCALE, 0)
                            Hide(Hint_D[c][p]); c++
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BG_ID, x+ (l * CELL_SCALE), y, Z- 0.1, 0., SCALE, 0)
                            Hide(Hint_D[c][p]); c++
                        }
                        else {
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BORDER_ID, x + (l * CELL_SCALE), y, Z, 0., SCALE, 0)
                            Hide(Hint_D[c][p]); c++
                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BG_ID, x+ (l * CELL_SCALE), y, Z- 0.1, 0., SCALE, 0)
                            Hide(Hint_D[c][p]); c++
                        }   
                        // from top to bottom
                        w = 1
                            while(w <= cell) {
                                // first width row
                                if l == 0 {
                                    if w < cell {
                                        Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BORDER_ID, x, y - (w * CELL_SCALE), Z, 90., SCALE, 0)
                                        Hide(Hint_D[c][p]); c++
                                    }
                                    // corner
                                    elseif w == cell {
                                        Hint_D[c][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x, y - (w * CELL_SCALE), Z, 90., SCALE, 0)
                                        Hide(Hint_D[c][p]); c++
                                    }
                                    Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BG_ID, x, y - (w * CELL_SCALE), Z- 0.1, 0., SCALE, 0)
                                    Hide(Hint_D[c][p]); c++
                                }
                                // last width row
                                elseif l == Hint_Length[h] {
                                    if w < cell {
                                        Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BORDER_ID, x + (l * CELL_SCALE), y - (w * CELL_SCALE), Z, 270., SCALE, 0)
                                        Hide(Hint_D[c][p]); c++
                                    }
                                    // corner
                                    elseif w == cell {
                                        Hint_D[c][p] = CreateDestructableZ(Hints_DESC_CORNER_ID, x + (l * CELL_SCALE), y - (w * CELL_SCALE), Z, 180., SCALE, 0)
                                        Hide(Hint_D[c][p]); c++
                                    }
                                    Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BG_ID, x + (l * CELL_SCALE), y - (w * CELL_SCALE), Z- 0.1, 0., SCALE, 0)
                                    Hide(Hint_D[c][p]); c++
                                }
                                else {
                                    Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BG_ID, x + (l * CELL_SCALE), y - (w * CELL_SCALE), Z- 0.1, 0., SCALE, 0)
                                    Hide(Hint_D[c][p]); c++
                                        if w == cell {
                                            //bottom close
                                            Hint_D[c][p] = CreateDestructableZ(Hints_DESC_BORDER_ID, x + (l * CELL_SCALE), y - (w * CELL_SCALE), Z, 180., SCALE, 0)
                                            Hide(Hint_D[c][p]); c++
                                        }
                                }
                                w++
                            }
                        l++
                    }
                }
    }
    
    
    
    private void HintActivation_Act(){
        int h = GetByA_Trackable(GetTriggeringTrackable())
        int button_id = Buttons_GetByTrackable(GetTriggeringTrackable())
        int p = GetPlayerA(h, GetTriggeringTrackable())
        real x, y
            if Hint_Enabled[h][p] {
                //something
                Build(h, button_id, p)
                ShowText(h, p)
                Cleared[p] = false
                TimerStartEx(DelayedClear[p], TIMEOUT, function ClearHints, p)
            }
    }
    
    public void SetText(int h, string s, int p){
        Hint_Content[h][p] = s
        C2S(h, p)
        ShowText(h, p)
        Cleared[p] = false
        TimerStartEx(DelayedClear[p], TIMEOUT, function ClearHints, p)
        //if show { ShowText(h, p) }
    }
    
    private void HintRemoval_Act(){
        int c = 0
        int h = GetByD_Trackable(GetTriggeringTrackable())
        int p = GetPlayerD(h, GetTriggeringTrackable())
            while(c++ < 75){ RemoveDestructable(Hint_D[c][p]) }
            c = 0
            while(c++ < MAX_ROWS){ DestroyTextTag(Hint_Texttag[c][p]) }
            Cleared[p] = true
    }
    
    
    private void Init(){
        int i = -1
            TriggerAddAction(HintRemoval, function HintRemoval_Act)
            TriggerAddAction(HintActivation, function HintActivation_Act)
            TriggerAddAction(HintEsc, function HintEsc_Act)
            
                while(i++ < PLAYERS) {
                    TriggerRegisterPlayerEvent(HintEsc, Player(i), EVENT_PLAYER_END_CINEMATIC)
                    DelayedClear[i] = CT
                    Cleared[i] = true
                }
    }

endlibrary
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
24
7 лет назад
0
Как я понимаю используется координатная сетка из трекейблов, учитывая невозможность их удаления и перемещения?
2
26
7 лет назад
2
darkowlom:
Как я понимаю используется координатная сетка из трекейблов, учитывая невозможность их удаления и перемещения?
трекейблы создаются по нужде на нужных координатах. нет смысла делать трекейблов на всю координатную сетку полноэкранки если кнопок будет гораздо меньше.
принцип в том, что сначала ты определяешь где у тебя будут кнопки, а затем на них вешается какой либо "аттач", типа иконки, количества "стаков" если нужно, и можно даже повесить нужный тебе инт на кнопку как кастом дату
и так же с тултипами, при создании тултипа на кнопку, там смотрится используется ли эти координаты уже, если да, просто берется уже созданный трекейбл, иначе создается новый
0
33
7 лет назад
Отредактирован PUVer
0
Сделай ещё в инвентаре меню быстрого доступа с зельями и свитками. Чтобы эти предметы в инвентаре отображались стандартном.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.