[E.O 2.0] - Sistema de PVP Hitskin_logo Hitskin.com

Isto é uma pré-visualização de um tema em Hitskin.com
Instalar o temaVoltar para a ficha do tema

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

[E.O 2.0] - Sistema de PVP

Ir para baixo

[E.O 2.0] - Sistema de PVP Empty [E.O 2.0] - Sistema de PVP

Mensagem por Kotol Qui Abr 27, 2023 1:56 am

O sistema de luta é entra dois jogadores. Infelizmente (por motivos de sono) não conta com um sistema de 'tempo de aceitar/recusar' , mas inclui muita coisa. (Talvez eu coloque um "Add-On" depois...)
Sistema PVP:
- Envio de convite em uma janela diferente da de "Troca";
- Checagem se o jogador está em uma arena, se possui convite, se está online ou se a si mesmo;
- Variável de posição do jogador salva antes de entrar na arena e após o resultado, retornam às suas posições;
- Jogador desloga:
*Se estiver em arena = perde a arena, retorna para sua posição, o desafiado é teleportado de volta e limpo;
*Se tem um convite = limpa a si e quem estava desafiando com um convite em espera, além de fechar a janela;
- Desafio por Target, checando se é válido;

Agora, vamos ao tutorial que tem um pouco de coisinhas.

CLIENT~SIDE


Primeiramente abra seu "Client.vbp" e crie na "FrmMain" : 

1x CommandButton -> Name: cmdArena / Caption: Desafiar
1x PictureBox -> Name: PicArena / Visible: False

DENTRO da PicArena crie:
1x Label -> Name: lblArenaDesc
1x Label -> Name: lblArenaAccept
1x Label -> Name: lblArenaDecline

Agora, dentro do "cmdArena", adicione isto:
Código:
If myTargetType = TARGET_TYPE_PLAYER And myTarget <> MyIndex Then
        SendArenaCommand 0, myTarget
        ' play sound
        PlaySound Sound_ButtonClick
    Else
        AddText "Alvo de batalha inválido", BrightRed
    End If


Agora, dentro da "lblArenaAccept" adicione isto:
Código:
SendArenaCommand 1, 0
    picArena.Visible = False


Agora, dentro da "lblArenaDecline" adicione isto:
Código:
SendArenaCommand 2, 0
    picArena.Visible = False

Agora, em "ModClientTCP" , no final adicione esta sub:
Código:
Sub SendArenaCommand(ByVal CommandNum As Long, ByVal curTarget 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.WriteLong CArena
    Buffer.WriteLong CommandNum
    Buffer.WriteLong curTarget
    SendData Buffer.ToArray()
    Set Buffer = Nothing
    
    ' Error handler
    Exit Sub
errorhandler:
    HandleError "SendArenaCommand", "modClientTCP", Err.Number, Err.Description, Err.Source, Err.HelpContext
    Err.Clear
    Exit Sub
End Sub

Agora, em "ModEnumerations", na "Public Enum ServerPackets" logo abaixo ANTES de:
Código:
' Make sure SMSG_COUNT is below everything else
    SMSG_COUNT
End Enum

Declare esta enumeração:
Código:
SArena

Ainda em "ModEnumerations", na "Public Enum ClientPackets" logo abaixo ANTES de:
Código:
' Make sure CMSG_COUNT is below everything else
    CMSG_COUNT
End Enum

Declare esta enumeração:
Código:
CArena

Agora, em "ModHandleData", na "Public Sub InitMessages()", depois de:
Código:
HandleDataSub(SPartyVitals) = GetAddress(AddressOf HandlePartyVitals)

Adicione isto:
Código:
HandleDataSub(SArena) = GetAddress(AddressOf HandleArena)

Ainda em "ModHandleData" , no final adicione isto:
Código:
Private Sub HandleArena(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddR As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer
    Dim Name As String, CommandNum As Long

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    Name = Buffer.ReadString
    CommandNum = Buffer.ReadLong
    Set Buffer = Nothing
    
    Select Case CommandNum
        Case 0
            With frmMain
                .picArena.Visible = True
                .lblArenaDesc = "O jogador " & Name & " te desafiou para uma luta. Deseja aceitar?"
            End With
        Case 1
            frmMain.picArena.Visible = False
    End Select
    
    
End Sub

E pronto, cliente completo! Vamos agora ao servidor!

SERVER~SIDE


Abra seu "Server.Vbp" e em "ModHandleData" na "Public Sub InitMessages()" , após:
Código:
HandleDataSub(CPartyLeave) = GetAddress(AddressOf HandlePartyLeave)

Adicione isto:
Código:
HandleDataSub(CArena) = GetAddress(AddressOf HandleArena)

Ainda em "ModHandleData", ao final adicione esta sub:
Código:
Sub HandleArena(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim n As Long, i As Long
Dim Buffer As clsBuffer
Dim QuestSize As Long
Dim QuestData() As Byte

    Set Buffer = New clsBuffer
    Buffer.WriteBytes Data()
    i = Buffer.ReadLong 'ArenaCommand
    n = Buffer.ReadLong 'Target
    Set Buffer = Nothing
    
    'Invalid command
    If i < 0 Or i > 2 Then Exit Sub
    
    Select Case i
        Case 0 'Send Invite
            
            'Check for a valid n
            If n <= 0 Or n > MAX_PLAYERS Then Exit Sub
        
            'Offline
            If Not IsPlaying(n) Then
                PlayerMsg Index, "O jogador está offline!", White
                Exit Sub
            End If
            
            If TempPlayer(n).InArena Then
                PlayerMsg Index, "O jogador está em uma arena!", White
                Exit Sub
            End If
            
            If TempPlayer(n).HasChallenge Then
                PlayerMsg Index, "Já desafiaram este jogador!", White
                Exit Sub
            End If
            
            If TempPlayer(Index).HasChallenge Then
                PlayerMsg Index, "Você já enviou um desafio!", White
                Exit Sub
            End If
            
            'Checar quem é o desafiado
            If n = Index Then
                PlayerMsg Index, "Você não pode se desafiar!", White
                Exit Sub
            End If
            
            TempPlayer(n).HasChallenge = True
            TempPlayer(Index).HasChallenge = True
            
            TempPlayer(n).ChallengeOwner = Index 'Index de quem manda o desafio
            TempPlayer(Index).ChallengeInvited = Index 'Index de quem manda o desafio
            
            TempPlayer(n).ChallengeInvited = Index 'Desafiante pega o Index do desafiado
            TempPlayer(Index).ChallengeInvited = n 'Desafiante pega o Index do desafiado
            
            'Envia a janela de desafio!
            SendChallenge Index, n, 0
            
        Case 1 'Accept
            
            'Check for a valid n
            If n <> 0 Then Exit Sub
            
            If TempPlayer(Index).HasChallenge = False Then
                PlayerMsg Index, "Você não está sendo desafiado...", White
                Exit Sub
            End If
            
            If TempPlayer(Index).InArena Then
                PlayerMsg Index, "Você não pode aceitar desafios na arena!", White
                Exit Sub
            End If
            
            n = TempPlayer(Index).ChallengeOwner
            
            'Offline
            If Not IsPlaying(n) Then
                PlayerMsg Index, "Quem te desafiou está offline...", White
                
                'Jogador off, só limpa e sai
                TempPlayer(Index).HasChallenge = False
                TempPlayer(Index).InArena = False
                TempPlayer(Index).ChallengeOwner = 0
                TempPlayer(Index).ChallengeInvited = 0
                Exit Sub
            End If
            
            If TempPlayer(n).InArena Then
                PlayerMsg Index, "O jogador está em uma arena!", White
                
                'Jogador off, só limpa e sai
                TempPlayer(Index).HasChallenge = False
                TempPlayer(Index).InArena = False
                TempPlayer(Index).ChallengeOwner = 0
                TempPlayer(Index).ChallengeInvited = 0
                Exit Sub
            End If
            
            'Recusou o desafio que você mesmo fez?
            If n = Index Then
                PlayerMsg Index, "Você não pode recusar o próprio desafio!", White
                Exit Sub
            End If
            
            'Guarda as posições Mapa, X e Y
            TempPlayer(Index).ResultPos.MapNum = GetPlayerMap(Index)
            TempPlayer(Index).ResultPos.x = GetPlayerX(Index)
            TempPlayer(Index).ResultPos.y = GetPlayerY(Index)
            
            TempPlayer(n).ResultPos.MapNum = GetPlayerMap(n)
            TempPlayer(n).ResultPos.x = GetPlayerX(n)
            TempPlayer(n).ResultPos.y = GetPlayerY(n)
            
            TempPlayer(Index).InArena = True
            TempPlayer(n).InArena = True
            
            PlayerWarp Index, 1, 2, 3
            PlayerWarp n, 1, 5, 6
            
            'Envia mensagem a ambos
            PlayerMsg Index, "Começe a batalha!", Yellow
            PlayerMsg n, "Começe a batalha!", Yellow
            
        Case 2 'Decline
            
            'Check for a valid n
            If n <> 0 Then Exit Sub
            
            If TempPlayer(Index).HasChallenge = False Then
                PlayerMsg Index, "Você não está sendo desafiado...", White
                Exit Sub
            End If
            
            If TempPlayer(Index).InArena Then
                PlayerMsg Index, "Você não pode aceitar desafios na arena!", White
                Exit Sub
            End If
            
            n = TempPlayer(Index).ChallengeOwner
            
            'Offline
            If Not IsPlaying(n) Then
                PlayerMsg Index, "Quem te desafiou está offline...", White
                
                'Jogador off, só limpa e sai
                TempPlayer(Index).HasChallenge = False
                TempPlayer(Index).InArena = False
                TempPlayer(Index).ChallengeOwner = 0
                TempPlayer(Index).ChallengeInvited = 0
                Exit Sub
            End If
            
            If TempPlayer(n).InArena Then
                PlayerMsg Index, "O jogador está em uma arena!", White
                
                'Jogador off, só limpa e sai
                TempPlayer(Index).HasChallenge = False
                TempPlayer(Index).InArena = False
                TempPlayer(Index).ChallengeOwner = 0
                TempPlayer(Index).ChallengeInvited = 0
                Exit Sub
            End If
            
            'Recusou o desafio que você mesmo fez?
            If n = Index Then
                PlayerMsg Index, "Você não pode recusar o próprio desafio!", White
                Exit Sub
            End If
            
            'Envia mensagem a ambos
            PlayerMsg Index, "Você recusou o desafio de " & Trim$(GetPlayerName(n)), White
            PlayerMsg n, "O jogador " & Trim$(GetPlayerName(Index)) & " recusou seu desafio!", White
            
            'Agora é hora de limpá-los, limpamos o outro
            TempPlayer(n).HasChallenge = False
            TempPlayer(n).InArena = False
            TempPlayer(n).ChallengeOwner = 0
            TempPlayer(n).ChallengeInvited = 0
            
            'Limpando quem recusou
            TempPlayer(Index).HasChallenge = False
            TempPlayer(Index).InArena = False
            TempPlayer(Index).ChallengeOwner = 0
            TempPlayer(Index).ChallengeInvited = 0
            
    End Select
    
End Sub

Agora, em "ModPlayer", na "Sub OnDeath(ByVal Index As Long)", procure por esta parte:
Código:
With Map(GetPlayerMap(index))
        ' to the bootmap if it is set
        If .BootMap > 0 Then
            PlayerWarp index, .BootMap, .BootX, .BootY
        Else
            Call PlayerWarp(index, START_MAP, START_X, START_Y)
        End If
    End With

E substitua essa parte por esta:
Código:
'Estavamos em uma arena
    If TempPlayer(Index).InArena Then 'estava em uma arena
        'Se sommos o dono do convite, então o index do outro é o convidado
        n = TempPlayer(Index).ChallengeInvited
        
        PlayerWarp Index, TempPlayer(Index).ResultPos.MapNum, TempPlayer(Index).ResultPos.x, TempPlayer(Index).ResultPos.y
        PlayerMsg Index, "Você perdeu...", BrightRed
        
        TempPlayer(Index).HasChallenge = False
        TempPlayer(Index).InArena = False
        TempPlayer(Index).ChallengeInvited = 0
        TempPlayer(Index).ChallengeOwner = 0
        
        'Checa se ainda está jogando também, apesar que mesmo que desloguem juntos
        'o index será checado por fila e irá limpar, mas é bom checar
        If IsPlaying(n) Then
            PlayerWarp n, TempPlayer(n).ResultPos.MapNum, TempPlayer(n).ResultPos.x, TempPlayer(n).ResultPos.y
            PlayerMsg n, "Você ganhou!", Yellow
            
            TempPlayer(n).HasChallenge = False
            TempPlayer(n).InArena = False
            TempPlayer(n).ChallengeInvited = 0
            TempPlayer(n).ChallengeOwner = 0
        End If
    Else
        With Map(GetPlayerMap(Index))
                ' to the bootmap if it is set
                If .BootMap > 0 Then
                    PlayerWarp Index, .BootMap, .BootX, .BootY
                Else
                    Call PlayerWarp(Index, START_MAP, START_X, START_Y)
                End If
        End With
    End If

Ainda em "ModPlayer", na "Sub LeftGame(ByVal Index As Long)",  e bem no início, substitua essa parte:
Código:
If TempPlayer(index).InGame Then
        TempPlayer(index).InGame = False

Por esta:
Código:
'Estavamos em uma arena
        If TempPlayer(Index).InArena Then 'estava em uma arena
            n = TempPlayer(Index).ChallengeInvited
            
            'Usemos SET sem update, o jogador já está de saída.
            If TempPlayer(Index).ResultPos.MapNum > 0 Then
                SetPlayerMap Index, TempPlayer(Index).ResultPos.MapNum
                SetPlayerX Index, TempPlayer(Index).ResultPos.x
                SetPlayerY Index, TempPlayer(Index).ResultPos.y
                
                TempPlayer(Index).ResultPos.MapNum = 0
                TempPlayer(Index).ResultPos.x = 0
                TempPlayer(Index).ResultPos.y = 0
            End If
            
            'Checa se ainda está jogando também, apesar que mesmo que desloguem juntos
            'o index será checado por fila e irá limpar, mas é bom checar
            If IsPlaying(n) Then
                If TempPlayer(n).ResultPos.MapNum > 0 Then
                    PlayerWarp n, TempPlayer(n).ResultPos.MapNum, TempPlayer(n).ResultPos.x, TempPlayer(n).ResultPos.y
                End If
                PlayerMsg n, "O jogador " & Trim$(GetPlayerName(Index)) & " deslogou, você ganhou!", Yellow
                
                TempPlayer(n).HasChallenge = False
                TempPlayer(n).InArena = False
                TempPlayer(n).ChallengeInvited = 0
                TempPlayer(n).ChallengeOwner = 0
            End If
        End If
        
        'Tínhamos um convite ativo!
        If TempPlayer(Index).HasChallenge Then  'estava em uma arena
            n = TempPlayer(Index).ChallengeInvited
            
            'Checa se ainda está jogando também, apesar que mesmo que desloguem juntos
            'o index será checado por fila e irá limpar, mas é bom checar
            If IsPlaying(n) Then
                PlayerMsg n, "O jogador " & Trim$(GetPlayerName(Index)) & " recusou o pedido de desafio!", Yellow
                
                TempPlayer(n).HasChallenge = False
                TempPlayer(Index).InArena = False
                TempPlayer(Index).ChallengeInvited = 0
                TempPlayer(Index).ChallengeOwner = 0
                
                'Fecha janela de desafio
                SendChallenge Index, n, 1
            End If
        End If
        TempPlayer(Index).InGame = False

Agora, em "ModTypes" , acima de "Public Type TempPlayerRec" , adicione isto:
Código:
Private Type RecordPosRec
    MapNum As Long
    x As Long
    y As Long
End Type

Ainda em "ModTypes" , na "Public Type TempPlayerRec", ANTES do primeiro "EndType", declare estes tipos:
Código:
'Arena System
    HasChallenge As Boolean
    InArena As Boolean
    ChallengeOwner As Long
    ChallengeInvited As Long
    ResultPos As RecordPosRec

Agora, em "ModServerTCP" , no final, adicione esta sub:
Código:
Sub SendChallenge(ByVal Index As Long, ByVal ChallengedIndex As Long, ByVal CommandNum As Long)
    Dim Buffer As clsBuffer

    Set Buffer = New clsBuffer
    Buffer.WriteLong SArena
    Buffer.WriteString Trim$(GetPlayerName(ChallengedIndex))
    Buffer.WriteLong CommandNum
    SendDataTo ChallengedIndex, Buffer.ToArray()
    Set Buffer = Nothing
   
End Sub



E pronto, agora você tem um sistema de Arena por convite, teleporte e tudo mais!  Very Happy

Dica: Caso você queira mudar "para onde os jogadores vão", basta você entra em "ModHandleData" na "Sub HandleArena" e modificar a parte:
Código:
PlayerWarp Index, 1, 2, 3
            PlayerWarp n, 1, 5, 6

Para as coordenadas que você preferir! Lembrando que nesse caso:
Index = quem aceitou o desafio;
n = o desafiante.

No mais é isso, boa criação! Qualquer dúvida, sugestão ou erro, manda aí que damos um suporte!

Edit1: Adicionado "SendChallenge" esquecido de colocar no tutorial do fórum.
Créditos


Kotol
Kotol
Kotol
Moderador Local
Moderador Local

Mensagens : 77
Créditos : 17

Valentine gosta desta mensagem

Ir para o topo Ir para baixo

Ir para o topo

- Tópicos semelhantes

 
Permissões neste sub-fórum
Não podes responder a tópicos