Como no título, é um sistema de magia de escudo. Este escudo irá receber o dano do jogador em sentido "Player Vs NPC" e "Player Vs Player". O sistema até onde foi testado, funciona na lógica:
[Lógica]
Dano = 100 com Escudo do Jogador = 200
-> Dano = -100 (Saída da Sub) , Escudo do jogador atual = 100
Dano = 200 com Escudo do Jogador = 100
-> Dano = 100 , Escudo do jogador atual = 0 ----> Continua o Dano , dando 100 de dano na vida normal.
[Fim da lógica]
O sistema conta com:
- Novo vital: Vitals.Shielding;
- Escudo será: Vital da Magia + Porcentagem do HP máximo escolhido no editor + Porcentagem do MP máximo escolhido no editor;
- Quantidade de escudo sendo mostrada no canto superior esquerdo da tela.
OBS. IMPORTANTE: Como o sistema vai adicionar mais um "VitalType", então pode ser necessário a criação de novas contas. Caso seu projeto já esteja online com contas Oficiais, basta criar uma variável no "PlayerRec" nova e indicar como "Escudo" ao invés do "VitalType".
Sem mais delongas, vamos ao sistema, primeiramente vamos começar com o cliente.
- 1x TextBox, Name: "txtShieldMP" , Caption: " "
Ainda no "frmEditor_Spell" , na parte de "Forms", na "cmbType" , na propriedade "List" , mude isto:
Para isto:
Agora, dê dois cliques na "cmbType" e na sua parte lógica, procure isto:
E logo abaixo adicione isto:
Agora, dê dois cliques na "txtShieldHP" e adicione isto:
E finalmente, dê dois cliques na "txtShieldMP" e adicione isto:
Agora, em "ModGameEditors", na "Public Sub SpellEditorInit()" , procure por esta parte:
E logo abaixo adicione isto:
Agora, em "ModConstants" , procure por:
E logo abaixo adicione:
Agora, em "ModEnumerations", procure por esta parte:
E substitua por isto:
Ainda em "ModEnumerations", procure por:
E abaixo adicione isto:
Agora, em "ModHandleData", na "Public Sub InitMessages()", abaixo de:
Adicione isto:
Ainda em "ModHandleData", procure pela "Private Sub HandlePlayerMp" , e ABAIXO DESTE SUB , ou seja, logo abaixo depois do primeiro "End Sub", adicione esta Sub:
Agora, em "ModDirectDraw7", procure por esta parte:
E logo abaixo adicione isto:
Finalmente, em "ModTypes" procure pela "Private Type SpellRec" e logo abaixo ANTES DO PRIMEIRO "End Type", adicione isto:
Agora o client~side está pronto, vamos ao server~side.
Adicione isto:
Ainda em "ModEnumerations", procure por esta parte:
E substitua por isto:
Agora em "ModServerTCP", procure por esta SUB:
E substitua ela toda por esta SUB:
Agora, em "ModCombat" na "Sub NpcAttackPlayer", defina uma nova variável:
Ainda em "ModCombat" na "Sub NpcAttackPlayer", procure por:
E logo acima dessa parte, adicione isto:
Ainda, em "ModCombat" na "Sub PlayerAttackPlayer", defina uma nova variável:
Ainda em "ModCombat" na "Sub PlayerAttackPlayer", procure por esta parte:
Logo abaixo disso, adicione isto:
Ainda em "ModCombat", na "Public Sub CastSpell", procure por esta parte:
Ainda em "ModCombat" na "Public Sub CastSpell", procure por esta parte:
E logo abaixo disso, adicione isto:
Agora, em "ModConstants", abaixo disto:
Adicione isto:
Finalmente, em "ModTypes" procure pela "Private Type SpellRec" e logo abaixo ANTES DO PRIMEIRO "End Type", adicione isto:
E pronto, seu sistema de escudo está pronto! Qualquer dúvida, sugestão ou até parte que vier a faltar, entre em contato!
[Lógica]
Dano = 100 com Escudo do Jogador = 200
-> Dano = -100 (Saída da Sub) , Escudo do jogador atual = 100
Dano = 200 com Escudo do Jogador = 100
-> Dano = 100 , Escudo do jogador atual = 0 ----> Continua o Dano , dando 100 de dano na vida normal.
[Fim da lógica]
O sistema conta com:
- Novo vital: Vitals.Shielding;
- Escudo será: Vital da Magia + Porcentagem do HP máximo escolhido no editor + Porcentagem do MP máximo escolhido no editor;
- Quantidade de escudo sendo mostrada no canto superior esquerdo da tela.
OBS. IMPORTANTE: Como o sistema vai adicionar mais um "VitalType", então pode ser necessário a criação de novas contas. Caso seu projeto já esteja online com contas Oficiais, basta criar uma variável no "PlayerRec" nova e indicar como "Escudo" ao invés do "VitalType".
Sem mais delongas, vamos ao sistema, primeiramente vamos começar com o cliente.
CLIENT~SIDE
Abra seu "Client.Vbp" e no "frmEditor_Spell" no modo "Forms" , crie:
- 1x Frame , Name: "FraShield" , Visible: False
- 1x Label, Caption: "% of HP:"
- 1x TextBox, Name: "txtShieldHP" , Caption: " "
- 1x Label, Caption: "% of MP:"- 1x TextBox, Name: "txtShieldMP" , Caption: " "
Ainda no "frmEditor_Spell" , na parte de "Forms", na "cmbType" , na propriedade "List" , mude isto:
- Código:
Damage HP
Damage MP
Heal HP
Heal MP
Warp
Para isto:
- Código:
Damage HP
Damage MP
Heal HP
Heal MP
Warp
Shielding
Agora, dê dois cliques na "cmbType" e na sua parte lógica, procure isto:
- Código:
Spell(EditorIndex).Type = cmbType.ListIndex
E logo abaixo adicione isto:
- Código:
'Shield
If Spell(EditorIndex).Type = SPELL_TYPE_SHIELD Then
fraShield.Visible = True
Else
fraShield.Visible = False
End If
Agora, dê dois cliques na "txtShieldHP" e adicione isto:
- Código:
If Not IsNumeric(txtShieldHP.text) Then Exit Sub
If Not Len(txtShieldHP.text) > 0 Then Exit Sub
Spell(EditorIndex).PercVitalHP = txtShieldHP.text
E finalmente, dê dois cliques na "txtShieldMP" e adicione isto:
- Código:
If Not IsNumeric(txtShieldMP.text) Then Exit Sub
If Not Len(txtShieldMP.text) > 0 Then Exit Sub
Spell(EditorIndex).PercVitalMP = txtShieldMP.text
Agora, em "ModGameEditors", na "Public Sub SpellEditorInit()" , procure por esta parte:
- Código:
' find the sound we have set
If .cmbSound.ListCount >= 0 Then
For i = 0 To .cmbSound.ListCount
If .cmbSound.List(i) = Trim$(Spell(EditorIndex).Sound) Then
.cmbSound.ListIndex = i
SoundSet = True
End If
Next
If Not SoundSet Or .cmbSound.ListIndex = -1 Then .cmbSound.ListIndex = 0
End If
E logo abaixo adicione isto:
- Código:
'Shield
.txtShieldHP.text = Spell(EditorIndex).PercVitalHP
.txtShieldMP.text = Spell(EditorIndex).PercVitalMP
Agora, em "ModConstants" , procure por:
- Código:
Public Const SPELL_TYPE_WARP As Byte = 4
E logo abaixo adicione:
- Código:
Public Const SPELL_TYPE_SHIELD As Byte = 5 'Shield
Agora, em "ModEnumerations", procure por esta parte:
- Código:
' Vitals used by Players, Npcs and Classes
Public Enum Vitals
HP = 1
MP
' Make sure Vital_Count is below everything else
Vital_Count
End Enum
E substitua por isto:
- Código:
' Vitals used by Players, Npcs and Classes
Public Enum Vitals
HP = 1
MP
Shielding
' Make sure Vital_Count is below everything else
Vital_Count
End Enum
Ainda em "ModEnumerations", procure por:
- Código:
SPlayerMp
E abaixo adicione isto:
- Código:
SPlayerShield
Agora, em "ModHandleData", na "Public Sub InitMessages()", abaixo de:
- Código:
HandleDataSub(SPlayerMp) = GetAddress(AddressOf HandlePlayerMp)
Adicione isto:
- Código:
HandleDataSub(SPlayerShield) = GetAddress(AddressOf HandlePlayerShield)
Ainda em "ModHandleData", procure pela "Private Sub HandlePlayerMp" , e ABAIXO DESTE SUB , ou seja, logo abaixo depois do primeiro "End Sub", adicione esta Sub:
- Código:
Private Sub HandlePlayerShield(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
Dim Buffer As clsBuffer
' If debug mode, handle error then exit out
If Options.Debug = 1 Then On Error GoTo errorhandler
Set Buffer = New clsBuffer
Buffer.WriteBytes Data()
Player(MyIndex).Vital(Vitals.Shielding) = Buffer.ReadLong
Set Buffer = Nothing
' Error handler
Exit Sub
errorhandler:
HandleError "HandlePlayerShield", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
Err.Clear
Exit Sub
End Sub
Agora, em "ModDirectDraw7", procure por esta parte:
- Código:
' draw FPS
If BFPS Then
Call DrawText(TexthDC, Camera.Right - (Len("FPS: " & GameFPS) * 8), Camera.top + 1, Trim$("FPS: " & GameFPS), QBColor(Yellow))
End If
E logo abaixo adicione isto:
- Código:
'Draw shield amount if > 0
If Player(MyIndex).Vital(Vitals.Shielding) > 0 Then
Call DrawText(TexthDC, Camera.Left, Camera.top + 12, Trim$("Shield: " & Player(MyIndex).Vital(Vitals.Shielding)), QBColor(Yellow))
End If
Finalmente, em "ModTypes" procure pela "Private Type SpellRec" e logo abaixo ANTES DO PRIMEIRO "End Type", adicione isto:
- Código:
'Shield
PercVitalHP As Long
PercVitalMP As Long
Agora o client~side está pronto, vamos ao server~side.
SERVER~SIDE
Abra seu "Server.Vbp" e em "ModEnumerations", abaixo de:
- Código:
SPlayerMp
Adicione isto:
- Código:
SPlayerShield
Ainda em "ModEnumerations", procure por esta parte:
- Código:
' Vitals used by Players, Npcs and Classes
Public Enum Vitals
HP = 1
MP
' Make sure Vital_Count is below everything else
Vital_Count
End Enum
E substitua por isto:
- Código:
' Vitals used by Players, Npcs and Classes
Public Enum Vitals
HP = 1
MP
Shielding
' Make sure Vital_Count is below everything else
Vital_Count
End Enum
Agora em "ModServerTCP", procure por esta SUB:
- Código:
Sub SendVital(ByVal index As Long, ByVal Vital As Vitals)
Dim packet As String
Dim Buffer As clsBuffer
Set Buffer = New clsBuffer
Select Case Vital
Case HP
Buffer.WriteLong SPlayerHp
Buffer.WriteLong GetPlayerMaxVital(index, Vitals.HP)
Buffer.WriteLong GetPlayerVital(index, Vitals.HP)
Case MP
Buffer.WriteLong SPlayerMp
Buffer.WriteLong GetPlayerMaxVital(index, Vitals.MP)
Buffer.WriteLong GetPlayerVital(index, Vitals.MP)
End Select
SendDataTo index, Buffer.ToArray()
Set Buffer = Nothing
End Sub
E substitua ela toda por esta SUB:
- Código:
Sub SendVital(ByVal index As Long, ByVal Vital As Vitals)
Dim packet As String
Dim Buffer As clsBuffer
Set Buffer = New clsBuffer
Select Case Vital
Case HP
Buffer.WriteLong SPlayerHp
Buffer.WriteLong GetPlayerMaxVital(index, Vitals.HP)
Buffer.WriteLong GetPlayerVital(index, Vitals.HP)
Case MP
Buffer.WriteLong SPlayerMp
Buffer.WriteLong GetPlayerMaxVital(index, Vitals.MP)
Buffer.WriteLong GetPlayerVital(index, Vitals.MP)
Case Shielding
Buffer.WriteLong SPlayerShield
Buffer.WriteLong GetPlayerVital(index, Vitals.Shielding)
End Select
SendDataTo index, Buffer.ToArray()
Set Buffer = Nothing
End Sub
Agora, em "ModCombat" na "Sub NpcAttackPlayer", defina uma nova variável:
- Código:
Dim dmgToShield As Long
Ainda em "ModCombat" na "Sub NpcAttackPlayer", procure por:
- Código:
If Damage <= 0 Then
Exit Sub
End If
E logo acima dessa parte, adicione isto:
- Código:
'Take damage from shield first
If Player(victim).Vital(Vitals.Shielding) > 0 Then
If Damage > Player(victim).Vital(Vitals.Shielding) Then
'200 - 100 -> -100 white, -100 brightred
'Get shield
dmgToShield = Player(victim).Vital(Vitals.Shielding)
Player(victim).Vital(Vitals.Shielding) = Player(victim).Vital(Vitals.Shielding) - Damage
If Player(victim).Vital(Vitals.Shielding) < 0 Then Player(victim).Vital(Vitals.Shielding) = 0
SendVital victim, Vitals.Shielding
Damage = Damage - dmgToShield
SendActionMsg GetPlayerMap(victim), "( -" & Damage & " )", White, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
'Just continue to do brightred damage
Else
'100 - 200 -> -100 white
SendActionMsg GetPlayerMap(victim), "( -" & Damage & " )", White, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
'Get Shield
dmgToShield = Player(victim).Vital(Vitals.Shielding)
Player(victim).Vital(Vitals.Shielding) = Player(victim).Vital(Vitals.Shielding) - Damage
If Player(victim).Vital(Vitals.Shielding) < 0 Then Player(victim).Vital(Vitals.Shielding) = 0
SendVital victim, Vitals.Shielding
Damage = Damage - dmgToShield
End If
End If
Ainda, em "ModCombat" na "Sub PlayerAttackPlayer", defina uma nova variável:
- Código:
Dim dmgToShield As Long
Ainda em "ModCombat" na "Sub PlayerAttackPlayer", procure por esta parte:
- Código:
' set the regen timer
TempPlayer(attacker).stopRegen = True
TempPlayer(attacker).stopRegenTimer = GetTickCount
Logo abaixo disso, adicione isto:
- Código:
'Take damage from shield first
If Player(victim).Vital(Vitals.Shielding) > 0 Then
If Damage > Player(victim).Vital(Vitals.Shielding) Then
'200 - 100 -> -100 white, -100 brightred
'Get shield
dmgToShield = Player(victim).Vital(Vitals.Shielding)
Player(victim).Vital(Vitals.Shielding) = Player(victim).Vital(Vitals.Shielding) - Damage
If Player(victim).Vital(Vitals.Shielding) < 0 Then Player(victim).Vital(Vitals.Shielding) = 0
SendVital victim, Vitals.Shielding
Damage = Damage - dmgToShield
SendActionMsg GetPlayerMap(victim), "( -" & Damage & " )", White, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
'Just continue to do brightred damage
Else
'100 - 200 -> -100 white
SendActionMsg GetPlayerMap(victim), "( -" & Damage & " )", White, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
'Get Shield
dmgToShield = Player(victim).Vital(Vitals.Shielding)
Player(victim).Vital(Vitals.Shielding) = Player(victim).Vital(Vitals.Shielding) - Damage
If Player(victim).Vital(Vitals.Shielding) < 0 Then Player(victim).Vital(Vitals.Shielding) = 0
SendVital victim, Vitals.Shielding
Damage = Damage - dmgToShield
End If
End If
'Exit if there's no damage
If Damage <= 0 Then Exit Sub
Ainda em "ModCombat", na "Public Sub CastSpell", procure por esta parte:
- Código:
Case SPELL_TYPE_WARP
SendAnimation mapNum, Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
PlayerWarp index, Spell(spellnum).Map, Spell(spellnum).x, Spell(spellnum).y
SendAnimation GetPlayerMap(index), Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
DidCast = True
E logo abaixo adicione isto:
- Código:
Case SPELL_TYPE_SHIELD
SendAnimation mapNum, Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
'Shield = % of HP + % of MP
Player(index).Vital(Vitals.Shielding) = Spell(spellnum).Vital + (GetPlayerMaxVital(index, HP) * Spell(spellnum).PercVitalHP * 0.01) + (GetPlayerMaxVital(index, MP) * Spell(spellnum).PercVitalMP * 0.01)
'Update Player Shield
SendVital index, Shielding
SendAnimation GetPlayerMap(index), Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
DidCast = True
Ainda em "ModCombat" na "Public Sub CastSpell", procure por esta parte:
- Código:
Case SPELL_TYPE_HEALHP, SPELL_TYPE_HEALMP, SPELL_TYPE_DAMAGEMP
If Spell(spellnum).Type = SPELL_TYPE_HEALHP Then
VitalType = Vitals.HP
increment = True
ElseIf Spell(spellnum).Type = SPELL_TYPE_HEALMP Then
VitalType = Vitals.MP
increment = True
ElseIf Spell(spellnum).Type = SPELL_TYPE_DAMAGEMP Then
VitalType = Vitals.MP
increment = False
End If
DidCast = True
For i = 1 To Player_HighIndex
If IsPlaying(i) Then
If GetPlayerMap(i) = GetPlayerMap(index) Then
If isInRange(AoE, x, y, GetPlayerX(i), GetPlayerY(i)) Then
SpellPlayer_Effect VitalType, increment, i, Vital, spellnum
End If
End If
End If
Next
For i = 1 To MAX_MAP_NPCS
If MapNpc(mapNum).Npc(i).Num > 0 Then
If MapNpc(mapNum).Npc(i).Vital(HP) > 0 Then
If isInRange(AoE, x, y, MapNpc(mapNum).Npc(i).x, MapNpc(mapNum).Npc(i).y) Then
SpellNpc_Effect VitalType, increment, i, Vital, spellnum, mapNum
End If
End If
End If
Next
E logo abaixo disso, adicione isto:
- Código:
Case SPELL_TYPE_SHIELD
SendAnimation mapNum, Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
'Shield = % of HP + % of MP
Player(index).Vital(Vitals.Shielding) = Spell(spellnum).Vital + (Player(index).Vital(Vitals.HP) * Spell(spellnum).PercVitalHP * 0.01) + (Player(index).Vital(Vitals.MP) * Spell(spellnum).PercVitalHP * 0.01)
'Update Player Shield
SendVital index, Shielding
SendAnimation GetPlayerMap(index), Spell(spellnum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, index
DidCast = True
Agora, em "ModConstants", abaixo disto:
- Código:
Public Const SPELL_TYPE_WARP As Byte = 4
Adicione isto:
- Código:
Public Const SPELL_TYPE_SHIELD As Byte = 5 'Shield
Finalmente, em "ModTypes" procure pela "Private Type SpellRec" e logo abaixo ANTES DO PRIMEIRO "End Type", adicione isto:
- Código:
'Shield
PercVitalHP As Long
PercVitalMP As Long
E pronto, seu sistema de escudo está pronto! Qualquer dúvida, sugestão ou até parte que vier a faltar, entre em contato!
Boa criação para você no seu projeto!
CRÉDITOS
Kotol