[Aportes indexados] Raghardas: Sistema de accesos rápidos en render (macros)

Anzhel

Oráculo Lvl 1
Hola!
Les traigo el sistema de accesos rápidos (conocido como macros) que usamos en Raghardas. Lo quería aportar para compartir algo (hace mucho que no lo hago).

El código (un form para configurar el macro + un módulo del sistema) lo pueden descargar en:

Aquí les dejo el contenido del módulo. Tiene algunas cosas (más que nada, esos bucles que se ejecutan miles de veces por minuto) que se pueden mejorar (y lo voy a hacer). Pero bueno, lo aporto tal cual lo estamos usando ahora mismo.

Antes que nada, describo lo que hace.

Es un sistema de 'macros', con slots variables (lo podés cambiar en la constante NumShortcuts). Cada macro tiene la posibilidad de ejecutar cuatro acciones:
  • Ejecutar un comando (/meditar, por ejemplo)
  • Usar un objeto (tomar potas, por ejemplo)
  • Equipar un ítem (como una espada o escudo)
  • Lanzar un hechizo (cualquiera que tenga tu personaje).
Se genera un archivo en '\init\shortcuts' (podés cambiarlo en una función) con los macros de cada personaje que loguees en esa computadora.
Los macros se renderizan en pantalla con una barra en la posición que desees, con un pergamino si es un hechizo o comando, y el gráfico del item (y si está equipado, un "+", si es un objeto como poción (no equipable), muestra la cantidad de items total que tenés)

Todo es 100% configurable. Hay alguuuunas cosas medias truchas pero de todos modos el código es súper entendible.

AVISO:
  • En Raghardas tenemos varias cosas que probablemente tengas que adaptar/implementar para hacer uso de este código, como tener el archivo obj.dat (y cargarlo) en el cliente, o funciones como Wearable que dicen si un objeto es equipable (como una espada) o no (pociones, comida).
  • Este código NO es para copiar y pegar. NO te va a servir, tenés que adaptarlo o cambiarle cosas.
  • Funciona perfecto, obviamente.
Código:
Option Explicit

Public Enum eShortcutTypes
    Command = 1     'Comando
    UseItem = 2     'Usar un item
    EquipItem = 3   'Equipar un item
    Spell = 4       'Lanzar un hechizo
    Attack = 5      'Atacar con golpe: no lo uso por ahora
End Enum

Public Type Shortcuts
    ShortcutType As eShortcutTypes  'Tipo de shortcut
    Name As String                  'Nombre del comando o Nombre del hechizo
    ObjIndex As Integer             'ObjIndex del item
End Type

Public Const NumShortcuts     As Byte = 12                              'Cantidad de shortcuts
Public Const ShortcutSizeX As Byte = 34                                 'Tamaño (en píxeles) horizontal del marco de los shortcuts
Public Const ShortcutSizeY As Byte = 34                                 'Tamaño (en píxeles) vertical del marco de los shortcuts
Public Const ShortcutOffsetX As Integer = frmMain.mainviewpic.Width / 2               'Pixel horizontal central de la barra de shortcuts
Public Const ShortcutOffsetY As Integer = frmMain.mainviewpic.Height - 39             'Pixel vertical donde se empieza a dibujar la barra de shortcuts
'Public Const ShortcutFrameGrhIndex As Long = 34147                      'GrhIndex del marco de los shortcuts + NumShortcuts índices para dibujar la tecla de acción (F1, F2, etc.)
'^ lo relativo al marquito decorativo alrededor de cada shortcut lo dejo comentado, dejo los recursos en el post para indexarlo

Public Shortcut(1 To NumShortcuts) As Shortcuts  'Array de shortcuts
Public ShortcutSelected As Byte

'Funciones con I/O
Private Function ShortcutFolder() As String
    ShortcutFolder = IniPath & "shortcuts\"
End Function

Public Sub ShortcutFileCheck()
    If Not FileExist(ShortcutFolder & UserName & ".dat", vbArchive) Then
        Call ShortcutEraseAll
    Else
        Call ShortcutLoadAll
    End If
End Sub

Public Sub ShortcutLoad(ByVal Index As Byte)
    Shortcut(Index).ShortcutType = CByte(GetVar(ShortcutFolder & UserName & ".dat", "SHORTCUT" & CStr(Index), "ShortcutType"))
    Shortcut(Index).Name = GetVar(ShortcutFolder & UserName & ".dat", "SHORTCUT" & CStr(Index), "Name")
    Shortcut(Index).ObjIndex = CInt(GetVar(ShortcutFolder & UserName & ".dat", "SHORTCUT" & CStr(Index), "ObjIndex"))
End Sub

Public Sub ShortcutLoadAll()
    Dim i As Byte

    For i = 1 To NumShortcuts
        Call ShortcutLoad(i)
    Next i

End Sub

Public Sub ShortcutWrite(ByVal Index As Byte)
    Call WriteVar(ShortcutFolder & UserName & ".dat", "SHORTCUT" & CStr(Index), "ShortcutType", CStr(Shortcut(Index).ShortcutType))
    Call WriteVar(ShortcutFolder & UserName & ".dat", "SHORTCUT" & CStr(Index), "Name", Shortcut(Index).Name)
    Call WriteVar(ShortcutFolder & UserName & ".dat", "SHORTCUT" & CStr(Index), "ObjIndex", CStr(Shortcut(Index).ObjIndex))
End Sub

Public Sub ShortcutWriteAll()
    Dim i As Byte

    For i = 1 To NumShortcuts
        Call ShortcutWrite(i)
    Next i

End Sub

'Funciones de Seteo de valores
Public Sub ShortcutSet_ShortcutType(ByVal Index As Byte, ByVal ShortcutType As eShortcutTypes)
    Shortcut(Index).ShortcutType = ShortcutType
 
    Call ShortcutWrite(Index)
End Sub

Public Sub ShortcutSet_Name(ByVal Index As Byte, ByVal Name As String)
    Shortcut(Index).Name = Name
 
    Call ShortcutWrite(Index)
End Sub

Public Sub ShortcutSet_ObjIndex(ByVal Index As Byte, ByVal ObjIndex As Integer)
    Shortcut(Index).ObjIndex = ObjIndex
 
    Call ShortcutWrite(Index)
End Sub

Public Sub ShortcutCopy(ByVal Index As Byte, ByRef ShortcutData As Shortcuts)
    Shortcut(Index).ShortcutType = ShortcutData.ShortcutType
    Shortcut(Index).Name = ShortcutData.Name
    Shortcut(Index).ObjIndex = ShortcutData.ObjIndex
 
    Call ShortcutWrite(Index)
End Sub

Public Sub ShortcutErase(ByVal Index As Byte)
    Shortcut(Index).ShortcutType = 0
    Shortcut(Index).Name = vbNullString
    Shortcut(Index).ObjIndex = 0
 
    Call ShortcutWrite(Index)
End Sub

Public Sub ShortcutEraseAll()
    Dim i As Byte
 
    For i = 1 To NumShortcuts
        Call ShortcutErase(i)
    Next i
End Sub

'Funciones auxiliares no relativas a shortcuts
Public Function SpellIconGet(Name As String) As Integer
'En Raghardas devuelve un gráfico de 32x32 que es diferente en cada hechizo, _
aquí les dejo el ejemplo, es algo feo y hardcodeado pero bueno, ya lo cambiaré jajaj

    Select Case Name

        Case "Apocalipsis"
            SpellIconGet = 609
        
        Case Else
            SpellIconGet = 609

    End Select

End Function

Public Function TotalItemAmountGet(ByVal ObjIndex As Integer) As Long
    Dim i As Byte
    For i = 1 To MAX_INVENTORY_SLOTS
        If Inventario.ObjIndex(i) = ObjIndex Then
            TotalItemAmountGet = TotalItemAmountGet + Inventario.Amount(i)
        End If
    Next i
End Function

Public Function ObjIndexEquipped(ByVal ObjIndex As Integer) As Boolean
    Dim i As Byte
    For i = 1 To MAX_INVENTORY_SLOTS
        If Inventario.Equipped(i) And (Inventario.ObjIndex(i) = ObjIndex) Then
            ObjIndexEquipped = True
            Exit Function
        End If
    Next i
End Function

'Funciones de uso general de los shortcuts
Public Function ShortcutClickCheck(RightButton As Boolean) As Boolean
'La fórmula es casi exacta pero súper ilegible
    Dim i As Byte

    If MouseBetween(ShortcutOffsetX - ((NumShortcuts * (ShortcutSizeX + 1)) / 2 + ShortcutSizeX - 2) + (1 * (ShortcutSizeX + 1)), _
                                ShortcutOffsetX - 5 - ((NumShortcuts * (ShortcutSizeX + 1)) / 2 + ShortcutSizeX - 2) + ((NumShortcuts + 1) * (ShortcutSizeX + 1)), _
                                ShortcutOffsetY + 1, _
                                ShortcutOffsetY + ShortcutSizeY) Then

        For i = 1 To NumShortcuts

            If MouseBetween(ShortcutOffsetX - ((NumShortcuts * (ShortcutSizeX + 1)) / 2 + ShortcutSizeX - 2) + (i * (ShortcutSizeX + 1)), _
                                        ShortcutOffsetX - Round(i / 4) - ((NumShortcuts * (ShortcutSizeX + 1)) / 2 + ShortcutSizeX - 2) + ((i + 1) * (ShortcutSizeX + 1)), _
                                        ShortcutOffsetY + 1, _
                                        ShortcutOffsetY + ShortcutSizeY) Then

                If RightButton = False Then
                    Call ShortcutAction(i)
                    Exit For
                Else
                    ShortcutSelected = i
                    frmShortcuts.Show , frmMain
                    Exit For
                End If
            End If

        Next i

        ShortcutClickCheck = True
    End If

End Function

Public Function ShortcutNull() As Shortcuts
    ShortcutNull.ShortcutType = 0
    ShortcutNull.Name = vbNullString
    ShortcutNull.ObjIndex = 0
End Function

'Funciones de aplicación de los shortcuts
Public Sub ShortcutRender()
    Dim i As Byte, ShortcutGrh As Grh ', FrameGrh As Grh

    For i = 1 To NumShortcuts

        Select Case Shortcut(i).ShortcutType

            Case eShortcutTypes.Command
                ShortcutGrh.GrhIndex = 609

            Case eShortcutTypes.UseItem, eShortcutTypes.EquipItem
                ShortcutGrh.GrhIndex = ObjData(Shortcut(i).ObjIndex).GrhIndex

            Case eShortcutTypes.Spell
                ShortcutGrh.GrhIndex = SpellIconGet(Shortcut(i).Name)
            
            Case 0
                ShortcutGrh.GrhIndex = 1
        End Select

        'FrameGrh.GrhIndex = ShortcutFrameGrhIndex
        'Call DDrawTransGrhtoSurface(FrameGrh, ShortcutOffsetX - ((NumShortcuts * (ShortcutSizeX + 1)) / 2 + ShortcutSizeX - 2) + (i * (ShortcutSizeX + 1)), ShortcutOffsetY + 1, 1, 0)
        Call DDrawTransGrhtoSurface(ShortcutGrh, ShortcutOffsetX - ((NumShortcuts * (ShortcutSizeX + 1)) / 2 + ShortcutSizeX - 2) + (i * (ShortcutSizeX + 1)), ShortcutOffsetY, 1, 0)
        'FrameGrh.GrhIndex = ShortcutFrameGrhIndex + i
        'Call DDrawTransGrhtoSurface(FrameGrh, ShortcutOffsetX - ((NumShortcuts * (ShortcutSizeX + 1)) / 2 + ShortcutSizeX - 1) + (i * (ShortcutSizeX + 1)), ShortcutOffsetY, 1, 0)

        Select Case Shortcut(i).ShortcutType

            Case eShortcutTypes.UseItem
                Call DrawText(ShortcutOffsetX - ((NumShortcuts * (ShortcutSizeX + 1)) / 2 + ShortcutSizeX - 3) + (i * (ShortcutSizeX + 1)), ShortcutOffsetY - 3, CStr(TotalItemAmountGet(Shortcut(i).ObjIndex)), -1)

            Case eShortcutTypes.EquipItem
                If ObjIndexEquipped(Shortcut(i).ObjIndex) Then
                    Call DrawText(ShortcutOffsetX - ((NumShortcuts * (ShortcutSizeX + 1)) / 2 + ShortcutSizeX - 28) + (i * (ShortcutSizeX + 1)), ShortcutOffsetY - 5, "+", -1)
                End If
        End Select

    Next i

End Sub

Public Sub ShortcutAction(ByVal Index As Byte)
    Dim i As Byte

    Select Case Shortcut(Index).ShortcutType

        Case eShortcutTypes.Command
            Call ParseUserCommand("/" & Shortcut(Index).Name)

        Case eShortcutTypes.UseItem

            If UserEstado = 1 Then

                With FontTypes(FontTypeNames.FONTTYPE_INFO)
                    Call ShowConsoleMsg("¡Estás muerto!", .Red, .Green, .Blue, .Bold, .Italic)
                End With

            Else

                For i = 1 To MAX_INVENTORY_SLOTS

                    If Inventario.ObjIndex(i) = Shortcut(Index).ObjIndex Then
                        If MainTimer.Check(TimersIndex.UseItemWithU) Then
                            Call WriteUseItem(i)
                            Exit For
                        End If
                    End If

                Next i

            End If

        Case eShortcutTypes.EquipItem

            If UserEstado = 1 Then

                With FontTypes(FontTypeNames.FONTTYPE_INFO)
                    Call ShowConsoleMsg("¡Estás muerto!", .Red, .Green, .Blue, .Bold, .Italic)
                End With

            Else

                For i = 1 To MAX_INVENTORY_SLOTS

                    If Inventario.ObjIndex(i) = Shortcut(Index).ObjIndex Then
                        Call WriteEquipItem(i)
                        Exit For
                    End If

                Next i

            End If

        Case eShortcutTypes.Spell

            If Shortcut(Index).Name <> "-" Then
                If UserEstado = 1 Then

                    With FontTypes(FontTypeNames.FONTTYPE_INFO)
                        Call ShowConsoleMsg("¡Estás muerto!", .Red, .Green, .Blue, .Bold, .Italic)
                    End With

                Else

                    For i = 1 To 35

                        If frmMain.hlst.List(i - 1) = Shortcut(Index).Name Then
                            If MainTimer.Check(TimersIndex.Work, False) Then
                                Call WriteCastSpell(i)
                                Call WriteWork(eSkill.Magia)
                            End If

                            Exit For
                        End If

                    Next i

                End If
            End If

    End Select

End Sub
Muestra de como se ven:
ELKXKOH.jpg

Marco alrededor de los shortcuts + números de función:
Aez6vc8.png
 
Última edición:

shermie80

Like a Boss
Este está más prolijo, completo, configurable (si cambiás la cantidad de macros en NumShortcuts no necesitás cambiar nada más) y encima es renderizado.
El que esta aportado, el que aporto batman también esta prolijo, guardado, configurable, y renderizado, etc
Puede que este este un poco mejor, pero para el copy/paste no le sirve.
 

Anzhel

Oráculo Lvl 1
El que esta aportado, el que aporto batman también esta prolijo, guardado, configurable, y renderizado, etc
Puede que este este un poco mejor, pero para el copy/paste no le sirve.
Pues no lo vi ese, porque jamás vi un sistema bien hecho de macros aportado xDD
Para el que quiera copy-paste, es tan simple como hacer dos llamadas (para leftbutton y rightbutton) en el frmmain.Form_Click al sub ShortcutClickCheck, luego hacer los checkeos de apretar las teclas vbkey1,2,3 etc y que active el macro (sub ShortcutAction(index)), luego en el renderscreen poner abajo de todo un call shortcutrender y listo, nada dificil (eso sí, para que los gráficos de items se vean, obj.dat en el cliente)
 
Última edición:

Dr. GoDKeR

El Rey y el As
Miembro del equipo
Administrador
Developer
Moderador de RRPP
Moderador de AO
Moderador de Tecnología
Moderador de Entretenimiento
Moderador de Diseño
Especialista de RRPP
Especialista de Entretenimiento
Especialista de Tecnología
Especialista de Argentum
Especialista de Diseño
El que esta aportado, el que aporto batman también esta prolijo, guardado, configurable, y renderizado, etc
Puede que este este un poco mejor, pero para el copy/paste no le sirve.

El de bateman NO esta prolijo, NO esta bien hecho y NO es renderizado (con renderizado se refiere a dibujarlo sobre el render, no a la negrada de meterlo en un picturebox).
 

Anzhel

Oráculo Lvl 1
Ah, me acordé ahora que vi la función mientras programaba:
Agreguen esto para el ClickCheck

Código:
Public Function MouseBetween(ByVal x1 As Integer, _
                             ByVal x2 As Integer, _
                             ByVal y1 As Integer, _
                             ByVal y2 As Integer) As Boolean

    If frmMain.MouseX >= x1 And frmMain.MouseX <= x2 And frmMain.MouseY >= y1 And frmMain.MouseY <= y2 Then MouseBetween = True
End Function
 
Arriba