É 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:
Agora, abaixo desta "Public Sub Party_ShareExp" , adicione esta sub:
Ainda no "ModGameLogic" , procure pela "Public Sub SpawnNpc" , e abaixo de:
Adicione isto:
Agora em "ModTypes" , ACIMA de "Private Type MapNpcRec", adicione esta 'type':
Ainda em "ModTypes" , na "Private Type MapNpcRec", logo abaixo ANTES do primeiro "End Type" que achar, declare esse type:
Agora, em 'ModConstants", no final dela, declare essa constante:
Agora, em "ModServerLoop", na "Private Sub UpdateGameLogic" , procure por esta parte:
E substitua por isto:
Agora, em "ModPlayer" na "Sub PlayerWarp", procure por esta parte:
E substitua por isto:
Agora, em "ModCombat" , abaixo disto:
Adicione isto:
Agora, nesta mesma Sub, mais abaixo procure por isto:
E substitua por isto:
Agora procure por isto ainda nesta Sub, mas logo abaixo:
E abaixo disso, adicione isto:
Agora, no final de "ModCombat", adicione esta 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.
-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
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