Sistema de Pet

    Compartilhe
    avatar
    Thales12
    Administrador
    Administrador

    Mensagens : 140
    Level : 8
    Data de inscrição : 01/11/2011
    Idade : 23
    Localização : Rio de Janeiro

    default Sistema de Pet

    Mensagem por Thales12 em Sex Fev 17, 2012 4:48 pm

    Olá, bem vindo ao meu tutorial sobre como criar um Basic Pet System. Quando este tutorial é longo, você deve ter criado uma base sólida Pet Sistema para trabalhar em outras, que também inclui algumas características-chave de qualquer sistema de animal de estimação. Antes de começar, certifique-se de ter o seguinte:

    Professional Visual Basic 6 / Enterprise
    Cliente / Servidor de Arquivos de Origem
    Conhecimento básico da utilização do IDE do VB6 e Linguagem
    Um cérebro

    Compatível com: Eclipse 2.0.0 Origens

    Mods Opcional:
    Abaixo estão as modificações outros usuários tenham criado para este sistema de estimação. É recomendado para a maioria dos mods que você siga esse mod primeiro tutorial, então vá e depois. Eu também tenho dado a classificação um tutorial estrelas (de cinco) e uma breve revisão. Por favor, não me PM para apoio a esses mods, eles não são criados por mim, e perguntas devem ser feitas aos criadores respectivos.

    No final deste tutorial, você deve ser capaz de usar um animal de estimação, talvez algo como isto:

    Demonstração 1:


    Demonstração 2:


    [size=18pt]~~Client~~[/size]

    Primeiro, vamos trabalhar sobre o código do cliente. Isto é principalmente o envio de comandos para o servidor para controlar o seu animal de estimação. Esses comandos incluem:

    Chamando o seu animal de estimação
    Atacar um alvo
    NPC simples sequência
    Deixando o seu animal passear ao redor do mapa
    Dissolução seu animal de estimação.


    Primeiro de tudo, você precisa trabalhar o seu caminho para modGameLogic.

    Vá até o final do módulo e colar esses cinco procedimentos:

    Código:

        Sub SpawnPet(ByVal Index As Long)
            Dim Buffer As clsBuffer
         
            Set Buffer = New clsBuffer
         
            Buffer.WriteLong CSpawnPet
         
            SendData Buffer.ToArray()
         
            Set Buffer = Nothing

        End Sub

        Sub PetFollow(ByVal Index As Long)
            Dim Buffer As clsBuffer
         
            Set Buffer = New clsBuffer
         
            Buffer.WriteLong CPetFollowOwner
         
            SendData Buffer.ToArray()
         
            Set Buffer = Nothing
        End Sub

        Sub PetAttack(ByVal Index As Long)
            Dim Buffer As clsBuffer
         
            Set Buffer = New clsBuffer
         
            Buffer.WriteLong CPetAttackTarget
         
            SendData Buffer.ToArray()
         
            Set Buffer = Nothing
        End Sub

        Sub PetWander(ByVal Index As Long)
            Dim Buffer As clsBuffer
         
            Set Buffer = New clsBuffer
         
            Buffer.WriteLong CPetWander
         
            SendData Buffer.ToArray()
         
            Set Buffer = Nothing
        End Sub

        Sub PetDisband(ByVal Index As Long)
            Dim Buffer As clsBuffer
         
            Set Buffer = New clsBuffer
         
            Buffer.WriteLong CPetDisband
         
            SendData Buffer.ToArray()
         
            Set Buffer = Nothing
        End Sub



    Estes procedimentos são os comandos para controlar o seu animal de estimação. Observe os nomes dos processos são nomeados de forma adequada para cada comando.

    Em seguida, você precisa abrir modEnumerations.
    Vá até o fundo do Enumerations do lado do cliente (Os que começam com um "C") e cole este CMSG_COUNT acima:

    Código:

        CSpawnPet
        CPetFollowOwner
        CPetAttackTarget
        CPetWander
        CPetDisband



    Em seguida, vá para modHandleData e substitua todo "Sub HandleSpawnNpc" por este:

    Código:

        Private Sub HandleSpawnNpc(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
        Dim n 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()
            n = Buffer.ReadLong

            With MapNpc(n)
                .Num = Buffer.ReadLong
                .x = Buffer.ReadLong
                .y = Buffer.ReadLong
                .Dir = Buffer.ReadLong
                .IsPet = Buffer.ReadByte
                .PetData.Name = Buffer.ReadString
                .PetData.Owner = Buffer.ReadLong
                ' Client use only
                .XOffset = 0
                .YOffset = 0
                .Moving = 0
            End With

            ' Error handler
            Exit Sub
        errorhandler:
            HandleError "HandleSpawnNpc", "modHandleData", Err.Number, Err.Description, Err.Source, Err.HelpContext
            Err.Clear
            Exit Sub
        End Sub



    Depois de ter feito isso, você precisará criar cinco botões ou etiquetas para acionar cada um dos comandos.

    Colocá-los no menu de opções, ou em qualquer outro menu que você deseja. Depois de ter criado eles, deve ser algo parecido com isto:



    Terá então a chamar cada um dos procedimentos anteriores para cada uma das suas respectivas funções. O parâmetro será necessário para passar para eles será "MyIndex" para cada um.

    Finalmente, você precisará adicionar o código abaixo para o final do "MapNpcRec" em modTypes:

    Código:

          'Pet Data
            IsPet As Byte
            PetData As PetRec



    Abaixo de "Dir As Byte" em PlayerRec, adicione isto(isso também em modTypes):

    Código:

        Pet As PetRec



    e adicionar esse tipo personalizado acima PlayerRec:

    Código:

        Public Type PetRec
            SpriteNum As Byte
            Name As String * 50
            Owner As Long
        End Type

    [size=18pt]~~Server~~[/size]

    Podemos agora passar para o código do lado do servidor mais complicada. O código do lado do servidor processa principalmente a desova e de que desova do animal de estimação, e manuseio de combate.


    Em primeiro lugar, você precisa abrir modEnumerations.
    Vá até o final do enumeration do lado do cliente (Os que começam com um "C") e cole este CMSG_COUNT acima:

    Código:

        CSpawnPet
        CPetFollowOwner
        CPetAttackTarget
        CPetWander
        CPetDisband



    Em seguida, passe para modHandleData e procure por "Public Sub InitMessages ()". Vá até o final do procedimento e acrescente:

    Código:

            'Pet System
            HandleDataSub(CSpawnPet) = GetAddress(AddressOf HandleSpawnPet)
            HandleDataSub(CPetFollowOwner) = GetAddress(AddressOf HandlePetFollowOwner)
            HandleDataSub(CPetAttackTarget) = GetAddress(AddressOf HandlePetAttackTarget)
            HandleDataSub(CPetWander) = GetAddress(AddressOf HandlePetWander)
            HandleDataSub(CPetDisband) = GetAddress(AddressOf HandlePetDisband)



    Estas cinco linhas chamará os respectivos procedimentos quando a Packet correta é recebida. Depois de ter colado estas linhas, vá até o final do modHandleData e adicione esses cinco procedimentos:

    Código:

        Public Sub HandleSpawnPet(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
            SpawnPet Index, GetPlayerMap(Index)
        End Sub

        Public Sub HandlePetFollowOwner(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
            Dim Buffer As clsBuffer
         
            PetFollowOwner Index
        End Sub

        Public Sub HandlePetAttackTarget(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
            Dim Buffer As clsBuffer
         
            If TempPlayer(Index).TempPetSlot < 1 Then Exit Sub
         
            MapNpc(GetPlayerMap(Index)).Npc(TempPlayer(Index).TempPetSlot).targetType = TempPlayer(Index).targetType
            MapNpc(GetPlayerMap(Index)).Npc(TempPlayer(Index).TempPetSlot).target = TempPlayer(Index).target
        End Sub

        Public Sub HandlePetWander(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
            Dim Buffer As clsBuffer
         
            PetWander Index
        End Sub

        Public Sub HandlePetDisband(ByVal Index As Long, ByRef Data() As Byte, ByVal StartAddr As Long, ByVal ExtraVar As Long)
            Dim Buffer As clsBuffer
         
            PetDisband Index, GetPlayerMap(Index)
            SendMap Index, GetPlayerMap(Index)
            PlayerWarp Index, GetPlayerMap(Index), GetPlayerX(Index), GetPlayerY(Index)
        End Sub



    Depois disso, vá para modGameLogic e adicione esses procedimentos para o final da questão:

    Código:

        'makes the pet follow its owner
        Sub PetFollowOwner(ByVal Index As Long)
            If TempPlayer(Index).TempPetSlot < 1 Then Exit Sub
         
            MapNpc(GetPlayerMap(Index)).Npc(TempPlayer(Index).TempPetSlot).targetType = 1
            MapNpc(GetPlayerMap(Index)).Npc(TempPlayer(Index).TempPetSlot).target = Index
        End Sub

        'makes the pet wander around the map
        Sub PetWander(ByVal Index As Long)
            If TempPlayer(Index).TempPetSlot < 1 Then Exit Sub

            MapNpc(GetPlayerMap(Index)).Npc(TempPlayer(Index).TempPetSlot).targetType = TARGET_TYPE_NONE
            MapNpc(GetPlayerMap(Index)).Npc(TempPlayer(Index).TempPetSlot).target = 0
        End Sub

        'Clear the npc from the map
        Sub PetDisband(ByVal Index As Long, ByVal MapNum As Long)
            If TempPlayer(Index).TempPetSlot < 1 Then Exit Sub
         
            Call ClearSingleMapNpc(TempPlayer(Index).TempPetSlot, MapNum)
            Map(GetPlayerMap(Index)).Npc(TempPlayer(Index).TempPetSlot) = 0
            TempPlayer(Index).TempPetSlot = 0
        End Sub

        Sub SpawnPet(ByVal Index As Long, ByVal MapNum As Long)
            Dim PlayerMap As Long
            Dim I As Integer
            Dim PetSlot As Byte
         
            'Prevent multiple pets for the same owner
            If TempPlayer(Index).TempPetSlot > 0 Then Exit Sub
         
            PlayerMap = GetPlayerMap(Index)
            PetSlot = 0
         
            For I = 1 To MAX_MAP_NPCS
                If Map(PlayerMap).Npc(I) = 0 Then
                    PetSlot = I
                    Exit For
                End If
            Next
         
            If PetSlot = 0 Then
                Call PlayerMsg(Index, "The map is too crowded for you to call on your pet!", Red)
                Exit Sub
            End If

            'create the pet for the map
            Map(PlayerMap).Npc(PetSlot) = #
            MapNpc(PlayerMap).Npc(PetSlot).Num = #
            'set its Pet Data
            MapNpc(PlayerMap).Npc(PetSlot).IsPet = YES
            MapNpc(PlayerMap).Npc(PetSlot).PetData.Name = GetPlayerName(Index) & "'s " & Npc(#).Name
            MapNpc(PlayerMap).Npc(PetSlot).PetData.Owner = Index
         
            'If Pet doesn't exist with player, link it to the player
            If Player(Index).Pet.SpriteNum <> # Then
                Player(Index).Pet.SpriteNum = #
                Player(Index).Pet.Name = GetPlayerName(Index) & "'s " & Npc(#).Name
            End If
         
            TempPlayer(Index).TempPetSlot = PetSlot
           
            'cache the map for sending
            Call MapCache_Create(PlayerMap)
         
            'send the update
            For I = 1 To Player_HighIndex
                If IsPlaying(I) Then
                    If GetPlayerMap(I) = GetPlayerMap(Index) Then
                        SendMap I, PlayerMap
                    End If
                End If
            Next

            Select Case GetPlayerDir(Index)
                Case DIR_UP
                    Call SpawnNpc(PetSlot, PlayerMap, GetPlayerX(Index), GetPlayerY(Index) - 1)
                Case DIR_DOWN
                    Call SpawnNpc(PetSlot, PlayerMap, GetPlayerX(Index), GetPlayerY(Index) + 1)
                Case DIR_LEFT
                    Call SpawnNpc(PetSlot, PlayerMap, GetPlayerX(Index) + 1, GetPlayerY(Index))
                Case DIR_RIGHT
                    Call SpawnNpc(PetSlot, PlayerMap, GetPlayerX(Index), GetPlayerY(Index) - 1)
            End Select
         
            're-warp the players on the map
            For I = 1 To Player_HighIndex
                If IsPlaying(I) Then
                    If GetPlayerMap(I) = GetPlayerMap(Index) Then
                        Call PlayerWarp(Index, PlayerMap, GetPlayerX(Index), GetPlayerY(Index))
                    End If
                End If
            Next
         
        End Sub



    Os nomes dos procedimentos de explicar claramente a sua função. O código também deve ser fácil de seguir. Substitua os hashes com seu número de NPC desejado.
    Também em modGameLogic, você precisará navegar no seu caminho para Sub SpawnNpc. Excluir este procedimento, e substituí-lo por isso:

    Código:

        Public Sub SpawnNpc(ByVal mapNpcNum As Long, ByVal MapNum As Long, Optional ByVal SetX As Long, Optional ByVal SetY As Long)
            Dim Buffer As clsBuffer
            Dim npcNum As Long
            Dim I As Long
            Dim x As Long
            Dim y As Long
            Dim Spawned As Boolean

            ' Check for subscript out of range
            If mapNpcNum <= 0 Or mapNpcNum > MAX_MAP_NPCS Or MapNum <= 0 Or MapNum > MAX_MAPS Then Exit Sub
            npcNum = Map(MapNum).Npc(mapNpcNum)

            If npcNum > 0 Then
         
                MapNpc(MapNum).Npc(mapNpcNum).Num = npcNum
                MapNpc(MapNum).Npc(mapNpcNum).target = 0
                MapNpc(MapNum).Npc(mapNpcNum).targetType = 0 ' clear
             
                MapNpc(MapNum).Npc(mapNpcNum).Vital(Vitals.HP) = GetNpcMaxVital(npcNum, Vitals.HP)
                MapNpc(MapNum).Npc(mapNpcNum).Vital(Vitals.MP) = GetNpcMaxVital(npcNum, Vitals.MP)
             
                MapNpc(MapNum).Npc(mapNpcNum).Dir = Int(Rnd * 4)
             
                'Check if theres a spawn tile for the specific npc
                For x = 0 To Map(MapNum).MaxX
                    For y = 0 To Map(MapNum).MaxY
                        If Map(MapNum).Tile(x, y).Type = TILE_TYPE_NPCSPAWN Then
                            If Map(MapNum).Tile(x, y).Data1 = mapNpcNum Then
                                MapNpc(MapNum).Npc(mapNpcNum).x = x
                                MapNpc(MapNum).Npc(mapNpcNum).y = y
                                MapNpc(MapNum).Npc(mapNpcNum).Dir = Map(MapNum).Tile(x, y).Data2
                                Spawned = True
                                Exit For
                            End If
                        End If
                    Next y
                Next x
             
                If Not Spawned Then
         
                    ' Well try 100 times to randomly place the sprite
                    For I = 1 To 100
                     
                        If SetX = 0 And SetY = 0 Then
                            x = Random(0, Map(MapNum).MaxX)
                            y = Random(0, Map(MapNum).MaxY)
                        Else
                            x = SetX
                            y = SetY
                        End If
         
                        If x > Map(MapNum).MaxX Then x = Map(MapNum).MaxX
                        If y > Map(MapNum).MaxY Then y = Map(MapNum).MaxY
         
                        ' Check if the tile is walkable
                        If NpcTileIsOpen(MapNum, x, y) Then
                            MapNpc(MapNum).Npc(mapNpcNum).x = x
                            MapNpc(MapNum).Npc(mapNpcNum).y = y
                            Spawned = True
                            Exit For
                        End If
         
                    Next
                 
                End If

                ' Didn't spawn, so now we'll just try to find a free tile
                If Not Spawned Then

                    For x = 0 To Map(MapNum).MaxX
                        For y = 0 To Map(MapNum).MaxY

                            If NpcTileIsOpen(MapNum, x, y) Then
                                MapNpc(MapNum).Npc(mapNpcNum).x = x
                                MapNpc(MapNum).Npc(mapNpcNum).y = y
                                Spawned = True
                            End If

                        Next
                    Next

                End If

                ' If we suceeded in spawning then send it to everyone
                If Spawned Then
                    Set Buffer = New clsBuffer
                    Buffer.WriteLong SSpawnNpc
                    Buffer.WriteLong mapNpcNum
                    Buffer.WriteLong MapNpc(MapNum).Npc(mapNpcNum).Num
                    Buffer.WriteLong MapNpc(MapNum).Npc(mapNpcNum).x
                    Buffer.WriteLong MapNpc(MapNum).Npc(mapNpcNum).y
                    Buffer.WriteLong MapNpc(MapNum).Npc(mapNpcNum).Dir
                    Buffer.WriteByte MapNpc(MapNum).Npc(mapNpcNum).IsPet
                    Buffer.WriteString MapNpc(MapNum).Npc(mapNpcNum).PetData.Name
                    Buffer.WriteLong MapNpc(MapNum).Npc(mapNpcNum).PetData.Owner
                    SendDataToMap MapNum, Buffer.ToArray()
                    Set Buffer = Nothing
                End If
             
                SendMapNpcVitals MapNum, mapNpcNum
            End If

        End Sub

    Outro parâmetro para esse procedimento poderia ser facilmente adicionados para vários números NPC, desencadeadas pelo uso de um item.

    Agora, vá para modCombat. Adicione estes procedimentos para o final do módulo. São TryNpcAttackNpc e CanNpcAttackNpc. Estes são, basicamente, rasgado de uma versão antiga do óxido de etileno com algumas modificações, por mim, por isso os créditos vão para Robin para eles. Eles são usados ??neste tutorial para combater o NPC Pet vs Outros.

    Código:

        Function CanNpcAttackNpc(ByVal MapNum As Long, ByVal Attacker As Long, ByVal Victim As Long) As Boolean
            Dim aNpcNum As Long
            Dim vNpcNum As Long
            Dim VictimX As Long
            Dim VictimY As Long
            Dim AttackerX As Long
            Dim AttackerY As Long
         
            CanNpcAttackNpc = False

            ' Check for subscript out of range
            If Attacker <= 0 Or Attacker > MAX_MAP_NPCS Then
                Exit Function
            End If
         
            If Victim <= 0 Or Victim > MAX_MAP_NPCS Then
                Exit Function
            End If

            ' Check for subscript out of range
            If MapNpc(MapNum).Npc(Attacker).Num <= 0 Then
                Exit Function
            End If
         
            ' Check for subscript out of range
            If MapNpc(MapNum).Npc(Victim).Num <= 0 Then
                Exit Function
            End If

            aNpcNum = MapNpc(MapNum).Npc(Attacker).Num
            vNpcNum = MapNpc(MapNum).Npc(Victim).Num
         
            If aNpcNum <= 0 Then Exit Function
            If vNpcNum <= 0 Then Exit Function

            ' Make sure the npcs arent already dead
            If MapNpc(MapNum).Npc(Attacker).Vital(Vitals.HP) <= 0 Then
                Exit Function
            End If
         
            ' Make sure the npc isn't already dead
            If MapNpc(MapNum).Npc(Victim).Vital(Vitals.HP) <= 0 Then
                Exit Function
            End If

            ' Make sure npcs dont attack more then once a second
            If GetTickCount < MapNpc(MapNum).Npc(Attacker).AttackTimer + 1000 Then
                Exit Function
            End If
         
            MapNpc(MapNum).Npc(Attacker).AttackTimer = GetTickCount
         
            AttackerX = MapNpc(MapNum).Npc(Attacker).x
            AttackerY = MapNpc(MapNum).Npc(Attacker).y
            VictimX = MapNpc(MapNum).Npc(Victim).x
            VictimY = MapNpc(MapNum).Npc(Victim).y

            ' Check if at same coordinates
            If (VictimY + 1 = AttackerY) And (VictimX = AttackerX) Then
                CanNpcAttackNpc = True
            Else

                If (VictimY - 1 = AttackerY) And (VictimX = AttackerX) Then
                    CanNpcAttackNpc = True
                Else

                    If (VictimY = AttackerY) And (VictimX + 1 = AttackerX) Then
                        CanNpcAttackNpc = True
                    Else

                        If (VictimY = AttackerY) And (VictimX - 1 = AttackerX) Then
                            CanNpcAttackNpc = True
                        End If
                    End If
                End If
            End If

        End Function

        Sub NpcAttackNpc(ByVal MapNum As Long, ByVal Attacker As Long, ByVal Victim As Long, ByVal Damage As Long)
            Dim i As Long
            Dim Buffer As clsBuffer
            Dim aNpcNum As Long
            Dim vNpcNum As Long
            Dim n As Long
            Dim PetOwner As Long
         
            If Attacker <= 0 Or Attacker > MAX_MAP_NPCS Then Exit Sub
            If Victim <= 0 Or Victim > MAX_MAP_NPCS Then Exit Sub
         
            If Damage <= 0 Then Exit Sub
         
            aNpcNum = MapNpc(MapNum).Npc(Attacker).Num
            vNpcNum = MapNpc(MapNum).Npc(Victim).Num
         
            If aNpcNum <= 0 Then Exit Sub
            If vNpcNum <= 0 Then Exit Sub
         
            'set the victim's target to the pet attacking it
            MapNpc(MapNum).Npc(Victim).targetType = 2 'Npc
            MapNpc(MapNum).Npc(Victim).target = Attacker
         
            ' Send this packet so they can see the person attacking
            Set Buffer = New clsBuffer
            Buffer.WriteLong SNpcAttack
            Buffer.WriteLong Attacker
            SendDataToMap MapNum, Buffer.ToArray()
            Set Buffer = Nothing

            If Damage >= MapNpc(MapNum).Npc(Victim).Vital(Vitals.HP) Then
                SendActionMsg MapNum, "-" & Damage, BrightRed, 1, (MapNpc(MapNum).Npc(Victim).x * 32), (MapNpc(MapNum).Npc(Victim).y * 32)
                SendBlood MapNum, MapNpc(MapNum).Npc(Victim).x, MapNpc(MapNum).Npc(Victim).y
             
                ' npc is dead.
                'Call GlobalMsg(CheckGrammar(Trim$(Npc(vNpcNum).Name), 1) & " has been killed by " & CheckGrammar(Trim$(Npc(aNpcNum).Name)) & "!", BrightRed)

                ' Set NPC target to 0
                MapNpc(MapNum).Npc(Attacker).target = 0
                MapNpc(MapNum).Npc(Attacker).targetType = 0
                'reset the targetter for the player
             
                If MapNpc(MapNum).Npc(Attacker).IsPet = YES Then
                    TempPlayer(MapNpc(MapNum).Npc(Attacker).PetData.Owner).target = 0
                    TempPlayer(MapNpc(MapNum).Npc(Attacker).PetData.Owner).targetType = TARGET_TYPE_NONE
                 
                    PetOwner = MapNpc(MapNum).Npc(Attacker).PetData.Owner
                 
                    SendTarget PetOwner
                 
                    'Give the player the pet owner some experience from the kill
                    Call SetPlayerExp(PetOwner, GetPlayerExp(PetOwner) + Npc(MapNpc(MapNum).Npc(Victim).Num).Exp)
                    CheckPlayerLevelUp PetOwner
                    SendActionMsg MapNum, "+" & Npc(MapNpc(MapNum).Npc(Victim).Num).Exp & "Exp", White, 1, GetPlayerX(PetOwner) * 32, GetPlayerY(PetOwner) * 32
                    SendEXP PetOwner
                           
                ElseIf MapNpc(MapNum).Npc(Victim).IsPet = YES Then
                    'Get the pet owners' index
                    PetOwner = MapNpc(MapNum).Npc(Victim).PetData.Owner
                    'Set the NPC's target on the owner now
                    MapNpc(MapNum).Npc(Attacker).targetType = 1 'player
                    MapNpc(MapNum).Npc(Attacker).target = PetOwner
                    'Disband the pet
                    PetDisband PetOwner, GetPlayerMap(PetOwner)
                End If
                   
                ' Drop the goods if they get it
                'For n = 1 To MAX_NPC_DROPS
                If Npc(vNpcNum).DropItem <> 0 Then
                    If Rnd <= Npc(vNpcNum).DropChance Then
                        Call SpawnItem(Npc(vNpcNum).DropItem, Npc(vNpcNum).DropItemValue, MapNum, MapNpc(MapNum).Npc(Victim).x, MapNpc(MapNum).Npc(Victim).y)
                    End If
                End If
                'Next
             
             
                ' Reset victim's stuff so it dies in loop
                MapNpc(MapNum).Npc(Victim).Num = 0
                MapNpc(MapNum).Npc(Victim).SpawnWait = GetTickCount
                MapNpc(MapNum).Npc(Victim).Vital(Vitals.HP) = 0
                   
                ' send npc death packet to map
                Set Buffer = New clsBuffer
                Buffer.WriteLong SNpcDead
                Buffer.WriteLong Victim
                SendDataToMap MapNum, Buffer.ToArray()
                Set Buffer = Nothing
             
                If PetOwner > 0 Then
                    PetFollowOwner PetOwner
                End If
            Else
                ' npc not dead, just do the damage
                MapNpc(MapNum).Npc(Victim).Vital(Vitals.HP) = MapNpc(MapNum).Npc(Victim).Vital(Vitals.HP) - Damage
           
                ' Say damage
                SendActionMsg MapNum, "-" & Damage, BrightRed, 1, (MapNpc(MapNum).Npc(Victim).x * 32), (MapNpc(MapNum).Npc(Victim).y * 32)
                SendBlood MapNum, MapNpc(MapNum).Npc(Victim).x, MapNpc(MapNum).Npc(Victim).y
            End If
         
            'Send both Npc's Vitals to the client
            SendMapNpcVitals MapNum, Attacker
            SendMapNpcVitals MapNum, Victim

        End Sub



    Também em modCombat, localize a função: "CanNpcAttackPlayer". Debaixo dos controlos principais: Acrescente este:

    Código:

        'check if the NPC attacking us is actually our pet.
        'We don't want a rebellion on our hands now do we?
             
        If MapNpc(MapNum).Npc(mapNpcNum).PetData.Owner = Index Then Exit Function



    Isto impede o animal de estimação atacar seu próprio dono. > _ <


    Em seguida, procure por "Sub closesocket". Substitua o actual procedimento com este:

    Código:

        Sub CloseSocket(ByVal Index As Long)
        Dim I As Integer

            If Index > 0 Then
                If TempPlayer(Index).TempPetSlot > 0 Then
                    Call PetDisband(Index, GetPlayerMap(Index))
                    For I = 1 To Player_HighIndex
                        If GetPlayerMap(I) = GetPlayerMap(Index) Then
                            SendMap I, GetPlayerMap(Index)
                        End If
                    Next
                End If
             
                Call LeftGame(Index)
                Call TextAdd("Connection from " & GetPlayerIP(Index) & " has been terminated.")
                frmServer.Socket(Index).Close
                Call UpdateCaption
                Call ClearPlayer(Index)
            End If

        End Sub



    A modificação aqui desfaz um animal de estimação se o seu dono fizer fora.
    Depois disso, procure por "This is used for npcs to attack targets". Isto irá levá-lo em modServerLoop> UpdateMapLogic.

    Nessa seção, até "This is used to regenerate HP NPCs", substitua esse código por o seguinte:

    Código:

        If Map(MapNum).Npc(x) > 0 And MapNpc(MapNum).Npc(x).Num > 0 Then
                            target = MapNpc(MapNum).Npc(x).target
                            targetType = MapNpc(MapNum).Npc(x).targetType

                            ' Check if the npc can attack the targeted player player
                            If target > 0 Then
                         
                                If targetType = 1 Then ' player

                                    ' Is the target playing and on the same map?
                                    If IsPlaying(target) And GetPlayerMap(target) = MapNum Then
                                        TryNpcAttackPlayer x, target
                                    Else
                                        ' Player left map or game, set target to 0
                                        MapNpc(MapNum).Npc(x).target = 0
                                        MapNpc(MapNum).Npc(x).targetType = 0 ' clear
                                    End If
                                ElseIf targetType = 2 Then
                                    ' lol no npc combat :( DATS WAT YOU THINK
                                    If CanNpcAttackNpc(MapNum, x, MapNpc(MapNum).Npc(x).target) = True Then
                                        Call NpcAttackNpc(MapNum, x, MapNpc(MapNum).Npc(x).target, Npc(Map(MapNum).Npc(x)).Damage)
                                    End If
                                Else
                             
                                End If
                            End If
                        End If



    A modificação que eu fiz aqui, basicamente, trata da luta contra o NPC NPC para o seu animal de estimação, mencionado anteriormente.

    Depois, vá para modDatabase e acrescente o seguinte:

    Código:

        Sub ClearSingleMapNpc(ByVal index As Long, ByVal MapNum As Long)
            Call ZeroMemory(ByVal VarPtr(MapNpc(MapNum).Npc(index)), LenB(MapNpc(MapNum).Npc(index)))
            Map(MapNum).Npc(index) = 0
            MapNpc(MapNum).Npc(index).Num = 0
            MapCache_Create (MapNum)
        End Sub



    Isso ajuda para eliminar um npc única a partir de um mapa, se em caso de morte ou demissão.


    Em seguida, passe para modPlayer e encontre o procedimento chamado "PlayerWarp". Substitua esse procedimento com esta versão modded:

    Código:

        Sub PlayerWarp(ByVal Index As Long, ByVal MapNum As Long, ByVal x As Long, ByVal y As Long)
            Dim shopNum As Long
            Dim OldMap As Long
            Dim I As Long
            Dim Buffer As clsBuffer

            ' Check for subscript out of range
            If IsPlaying(Index) = False Or MapNum <= 0 Or MapNum > MAX_MAPS Then
                Exit Sub
            End If

            ' Check if you are out of bounds
            If x > Map(MapNum).MaxX Then x = Map(MapNum).MaxX
            If y > Map(MapNum).MaxY Then y = Map(MapNum).MaxY
            If x < 0 Then x = 0
            If y < 0 Then y = 0
         
            ' if same map then just send their co-ordinates
            If MapNum = GetPlayerMap(Index) Then
                SendPlayerXYToMap Index
            End If
         
            ' clear target
            TempPlayer(Index).target = 0
            TempPlayer(Index).targetType = TARGET_TYPE_NONE
            SendTarget Index

            ' Save old map to send erase player data to
            OldMap = GetPlayerMap(Index)

            If OldMap <> MapNum Then
                Call SendLeaveMap(Index, OldMap)
            End If

            Call SetPlayerMap(Index, MapNum)
            Call SetPlayerX(Index, x)
            Call SetPlayerY(Index, y)
         
            'If 'refreshing' map
            If (OldMap <> MapNum) And TempPlayer(Index).TempPetSlot > 0 Then
                'switch maps
              PetDisband Index, OldMap
                SpawnPet Index, MapNum
                PetFollowOwner Index
            End If
         
            ' send player's equipment to new map
            SendMapEquipment Index
         
            ' send equipment of all people on new map
            If GetTotalMapPlayers(MapNum) > 0 Then
                For I = 1 To Player_HighIndex
                    If IsPlaying(I) Then
                        If GetPlayerMap(I) = MapNum Then
                            SendMapEquipmentTo I, Index
                        End If
                    End If
                Next
            End If

            ' 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

            ' Sets it so we know to process npcs on the map
            PlayersOnMap(MapNum) = YES
            TempPlayer(Index).GettingMap = YES
            Set Buffer = New clsBuffer
            Buffer.WriteLong SCheckForMap
            Buffer.WriteLong MapNum
            Buffer.WriteLong Map(MapNum).Revision
            SendDataTo Index, Buffer.ToArray()
            Set Buffer = Nothing
        End Sub



    A modificação aqui meramente de-desova o animal de estimação a partir do mapa antigo e gera-lo para o novo.

    Finalmente, vá para modTypes e modifique esses pedaços de código. Adicione PetRec acima PlayerRec:

    Código:

        Public Type PetRec
            SpriteNum As Byte
            Name As String * 50
            Owner As Long
        End Type



    Adicione esta no final do PlayerRec:

    Código:

        Pet As PetRec



    Adicione esta no final do TempPlayerRec:

    Código:

        TempPetSlot As Byte



    Finalmente, adicione-o no final do MapNpcRec:

    Código:

        'Pet Data
            IsPet As Byte
            PetData As PetRec



    [size=18pt]Então MMORPGBR esse é o fim do Tutorial de Pet para EO.[/size]

    Créditos:
    Lightning - Criador do sistema em inglês
    Lucas Roberto - Tradutor
    Surface - Correção dos erros

      Data/hora atual: Seg Dez 17, 2018 8:13 am