[E.O 2.0] NPC dividindo EXP conforme o dano 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] NPC dividindo EXP conforme o dano

Ir para baixo

[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
Kotol
Kotol
Moderador Local
Moderador Local

Mensagens : 77
Créditos : 17

Valentine, Sonart e Maxminus gostam 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