Suporte ao desenvolvimento de jogos!


    [Prof~] Sistema de Reputação

    Compartilhe
    avatar
    Profane ~
    Administrador
    Administrador

    Mensagens : 723
    Créditos : 124

    [Prof~] Sistema de Reputação

    Mensagem por Profane ~ em Seg Abr 30, 2018 11:22 am

    Oin turu baum?

    Venho trazer um sistemazinho simples.
    O que se tem de entender dele é que ele não necessariamente é um Sistema de Reputação, mas sim uma Base Geral de se ter Valores Salvos e de se Enviar tais valores pela comunicação Server <> Cliente.

    Esse Pedido foi feito pelo Yashi (Allan) via PM, e aqui estou disponibilizando.

    Vai servir como uma Leve Aula para os que ainda não tem conhecimento de como enviar valores, fazer atualização dos mesmos e salva-los.




    Qual a Lógica por trás?

    Bem, teremos de abrir uma memoria no NPC, onde ela armazenará o valor de "Reputação". 

    Quando este NPC for derrotado o Player ganhará esse valor de Reputação.

    Logo o Player também precisará de uma memoria para salvar este valor de reputação que vamos usar.



    Ficha Tecnina

     Dificuldade: Fácil
     Compatibilidade: Qualquer EO/CS
     Necessário
    - Visual Basic 6
    - Após o Termino apagar NPC's e Player's nas pastas do Servidor. (Evitar Probleminhas ;3)


     Engine Já Modificada: Download  (Menos de 2mb)
     (Baixe caso queria apenas Ripar o Sistema de Engine - Ou o ver funcionando.)
     (Caso queira Ripar, procurar por tudo que tenha "Reputation" ou "Reputação".)




    Ao Sistema


    [ Parte 1 - Criando as Memórias ]

    Vamos estar Indo aos Types para poder adicionar a Variável Type que irá armazenar o Valor que desejamos criar.

     No Cliente e no Servidor, procure por:
    Código:
    Private Type PlayerRec

     Dentro dele, antes do End Type, adicione:

    Código:
       Reputation As Long

    Colocamos um valor Long na Memória já que em geral esses jogos vão trabalhar na casa de milhões mais.. (Absurdo /o/)
    Com isso a memoria no Player já vai estar lá.

    Vamos tratar dos Npc's.

    Procure por:
    Código:
    Private Type NpcRec

    Dentro dele e antes do End Type, adicione:

    Código:
       Reputation As Long

    O Npc irá armazenar o Valor de reputação a qual ele dará ao morrer.

    [ Parte 2 - Preparando o NPC ]

    No Cliente

    Acesse a FrmEditor_NPC e prepare os componentes a qual irão nos ajudar na edição do Npc.

    Poderá ficar mais o menos assim:

     Componentes Principais ai são: 
     - Label (Sem nome necessário, apenas para ficar indicado que é ali que fica a reputação.)
     - textBox (Name = txtReputation)

    Apague todo o conteúdo da propriedade "Text" do textBox (txtReputation), deixando ele Limpo.

    Dê 2 click's sobre o txtReputation e vamos aos seus códigos:

    Código:
     ' If debug mode, handle error then exit out
        If Options.Debug = 1 Then On Error GoTo errorhandler
        
        If Not Len(txtReputation.text) > 0 Then Exit Sub
        If IsNumeric(txtReputation.text) Then Npc(EditorIndex).Reputation = Val(txtReputation.text)
        
        ' Error handler
        Exit Sub
    errorhandler:
        HandleError "txtReputation_Change", "frmEditor_NPC", Err.Number, Err.Description, Err.Source, Err.HelpContext
        Err.Clear
        Exit Sub

    Adicionado isso a parte interna do txtReputation, vamos agora garantir que ao Npc ser carregado no Editor, ele carregue também o valor de reputação atual do Npc.

    Procure por:

    Código:
    Public Sub NpcEditorInit()

    Esta sub processa cada carregamento de NPC no Editor. É muito importante que ao fazer componentes novos que usem memória, seja adicionado o carregamento do mesmo no Editor usando essa Sub.

    Dentro dela e abaixo de :

    Código:
    With frmEditor_NPC

    Adicione:

    Código:
    .txtReputation.text = Npc(EditorIndex).Reputation

    Dessa forma, toda vez que acessar o Editor de Npc's, será posto o valor de Reputação do NPC no TextBox de Reputação.

    [ Parte 3 - Packets e Trocas ]

    Nessa parte faremos o Pacote que irá transitar a reputação de forma principal. Ele será pequeno já que toda vez que um NPC com Reputação morrer ele será enviado ao Jogador atualizando assim o valor de Reputação do Jogador.

    Ainda no cliente procure por:

    Código:
    SMSG_COUNT

    Acima dele adicione:

    Código:
    SPlayerReputation

    Estamos aumentando o Limite de Pacotes conhecidos pelo Cliente.

    Faremos o mesmo no Servidor.

    No servidor procure por:

    Código:
    SMSG_COUNT

    Acima dele adicione:

    Código:
    SPlayerReputation


    Extremamente Importante que essa parte do modEnumerations esteja de acordo e igual Cliente e Servidor. O Mesmo Numero de Pacotes e de preferencia o Mesmo Nome! Caso contrário você vai começar a ter dores de cabeça >
    Vá ao final do modServerTCP (Modulo que é responsável por armazenar os Envios de Pacotes para o Cliente.)

    No Final dele adicione:
    Código:
    Sub SendReputationTo(ByVal index As Long)
    Dim Buffer As clsBuffer, i As Long, partyNum As Long

        Set Buffer = New clsBuffer
        Buffer.WriteLong SPlayerReputation
        Buffer.WriteLong Player(index).Reputation
        
        SendDataTo index, Buffer.ToArray()
        Set Buffer = Nothing
    End Sub

    Tendo isso, quando chamarmos pela Call SendReputation(?), ela pegará o valor de memoria "Reputation" do jogador Alvo e tentará enviar para o Cliente.

    Agora vamos fazer o cliente receber.

    Voltando ao Cliente, vá ao modHandleData (Modulo responsável por receber os Pacotes que vem do Servidor para o Cliente.)

    Procure por:

    Código:
    Public Sub InitMessages()

    Dentro dele, depois de todos os :

    Código:
    HandleDataSub(

    Você adiciona:

    Código:
    HandleDataSub(SPlayerReputation) = GetAddress(AddressOf HandlePlayerReputation)

    Não é estritamente necessário que você adicione isso em um "Padrão". Como assim? A ordem ali dentro não é importante, é mais organização. Já que se adicionou um novo pacote, ele "teria" de ficar no final.

    Agora que o Cliente já tem conhecimento do que fazer com o Pacote que criamos, vamos fazer ele ler o pacote.

    O Pacote ao chegar será enviado para a "HandlePlayerReputation", sendo assim no final da ModHandleData, coloque:

    Código:
    Private Sub HandlePlayerReputation(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
    Dim Buffer As clsBuffer, i As Long
    Dim Reputation As Long

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

        Reputation = Buffer.ReadLong
        
        If Index = MyIndex Then
            Player(MyIndex).Reputation = Reputation
        End If
      
        ' Error handler
        Exit Sub
    errorhandler:
        HandleError "HandlePlayerReputation", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
        Err.Clear
        Exit Sub
    End Sub


    Pronto, dessa forma o Servidor já sabe enviar o valor ao Cliente, o Cliente já recebe o Pacote e também já faz a leitura guardando o valor recebido dentro da Memória que criamos para ele.

    [ Parte 4 - Fazendo o NPC dar Reputação ao ser Abatido ]

     No Servidor, vamos procurar pela SUB que processa a morte do NPC.

    Procure por:

    Código:
    Public Sub PlayerAttackNpc(ByVal attacker As Long

    Dentro dela, procure por isso aqui...

    Código:
     ' Now set HP to 0 so we know to actually kill them in the server loop (this prevents subscript out of range)
            MapNpc(mapNum).Npc(mapNpcNum).Num = 0
            MapNpc(mapNum).Npc(mapNpcNum).SpawnWait = GetTickCount
            MapNpc(mapNum).Npc(mapNpcNum).Vital(Vitals.HP) = 0

    Esta parte acima determina e faz o começo da limpeza do NPC, mas queremos que antes dele ser "limpo" entregue a nós a reputação num é mermu?

    Então, acima disso adicione:

    Código:
    'Get Reputation
       If Npc(npcNum).Reputation > 0 Then
            Player(attacker).Reputation = Player(attacker).Reputation + Npc(npcNum).Reputation 'Add Reputação
            SendReputationTo attacker 'Envia ao Player que Matou
       End If

    Em outras palavras o código analisa se o Npc tem reputação para ser entregue, caso tenha, ele adiciona a reputação a memoria do Player, e logo em seguida pede para enviar o Pacote de atualização de Reputação ao Cliente do Player.

    [ Parte 5 *-* - Mostrando a Reputação no Cliente ]

    De forma simples apenas para mostrar a reputação na tela, eu criei uma Label no FrmMain.

    Name da Label: (lblReputation)


    Agora procure pelo nosso pacote que recebe a Reputação do Servidor...
    Ainda no Cliente procure por:

    Código:
    Private Sub HandlePlayerReputation(B

    Dentro dessa Sub procure por:

    Código:
    Player(MyIndex).Reputation = Reputation

    Abaixo dele adicione:

    Código:
    frmMain.lblReputation.Caption = "Reputação: " & Reputation

    Dessa forma, toda vez que o Pacote chegar, ele irá atualizar a Propriedade Caption da Label que criamos para mostrar a Reputação.

    Até aqui o sistema está basicamente terminado, faltando apenas mais um detalhe!

    [ Parte Ultima - Detalhe! ]

    Esse detalhe se trata de uma atualização vital que se segue pelo cliente<>Server. 

    É o Nosso PlayerData() que  envia muitas vezes boa parte de todas as memorias do Player.

    Vamos por nossa memoria de Reputação para ser atualizada também via ele, porque caso contrario.. Ao Você logar no jogo, o Player só receberia a Reputação de 2 Jeitos:

     [ 1 ] Caso esteja no PlayerData()
     [ 2 ] Caso envie a Reputação via JoinGame()

    Como eu estou fazendo esse sistema visando que vocês aprendam e assim modifiquem essa "logica" e memorias para serem usadas de outras maneiras e com outros nomes /o/ para outras diversas finalidades então vou ensinar a mover isso pelo PlayerData(), o que para a Situação Atual seria melhor ser enviada pelo JoinGame (Assim que o Player Logar). 

    Mas não chega a ser um problema.

    Vamos lá.

    No Servidor, procure por:

    Código:
    Function PlayerData(ByVal index As Long) As Byte()

    Fique bem atento a isso, entenda que os Buffer's empacotam os valores em ORDEM , no caso Listagem! E o Cliente precisa desempacotar na mesma ORDEM de listagem. Caso contrário você ter dor de cabecinha bb ><

    Uma maneira fácil de por é, procure um Buffer de preferencia sem estar dentro de um For/Next

    Ex:

    Código:
    Buffer.WriteLong GetPlayerPK(index)

    Esse Buffer empacota o valor de PK do Player.

    Abaixo adicione:

    Código:
    Buffer.WriteLong Player(index).Reputation
    Agora o PlayerData() vai estar enviando o Reputation do Player.

    Vamos ao Cliente,

    Iremos agora procurar a Leitura do Pacote do PlayerData() que se chama HandlePlayerData()

    Procure por:

    Código:
    Private Sub HandlePlayerData(ByVal Index As Long,

    Dentro dela, LEMBRANDO QUE A ESTRUTURA TEM DE SER DESEMPACOTADA EM ORDEM QUE FOI EMPACOTADA!

    Como botamos o Buffer do Reputation para ser Empacotado embaixo do Buffer de PK, então procuremos pelo de PK Primeiro:

    Código:
    Call SetPlayerPK(i, Buffer.ReadLong)

    Abaixo dele, adicionaremos:

    Código:
    Player(i).Reputation = Buffer.ReadLong

    Pronto! Agora, o Cliente desempacota com tranquilidade e na ordem correta. 

    Caso você ponha em ordem errada, o Valor vai ser Atribuído a outra MEMORIA, e assim Você pode imaginar sua Reputação sendo colocada no HP, ou em diversos outros locais dependendo da ordem de desempacotamento /o/ ~ É uma reação em cadeia que iria lhe dar dores de cabeça não só a você... pq provavelmente iria vir aqui trazer o problema < 3

    Para Finalizar...

    Ainda na HandlePlayerData, procure por isso aqui:

    Código:
    ' Check if the player is the client player
        If i = MyIndex Then

    Abaixo disso adicione:

    Código:
     'Refresh Reputation Label
            frmMain.lblReputation.Caption = "Reputation: " & Player(MyIndex).Reputation

    Agora a Label que criamos lá no FrmMain será atualizada assim que o Player Receber a PlayerData também /o/

    FIM * o *

    Espero que tenham gostado e que com isso possam pensar em diversas outras memórias,valores e possíveis customizações para a falência de vocês!

    Att amores < 3


    _________________
    "If you don't belong here, just build a place where you do."
    avatar
    Takabe
    Novato
    Novato

    Mensagens : 12
    Créditos : 1

    Ficha do personagem
    Nível: 1
    Vida:
    30/30  (30/30)
    Energia:
    0/0  (0/0)

    Re: [Prof~] Sistema de Reputação

    Mensagem por Takabe em Seg Abr 30, 2018 3:53 pm

    U.u Maravilhoso minha fadinha rsrs
    avatar
    Mizuki
    Novato
    Novato

    Mensagens : 9
    Créditos : 1

    Ficha do personagem
    Nível: 1
    Vida:
    30/30  (30/30)
    Energia:
    0/0  (0/0)

    Re: [Prof~] Sistema de Reputação

    Mensagem por Mizuki em Qua Ago 08, 2018 11:54 pm

    como faria pra usar essa reputação pra compra algo ou ter ela como restrição tipo pra itens ou personagens?


    _________________
    vem sempre aqui?  I love you
    avatar
    Kies
    Membro de Honra
    Membro de Honra

    Mensagens : 1055
    Créditos : 114

    Ficha do personagem
    Nível: 1
    Vida:
    30/30  (30/30)
    Energia:
    0/0  (0/0)

    Re: [Prof~] Sistema de Reputação

    Mensagem por Kies em Qui Ago 09, 2018 9:27 am

    @Mizuki escreveu:como faria pra usar essa reputação pra compra algo ou ter ela como restrição tipo pra itens ou personagens?

    Sobre comprar algo tu poderia fazer com que:

    A cada x de reputação ele ganhasse uma moeda especifica no jogo.

    Sobre restrição... bom neh não creio que seja algo muito útil.


    Profane seria interessante dar uma luz sobre rank de reputação ai sim seria maneiro.


    _________________
    Visite Vofawus Online no IndieDB


    Vofawus Online

    Conteúdo patrocinado

    Re: [Prof~] Sistema de Reputação

    Mensagem por Conteúdo patrocinado


      Data/hora atual: Seg Ago 20, 2018 12:22 am