Aldeia RPG

Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.

Suporte ao desenvolvimento de jogos


    [EO 2.0] Spell dando Escudo

    Kotol
    Kotol
    Moderador Local
    Moderador Local


    Mensagens : 69
    Créditos : 13

    [EO 2.0] Spell dando Escudo Empty [EO 2.0] Spell dando Escudo

    Mensagem por Kotol Sáb maio 13, 2023 7:47 pm

    Como no título, é um sistema de magia de escudo. Este escudo irá receber o dano do jogador em sentido "Player Vs NPC" e "Player Vs Player". O sistema até onde foi testado, funciona na lógica:

    [Lógica]
    Dano = 100 com Escudo do Jogador = 200
    -> Dano = -100 (Saída da Sub) , Escudo do jogador atual = 100

    Dano = 200 com Escudo do Jogador = 100
    -> Dano = 100 , Escudo do jogador atual = 0 ----> Continua o Dano , dando 100 de dano na vida normal.
    [Fim da lógica]

    O sistema conta com: 

    - Novo vital: Vitals.Shielding;
    - Escudo será: Vital da Magia + Porcentagem do HP máximo escolhido no editor + Porcentagem do MP máximo escolhido no editor;
    - Quantidade de escudo sendo mostrada no canto superior esquerdo da tela.

    OBS. IMPORTANTE: Como o sistema vai adicionar mais um "VitalType", então pode ser necessário a criação de novas contas. Caso seu projeto já esteja online com contas Oficiais, basta criar uma variável no "PlayerRec" nova e indicar como "Escudo" ao invés do "VitalType".

    Sem mais delongas, vamos ao sistema, primeiramente vamos começar com o cliente.

    CLIENT~SIDE


    Abra seu "Client.Vbp" e no "frmEditor_Spell" no modo "Forms" , crie:

    - 1x Frame , Name: "FraShield" , Visible: False
    - 1x Label, Caption: "% of HP:"
    - 1x TextBox, Name: "txtShieldHP" , Caption: " "
    - 1x Label, Caption: "% of MP:"
    - 1x TextBox, Name: "txtShieldMP" , Caption: " "

    Ainda no "frmEditor_Spell" , na parte de "Forms", na "cmbType" , na propriedade "List" , mude isto:
    Código:
    Damage HP
    Damage MP
    Heal HP
    Heal MP
    Warp
     
    Para isto:
    Código:
    Damage HP
    Damage MP
    Heal HP
    Heal MP
    Warp
    Shielding


    Agora, dê dois cliques na "cmbType" e na sua parte lógica, procure isto:
    Código:
    Spell(EditorIndex).Type = cmbType.ListIndex

    E logo abaixo adicione isto:
    Código:
    'Shield
        If Spell(EditorIndex).Type = SPELL_TYPE_SHIELD Then
            fraShield.Visible = True
        Else
            fraShield.Visible = False
        End If

    Agora, dê dois cliques na "txtShieldHP" e adicione isto:
    Código:
    If Not IsNumeric(txtShieldHP.text) Then Exit Sub
        If Not Len(txtShieldHP.text) > 0 Then Exit Sub
        Spell(EditorIndex).PercVitalHP = txtShieldHP.text

    E finalmente, dê dois cliques na "txtShieldMP" e adicione isto:
    Código:
    If Not IsNumeric(txtShieldMP.text) Then Exit Sub
        If Not Len(txtShieldMP.text) > 0 Then Exit Sub
        Spell(EditorIndex).PercVitalMP = txtShieldMP.text


    Agora, em "ModGameEditors", na "Public Sub SpellEditorInit()" , procure por esta parte:
    Código:
    ' find the sound we have set
            If .cmbSound.ListCount >= 0 Then
                For i = 0 To .cmbSound.ListCount
                    If .cmbSound.List(i) = Trim$(Spell(EditorIndex).Sound) Then
                        .cmbSound.ListIndex = i
                        SoundSet = True
                    End If
                Next
                If Not SoundSet Or .cmbSound.ListIndex = -1 Then .cmbSound.ListIndex = 0
            End If


    E logo abaixo adicione isto:
    Código:
    'Shield
            .txtShieldHP.text = Spell(EditorIndex).PercVitalHP
            .txtShieldMP.text = Spell(EditorIndex).PercVitalMP


    Agora, em "ModConstants" , procure por:
    Código:
    Public Const SPELL_TYPE_WARP As Byte = 4

    E logo abaixo adicione:
    Código:
    Public Const SPELL_TYPE_SHIELD As Byte = 5 'Shield

    Agora, em "ModEnumerations", procure por esta parte:
    Código:
    ' Vitals used by Players, Npcs and Classes
    Public Enum Vitals
        HP = 1
        MP
        ' Make sure Vital_Count is below everything else
        Vital_Count
    End Enum

    E substitua por isto:
    Código:
    ' Vitals used by Players, Npcs and Classes
    Public Enum Vitals
        HP = 1
        MP
        Shielding
        ' Make sure Vital_Count is below everything else
        Vital_Count
    End Enum

    Ainda em "ModEnumerations", procure por:
    Código:
    SPlayerMp

    E abaixo adicione isto:
    Código:
    SPlayerShield

    Agora, em "ModHandleData", na "Public Sub InitMessages()", abaixo de:
    Código:
    HandleDataSub(SPlayerMp) = GetAddress(AddressOf HandlePlayerMp)

    Adicione isto:
    Código:
    HandleDataSub(SPlayerShield) = GetAddress(AddressOf HandlePlayerShield)

    Ainda em "ModHandleData", procure pela "Private Sub HandlePlayerMp" , e ABAIXO DESTE SUB , ou seja, logo abaixo depois do primeiro "End Sub", adicione esta Sub:
    Código:
    Private Sub HandlePlayerShield(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer

        ' If debug mode, handle error then exit out
        If Options.Debug = 1 Then On Error GoTo errorhandler
        
        Set Buffer = New clsBuffer
        Buffer.WriteBytes Data()
        Player(MyIndex).Vital(Vitals.Shielding) = Buffer.ReadLong
        Set Buffer = Nothing

        ' Error handler
        Exit Sub
    errorhandler:
        HandleError "HandlePlayerShield", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
        Err.Clear
        Exit Sub
    End Sub


    Agora, em "ModDirectDraw7", procure por esta parte:
    Código:
    ' draw FPS
        If BFPS Then
            Call DrawText(TexthDC, Camera.Right - (Len("FPS: " & GameFPS) * 8), Camera.top + 1, Trim$("FPS: " & GameFPS), QBColor(Yellow))
        End If
     
    E logo abaixo adicione isto:
    Código:
    'Draw shield amount if > 0
        If Player(MyIndex).Vital(Vitals.Shielding) > 0 Then
            Call DrawText(TexthDC, Camera.Left, Camera.top + 12, Trim$("Shield: " & Player(MyIndex).Vital(Vitals.Shielding)), QBColor(Yellow))
        End If

    Finalmente, em "ModTypes" procure pela "Private Type SpellRec" e logo abaixo ANTES DO PRIMEIRO "End Type", adicione isto:
    Código:
    'Shield
        PercVitalHP As Long
        PercVitalMP As Long


    Agora o client~side está pronto, vamos ao server~side.


    SERVER~SIDE


    Abra seu "Server.Vbp" e em "ModEnumerations", abaixo de:
    Código:
    SPlayerMp

    Adicione isto:
    Código:
    SPlayerShield

    Ainda em "ModEnumerations", procure por esta parte:
    Código:
    ' Vitals used by Players, Npcs and Classes
    Public Enum Vitals
        HP = 1
        MP
        ' Make sure Vital_Count is below everything else
        Vital_Count
    End Enum

    E substitua por isto:
    Código:
    ' Vitals used by Players, Npcs and Classes
    Public Enum Vitals
        HP = 1
        MP
        Shielding
        ' Make sure Vital_Count is below everything else
        Vital_Count
    End Enum

    Agora em "ModServerTCP", procure por esta SUB:
    Código:
    Sub SendVital(ByVal index As Long, ByVal Vital As Vitals)
        Dim packet As String
        Dim Buffer As clsBuffer
        Set Buffer = New clsBuffer

        Select Case Vital
            Case HP
                Buffer.WriteLong SPlayerHp
                Buffer.WriteLong GetPlayerMaxVital(index, Vitals.HP)
                Buffer.WriteLong GetPlayerVital(index, Vitals.HP)
            Case MP
                Buffer.WriteLong SPlayerMp
                Buffer.WriteLong GetPlayerMaxVital(index, Vitals.MP)
                Buffer.WriteLong GetPlayerVital(index, Vitals.MP)
        End Select

        SendDataTo index, Buffer.ToArray()
        
        Set Buffer = Nothing
    End Sub

    E substitua ela toda por esta SUB:
    Código:
    Sub SendVital(ByVal index As Long, ByVal Vital As Vitals)
        Dim packet As String
        Dim Buffer As clsBuffer
        Set Buffer = New clsBuffer

        Select Case Vital
            Case HP
                Buffer.WriteLong SPlayerHp
                Buffer.WriteLong GetPlayerMaxVital(index, Vitals.HP)
                Buffer.WriteLong GetPlayerVital(index, Vitals.HP)
            Case MP
                Buffer.WriteLong SPlayerMp
                Buffer.WriteLong GetPlayerMaxVital(index, Vitals.MP)
                Buffer.WriteLong GetPlayerVital(index, Vitals.MP)
            Case Shielding
                Buffer.WriteLong SPlayerShield
                Buffer.WriteLong GetPlayerVital(index, Vitals.Shielding)
        End Select

        SendDataTo index, Buffer.ToArray()
        
        Set Buffer = Nothing
    End Sub

    Agora, em "ModCombat" na "Sub NpcAttackPlayer", defina uma nova variável:
    Código:
    Dim dmgToShield As Long

    Ainda em "ModCombat" na "Sub NpcAttackPlayer", procure por:
    Código:
    If Damage <= 0 Then
            Exit Sub
        End If

    E logo acima dessa parte, adicione isto:
    Código:
    'Take damage from shield first
        If Player(victim).Vital(Vitals.Shielding) > 0 Then
            
            If Damage > Player(victim).Vital(Vitals.Shielding) Then
                '200 - 100 -> -100 white, -100 brightred
                
                'Get shield
                dmgToShield = Player(victim).Vital(Vitals.Shielding)
                Player(victim).Vital(Vitals.Shielding) = Player(victim).Vital(Vitals.Shielding) - Damage
                If Player(victim).Vital(Vitals.Shielding) < 0 Then Player(victim).Vital(Vitals.Shielding) = 0
                SendVital victim, Vitals.Shielding
                
                Damage = Damage - dmgToShield
                SendActionMsg GetPlayerMap(victim), "( -" & Damage & " )", White, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
                
                'Just continue to do brightred damage
            Else
                '100 - 200 -> -100 white
                SendActionMsg GetPlayerMap(victim), "( -" & Damage & " )", White, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
                
                'Get Shield
                dmgToShield = Player(victim).Vital(Vitals.Shielding)
                Player(victim).Vital(Vitals.Shielding) = Player(victim).Vital(Vitals.Shielding) - Damage
                If Player(victim).Vital(Vitals.Shielding) < 0 Then Player(victim).Vital(Vitals.Shielding) = 0
                SendVital victim, Vitals.Shielding
                
                Damage = Damage - dmgToShield
            End If
        End If

    Ainda, em "ModCombat" na "Sub PlayerAttackPlayer", defina uma nova variável:
    Código:
    Dim dmgToShield As Long

    Ainda em "ModCombat" na "Sub PlayerAttackPlayer", procure por esta parte:
    Código:
    ' set the regen timer
        TempPlayer(attacker).stopRegen = True
        TempPlayer(attacker).stopRegenTimer = GetTickCount

    Logo abaixo disso, adicione isto:
    Código:
    'Take damage from shield first
        If Player(victim).Vital(Vitals.Shielding) > 0 Then
            
            If Damage > Player(victim).Vital(Vitals.Shielding) Then
                '200 - 100 -> -100 white, -100 brightred
                
                'Get shield
                dmgToShield = Player(victim).Vital(Vitals.Shielding)
                Player(victim).Vital(Vitals.Shielding) = Player(victim).Vital(Vitals.Shielding) - Damage
                If Player(victim).Vital(Vitals.Shielding) < 0 Then Player(victim).Vital(Vitals.Shielding) = 0
                SendVital victim, Vitals.Shielding
                
                Damage = Damage - dmgToShield
                SendActionMsg GetPlayerMap(victim), "( -" & Damage & " )", White, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
                
                'Just continue to do brightred damage
            Else
                '100 - 200 -> -100 white
                SendActionMsg GetPlayerMap(victim), "( -" & Damage & " )", White, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
                
                'Get Shield
                dmgToShield = Player(victim).Vital(Vitals.Shielding)
                Player(victim).Vital(Vitals.Shielding) = Player(victim).Vital(Vitals.Shielding) - Damage
                If Player(victim).Vital(Vitals.Shielding) < 0 Then Player(victim).Vital(Vitals.Shielding) = 0
                SendVital victim, Vitals.Shielding
                
                Damage = Damage - dmgToShield
            End If
        End If
        
        'Exit if there's no damage
        If Damage <= 0 Then Exit Sub

    Ainda em "ModCombat", na "Public Sub CastSpell", procure por esta parte:
    Código:
    Case SPELL_TYPE_WARP
                        SendAnimation mapNum, Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
                        PlayerWarp index, Spell(spellnum).Map, Spell(spellnum).x, Spell(spellnum).y
                        SendAnimation GetPlayerMap(index), Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
                        DidCast = True
    E logo abaixo adicione isto:
    Código:
    Case SPELL_TYPE_SHIELD
                        SendAnimation mapNum, Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
                        
                        'Shield =  % of HP + % of MP
                        Player(index).Vital(Vitals.Shielding) = Spell(spellnum).Vital + (GetPlayerMaxVital(index, HP) * Spell(spellnum).PercVitalHP * 0.01) + (GetPlayerMaxVital(index, MP) * Spell(spellnum).PercVitalMP * 0.01)
                        'Update Player Shield
                        SendVital index, Shielding
                        
                        SendAnimation GetPlayerMap(index), Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
                        DidCast = True

    Ainda em "ModCombat" na "Public Sub CastSpell", procure por esta parte:
    Código:
    Case SPELL_TYPE_HEALHP, SPELL_TYPE_HEALMP, SPELL_TYPE_DAMAGEMP
                        If Spell(spellnum).Type = SPELL_TYPE_HEALHP Then
                            VitalType = Vitals.HP
                            increment = True
                        ElseIf Spell(spellnum).Type = SPELL_TYPE_HEALMP Then
                            VitalType = Vitals.MP
                            increment = True
                        ElseIf Spell(spellnum).Type = SPELL_TYPE_DAMAGEMP Then
                            VitalType = Vitals.MP
                            increment = False
                        End If
                        
                        DidCast = True
                        For i = 1 To Player_HighIndex
                            If IsPlaying(i) Then
                                If GetPlayerMap(i) = GetPlayerMap(index) Then
                                    If isInRange(AoE, x, y, GetPlayerX(i), GetPlayerY(i)) Then
                                        SpellPlayer_Effect VitalType, increment, i, Vital, spellnum
                                    End If
                                End If
                            End If
                        Next
                        For i = 1 To MAX_MAP_NPCS
                            If MapNpc(mapNum).Npc(i).Num > 0 Then
                                If MapNpc(mapNum).Npc(i).Vital(HP) > 0 Then
                                    If isInRange(AoE, x, y, MapNpc(mapNum).Npc(i).x, MapNpc(mapNum).Npc(i).y) Then
                                        SpellNpc_Effect VitalType, increment, i, Vital, spellnum, mapNum
                                    End If
                                End If
                            End If
                        Next

    E logo abaixo disso, adicione isto:
    Código:
    Case SPELL_TYPE_SHIELD
                        SendAnimation mapNum, Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
                        
                        'Shield =  % of HP + % of MP
                        Player(index).Vital(Vitals.Shielding) = Spell(spellnum).Vital + (Player(index).Vital(Vitals.HP) * Spell(spellnum).PercVitalHP * 0.01) + (Player(index).Vital(Vitals.MP) * Spell(spellnum).PercVitalHP * 0.01)
                        'Update Player Shield
                        SendVital index, Shielding
                        
                        SendAnimation GetPlayerMap(index), Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
                        DidCast = True

    Agora, em "ModConstants", abaixo disto:
    Código:
    Public Const SPELL_TYPE_WARP As Byte = 4

    Adicione isto:
    Código:
    Public Const SPELL_TYPE_SHIELD As Byte = 5 'Shield

    Finalmente, em "ModTypes" procure pela "Private Type SpellRec" e logo abaixo ANTES DO PRIMEIRO "End Type", adicione isto:
    Código:
    'Shield
        PercVitalHP As Long
        PercVitalMP As Long


    E pronto, seu sistema de escudo está pronto! Qualquer dúvida, sugestão ou até parte que vier a faltar, entre em contato!
    Boa criação para você no seu projeto!

    CRÉDITOS


    Kotol

    Valentine, Uchiha ~, Sonart e Kiyoko gostam desta mensagem


      Data/hora atual: Seg Jun 05, 2023 8:30 pm