[2016] Npc atacando com spells 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.

[2016] Npc atacando com spells

2 participantes

Ir para baixo

[2016] Npc atacando com spells Empty [2016] Npc atacando com spells

Mensagem por EpicMelanie Sex Abr 08, 2016 5:26 pm

Andei procurando por algum sistema que faça o NPC usar spells, encontrei vários tutoriais que, ao final da explicação, pediam para baixar um arquivo... Porém TODOS os links estavam quebrados.
Então consegui extrair esse sistema de uma modificação que fizeram da eclipse e, pelo menos aqui está funcionando perfeitamente.

(Obs: Não sei quem criou esse sistema, por isso não coloquei créditos.)

~ Server Side~
Em modConstants, encontre:

Código:
Public Const MAX_PARTY_MEMBERS As Long = 4

e adicione em baixo:

Código:
Public Const MAX_NPC_SPELLS As Long = 5

- Define o máximo de spells que o Npc pode usar.

Em modTypes, encontre Private Type NpcRec e adicione isso antes de End Type:
Código:
Spell(1 To MAX_NPC_SPELLS) As Long

Em modTypes, encontre Private Type MapNpcRec e adicione isso antes de End Type:

Código:
   SpellTimer(1 To MAX_NPC_SPELLS) As Long

    Heals As Integer


Em modGameLogic, encontre Sub NpcAttackPlayer e adicione esse código DEPOIS do final da sub NpcAttackPlayer (depois do End Sub):
Código:
Sub NpcSpellPlayer(ByVal MapNpcNum As Long, ByVal Victim As Long, SpellSlotNum As Long)
    Dim mapnum As Long
    Dim i As Long
    Dim n As Long
    Dim SpellNum As Long
    Dim Buffer As clsBuffer
    Dim InitDamage As Long
    Dim Damage As Long
    Dim MaxHeals As Long

    ' Check for subscript out of range
    If MapNpcNum <= 0 Or MapNpcNum > MAX_MAP_NPCS Or IsPlaying(Victim) = False Then
        Exit Sub
    End If

    ' Check for subscript out of range
    If MapNpc(GetPlayerMap(Victim)).NPC(MapNpcNum).Num <= 0 Then
        Exit Sub
    End If
    
    If SpellSlotNum <= 0 Or SpellSlotNum > MAX_NPC_SPELLS Then Exit Sub

    ' The Variables
    mapnum = GetPlayerMap(Victim)
    SpellNum = NPC(MapNpc(mapnum).NPC(MapNpcNum).Num).Spell(SpellSlotNum)
    
    ' Send this packet so they can see the person attacking
    Set Buffer = New clsBuffer
    Buffer.WriteLong SNpcAttack
    Buffer.WriteLong MapNpcNum
    SendDataToMap mapnum, Buffer.ToArray()
    Set Buffer = Nothing
    
    ' CoolDown Time
    If MapNpc(mapnum).NPC(MapNpcNum).SpellTimer(SpellSlotNum) > GetTickCount Then Exit Sub
    ' Spell Types
        Select Case Spell(SpellNum).Type
    
            ' AOE Healing Spells
            Case SPELL_TYPE_HEALHP
            If SpellSlotNum <= 0 Or SpellSlotNum > MAX_NPC_SPELLS Then Exit Sub 'check for subscript out of range
            ' Make sure an npc waits for the spell to cooldown
            MaxHeals = 1 + NPC(MapNpc(mapnum).NPC(MapNpcNum).Num).Stat(Stats.intelligence) \ 25
            If MapNpc(mapnum).NPC(MapNpcNum).Heals >= MaxHeals Then Exit Sub
                If MapNpc(mapnum).NPC(MapNpcNum).Vital(Vitals.HP) <= NPC(MapNpc(mapnum).NPC(MapNpcNum).Num).HP * 0.3 Then
                    If Spell(SpellNum).IsAoE Then
                        For i = 1 To MAX_MAP_NPCS
                            If MapNpc(mapnum).NPC(i).Num > 0 Then
                                If MapNpc(mapnum).NPC(i).Vital(Vitals.HP) > 0 Then
                                    If isInRange(Spell(SpellNum).AoE, MapNpc(mapnum).NPC(MapNpcNum).x, MapNpc(mapnum).NPC(MapNpcNum).y, MapNpc(mapnum).NPC(i).x, MapNpc(mapnum).NPC(i).y) Then
                                        InitDamage = Spell(SpellNum).Vital + (NPC(MapNpc(mapnum).NPC(MapNpcNum).Num).Stat(Stats.intelligence) / 2)
                    
                                        MapNpc(mapnum).NPC(i).Vital(Vitals.HP) = MapNpc(mapnum).NPC(i).Vital(Vitals.HP) + InitDamage
                                        SendActionMsg mapnum, "+" & InitDamage, BrightGreen, 1, (MapNpc(mapnum).NPC(i).x * 32), (MapNpc(mapnum).NPC(i).y * 32)
                                        Call SendAnimation(mapnum, Spell(SpellNum).SpellAnim, 0, 0, TARGET_TYPE_NPC, MapNpcNum)
                    
                                        If MapNpc(mapnum).NPC(i).Vital(Vitals.HP) > NPC(MapNpc(mapnum).NPC(i).Num).HP Then
                                            MapNpc(mapnum).NPC(i).Vital(Vitals.HP) = NPC(MapNpc(mapnum).NPC(i).Num).HP
                                        End If
                    
                                        MapNpc(mapnum).NPC(MapNpcNum).Heals = MapNpc(mapnum).NPC(MapNpcNum).Heals + 1
                    
                                        MapNpc(mapnum).NPC(MapNpcNum).SpellTimer(SpellSlotNum) = GetTickCount + Spell(SpellNum).CDTime * 1000
                                        Exit Sub
                                    End If
                                End If
                            End If
                        Next
                    Else
                    ' Non AOE Healing Spells
                        InitDamage = Spell(SpellNum).Vital + (NPC(MapNpc(mapnum).NPC(MapNpcNum).Num).Stat(Stats.intelligence) / 2)
                    
                        MapNpc(mapnum).NPC(MapNpcNum).Vital(Vitals.HP) = MapNpc(mapnum).NPC(MapNpcNum).Vital(Vitals.HP) + InitDamage
                        SendActionMsg mapnum, "+" & InitDamage, BrightGreen, 1, (MapNpc(mapnum).NPC(MapNpcNum).x * 32), (MapNpc(mapnum).NPC(MapNpcNum).y * 32)
                        Call SendAnimation(mapnum, Spell(SpellNum).SpellAnim, 0, 0, TARGET_TYPE_NPC, MapNpcNum)
                    
                        If MapNpc(mapnum).NPC(MapNpcNum).Vital(Vitals.HP) > NPC(MapNpc(mapnum).NPC(MapNpcNum).Num).HP Then
                            MapNpc(mapnum).NPC(MapNpcNum).Vital(Vitals.HP) = NPC(MapNpc(mapnum).NPC(MapNpcNum).Num).HP
                        End If
                    
                        MapNpc(mapnum).NPC(MapNpcNum).Heals = MapNpc(mapnum).NPC(MapNpcNum).Heals + 1
                    
                        MapNpc(mapnum).NPC(MapNpcNum).SpellTimer(SpellSlotNum) = GetTickCount + Spell(SpellNum).CDTime * 1000
                        Exit Sub
                    End If
                End If
                
            ' AOE Damaging Spells
            Case SPELL_TYPE_DAMAGEHP
                 If SpellSlotNum <= 0 Or SpellSlotNum > MAX_NPC_SPELLS Then Exit Sub 'check for subscript out of range
            ' Make sure an npc waits for the spell to cooldown
                If Spell(SpellNum).IsAoE Then
                    For i = 1 To Player_HighIndex
                        If IsPlaying(i) Then
                            If GetPlayerMap(i) = mapnum Then
                                If isInRange(Spell(SpellNum).AoE, MapNpc(mapnum).NPC(MapNpcNum).x, MapNpc(mapnum).NPC(MapNpcNum).y, GetPlayerX(i), GetPlayerY(i)) Then
                                    InitDamage = Spell(SpellNum).Vital + (NPC(MapNpc(mapnum).NPC(MapNpcNum).Num).Stat(Stats.intelligence) / 2)
                                    Damage = InitDamage - Player(i).Stat(Stats.willpower)
                                        If Damage <= 0 Then
                                            SendActionMsg GetPlayerMap(i), "RESIST!", Pink, 1, (GetPlayerX(i) * 32), (GetPlayerY(i) * 32)
                                            Exit Sub
                                        Else
                                            NpcAttackPlayer MapNpcNum, i, Damage
                                            SendAnimation mapnum, Spell(SpellNum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, MapNpcNum
                                            MapNpc(mapnum).NPC(MapNpcNum).SpellTimer(SpellSlotNum) = GetTickCount + Spell(SpellNum).CDTime * 1000
                                            Exit Sub
                                        End If
                                End If
                            End If
                        End If
                    Next
                ' Non AoE Damaging Spells
                Else
                    If isInRange(Spell(SpellNum).Range, MapNpc(mapnum).NPC(MapNpcNum).x, MapNpc(mapnum).NPC(MapNpcNum).y, GetPlayerX(Victim), GetPlayerY(Victim)) Then
                    InitDamage = Spell(SpellNum).Vital + (NPC(MapNpc(mapnum).NPC(MapNpcNum).Num).Stat(Stats.intelligence) / 2)
                    Damage = InitDamage - Player(Victim).Stat(Stats.willpower)
                        If Damage <= 0 Then
                            SendActionMsg GetPlayerMap(Victim), "RESIST!", Pink, 1, (GetPlayerX(Victim) * 32), (GetPlayerY(Victim) * 32)
                            Exit Sub
                        Else
                            NpcAttackPlayer MapNpcNum, Victim, Damage
                            SendAnimation mapnum, Spell(SpellNum).SpellAnim, 0, 0, TARGET_TYPE_PLAYER, Victim
                            MapNpc(mapnum).NPC(MapNpcNum).SpellTimer(SpellSlotNum) = GetTickCount + Spell(SpellNum).CDTime * 1000
                            Exit Sub
                        End If
                    End If
                End If
            End Select
End Sub

Em modServerLoop, encontre essas 3 linhas e DELETE:

Código:
Else
                            ' lol no npc combat
                        End If
Procure por isso:

Código:
' ////////////////////////////////////////////
' // This is used for regenerating NPC's HP //
' ////////////////////////////////////////////

Acima disso, adicione esse código:

Código:
' Spell Casting

                                For i = 1 To MAX_NPC_SPELLS

                                    If Npc(npcNum).Spell(i) > 0 Then

                                        If MapNpc(mapnum).Npc(x).SpellTimer(i) + (Spell(Npc(npcNum).Spell(i)).CastTime * 1000) < GetTickCount Then

                                            NpcSpellPlayer x, target, i

                                        End If

                                    End If

                                Next

                            End If

Agora, ~CLIENT SIDE~:


Em modConstants, encontre:

Código:
Public Const MAX_PARTY_MEMBERS As Long = 4

e adicione em baixo:

Código:
Public Const MAX_NPC_SPELLS As Long = 5

Encontre Private Type NpcRec e adicione isso antes de End Type:
Código:
Spell(1 To MAX_NPC_SPELLS) As Long

Em modGameEditors, vá até Public Sub NpcEditorInit e encontre essa linha:

Código:
.txtDamage.text = Npc(EditorIndex).Damage
Abaixo disso, adicione:

Código:
.scrlSpellNum.Max = MAX_NPC_SPELLS
 .scrlSpellNum.Value = 1



Agora é a parte que falta em vários (se não todos) tutoriais:


Vá até frmEditor_NPC e aumente o tamanho da frm, de forma que caiba outro Frame.

E, faça o seguinte:


Img:


-Adicione um frame, e em (name) coloque fraSpell

-Adicione um HScrollBar, e em (name) coloque scrlSpellNum  e Height: 255

-Adicione um Label, em (name) coloque lblSpellName e em Caption coloque Spell: None

-Adicione outro Label, em (name) coloque lblSpellNum e em Caption coloque Num: 0

-Adicione outro HScrollBar e em (name) coloque scrlSpell  e Height: 255

Agora de 2 cliques no Form para editar os códigos.
No topo dos códigos, encontre Option Explicit e, adicione em baixo:

Código:
Private SpellIndex As Long

Agora, no FINAL dos códigos do frmEditor_NPC, depois de end sub, adicione:

Código:
Private Sub scrlSpell_Change()
lblSpellNum.Caption = "Num: " & scrlSpell.Value
    If scrlSpell.Value > 0 Then
        lblSpellName.Caption = "Spell: " & Trim$(Spell(scrlSpell.Value).Name)
    Else
        lblSpellName.Caption = "Spell: None"
    End If
    NPC(EditorIndex).Spell(SpellIndex) = scrlSpell.Value
End Sub

Private Sub scrlSpellNum_Change()
SpellIndex = scrlSpellNum.Value
    fraSpell.Caption = "Spell - " & SpellIndex
    scrlSpell.Value = NPC(EditorIndex).Spell(SpellIndex)
End Sub

Salve e compile.
EpicMelanie
EpicMelanie
Novato
Novato

Mensagens : 12
Créditos : 5

Ir para o topo Ir para baixo

[2016] Npc atacando com spells Empty Re: [2016] Npc atacando com spells

Mensagem por Profane ~ Dom Abr 10, 2016 2:32 pm

Algo a citar em relação o uso de tal fatores; 

Ao usar isso, em questão de loop do server, e leituras; Caso tenha mais de um Npc com spell implantada em sua classe, e o mesmo targetar o alvo player; e o mesmo não se encontrar no mapa; Tem grandes chances de quebrar o servidor.

O Castspell usa a leitura de envio para seres que estão nos quadrantes do GetPlayerMap Atual; porém basicamente o Npc não muda de mapa ><; Os players, sim. 

Npc -> castspell enquanto o player está no mapa, player muda de mapa por N motivos, acaba gerando o out of range. 

Uma defesa contra isso é em seu serverloop, na leitura de envio e pós analisar se de fato o Alvo em questão está no Mapa.

_________________
"Mistress of shattered hopes and forever broken dreams"
Profane ~
Profane ~
Colaborador
Colaborador

Mensagens : 818
Créditos : 130

Ir para o topo Ir para baixo

[2016] Npc atacando com spells Empty Re: [2016] Npc atacando com spells

Mensagem por EpicMelanie Dom Abr 10, 2016 4:09 pm

Então, algo para evitar isso seria adicionar essa checagem:

Edit: Não deu certo.
Apesar de eu ter feito testes com esse sistema e ele não ter bugado (ainda), vou tentar fazer esse tipo de checagem ( se o jogador não estiver no mapa, exit sub e bla bla bla ).

-------------------------------------------------------------------------------------------------------
Eu apenas copiei e colei o código pois não tenho tanta experiência para desenvolver meus próprios sistemas (comecei há pouco tempo), peço desculpas.
EpicMelanie
EpicMelanie
Novato
Novato

Mensagens : 12
Créditos : 5

Ir para o topo Ir para baixo

[2016] Npc atacando com spells Empty Re: [2016] Npc atacando com spells

Mensagem por Profane ~ Seg Abr 11, 2016 1:54 pm

Não precisa pedir desculpas >< Entendo o que fez, eh uma contribuição excelente sem dúvidas >< 

Vi que informou que copiou, colou e etc.. mas você foi preparar o topico, separar os codigos, verificar entre outros. Bom trabalho. 

Em relação a checagem, a propria sub já tem; observe:

Código:
 Check for subscript out of range[size=12][/size]
    If MapNpc(GetPlayerMap(Victim)).NPC(MapNpcNum).Num <= 0 Then[size=12][/size]
        Exit Sub[size=12][/size]
    End If

O Caso é que apenas na sub eu creio que não processe tudo, pq ao enviar dps dessa checagem que é o problema ><

Player Está no mapa, Npc envia a spell, passou por essa primeira checagem, player muda de mapa, bump >< quebra.

Com muitos players ai que vira um problema ou muitos npc's. 

Precisando de ajuda montamos algo ;3 De qualquer forma, bom trabalho.

_________________
"Mistress of shattered hopes and forever broken dreams"
Profane ~
Profane ~
Colaborador
Colaborador

Mensagens : 818
Créditos : 130

Ir para o topo Ir para baixo

[2016] Npc atacando com spells Empty Re: [2016] Npc atacando com spells

Mensagem por Conteúdo patrocinado


Conteúdo patrocinado


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