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

NPC Targetting & Movement


SeeingBlue
 Share

Recommended Posts

I've recently arrived to the point where it's time to tweak my PvE mechanics. First thing I noticed about the creatures behavior is they don't stand still around you in the diagonal positions. The North, South, East, & West position are fine, creatures will crowd into those positions, but not the NE, NW, or SE, SW position.. Any idea why?

Also has anyone worked on a better path finding system for the NCPs?
Link to comment
Share on other sites

What do you mean by, they crowd to N E S W but not the other ones?
Npc movement is random. They try to walk, if they couldn't they're forced to try all 4 directions.
To find to the npc is almost the same. They just shrink the x & y positions to your character. if it doesn't work, they try another way. So normally they shouldn't stop at a tree or something.
Link to comment
Share on other sites

I mean, you have 8 squares around your character. NPCs will attack you from 4 of those squares. The Top, bottom, left & right squares, but not from the diagonal squares. They will move into those squares & maybe even hit you, I'm not sure, but they won't stay there.

Also the issue I have with the pathfinding is 1, it's slow & the NPCs look clumsy & 2, If the NPC has to walk 2 squares in another direction to get un-stuck, forget it, won't happen…
Link to comment
Share on other sites

Why should the npc attack you from a position, where you can't attack back?
If you want to do that you have to check where the position is check. Because it check if the positions N E S W.
(x+1 / y) (x-1 / y) (x / y+1) (x / y-1)

The other thing is. You could write a better pathfinding by yourself i think.
How would you do this?
Draw a coordinate system. Draw 2 Points. Draw some hurdes. And look how would you go through it and how you could say this to a pc.
Link to comment
Share on other sites

I put blocks around me in the + position & the creature still attacked & damaged me, but they won't stay in the Diagonal position.

72jYRe_btuw

Btw Kamii, My attacks aren't direction based, they are only distance based. As long as I have a target & they are within 1sq away, they can be attacked in any direction.
Link to comment
Share on other sites

You have to use 720 & full screen to see any real detail.

How is that different from the NPC that are in the N,S,E,W positions? Do they have that check & I'm just looking over it?

Thanks for your help. I'm comb through the code more carefully & see if I can find what is different.
Link to comment
Share on other sites

Well i personally optimised my code for myself so it doesn't look like original EO..
But Basicly, the Npcs trys to get X & Y difference to 0 1 or 1 0 (because 0 0 doesn't work).
So i think you have to check extra if they're 1 1 because this is legal too for you.
Link to comment
Share on other sites

I'm not able to see where my problem is. I even have the source printed out & I've been marking on it, trying to break it down so I can understand what's going on, but I'm not able to figure out what makes the difference in an NPC standing N, S, E, or W.  from an NPC standing diagonal from you.

As far as I know, all my distance checks include <= 1 so that it should be ok, but I just can't find what continues to make them walk when standing 1sq diagonal.
Link to comment
Share on other sites

Here is everything that should be related.

```
Public Sub TryNpcAttackPlayer(ByVal mapNpcNum As Long, ByVal index As Long)
Dim mapNum As Long, npcNum As Long, blockAmount As Long, Damage As Long

    ' Can the npc attack the player?
    If CanNpcAttackPlayer(mapNpcNum, index) Then
        mapNum = GetPlayerMap(index)
        npcNum = MapNpc(mapNum).Npc(mapNpcNum).Num

        ' check if PLAYER can avoid the attack
        If CanPlayerDodge(index) Then
            SendActionMsg mapNum, "Dodge!", Pink, 1, (Player(index).x * 32), (Player(index).y * 32)
            Exit Sub
        End If
        If CanPlayerParry(index) Then
            SendActionMsg mapNum, "Parry!", Pink, 1, (Player(index).x * 32), (Player(index).y * 32)
            Exit Sub
        End If

        ' Get the damage we can do
        Damage = GetNpcDamage(npcNum)

        ' if the player blocks, take away the block amount
        blockAmount = CanPlayerBlock(index)
        Damage = Damage - blockAmount

        ' take away armour
        Damage = Damage - RAND(1, (GetPlayerStat(index, Agility) * 2))

        ' randomise for up to 10% lower than max hit
        Damage = RAND(1, Damage)

        ' * 1.5 if crit hit
        If CanNpcCrit(index) Then
            Damage = Damage * 1.5
            SendActionMsg mapNum, "Critical!", BrightCyan, 1, (MapNpc(mapNum).Npc(mapNpcNum).x * 32), (MapNpc(mapNum).Npc(mapNpcNum).y * 32)
        End If

        If Damage > 0 Then
            Call NpcAttackPlayer(mapNpcNum, index, Damage)
        End If
    End If
End Sub

```
```
Function CanNpcAttackPlayer(ByVal mapNpcNum As Long, ByVal index As Long) As Boolean
    Dim mapNum, npcNum, DistanceX, DistanceY As Long

    ' Check for subscript out of range
    If mapNpcNum <= 0 Or mapNpcNum > MAX_MAP_NPCS Or Not IsPlaying(index) Then
        Exit Function
    End If

    ' Check for subscript out of range
    If MapNpc(GetPlayerMap(index)).Npc(mapNpcNum).Num <= 0 Then
        Exit Function
    End If

    mapNum = GetPlayerMap(index)
    npcNum = MapNpc(mapNum).Npc(mapNpcNum).Num

    ' Make sure the npc isn't already dead
    If MapNpc(mapNum).Npc(mapNpcNum).Vital(Vitals.HP) <= 0 Then
        Exit Function
    End If

    ' Make sure npcs dont attack more then once a second
    If GetTickCount < MapNpc(mapNum).Npc(mapNpcNum).AttackTimer + Npc(npcNum).Speed Then
        Exit Function
    End If

    ' Make sure we dont attack the player if they are switching maps
    If TempPlayer(index).GettingMap = YES Then
        Exit Function
    End If

    MapNpc(mapNum).Npc(mapNpcNum).AttackTimer = GetTickCount

    ' Make sure they are on the same map
    If IsPlaying(index) Then
        If npcNum > 0 Then
            DistanceX = MapNpc(mapNum).Npc(mapNpcNum).x - GetPlayerX(index)
            DistanceY = MapNpc(mapNum).Npc(mapNpcNum).y - GetPlayerY(index)
            If DistanceX < 0 Then DistanceX = DistanceX * -1
            If DistanceY < 0 Then DistanceY = DistanceY * -1
            ' Check if at same coordinates
            If DistanceX <= 1 And DistanceY <= 1 Then
                CanNpcAttackPlayer = True
            ElseIf DistanceX > 17 Or DistanceY > 14 Then
                MapNpc(mapNum).Npc(mapNpcNum).target = 0
                MapNpc(mapNum).Npc(mapNpcNum).targetType = 0
            End If
        End If
    End If
End Function

```
```
Sub NpcAttackPlayer(ByVal mapNpcNum As Long, ByVal victim As Long, ByVal Damage As Long)
    Dim Name As String
    Dim exp As Long
    Dim mapNum As Long
    Dim i As Long
    Dim Buffer As clsBuffer

    ' 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

    mapNum = GetPlayerMap(victim)
    Name = Trim$(Npc(MapNpc(mapNum).Npc(mapNpcNum).Num).Name)

    ' Send this packet so they can see the npc attacking
    Set Buffer = New clsBuffer
    Buffer.WriteLong SNpcAttack
    Buffer.WriteLong mapNpcNum
    SendDataToMap mapNum, Buffer.ToArray()
    Set Buffer = Nothing

    If Damage <= 0 Then
        Exit Sub
    End If

    ' set the regen timer
    MapNpc(mapNum).Npc(mapNpcNum).stopRegen = True
    MapNpc(mapNum).Npc(mapNpcNum).stopRegenTimer = GetTickCount

    If Damage >= GetPlayerVital(victim, Vitals.HP) Then
        ' Say damage
        SendActionMsg GetPlayerMap(victim), "-" & GetPlayerVital(victim, Vitals.HP), BrightRed, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)

        ' send the sound
        SendMapSound victim, GetPlayerX(victim), GetPlayerY(victim), SoundEntity.seNpc, MapNpc(mapNum).Npc(mapNpcNum).Num

        ' kill player
        KillPlayer victim

        ' Player is dead
        Call GlobalMsg(GetPlayerName(victim) & " has been killed by " & Name, BrightRed)

        ' Set NPC target to 0
        MapNpc(mapNum).Npc(mapNpcNum).target = 0
        MapNpc(mapNum).Npc(mapNpcNum).targetType = 0
    Else
        ' Player not dead, just do the damage
        Call SetPlayerVital(victim, Vitals.HP, GetPlayerVital(victim, Vitals.HP) - Damage)
        Call SendVital(victim, Vitals.HP)
        Call SendAnimation(mapNum, Npc(MapNpc(GetPlayerMap(victim)).Npc(mapNpcNum).Num).Animation, 0, 0, TARGET_TYPE_PLAYER, victim)

        ' send vitals to party if in one
        If TempPlayer(victim).inParty > 0 Then SendPartyVitals TempPlayer(victim).inParty, victim

        ' send the sound
        SendMapSound victim, GetPlayerX(victim), GetPlayerY(victim), SoundEntity.seNpc, MapNpc(mapNum).Npc(mapNpcNum).Num

        ' Say damage
        SendActionMsg GetPlayerMap(victim), "-" & Damage, BrightRed, 1, (GetPlayerX(victim) * 32), (GetPlayerY(victim) * 32)
        SendBlood GetPlayerMap(victim), GetPlayerX(victim), GetPlayerY(victim)

        ' set the regen timer
        TempPlayer(victim).stopRegen = True
        TempPlayer(victim).stopRegenTimer = GetTickCount
    End If

End Sub

```
UpdateMapLogic won't fit.

```
                ' /////////////////////////////////////////////
                ' // This is used for NPC walking/targetting //
                ' /////////////////////////////////////////////
                ' Make sure theres a npc with the map
                If Map(mapNum).Npc(x) > 0 And MapNpc(mapNum).Npc(x).Num > 0 Then
                    If MapNpc(mapNum).Npc(x).StunDuration > 0 Then
                        ' check if we can unstun them
                        If GetTickCount > MapNpc(mapNum).Npc(x).StunTimer + (MapNpc(mapNum).Npc(x).StunDuration * 1000) Then
                            MapNpc(mapNum).Npc(x).StunDuration = 0
                            MapNpc(mapNum).Npc(x).StunTimer = 0
                        End If
                    Else

                        target = MapNpc(mapNum).Npc(x).target
                        targetType = MapNpc(mapNum).Npc(x).targetType

                        ' Check to see if its time for the npc to walk
                        'If Npc(npcNum).Behaviour <> NPC_BEHAVIOUR_SHOPKEEPER Then

                            If targetType = 1 Then ' player

                                ' Check to see if we are following a player or not
                                If target > 0 Then

                                    ' Check if the player is even playing, if so follow'm
                                    If IsPlaying(target) And GetPlayerMap(target) = mapNum Then
                                        DidWalk = False
                                        target_verify = True
                                        TargetY = GetPlayerY(target)
                                        TargetX = GetPlayerX(target)
                                    Else
                                        MapNpc(mapNum).Npc(x).targetType = 0 ' clear
                                        MapNpc(mapNum).Npc(x).target = 0
                                    End If
                                End If

                            ElseIf targetType = 2 Then 'npc

                                If target > 0 Then

                                    If MapNpc(mapNum).Npc(target).Num > 0 Then
                                        DidWalk = False
                                        target_verify = True
                                        TargetY = MapNpc(mapNum).Npc(target).y
                                        TargetX = MapNpc(mapNum).Npc(target).x
                                    Else
                                        MapNpc(mapNum).Npc(x).targetType = 0 ' clear
                                        MapNpc(mapNum).Npc(x).target = 0
                                    End If
                                End If
                            End If

                            If target_verify Then

                                i = Int(Rnd * 5)

                                ' Lets move the npc
                                Select Case i
                                    Case 0

                                        ' Up
                                        If MapNpc(mapNum).Npc(x).y > TargetY And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_UP) Then
                                                Call NpcMove(mapNum, x, DIR_UP, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Down
                                        If MapNpc(mapNum).Npc(x).y < TargetY And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_DOWN) Then
                                                Call NpcMove(mapNum, x, DIR_DOWN, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Left
                                        If MapNpc(mapNum).Npc(x).x > TargetX And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_LEFT) Then
                                                Call NpcMove(mapNum, x, DIR_LEFT, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Right
                                        If MapNpc(mapNum).Npc(x).x < TargetX And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_RIGHT) Then
                                                Call NpcMove(mapNum, x, DIR_RIGHT, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                    Case 1

                                        ' Right
                                        If MapNpc(mapNum).Npc(x).x < TargetX And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_RIGHT) Then
                                                Call NpcMove(mapNum, x, DIR_RIGHT, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Left
                                        If MapNpc(mapNum).Npc(x).x > TargetX And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_LEFT) Then
                                                Call NpcMove(mapNum, x, DIR_LEFT, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Down
                                        If MapNpc(mapNum).Npc(x).y < TargetY And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_DOWN) Then
                                                Call NpcMove(mapNum, x, DIR_DOWN, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Up
                                        If MapNpc(mapNum).Npc(x).y > TargetY And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_UP) Then
                                                Call NpcMove(mapNum, x, DIR_UP, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                    Case 2

                                        ' Down
                                        If MapNpc(mapNum).Npc(x).y < TargetY And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_DOWN) Then
                                                Call NpcMove(mapNum, x, DIR_DOWN, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Up
                                        If MapNpc(mapNum).Npc(x).y > TargetY And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_UP) Then
                                                Call NpcMove(mapNum, x, DIR_UP, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Right
                                        If MapNpc(mapNum).Npc(x).x < TargetX And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_RIGHT) Then
                                                Call NpcMove(mapNum, x, DIR_RIGHT, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Left
                                        If MapNpc(mapNum).Npc(x).x > TargetX And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_LEFT) Then
                                                Call NpcMove(mapNum, x, DIR_LEFT, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                    Case 3

                                        ' Left
                                        If MapNpc(mapNum).Npc(x).x > TargetX And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_LEFT) Then
                                                Call NpcMove(mapNum, x, DIR_LEFT, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Right
                                        If MapNpc(mapNum).Npc(x).x < TargetX And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_RIGHT) Then
                                                Call NpcMove(mapNum, x, DIR_RIGHT, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Up
                                        If MapNpc(mapNum).Npc(x).y > TargetY And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_UP) Then
                                                Call NpcMove(mapNum, x, DIR_UP, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                        ' Down
                                        If MapNpc(mapNum).Npc(x).y < TargetY And Not DidWalk Then
                                            If CanNpcMove(mapNum, x, DIR_DOWN) Then
                                                Call NpcMove(mapNum, x, DIR_DOWN, MOVING_WALKING)
                                                DidWalk = True
                                            End If
                                        End If

                                End Select

                                ' Check if we can't move and if Target is behind something and if we can just switch dirs
                                If Not DidWalk Then
                                    If MapNpc(mapNum).Npc(x).x - 1 = TargetX And MapNpc(mapNum).Npc(x).y = TargetY Then
                                        If MapNpc(mapNum).Npc(x).Dir <> DIR_LEFT Then
                                            Call NpcDir(mapNum, x, DIR_LEFT)
                                        End If

                                        DidWalk = True
                                    End If

                                    If MapNpc(mapNum).Npc(x).x + 1 = TargetX And MapNpc(mapNum).Npc(x).y = TargetY Then
                                        If MapNpc(mapNum).Npc(x).Dir <> DIR_RIGHT Then
                                            Call NpcDir(mapNum, x, DIR_RIGHT)
                                        End If

                                        DidWalk = True
                                    End If

                                    If MapNpc(mapNum).Npc(x).x = TargetX And MapNpc(mapNum).Npc(x).y - 1 = TargetY Then
                                        If MapNpc(mapNum).Npc(x).Dir <> DIR_UP Then
                                            Call NpcDir(mapNum, x, DIR_UP)
                                        End If

                                        DidWalk = True
                                    End If

                                    If MapNpc(mapNum).Npc(x).x = TargetX And MapNpc(mapNum).Npc(x).y + 1 = TargetY Then
                                        If MapNpc(mapNum).Npc(x).Dir <> DIR_DOWN Then
                                            Call NpcDir(mapNum, x, DIR_DOWN)
                                        End If

                                        DidWalk = True
                                    End If

                                    ' We could not move so Target must be behind something, walk randomly.
                                    If Not DidWalk Then
                                        i = Int(Rnd * 2)

                                        If i = 1 Then
                                            i = Int(Rnd * 4)

                                            If CanNpcMove(mapNum, x, i) Then
                                                Call NpcMove(mapNum, x, i, MOVING_WALKING)
                                            End If
                                        End If
                                    End If
                                End If

                            Else
                                i = Int(Rnd * 4)

                                If i = 1 Then
                                    i = Int(Rnd * 4)

                                    If CanNpcMove(mapNum, x, i) Then
                                        Call NpcMove(mapNum, x, i, MOVING_WALKING)
                                    End If
                                End If
                            End If
                        'End If
                    End If
                End If

```
Link to comment
Share on other sites

```
Function CanNpcMove(ByVal mapNum As Long, ByVal mapNpcNum As Long, ByVal Dir As Byte) As Boolean
    Dim i As Long
    Dim n As Long
    Dim x As Long
    Dim y As Long

    ' Check for subscript out of range
    If mapNum <= 0 Or mapNum > MAX_MAPS Or mapNpcNum <= 0 Or mapNpcNum > MAX_MAP_NPCS Or Dir < DIR_UP Or Dir > DIR_RIGHT Then
        Exit Function
    End If

    x = MapNpc(mapNum).Npc(mapNpcNum).x
    y = MapNpc(mapNum).Npc(mapNpcNum).y
    CanNpcMove = True

    Select Case Dir
        Case DIR_UP

            ' Check to make sure not outside of boundries
            If y > 0 Then
                n = Map(mapNum).Tile(x, y - 1).Type

                ' Check to make sure that the tile is walkable
                If n <> TILE_TYPE_WALKABLE And n <> TILE_TYPE_ITEM And n <> TILE_TYPE_NPCSPAWN Then
                    CanNpcMove = False
                    Exit Function
                End If

                ' Check to make sure that there is not a player in the way
                For i = 1 To Player_HighIndex
                    If IsPlaying(i) Then
                        If (GetPlayerMap(i) = mapNum) And (GetPlayerX(i) = MapNpc(mapNum).Npc(mapNpcNum).x) And (GetPlayerY(i) = MapNpc(mapNum).Npc(mapNpcNum).y - 1) Then
                            CanNpcMove = False
                            Exit Function
                        End If
                    End If
                Next

                ' Check to make sure that there is not another npc in the way
                For i = 1 To MAX_MAP_NPCS
                    If (i <> mapNpcNum) And (MapNpc(mapNum).Npc(i).Num > 0) And (MapNpc(mapNum).Npc(i).x = MapNpc(mapNum).Npc(mapNpcNum).x) And (MapNpc(mapNum).Npc(i).y = MapNpc(mapNum).Npc(mapNpcNum).y - 1) Then
                        CanNpcMove = False
                        Exit Function
                    End If
                Next

                ' Directional blocking
                If isDirBlocked(Map(mapNum).Tile(MapNpc(mapNum).Npc(mapNpcNum).x, MapNpc(mapNum).Npc(mapNpcNum).y).DirBlock, DIR_UP + 1) Then
                    CanNpcMove = False
                    Exit Function
                End If
            Else
                CanNpcMove = False
            End If

        Case DIR_DOWN

            ' Check to make sure not outside of boundries
            If y < Map(mapNum).MaxY Then
                n = Map(mapNum).Tile(x, y + 1).Type

                ' Check to make sure that the tile is walkable
                If n <> TILE_TYPE_WALKABLE And n <> TILE_TYPE_ITEM And n <> TILE_TYPE_NPCSPAWN Then
                    CanNpcMove = False
                    Exit Function
                End If

                ' Check to make sure that there is not a player in the way
                For i = 1 To Player_HighIndex
                    If IsPlaying(i) Then
                        If (GetPlayerMap(i) = mapNum) And (GetPlayerX(i) = MapNpc(mapNum).Npc(mapNpcNum).x) And (GetPlayerY(i) = MapNpc(mapNum).Npc(mapNpcNum).y + 1) Then
                            CanNpcMove = False
                            Exit Function
                        End If
                    End If
                Next

                ' Check to make sure that there is not another npc in the way
                For i = 1 To MAX_MAP_NPCS
                    If (i <> mapNpcNum) And (MapNpc(mapNum).Npc(i).Num > 0) And (MapNpc(mapNum).Npc(i).x = MapNpc(mapNum).Npc(mapNpcNum).x) And (MapNpc(mapNum).Npc(i).y = MapNpc(mapNum).Npc(mapNpcNum).y + 1) Then
                        CanNpcMove = False
                        Exit Function
                    End If
                Next

                ' Directional blocking
                If isDirBlocked(Map(mapNum).Tile(MapNpc(mapNum).Npc(mapNpcNum).x, MapNpc(mapNum).Npc(mapNpcNum).y).DirBlock, DIR_DOWN + 1) Then
                    CanNpcMove = False
                    Exit Function
                End If
            Else
                CanNpcMove = False
            End If

        Case DIR_LEFT

            ' Check to make sure not outside of boundries
            If x > 0 Then
                n = Map(mapNum).Tile(x - 1, y).Type

                ' Check to make sure that the tile is walkable
                If n <> TILE_TYPE_WALKABLE And n <> TILE_TYPE_ITEM And n <> TILE_TYPE_NPCSPAWN Then
                    CanNpcMove = False
                    Exit Function
                End If

                ' Check to make sure that there is not a player in the way
                For i = 1 To Player_HighIndex
                    If IsPlaying(i) Then
                        If (GetPlayerMap(i) = mapNum) And (GetPlayerX(i) = MapNpc(mapNum).Npc(mapNpcNum).x - 1) And (GetPlayerY(i) = MapNpc(mapNum).Npc(mapNpcNum).y) Then
                            CanNpcMove = False
                            Exit Function
                        End If
                    End If
                Next

                ' Check to make sure that there is not another npc in the way
                For i = 1 To MAX_MAP_NPCS
                    If (i <> mapNpcNum) And (MapNpc(mapNum).Npc(i).Num > 0) And (MapNpc(mapNum).Npc(i).x = MapNpc(mapNum).Npc(mapNpcNum).x - 1) And (MapNpc(mapNum).Npc(i).y = MapNpc(mapNum).Npc(mapNpcNum).y) Then
                        CanNpcMove = False
                        Exit Function
                    End If
                Next

                ' Directional blocking
                If isDirBlocked(Map(mapNum).Tile(MapNpc(mapNum).Npc(mapNpcNum).x, MapNpc(mapNum).Npc(mapNpcNum).y).DirBlock, DIR_LEFT + 1) Then
                    CanNpcMove = False
                    Exit Function
                End If
            Else
                CanNpcMove = False
            End If

        Case DIR_RIGHT

            ' Check to make sure not outside of boundries
            If x < Map(mapNum).MaxX Then
                n = Map(mapNum).Tile(x + 1, y).Type

                ' Check to make sure that the tile is walkable
                If n <> TILE_TYPE_WALKABLE And n <> TILE_TYPE_ITEM And n <> TILE_TYPE_NPCSPAWN Then
                    CanNpcMove = False
                    Exit Function
                End If

                ' Check to make sure that there is not a player in the way
                For i = 1 To Player_HighIndex
                    If IsPlaying(i) Then
                        If (GetPlayerMap(i) = mapNum) And (GetPlayerX(i) = MapNpc(mapNum).Npc(mapNpcNum).x + 1) And (GetPlayerY(i) = MapNpc(mapNum).Npc(mapNpcNum).y) Then
                            CanNpcMove = False
                            Exit Function
                        End If
                    End If
                Next

                ' Check to make sure that there is not another npc in the way
                For i = 1 To MAX_MAP_NPCS
                    If (i <> mapNpcNum) And (MapNpc(mapNum).Npc(i).Num > 0) And (MapNpc(mapNum).Npc(i).x = MapNpc(mapNum).Npc(mapNpcNum).x + 1) And (MapNpc(mapNum).Npc(i).y = MapNpc(mapNum).Npc(mapNpcNum).y) Then
                        CanNpcMove = False
                        Exit Function
                    End If
                Next

                ' Directional blocking
                If isDirBlocked(Map(mapNum).Tile(MapNpc(mapNum).Npc(mapNpcNum).x, MapNpc(mapNum).Npc(mapNpcNum).y).DirBlock, DIR_RIGHT + 1) Then
                    CanNpcMove = False
                    Exit Function
                End If
            Else
                CanNpcMove = False
            End If

    End Select

End Function

```
```
Sub NpcMove(ByVal mapNum As Long, ByVal mapNpcNum As Long, ByVal Dir As Long, ByVal movement As Long)
    Dim packet As String
    Dim Buffer As clsBuffer

    ' Check for subscript out of range
    If mapNum <= 0 Or mapNum > MAX_MAPS Or mapNpcNum <= 0 Or mapNpcNum > MAX_MAP_NPCS Or Dir < DIR_UP Or Dir > DIR_RIGHT Or movement < 1 Or movement > 2 Then
        Exit Sub
    End If

    MapNpc(mapNum).Npc(mapNpcNum).Dir = Dir

    Select Case Dir
        Case DIR_UP
            MapNpc(mapNum).Npc(mapNpcNum).y = MapNpc(mapNum).Npc(mapNpcNum).y - 1
            Set Buffer = New clsBuffer
            Buffer.WriteLong SNpcMove
            Buffer.WriteLong mapNpcNum
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).x
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).y
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).Dir
            Buffer.WriteLong movement
            SendDataToMap mapNum, Buffer.ToArray()
            Set Buffer = Nothing
        Case DIR_DOWN
            MapNpc(mapNum).Npc(mapNpcNum).y = MapNpc(mapNum).Npc(mapNpcNum).y + 1
            Set Buffer = New clsBuffer
            Buffer.WriteLong SNpcMove
            Buffer.WriteLong mapNpcNum
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).x
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).y
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).Dir
            Buffer.WriteLong movement
            SendDataToMap mapNum, Buffer.ToArray()
            Set Buffer = Nothing
        Case DIR_LEFT
            MapNpc(mapNum).Npc(mapNpcNum).x = MapNpc(mapNum).Npc(mapNpcNum).x - 1
            Set Buffer = New clsBuffer
            Buffer.WriteLong SNpcMove
            Buffer.WriteLong mapNpcNum
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).x
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).y
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).Dir
            Buffer.WriteLong movement
            SendDataToMap mapNum, Buffer.ToArray()
            Set Buffer = Nothing
        Case DIR_RIGHT
            MapNpc(mapNum).Npc(mapNpcNum).x = MapNpc(mapNum).Npc(mapNpcNum).x + 1
            Set Buffer = New clsBuffer
            Buffer.WriteLong SNpcMove
            Buffer.WriteLong mapNpcNum
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).x
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).y
            Buffer.WriteLong MapNpc(mapNum).Npc(mapNpcNum).Dir
            Buffer.WriteLong movement
            SendDataToMap mapNum, Buffer.ToArray()
            Set Buffer = Nothing
    End Select

End Sub

```
```
Sub NpcDir(ByVal mapNum As Long, ByVal mapNpcNum As Long, ByVal Dir As Long)
    Dim packet As String
    Dim Buffer As clsBuffer

    ' Check for subscript out of range
    If mapNum <= 0 Or mapNum > MAX_MAPS Or mapNpcNum <= 0 Or mapNpcNum > MAX_MAP_NPCS Or Dir < DIR_UP Or Dir > DIR_RIGHT Then
        Exit Sub
    End If

    MapNpc(mapNum).Npc(mapNpcNum).Dir = Dir
    Set Buffer = New clsBuffer
    Buffer.WriteLong SNpcDir
    Buffer.WriteLong mapNpcNum
    Buffer.WriteLong Dir
    SendDataToMap mapNum, Buffer.ToArray()
    Set Buffer = Nothing
End Sub

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