Oin!!!
Bem esse pedido foi feito pelo @~Felipe em nossa sessão de Pedidos.
O Tópico pode ser achado aqui:
Toda via eu dei uma pequena palhetada de como deveria ser feito o código, mas ainda sim ele não conseguiu reproduzir.
Então venho através deste postar o tutorial de como se fazer tal.
Como funciona o sistema e para quê serve?
O Sistema irá fazer com que o Cliente receba o HP dos Player's do Mapa sempre que tiver atualização, na parte de Receber Dano de NPC ou de Receber dano de Player.
É interessante talvez também colocar na UpdateVitals. (Vou ensinar a por no final do Tutorial)
O Sistema então mostrará o Hp das Crianças Todas do Mapa podendo ser de Ajuda no PVP ou em outros momentos. (Saber que seu enemy está morrendo...)
Ou mesmo você customiza-lo para isso ocorrer apenas em mapas como de Arena/Outros... Fica a seu critério os usos futuros.
Pica do Sistema Funcionando
https://imgur.com/a/vZwGbqw
Ficha Técnica
Dificuldade: Fácil
Compatibilidade: Eo2.0 (Algumas Partes tem de ser Adaptadas para Eo3.0/CS devido o DrawBars mudar para dx8 )
Necessário:
- Visual Basic 6
Engine Já Editada: Download (Cerca de 2mb)
Caso queira apenas Ripar/Ver Funcionando, ou dúvidas de como setar os Códigos, procure por tudo que tenha
- Código:
'[HP]
Ao Sistema
Não irie dar uma aula e explicar o porque de cada coisa ~
Mas a modificação é bem simples apesar de parecer um tanto longa /o/
[ Parte 1 - Modificações no Servidor ]
Procure por:
- Código:
Sub SendVital(ByVal index As Long, ByVal Vital As Vitals,
Substitua toda a Sub por esta sub:
- Código:
'[HP]
Sub SendVital(ByVal index As Long, ByVal Vital As Vitals, Optional ByVal toAll As Boolean)
Dim packet As String
Dim Buffer As clsBuffer
Set Buffer = New clsBuffer
Select Case Vital
Case HP
Buffer.WriteLong SPlayerHp
Buffer.WriteLong index
Buffer.WriteLong GetPlayerMaxVital(index, Vitals.HP)
Buffer.WriteLong GetPlayerVital(index, Vitals.HP)
Case MP
Buffer.WriteLong SPlayerMp
Buffer.WriteLong index
Buffer.WriteLong GetPlayerMaxVital(index, Vitals.MP)
Buffer.WriteLong GetPlayerVital(index, Vitals.MP)
End Select
If Not toAll Then
SendDataTo index, Buffer.ToArray()
Else
SendDataToMap GetPlayerMap(index), Buffer.ToArray()
End If
Set Buffer = Nothing
End Sub
Procure agora por:
- Código:
Function PlayerData(ByVal index As Long) As Byte()
Dentro dela procure por isso aqui:
- Código:
For i = 1 To Stats.Stat_Count - 1
Buffer.WriteLong GetPlayerStat(index, i)
Next
Abaixo dela adicione:
- Código:
'[HP]
Buffer.WriteLong GetPlayerMaxVital(index, Vitals.HP)
Buffer.WriteLong GetPlayerVital(index, Vitals.HP)
Vá ao ModCombat, e procure por isso aqui:
- Código:
Sub PlayerAttackPlayer(ByVal attacker As Long, ByVal victim As Long,
Dentro dessa Sub você achará isso aqui:
- Código:
Call SendVital(victim, Vitals.HP)
Substitua essa linha por esta:
- Código:
Call SendVital(victim, Vitals.HP, True) '[HP]
Ainda no ModCombat, procure por:
- Código:
Sub NpcAttackPlayer(ByVal mapNpcNum As Long,
Dentro desta sub procure por :
- Código:
Call SendVital(victim, Vitals.HP)
Substitua esta linha por isso aqui:
- Código:
Call SendVital(victim, Vitals.HP, True) '[HP]
[ Parte 2 - Modificações no Cliente ]
Dentro do Cliente, Procure por isso aqui:
- Código:
Private Sub HandlePlayerHp(ByVal Index As Long,
Substitua toda a Sub por isso aqui:
- Código:
'[HP]
Private Sub HandlePlayerHp(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim Buffer As clsBuffer
Dim i 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()
i = Buffer.ReadLong 'Lê quem é
'Prevent Script out of Range
If i <= 0 Or i > MAX_PLAYERS Then Exit Sub
If Not IsPlaying(i) Then Exit Sub
Player(i).MaxVital(Vitals.HP) = Buffer.ReadLong
Call SetPlayerVital(i, Vitals.HP, Buffer.ReadLong)
If i = MyIndex Then
If GetPlayerMaxVital(MyIndex, Vitals.HP) > 0 Then
'frmMain.lblHP.Caption = Int(GetPlayerVital(MyIndex, Vitals.HP) / GetPlayerMaxVital(MyIndex, Vitals.HP) * 100) & "%"
frmMain.lblHP.Caption = GetPlayerVital(MyIndex, Vitals.HP) & "/" & GetPlayerMaxVital(MyIndex, Vitals.HP)
' hp bar
frmMain.imgHPBar.width = ((GetPlayerVital(MyIndex, Vitals.HP) / HPBar_Width) / (GetPlayerMaxVital(MyIndex, Vitals.HP) / HPBar_Width)) * HPBar_Width
End If
End If
' Error handler
Exit Sub
errorhandler:
HandleError "HandlePlayerHP", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
Err.Clear
Exit Sub
End Sub
Logo abaixo você encontra outra Sub, esta aqui:
- Código:
Private Sub HandlePlayerMp(ByVal Index As Long,
Substitua toda a Sub por isso aqui:
- Código:
'[HP]
Private Sub HandlePlayerMp(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim Buffer As clsBuffer
Dim i 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()
i = Buffer.ReadLong 'Lê quem é
'Prevent Script out of Range
If i <= 0 Or i > MAX_PLAYERS Then Exit Sub
If Not IsPlaying(i) Then Exit Sub
Player(i).MaxVital(Vitals.MP) = Buffer.ReadLong
Call SetPlayerVital(i, Vitals.MP, Buffer.ReadLong)
If i = MyIndex Then
If GetPlayerMaxVital(MyIndex, Vitals.MP) > 0 Then
'frmMain.lblMP.Caption = Int(GetPlayerVital(MyIndex, Vitals.MP) / GetPlayerMaxVital(MyIndex, Vitals.MP) * 100) & "%"
frmMain.lblMP.Caption = GetPlayerVital(MyIndex, Vitals.MP) & "/" & GetPlayerMaxVital(MyIndex, Vitals.MP)
' mp bar
frmMain.imgMPBar.width = ((GetPlayerVital(MyIndex, Vitals.MP) / SPRBar_Width) / (GetPlayerMaxVital(MyIndex, Vitals.MP) / SPRBar_Width)) * SPRBar_Width
End If
End If
' Error handler
Exit Sub
errorhandler:
HandleError "HandlePlayerMP", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
Err.Clear
Exit Sub
End Sub
Ainda no mesmo Modulo, procure por:
- Código:
Private Sub HandlePlayerData(ByVal Index As Long,
Dentro dele procure por:
- Código:
For x = 1 To Stats.Stat_Count - 1
SetPlayerStat i, x, Buffer.ReadLong
Next
Abaixo adicione:
- Código:
'[HP]
Call SetPlayerMaxVital(i, Vitals.HP, Buffer.ReadLong)
Call SetPlayerVital(i, Vitals.HP, Buffer.ReadLong)
Vá ao ModDatabase, no final dele adicione:
- Código:
'[HP]
Sub SetPlayerMaxVital(ByVal Index As Long, ByVal Vital As Vitals, ByVal Value As Long)
' If debug mode, handle error then exit out
If Options.Debug = 1 Then On Error GoTo errorhandler
If Index > MAX_PLAYERS Then Exit Sub
Player(Index).MaxVital(Vital) = Value
' Error handler
Exit Sub
errorhandler:
HandleError "SetPlayerMaxVital", "modDatabase", Err.Number, Err.Description, Err.Source, Err.HelpContext
Err.Clear
Exit Sub
End Sub
Agora procure por isso aqui:
- Código:
Private Sub BltBars()
Dentro dessa sub vamos estar mexendo nas Barras.
Procure por isso aqui:
- Código:
' draw own health bar
If GetPlayerVital(MyIndex, Vitals.HP) > 0 And GetPlayerVital(MyIndex, Vitals.HP) < GetPlayerMaxVital(MyIndex, Vitals.HP) Then
' lock to Player
tmpX = GetPlayerX(MyIndex) * PIC_X + Player(MyIndex).XOffset + 16 - (sWidth / 2)
tmpY = GetPlayerY(MyIndex) * PIC_X + Player(MyIndex).YOffset + 35
' calculate the width to fill
barWidth = ((GetPlayerVital(MyIndex, Vitals.HP) / sWidth) / (GetPlayerMaxVital(MyIndex, Vitals.HP) / sWidth)) * sWidth
' draw bar background
With sRECT
.top = sHeight * 1 ' HP bar background
.Left = 0
.Right = .Left + sWidth
.Bottom = .top + sHeight
End With
Engine_BltFast ConvertMapX(tmpX), ConvertMapY(tmpY), DDS_Bars, sRECT, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY
' draw the bar proper
With sRECT
.top = 0 ' HP bar
.Left = 0
.Right = .Left + barWidth
.Bottom = .top + sHeight
End With
Engine_BltFast ConvertMapX(tmpX), ConvertMapY(tmpY), DDS_Bars, sRECT, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY
End If
Se você comentar esse Primeiro If / End If, você passará a deixar a barra de HP do SEU personagem sempre visível!
Caso queira isso, substitua esse código acima por este aqui:
Agora, abaixo desse código adicione:
- Código:
'[HP]
For i = 1 To MAX_PLAYERS
If IsPlaying(i) Then
If i <> MyIndex Then
' draw own health bar
'If GetPlayerVital(i, Vitals.HP) > 0 And GetPlayerVital(i, Vitals.HP) < GetPlayerMaxVital(i, Vitals.HP) Then
' lock to Player
tmpX = GetPlayerX(i) * PIC_X + Player(i).XOffset + 16 - (sWidth / 2)
tmpY = GetPlayerY(i) * PIC_X + Player(i).YOffset + 35
' calculate the width to fill
barWidth = ((GetPlayerVital(i, Vitals.HP) / sWidth) / (GetPlayerMaxVital(i, Vitals.HP) / sWidth)) * sWidth
' draw bar background
With sRECT
.top = sHeight * 1 ' HP bar background
.Left = 0
.Right = .Left + sWidth
.Bottom = .top + sHeight
End With
Engine_BltFast ConvertMapX(tmpX), ConvertMapY(tmpY), DDS_Bars, sRECT, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY
' draw the bar proper
With sRECT
.top = 0 ' HP bar
.Left = 0
.Right = .Left + barWidth
.Bottom = .top + sHeight
End With
Engine_BltFast ConvertMapX(tmpX), ConvertMapY(tmpY), DDS_Bars, sRECT, DDBLTFAST_WAIT Or DDBLTFAST_SRCCOLORKEY
'End If
End If
End If
Next
Salve e Teste, seja feliz.
[ Parte Bônus - UpdateVitals ]
Esta parte não contém na engine que disponibilizei para Download!
O UpdateVitals é a sub que processa a Regen do Player. Caso queira que o HP se atualize sempre com a Regen e não apenas ao player ser Atacado por outro Player ou NPC siga abaixo.
No Servidor,
Procure por:
- Código:
Private Sub UpdatePlayerVitals()
Substitua toda a sub por isso aqui:
- Código:
Private Sub UpdatePlayerVitals()
Dim i As Long
For i = 1 To Player_HighIndex
If IsPlaying(i) Then
If Not TempPlayer(i).stopRegen Then
If GetPlayerVital(i, Vitals.HP) <> GetPlayerMaxVital(i, Vitals.HP) Then
Call SetPlayerVital(i, Vitals.HP, GetPlayerVital(i, Vitals.HP) + GetPlayerVitalRegen(i, Vitals.HP))
Call SendVital(i, Vitals.HP, True) '[HP]
' send vitals to party if in one
If TempPlayer(i).inParty > 0 Then SendPartyVitals TempPlayer(i).inParty, i
End If
If GetPlayerVital(i, Vitals.MP) <> GetPlayerMaxVital(i, Vitals.MP) Then
Call SetPlayerVital(i, Vitals.MP, GetPlayerVital(i, Vitals.MP) + GetPlayerVitalRegen(i, Vitals.MP))
Call SendVital(i, Vitals.MP)
' send vitals to party if in one
If TempPlayer(i).inParty > 0 Then SendPartyVitals TempPlayer(i).inParty, i
End If
End If
End If
Next
End Sub
Att e bju na Boka!