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


    [E.O 2.0] NPC dividindo EXP conforme o dano

    Kotol
    Kotol
    Moderador Local
    Moderador Local


    Mensagens : 74
    Créditos : 15

    [E.O 2.0] NPC dividindo EXP conforme o dano Empty [E.O 2.0] NPC dividindo EXP conforme o dano

    Mensagem por Kotol Dom Abr 02, 2023 11:35 am

    É meio chatinho quando se está matando um NPC e outra pessoa simplesmente finaliza, certo? Bem, a caráter de drop, existe o sistema de PK para inibir, mas a EXP ainda assim é perdida, pensa estar matando um Boss Global e isso acontece. Pra isso tem esse sistema que conta com: 

    -Lista de até 20 jogadores;
    -Cada jogador tem um valor de "Dano causado", sendo a exp proporcional ao dano causado;
    -Caso o NPC fique sem alvo e com o HP totalmente cheio, a lista é zerada;
    -Em grupo, a EXP recebida vai ser dividida pelos membros igualmente independente do dano causado;
    -Somente ganhará exp o jogador que estiver no mesmo mapa;
    -Se sair do mapa, o jogador é retirado da lista e seu dano zerado;
    -Sistema de Grupo: [E.O 2.0] - Grupo: Mapas diferentes não dividir exp, mas certo (v1.0) ;

    O sistema é totalmente server~side, então vamos lá, primeiramente abra seu "SERVER.VBP" e em "ModGameLogic" , procure pela "Public Sub Party_ShareExp" e substitua ela por esta:

    Código:
    Public Sub Party_ShareExp(ByVal partyNum As Long, ByVal Exp As Long, ByVal Index As Long, Optional MapNpcNum As Long = 0)
    Dim expShare As Long, leftOver As Long, i As Long, tmpIndex As Long
    Dim SameMap As Long
    Dim MapNum As Long, n As Long
        
        MapNum = GetPlayerMap(Index)

        ' check if it's worth sharing
        If Not Exp >= Party(partyNum).MemberCount Then
            ' no party - keep exp for self
            GivePlayerEXP Index, Exp
            Exit Sub
        End If
        
        SameMap = 0
        For i = 1 To Party(partyNum).MemberCount
            tmpIndex = Party(partyNum).Member(i)
            ' Same Map?
            If tmpIndex > 0 And GetPlayerMap(tmpIndex) = GetPlayerMap(Index) Then
                ' playing?
                If IsConnected(tmpIndex) And IsPlaying(tmpIndex) Then
                ' find out the equal share
                SameMap = SameMap + 1
                End If
            End If
        Next
        If SameMap <= 0 Then SameMap = 1
        
        
        ' find out the equal share
        expShare = Exp \ SameMap
        leftOver = Exp Mod Party(partyNum).MemberCount
        
        ' loop through and give everyone exp
        For i = 1 To MAX_PARTY_MEMBERS
            tmpIndex = Party(partyNum).Member(i)
            ' existing member?Kn
            If tmpIndex > 0 Then
                ' Member on same map, can share
                If GetPlayerMap(tmpIndex) = GetPlayerMap(Index) Then
                    ' playing?
                    If IsConnected(tmpIndex) And IsPlaying(tmpIndex) Then
                        
                        If MapNpcNum > 0 Then
                            'Check on mapnpc list if we have player or party members on list
                            For n = 1 To Max_MapNpc_Targets
                                If MapNpc(MapNum).NPC(MapNpcNum).TargetList(n).num = tmpIndex Then
                                    MapNpc(MapNum).NPC(MapNpcNum).TargetList(n).num = 0
                                    MapNpc(MapNum).NPC(MapNpcNum).TargetList(n).damage = 0
                                End If
                            Next
                        End If
                        
                        ' give them their share
                        GivePlayerEXP tmpIndex, expShare
                    End If
                End If
            End If
        Next
        
        ' give the remainder to a random member
        tmpIndex = Party(partyNum).Member(RAND(1, Party(partyNum).MemberCount))
        
        
        ' give the exp
        GivePlayerEXP tmpIndex, leftOver
    End Sub

    Agora, abaixo desta "Public Sub Party_ShareExp" , adicione esta sub:

    Código:
    Public Sub MapNpc_ShareExp(ByVal MapNum As Long, ByVal MapNpcNum As Long, ByVal Exp As Long)
    Dim expShare As Long, leftOver As Long, i As Long, tmpIndex As Long
    Dim SameMap As Long
    Dim percExp As Double
        
        'Check for errors and exit
        If MapNpcNum <= 0 Or MapNpcNum > MAX_MAP_NPCS Then Exit Sub
        If MapNum <= 0 Or MapNum > MAX_MAPS Then Exit Sub
            
        For i = 1 To Max_MapNpc_Targets
            tmpIndex = MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).Num
            If tmpIndex > 0 Then
                ' Same Map?
                If GetPlayerMap(tmpIndex) = MapNum Then
                    ' playing?
                    If IsConnected(tmpIndex) And IsPlaying(tmpIndex) Then
                        If MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).Damage > 0 Then
                            ' in party?
                            If TempPlayer(tmpIndex).inParty > 0 Then
                                ' pass through party sharing function
                                Party_ShareExp TempPlayer(tmpIndex).inParty, Exp, tmpIndex, MapNpcNum
                            Else
                                percExp = MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).Damage / (GetNpcMaxVital(MapNpc(MapNum).NPC(MapNpcNum).Num, HP) + 1) * 100
                                If percExp <= 0 Then percExp = 100
                                If percExp > 100 Then percExp = 100
                                expShare = Exp * percExp * 0.01
                                GivePlayerEXP tmpIndex, expShare
                            End If
                            MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).Num = 0
                            MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).Damage = 0
                        End If
                    End If
                End If
            End If
        Next
        
    End Sub


    Ainda no "ModGameLogic" , procure pela "Public Sub SpawnNpc" , e abaixo de:

    Código:
    MapNpc(MapNum).NPC(MapNpcNum).dir = Int(Rnd * 4)

    Adicione isto:

    Código:
    'Clear his list
            For i = 1 To Max_MapNpc_Targets
                MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).Num = 0
                MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).Damage = 0
            Next


    Agora em "ModTypes" , ACIMA de "Private Type MapNpcRec", adicione esta 'type':

    Código:
    Private Type TargetListRec
        Num As Long
        Damage As Long
    End Type


    Ainda em "ModTypes" , na "Private Type MapNpcRec", logo abaixo ANTES do primeiro "End Type" que achar, declare esse type:

    Código:
    'Targets
        TargetList(1 To Max_MapNpc_Targets) As TargetListRec


    Agora, em 'ModConstants", no final dela, declare essa constante:

    Código:
    Public Const Max_MapNpc_Targets As Long = 20


    Agora, em "ModServerLoop", na "Private Sub UpdateGameLogic" , procure por esta parte:

    Código:
    ' Check if they have more then they should and if so just set it to max
                                If MapNpc(MapNum).NPC(x).Vital(Vitals.HP) > GetNpcMaxVital(npcnum, Vitals.HP) Then
                                    MapNpc(MapNum).NPC(x).Vital(Vitals.HP) = GetNpcMaxVital(npcnum, Vitals.HP)
                                End If

    E substitua por isto:

    Código:
    ' Check if they have more then they should and if so just set it to max
                                If MapNpc(MapNum).NPC(x).Vital(Vitals.HP) > GetNpcMaxVital(npcnum, Vitals.HP) Then
                                    MapNpc(MapNum).NPC(x).Vital(Vitals.HP) = GetNpcMaxVital(npcnum, Vitals.HP)
                                    
                                    'Clear list if not inBattle and HP maxed
                                    If MapNpc(MapNum).NPC(x).Target = 0 Then
                                        For i = 1 To Max_MapNpc_Targets
                                            If MapNpc(MapNum).NPC(x).TargetList(i).Num > 0 Then
                                                MapNpc(MapNum).NPC(x).TargetList(i).Num = 0
                                                MapNpc(MapNum).NPC(x).TargetList(i).Damage = 0
                                            End If
                                        Next
                                    End If
                                End If                        


    Agora, em "ModPlayer" na "Sub PlayerWarp", procure por esta parte:
    Código:
    ' Now we check if there were any players left on the map the player just left, and if not stop processing npcs
        If GetTotalMapPlayers(OldMap) = 0 Then
            PlayersOnMap(OldMap) = NO

            ' Regenerate all NPCs' health
            For i = 1 To MAX_MAP_NPCS

                If MapNpc(OldMap).NPC(i).Num > 0 Then
                    MapNpc(OldMap).NPC(i).Vital(Vitals.HP) = GetNpcMaxVital(MapNpc(OldMap).NPC(i).Num, Vitals.HP)
                End If

            Next

        End If

    E substitua por isto:
    Código:
    ' Now we check if there were any players left on the map the player just left, and if not stop processing npcs
        If GetTotalMapPlayers(OldMap) = 0 Then
            PlayersOnMap(OldMap) = NO

            ' Regenerate all NPCs' health
            For i = 1 To MAX_MAP_NPCS
                If MapNpc(OldMap).NPC(i).Num > 0 Then
                    MapNpc(OldMap).NPC(i).Vital(Vitals.HP) = GetNpcMaxVital(MapNpc(OldMap).NPC(i).Num, Vitals.HP)
                End If
                'check If player already exists in list
                For x = 1 To Max_MapNpc_Targets
                    If MapNpc(MapNum).NPC(i).TargetList(x).Num = Index Then
                        MapNpc(MapNum).NPC(i).TargetList(x).Num = 0
                        MapNpc(MapNum).NPC(i).TargetList(x).Damage = 0
                    End If
                Next
            Next
        Else
            ' Regenerate all NPCs' health
            For i = 1 To MAX_MAP_NPCS
                'check If player already exists in list
                For x = 1 To Max_MapNpc_Targets
                    If MapNpc(MapNum).NPC(i).TargetList(x).Num = Index Then
                        MapNpc(MapNum).NPC(i).TargetList(x).Num = 0
                        MapNpc(MapNum).NPC(i).TargetList(x).Damage = 0
                    End If
                Next
            Next

        End If
    (E sim, podemos usar o X , já que não há mais nada abaixo para mudar a posição do jogador pelo 'X', portanto se atente, se sua versão é modificada, veja se não há nada abaixo usando o X)


    Agora, em "ModCombat" , abaixo disto: 

    Código:
    SendActionMsg GetPlayerMap(Attacker), "-" & MapNpc(MapNum).NPC(MapNpcNum).Vital(Vitals.HP), BrightRed, 1, (MapNpc(MapNum).NPC(MapNpcNum).x * 32), (MapNpc(MapNum).NPC(MapNpcNum).y * 32)
            SendBlood GetPlayerMap(Attacker), MapNpc(MapNum).NPC(MapNpcNum).x, MapNpc(MapNum).NPC(MapNpcNum).y

    Adicione isto:
    Código:
    'Check in final for last damage
            Call CheckMapNpcTargetListFor(Attacker, MapNum, MapNpcNum, Damage)

    Agora, nesta mesma Sub, mais abaixo procure por isto:
    Código:
    ' in party?
                If TempPlayer(Attacker).inParty > 0 Then
                    ' pass through party sharing function
                    Party_ShareExp TempPlayer(Attacker).inParty, Exp, Attacker
                Else
                    ' no party - keep exp for self
                    GivePlayerEXP Attacker, Exp
                    GivePlayerTalentEXP Attacker, Exp
                End If

    E substitua por isto:
    Código:
    'Get new exp
            Call MapNpc_ShareExp(MapNum, MapNpcNum, Exp)


    Agora procure por isto ainda nesta Sub, mas logo abaixo:
    Código:
    ' NPC not dead, just do the damage
            MapNpc(MapNum).NPC(MapNpcNum).Vital(Vitals.HP) = MapNpc(MapNum).NPC(MapNpcNum).Vital(Vitals.HP) - Damage


    E abaixo disso, adicione isto:
    Código:
    'Check in final for last damage
            Call CheckMapNpcTargetListFor(Attacker, MapNum, MapNpcNum, Damage)

    Agora, no final de "ModCombat", adicione esta Sub:
    Código:
    Public Sub CheckMapNpcTargetListFor(ByVal Attacker As Long, ByVal MapNum As Long, ByVal MapNpcNum As Long, ByVal Damage As Long)
    Dim i As Long
        
        
        For i = 1 To Max_MapNpc_Targets
            'If Index exists, just add damage to counter
            If MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).num = Attacker Then
                MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).Damage = MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).Damage + Damage
                Exit Sub
            End If
            
            'If Index not exists, add it and exit
            If MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).num = 0 Then
                MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).num = Attacker
                MapNpc(MapNum).NPC(MapNpcNum).TargetList(i).Damage = Damage
                Exit For
            End If
        Next
        
            
    End Sub


    E pronto! Agora jogadores que quiserem dar "KillSteal" , podem até fazer como sempre fizeram, mas vai ter só a exp que realmente merecem.
    Qualquer dúvida ou erro que der, dêem feedback, testei na engine que programei e inclusive peguei uma "2.0" limpa para refazer e postar aqui e deu tudo certinho.

    Créditos
    Kotol  Very Happy

    Valentine, Sonart e Maxminus gostam desta mensagem


      Data/hora atual: Sáb Abr 27, 2024 5:49 pm