Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[EO] Lightning's Pet System [Completely Bug-Free!]


Yxxe
 Share

Recommended Posts

  • Replies 304
  • Created
  • Last Reply

Top Posters In This Topic

just implemented this system just then… i noticed there are a few issues with combat etc.

+ Pets Dmg doesnt affect the npc's health bar
+ Npc's do not attack pets back
+ Pet slots in mapnpc slots

thats what ive noticed so far im going to fiddle around with it and fix it up to my liking i will prob be making a new NPC_TYPE_PET or something and maybe changing to pet slots depends what time i have

any other issues anyone has noticed?
Link to comment
Share on other sites

@peekay:

> just implemented this system just then… i noticed there are a few issues with combat etc.
>
> + Pets Dmg doesnt affect the npc's health bar
> + Npc's do not attack pets back
> + Pet slots in mapnpc slots
>
> thats what ive noticed so far im going to fiddle around with it and fix it up to my liking i will prob be making a new NPC_TYPE_PET or something and maybe changing to pet slots depends what time i have
>
> any other issues anyone has noticed?

Thanks for bringing those errors up. For npcs attacking, you will just need to add 2 lines to set the enemies targetting. I`ll also fix the health bars later, once I get back from work.
Link to comment
Share on other sites

ive just finished spawning pets by items, using a npc selecting scroll bar in item editor ill release it as a tutorial as well as a spell spawn when i get it done

hope u dont mind me branching tut's off ur base lightning ?
Link to comment
Share on other sites

@peekay:

> ive just finished spawning pets by items, using a npc selecting scroll bar in item editor ill release it as a tutorial as well as a spell spawn when i get it done
>
> hope u dont mind me branching tut's off ur base lightning ?

Thats what the base is for. Just make sure that you give me credit for the base and link back to this tutorial. Also dont post any fixes in you tut for this system, I can do that myself. ;-) Once I get back from work i'll add a mod list to the main post.

Thanks for asking. :-D
Link to comment
Share on other sites

ok well ill let you know of any bugs in your base so u can fix them in your tut any mods ill be posting linking back to your base :)

well i finished my firs tut and i went to post and some error occured and i lost it all >_> sigh
Link to comment
Share on other sites

Fixed code, thanks peekay.

Sub NpcAttackNpc:

```
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
        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
        ' 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

        '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", Green, 1, GetPlayerX(PetOwner) * 32, GetPlayerY(PetOwner) * 32
        SendEXP PetOwner

        ' 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

        PetFollowOwner PetOwner
    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
```
HandlePetAttackTarget:

```
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
```

Npc's now both attack each other, HP bars updated, and click events fixed.

EDIT: Also added Optional Mods of this Pet System to the main post.
Link to comment
Share on other sites

no problem if i find anything else ill let you know

i got spawn pets working from items and spells also have a mini pet bar, im goin to be working on pet spells etc this week when i get a chance and get some mod tuts happening
Link to comment
Share on other sites

@peekay:

> no problem if i find anything else ill let you know
>
> i got spawn pets working from items and spells also have a mini pet bar, im goin to be working on pet spells etc this week when i get a chance and get some mod tuts happening

Don't do too much, hah! ;) You might want to leave some for yourself! :P
Link to comment
Share on other sites

@Helladen:

> Saving npcs to the map, you need to alter it. It has a lot of problems such as limiting the amounts of pets per map and if they force close the client or server they remain saved to the map.

Hah, I saw that in the other thread, I removed it about 20 minutes ago. It shouldn't result in any problems now, I will just have to check it with multiple players logging in at different times tomorrow, but seeing as most of it is cached there shouldn't be any problems. :P
Link to comment
Share on other sites

@Helladen:

> Alright that's good. I personally have no idea how to fix it myself. I tried a lot of different things so hopefully it's fixed in the new release. :)

All that needs to be removed it one line in Sub SpawnNPC: "SaveMap PlayerMap". :P I tried it out myself and no errors cropped up when exiting and re-entering a game. I restarted the server and the Pet wasn't there, so all is good. ^^
Link to comment
Share on other sites

@RyokuHasu:

> Thank you =D i was filling up my map with test char pets XD lol
>
> And please let me know if you change any thing in the sub spawnpet i tell people to rewrite, i don't want to undermine your work and progress =P

No problem. ;) Just check back here every so often and check the last few posts I have done, there will usually be a post with a fix of some sort in. If you are uncertain, send me a PM, but bear in mind I don't want to be bombarded with PM's. xD
Link to comment
Share on other sites

D= ERROR:

when the pet DIED it had an out of range error happened and tyhe server crashed… ill find the location in debug mode for you =X

In modcombat  in Sub NpcAttackNpc

Error:
```
TempPlayer(MapNpc(MapNum).Npc(attacker).PetData.Owner).target = 0

```
when your Pet dies

upon a closer look i see there is only setting for if the Pet make the kill, and not if it GETS KILLED… =X however i have no ability to fix this....

maby somthing along the lines of

if target = pet then
set of commands for an NPC win
end if
else
if target = NPC then
set of commands for a Pet win
end if

T_T but this is just an outline i have no idea how to make yet =X
Link to comment
Share on other sites

Sorry for tripple post but….

I FIXED IT =D your pet will now die ... and not cause error

basicly i made it check if the victim had an owner, if it did, its a pet, if it has no owner its a Regular NPC

i just took the victim commands from Player attacking NPC and addapted them to the "if-then-else" i made

and i added the loop remove target from all others for pet and NPC for mor complex battle conditions... i hope i helped... =D

* * *

Replace Sub NpcAttackNpc with:

```
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
              'Check if the Attacker has an owner, if it dose its a pet
              If MapNpc(MapNum).Npc(attacker).PetData.Owner <> 0 Then

                    'If the NPC died, follow this
                      MapNpc(MapNum).Npc(attacker).target = 0
                      MapNpc(MapNum).Npc(attacker).targetType = 0
                      'reset the targetter for the player
                      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
                      ' 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
                      '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", Green, 1, GetPlayerX(PetOwner) * 32, GetPlayerY(PetOwner) * 32
                      SendEXP PetOwner
                        ' 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

                      'Loop through entire map and purge NPC from targets
            For i = 1 To Player_HighIndex
                If IsPlaying(i) And IsConnected(i) Then
                    If Player(i).Map = MapNum Then
                        If TempPlayer(i).targetType = TARGET_TYPE_NPC Then
                            If TempPlayer(i).target = Victim Then
                                TempPlayer(i).target = 0
                                TempPlayer(i).targetType = TARGET_TYPE_NONE
                                SendTarget i
                            End If
                        End If
                    End If
                End If
            Next

            ' send npc death packet to map
                  Set Buffer = New clsBuffer
                  Buffer.WriteLong SNpcDead
                  Buffer.WriteLong Victim
                  SendDataToMap MapNum, Buffer.ToArray()
                  Set Buffer = Nothing
                  PetFollowOwner PetOwner

                  Else
                  'If the Pet died Follow this
                  MapNpc(MapNum).Npc(Victim).Num = 0

                ' send death to the map
                  Set Buffer = New clsBuffer
                  Buffer.WriteLong SNpcDead
                  Buffer.WriteLong Victim
                SendDataToMap MapNum, Buffer.ToArray()
                Set Buffer = Nothing

              'Loop through entire map and purge NPC from targets
                For i = 1 To Player_HighIndex
                    If IsPlaying(i) And IsConnected(i) Then
                        If Player(i).Map = MapNum Then
                            If TempPlayer(i).targetType = TARGET_TYPE_NPC Then
                              If TempPlayer(i).target = Victim Then
                                  TempPlayer(i).target = 0
                                  TempPlayer(i).targetType = TARGET_TYPE_NONE
                                  SendTarget i
                              End If
                            End If
                        End If
                      End If
              Next
            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

```
Link to comment
Share on other sites

@peekay:

> some more bugs
>
> - when ur pet dies it doesnt despawn
>
> - when u warp maps pet does not get respawned

I'll check there bugs out later, although they weren't present when I released the tutorial. Did you use Ryokos Mod? If so that one doesn't have the ability to change maps. :'( I'll also go and fix set deaths.
Link to comment
Share on other sites

New fixes:

Sub NpcAttackNpc:

```
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
            PetOwner = MapNpc(MapNum).Npc(Victim).PetData.Owner
            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
```
Sub ClearSingleMapNpc:

```
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
```
That should be pretty much it. All the data is cached, the map saving has been removed and the NPC combat fixed (it will work as it has been taken directly out of my own game's source code). Warping worked anyway, and has been made completely bug-free with the updated ClearSingleMapNpc.
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share


×
×
  • Create New...