Mirage Source

Free ORPG making software.
It is currently Thu May 23, 2024 4:23 am

All times are UTC




Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Tue Mar 17, 2009 4:20 pm 
Offline
Pro
User avatar

Joined: Tue Nov 13, 2007 2:42 pm
Posts: 509
I decided to clean up MS4's updateNpcAI. I removed some checks and combined some with other checks.

I did some basic testing and it seems to be working well. If you notice any problems let me know. Let's get it cleaned up!

Some of the changes:
Removed all the checks for the npc num, might have to re-add this. Will test.
Attack on sight: Checks for target before looping through players.
Attack on sight: If it finds a target then it exits' the player loop.
Combined following a player and the npc attacking stuff.

Code:
Private Sub UpdateNpcAI()
Dim i As Long, n As Long
Dim MapNum As Long, MapNpcNum As Long
Dim NpcNum As Long, Target As Long
Dim TickCount As Long
Dim Damage As Long
Dim DistanceX As Long
Dim DistanceY As Long
Dim DidWalk As Boolean
           
    For MapNum = 1 To MAX_MAPS
        If PlayersOnMap(MapNum) = YES Then
            TickCount = GetTickCount
           
            For MapNpcNum = 1 To MAX_MAP_NPCS
                NpcNum = MapNpc(MapNum, MapNpcNum).Num
               
                ' Make sure theres a npc with the map
                If NpcNum > 0 Then
                   
                    ' Get the target
                    Target = MapNpc(MapNum, MapNpcNum).Target
                   
                    ' /////////////////////////////////////////
                    ' // This is used for ATTACKING ON SIGHT //
                    ' /////////////////////////////////////////
                    ' If the npc is a attack on sight, search for a player on the map
                    If Npc(NpcNum).Behavior = NPC_BEHAVIOR_ATTACKONSIGHT Or Npc(NpcNum).Behavior = NPC_BEHAVIOR_GUARD Then
                        ' First check if they don't have a target before looping...
                        If Target = 0 Then
                            For i = 1 To High_Index
                                If IsPlaying(i) Then
                                    If GetPlayerMap(i) = MapNum Then
                                        If GetPlayerAccess(i) <= ADMIN_MONITOR Then
                                            n = Npc(NpcNum).Range
                                           
                                            DistanceX = MapNpc(MapNum, MapNpcNum).X - GetPlayerX(i)
                                            DistanceY = MapNpc(MapNum, MapNpcNum).Y - GetPlayerY(i)
                                           
                                            ' Make sure we get a positive value
                                            If DistanceX < 0 Then DistanceX = -DistanceX
                                            If DistanceY < 0 Then DistanceY = -DistanceY
                                           
                                            ' Are they in range?  if so GET'M!
                                            If DistanceX <= n Then
                                                If DistanceY <= n Then
                                                    If Npc(NpcNum).Behavior = NPC_BEHAVIOR_ATTACKONSIGHT Or GetPlayerPK(i) = YES Then
                                                        If LenB(Trim$(Npc(NpcNum).AttackSay)) > 0 Then
                                                            Call PlayerMsg(i, "A " & Trim$(Npc(NpcNum).Name) & " says, '" & Trim$(Npc(NpcNum).AttackSay) & "' to you.", SayColor)
                                                        End If
                                                       
                                                        MapNpc(MapNum, MapNpcNum).Target = i
                                                        Exit For
                                                    End If
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            Next
                        End If
                    End If
               
                                                                       
                    ' /////////////////////////////////////////////
                    ' // This is used for NPC walking/targetting //
                    ' /////////////////////////////////////////////
                    ' Check to see if its time for the npc to walk
                    If Npc(NpcNum).Behavior <> NPC_BEHAVIOR_SHOPKEEPER Then
                        ' 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) Then
                                If GetPlayerMap(Target) = MapNum Then
                                    DidWalk = False
                                   
                                    i = Int(Rnd * 4)
                                   
                                    ' Lets move the npc
                                    Select Case i
                                        Case 0
                                            ' Up
                                            If MapNpc(MapNum, MapNpcNum).Y > GetPlayerY(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_UP) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_UP, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Down
                                            If MapNpc(MapNum, MapNpcNum).Y < GetPlayerY(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_DOWN) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_DOWN, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Left
                                            If MapNpc(MapNum, MapNpcNum).X > GetPlayerX(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_LEFT) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_LEFT, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Right
                                            If MapNpc(MapNum, MapNpcNum).X < GetPlayerX(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_RIGHT) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_RIGHT, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                       
                                        Case 1
                                            ' Right
                                            If MapNpc(MapNum, MapNpcNum).X < GetPlayerX(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_RIGHT) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_RIGHT, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Left
                                            If MapNpc(MapNum, MapNpcNum).X > GetPlayerX(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_LEFT) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_LEFT, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Down
                                            If MapNpc(MapNum, MapNpcNum).Y < GetPlayerY(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_DOWN) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_DOWN, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Up
                                            If MapNpc(MapNum, MapNpcNum).Y > GetPlayerY(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_UP) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_UP, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                           
                                        Case 2
                                            ' Down
                                            If MapNpc(MapNum, MapNpcNum).Y < GetPlayerY(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_DOWN) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_DOWN, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Up
                                            If MapNpc(MapNum, MapNpcNum).Y > GetPlayerY(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_UP) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_UP, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Right
                                            If MapNpc(MapNum, MapNpcNum).X < GetPlayerX(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_RIGHT) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_RIGHT, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Left
                                            If MapNpc(MapNum, MapNpcNum).X > GetPlayerX(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_LEFT) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_LEFT, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                       
                                        Case 3
                                            ' Left
                                            If MapNpc(MapNum, MapNpcNum).X > GetPlayerX(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_LEFT) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_LEFT, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Right
                                            If MapNpc(MapNum, MapNpcNum).X < GetPlayerX(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_RIGHT) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_RIGHT, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Up
                                            If MapNpc(MapNum, MapNpcNum).Y > GetPlayerY(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_UP) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_UP, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                            ' Down
                                            If MapNpc(MapNum, MapNpcNum).Y < GetPlayerY(Target) And Not DidWalk Then
                                                If CanNpcMove(MapNum, MapNpcNum, DIR_DOWN) Then
                                                    Call NpcMove(MapNum, MapNpcNum, DIR_DOWN, MOVING_WALKING)
                                                    DidWalk = True
                                                End If
                                            End If
                                    End Select
                           
                                    ' Check if we can't move and if player is behind something and if we can just switch dirs
                                    If Not DidWalk Then
                                        If MapNpc(MapNum, MapNpcNum).X - 1 = GetPlayerX(Target) And MapNpc(MapNum, MapNpcNum).Y = GetPlayerY(Target) Then
                                            If MapNpc(MapNum, MapNpcNum).Dir <> DIR_LEFT Then
                                                Call NpcDir(MapNum, MapNpcNum, DIR_LEFT)
                                            End If
                                            DidWalk = True
                                        End If
                                    End If
                                   
                                    If Not DidWalk Then
                                        If MapNpc(MapNum, MapNpcNum).X + 1 = GetPlayerX(Target) And MapNpc(MapNum, MapNpcNum).Y = GetPlayerY(Target) Then
                                            If MapNpc(MapNum, MapNpcNum).Dir <> DIR_RIGHT Then
                                                Call NpcDir(MapNum, MapNpcNum, DIR_RIGHT)
                                            End If
                                            DidWalk = True
                                        End If
                                    End If
                                   
                                    If Not DidWalk Then
                                        If MapNpc(MapNum, MapNpcNum).X = GetPlayerX(Target) And MapNpc(MapNum, MapNpcNum).Y - 1 = GetPlayerY(Target) Then
                                            If MapNpc(MapNum, MapNpcNum).Dir <> DIR_UP Then
                                                Call NpcDir(MapNum, MapNpcNum, DIR_UP)
                                            End If
                                            DidWalk = True
                                        End If
                                    End If
                                   
                                    If Not DidWalk Then
                                        If MapNpc(MapNum, MapNpcNum).X = GetPlayerX(Target) And MapNpc(MapNum, MapNpcNum).Y + 1 = GetPlayerY(Target) Then
                                            If MapNpc(MapNum, MapNpcNum).Dir <> DIR_DOWN Then
                                                Call NpcDir(MapNum, MapNpcNum, DIR_DOWN)
                                            End If
                                            DidWalk = True
                                        End If
                                    End If
                                   
                                    ' We could not move so player 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, MapNpcNum, i) Then
                                                Call NpcMove(MapNum, MapNpcNum, i, MOVING_WALKING)
                                            End If
                                        End If
                                    End If
                                   
                                    ' /////////////////////////////////////////////
                                    ' // This is used for npcs to attack players //
                                    ' /////////////////////////////////////////////
                                    ' Can the npc attack the player?
                                    If CanNpcAttackPlayer(MapNpcNum, Target) Then
                                        If Not CanPlayerBlockHit(Target) Then
                                            Damage = Npc(NpcNum).Stat(Stats.Strength) - GetPlayerProtection(Target)
                                            Call NpcAttackPlayer(MapNpcNum, Target, Damage)
                                        Else
                                            Call PlayerMsg(Target, "Your " & Trim$(Item(GetPlayerInvItemNum(Target, GetPlayerEquipmentSlot(Target, Shield))).Name) & " blocks the " & Trim$(Npc(NpcNum).Name) & "'s hit!", BrightCyan)
                                        End If
                                    End If
                                Else
                                    MapNpc(MapNum, MapNpcNum).Target = 0
                                End If
                            Else
                                MapNpc(MapNum, MapNpcNum).Target = 0
                            End If
                        Else
                            If Int(Rnd * 4) = 1 Then
                                i = Int(Rnd * 4)
                                If CanNpcMove(MapNum, MapNpcNum, i) Then
                                    Call NpcMove(MapNum, MapNpcNum, i, MOVING_WALKING)
                                End If
                            End If
                        End If
                    End If
               
                    ' ////////////////////////////////////////////
                    ' // This is used for regenerating NPC's HP //
                    ' ////////////////////////////////////////////
                    If TickCount > GiveNPCHPTimer + 10000 Then
                        If MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) > 0 Then
                            MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) = MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) + GetNpcVitalRegen(NpcNum, Vitals.HP)
                       
                            ' Check if they have more then they should and if so just set it to max
                            If MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) > GetNpcMaxVital(NpcNum, Vitals.HP) Then
                                MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) = GetNpcMaxVital(NpcNum, Vitals.HP)
                            End If
                        End If
                        GiveNPCHPTimer = TickCount
                    End If
                   
                End If
               
                ' //////////////////////////////////////
                ' // This is used for spawning an NPC //
                ' //////////////////////////////////////
                ' Check if we are supposed to spawn an npc or not
                If MapNpc(MapNum, MapNpcNum).Num = 0 Then
                    If Map(MapNum).Npc(MapNpcNum) > 0 Then
                        If TickCount > MapNpc(MapNum, MapNpcNum).SpawnWait + (Npc(Map(MapNum).Npc(MapNpcNum)).SpawnSecs * 1000) Then
                            Call SpawnNpc(MapNpcNum, MapNum)
                        End If
                    End If
                End If
               
            Next
        End If
        DoEvents
    Next

End Sub


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 4:27 pm 
Offline
Community Leader
User avatar

Joined: Mon May 29, 2006 1:00 pm
Posts: 2538
Location: Sweden
Google Talk: johansson_tk@hotmail.com
I combined some too :roll:

Code:
    Private Sub UpdateNpcAI()
    Dim i As Long, n As Long
    Dim MapNum As Long, MapNpcNum As Long
    Dim NpcNum As Long, Target As Long
    Dim TickCount As Long
    Dim Damage As Long
    Dim DistanceX As Long
    Dim DistanceY As Long
    Dim DidWalk As Boolean
               
        For MapNum = 1 To MAX_MAPS
            If PlayersOnMap(MapNum) = YES Then
                TickCount = GetTickCount
               
                For MapNpcNum = 1 To MAX_MAP_NPCS
                    NpcNum = MapNpc(MapNum, MapNpcNum).Num
                   
                    ' Make sure theres a npc with the map
                    If NpcNum > 0 Then
                       
                        ' Get the target
                        Target = MapNpc(MapNum, MapNpcNum).Target
                       
                        ' /////////////////////////////////////////
                        ' // This is used for ATTACKING ON SIGHT //
                        ' /////////////////////////////////////////
                        ' If the npc is a attack on sight, search for a player on the map
                        If Npc(NpcNum).Behavior = NPC_BEHAVIOR_ATTACKONSIGHT Or Npc(NpcNum).Behavior = NPC_BEHAVIOR_GUARD Then
                            ' First check if they don't have a target before looping...
                            If Target = 0 Then
                                For i = 1 To High_Index
                                    If IsPlaying(i) And GetPlayerMap(i) = MapNum And GetPlayerAccess(i) <= ADMIN_MONITOR Then
                                        n = Npc(NpcNum).Range
                                               
                                        DistanceX = MapNpc(MapNum, MapNpcNum).X - GetPlayerX(i)
                                        DistanceY = MapNpc(MapNum, MapNpcNum).Y - GetPlayerY(i)
                                               
                                        ' Make sure we get a positive value
                                        If DistanceX < 0 Then DistanceX = -DistanceX
                                        If DistanceY < 0 Then DistanceY = -DistanceY
                                               
                                        ' Are they in range?  if so GET'M!
                                        If DistanceX <= n And DistanceY <= n Then
                                            If Npc(NpcNum).Behavior = NPC_BEHAVIOR_ATTACKONSIGHT Or GetPlayerPK(i) = YES Then
                                                If LenB(Trim$(Npc(NpcNum).AttackSay)) > 0 Then
                                                    Call PlayerMsg(i, "A " & Trim$(Npc(NpcNum).Name) & " says, '" & Trim$(Npc(NpcNum).AttackSay) & "' to you.", SayColor)
                                                End If
                                                           
                                                MapNpc(MapNum, MapNpcNum).Target = i
                                                Exit For
                                            End If
                                        End If
                                    End If
                                Next
                            End If
                        End If
                   
                                                                           
                        ' /////////////////////////////////////////////
                        ' // This is used for NPC walking/targetting //
                        ' /////////////////////////////////////////////
                        ' Check to see if its time for the npc to walk
                        If Npc(NpcNum).Behavior <> NPC_BEHAVIOR_SHOPKEEPER Then
                            ' 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) Then
                                    If GetPlayerMap(Target) = MapNum Then
                                        DidWalk = False
                                       
                                        i = Int(Rnd * 4)
                                       
                                        ' Lets move the npc
                                        Select Case i
                                            Case 0
                                                ' Up
                                                If MapNpc(MapNum, MapNpcNum).Y > GetPlayerY(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_UP) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_UP, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Down
                                                If MapNpc(MapNum, MapNpcNum).Y < GetPlayerY(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_DOWN) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_DOWN, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Left
                                                If MapNpc(MapNum, MapNpcNum).X > GetPlayerX(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_LEFT) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_LEFT, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Right
                                                If MapNpc(MapNum, MapNpcNum).X < GetPlayerX(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_RIGHT) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_RIGHT, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                           
                                            Case 1
                                                ' Right
                                                If MapNpc(MapNum, MapNpcNum).X < GetPlayerX(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_RIGHT) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_RIGHT, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Left
                                                If MapNpc(MapNum, MapNpcNum).X > GetPlayerX(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_LEFT) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_LEFT, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Down
                                                If MapNpc(MapNum, MapNpcNum).Y < GetPlayerY(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_DOWN) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_DOWN, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Up
                                                If MapNpc(MapNum, MapNpcNum).Y > GetPlayerY(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_UP) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_UP, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                               
                                            Case 2
                                                ' Down
                                                If MapNpc(MapNum, MapNpcNum).Y < GetPlayerY(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_DOWN) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_DOWN, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Up
                                                If MapNpc(MapNum, MapNpcNum).Y > GetPlayerY(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_UP) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_UP, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Right
                                                If MapNpc(MapNum, MapNpcNum).X < GetPlayerX(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_RIGHT) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_RIGHT, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Left
                                                If MapNpc(MapNum, MapNpcNum).X > GetPlayerX(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_LEFT) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_LEFT, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                           
                                            Case 3
                                                ' Left
                                                If MapNpc(MapNum, MapNpcNum).X > GetPlayerX(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_LEFT) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_LEFT, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Right
                                                If MapNpc(MapNum, MapNpcNum).X < GetPlayerX(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_RIGHT) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_RIGHT, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Up
                                                If MapNpc(MapNum, MapNpcNum).Y > GetPlayerY(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_UP) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_UP, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                                ' Down
                                                If MapNpc(MapNum, MapNpcNum).Y < GetPlayerY(Target) And Not DidWalk Then
                                                    If CanNpcMove(MapNum, MapNpcNum, DIR_DOWN) Then
                                                        Call NpcMove(MapNum, MapNpcNum, DIR_DOWN, MOVING_WALKING)
                                                        DidWalk = True
                                                    End If
                                                End If
                                        End Select
                               
                                        ' Check if we can't move and if player is behind something and if we can just switch dirs
                                        If Not DidWalk Then
                                            If MapNpc(MapNum, MapNpcNum).X - 1 = GetPlayerX(Target) And MapNpc(MapNum, MapNpcNum).Y = GetPlayerY(Target) Then
                                                If MapNpc(MapNum, MapNpcNum).Dir <> DIR_LEFT Then
                                                    Call NpcDir(MapNum, MapNpcNum, DIR_LEFT)
                                                End If
                                                DidWalk = True
                                            End If
                                        End If
                                       
                                        If Not DidWalk Then
                                            If MapNpc(MapNum, MapNpcNum).X + 1 = GetPlayerX(Target) And MapNpc(MapNum, MapNpcNum).Y = GetPlayerY(Target) Then
                                                If MapNpc(MapNum, MapNpcNum).Dir <> DIR_RIGHT Then
                                                    Call NpcDir(MapNum, MapNpcNum, DIR_RIGHT)
                                                End If
                                                DidWalk = True
                                            End If
                                        End If
                                       
                                        If Not DidWalk Then
                                            If MapNpc(MapNum, MapNpcNum).X = GetPlayerX(Target) And MapNpc(MapNum, MapNpcNum).Y - 1 = GetPlayerY(Target) Then
                                                If MapNpc(MapNum, MapNpcNum).Dir <> DIR_UP Then
                                                    Call NpcDir(MapNum, MapNpcNum, DIR_UP)
                                                End If
                                                DidWalk = True
                                            End If
                                        End If
                                       
                                        If Not DidWalk Then
                                            If MapNpc(MapNum, MapNpcNum).X = GetPlayerX(Target) And MapNpc(MapNum, MapNpcNum).Y + 1 = GetPlayerY(Target) Then
                                                If MapNpc(MapNum, MapNpcNum).Dir <> DIR_DOWN Then
                                                    Call NpcDir(MapNum, MapNpcNum, DIR_DOWN)
                                                End If
                                                DidWalk = True
                                            End If
                                        End If
                                       
                                        ' We could not move so player 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, MapNpcNum, i) Then
                                                    Call NpcMove(MapNum, MapNpcNum, i, MOVING_WALKING)
                                                End If
                                            End If
                                        End If
                                       
                                        ' /////////////////////////////////////////////
                                        ' // This is used for npcs to attack players //
                                        ' /////////////////////////////////////////////
                                        ' Can the npc attack the player?
                                        If CanNpcAttackPlayer(MapNpcNum, Target) Then
                                            If Not CanPlayerBlockHit(Target) Then
                                                Damage = Npc(NpcNum).Stat(Stats.Strength) - GetPlayerProtection(Target)
                                                Call NpcAttackPlayer(MapNpcNum, Target, Damage)
                                            Else
                                                Call PlayerMsg(Target, "Your " & Trim$(Item(GetPlayerInvItemNum(Target, GetPlayerEquipmentSlot(Target, Shield))).Name) & " blocks the " & Trim$(Npc(NpcNum).Name) & "'s hit!", BrightCyan)
                                            End If
                                        End If
                                    Else
                                        MapNpc(MapNum, MapNpcNum).Target = 0
                                    End If
                                Else
                                    MapNpc(MapNum, MapNpcNum).Target = 0
                                End If
                            Else
                                If Int(Rnd * 4) = 1 Then
                                    i = Int(Rnd * 4)
                                    If CanNpcMove(MapNum, MapNpcNum, i) Then
                                        Call NpcMove(MapNum, MapNpcNum, i, MOVING_WALKING)
                                    End If
                                End If
                            End If
                        End If
                   
                        ' ////////////////////////////////////////////
                        ' // This is used for regenerating NPC's HP //
                        ' ////////////////////////////////////////////
                        If TickCount > GiveNPCHPTimer + 10000 Then
                            If MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) > 0 Then
                                MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) = MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) + GetNpcVitalRegen(NpcNum, Vitals.HP)
                           
                                ' Check if they have more then they should and if so just set it to max
                                If MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) > GetNpcMaxVital(NpcNum, Vitals.HP) Then
                                    MapNpc(MapNum, MapNpcNum).Vital(Vitals.HP) = GetNpcMaxVital(NpcNum, Vitals.HP)
                                End If
                            End If
                            GiveNPCHPTimer = TickCount
                        End If
                       
                    End If
                   
                    ' //////////////////////////////////////
                    ' // This is used for spawning an NPC //
                    ' //////////////////////////////////////
                    ' Check if we are supposed to spawn an npc or not
                    If MapNpc(MapNum, MapNpcNum).Num = 0 Then
                        If Map(MapNum).Npc(MapNpcNum) > 0 Then
                            If TickCount > MapNpc(MapNum, MapNpcNum).SpawnWait + (Npc(Map(MapNum).Npc(MapNpcNum)).SpawnSecs * 1000) Then
                                Call SpawnNpc(MapNpcNum, MapNum)
                            End If
                        End If
                    End If
                   
                Next
            End If
            DoEvents
        Next

    End Sub

_________________
I'm on Facebook!My Youtube Channel Send me an email
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:16 pm 
Offline
Pro
User avatar

Joined: Tue Nov 13, 2007 2:42 pm
Posts: 509
I don't see anything different from mine?


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:18 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Mar 29, 2007 10:30 pm
Posts: 1510
Location: Virginia, USA
Google Talk: hpmccloud@gmail.com
All those Dim's :|

Need to move the UpdateNPCAI into it's own module and move all those Dim's to Privates so they aren't recreated every loop.

_________________
Nean wrote:
Yes harold. Give it to me.

Image
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:20 pm 
Offline
Community Leader
User avatar

Joined: Mon May 29, 2006 1:00 pm
Posts: 2538
Location: Sweden
Google Talk: johansson_tk@hotmail.com
Dugor wrote:
I don't see anything different from mine?


Code:
If IsPlaying(i) And GetPlayerMap(i) = MapNum And GetPlayerAccess(i) <= ADMIN_MONITOR Then

Etc..

_________________
I'm on Facebook!My Youtube Channel Send me an email
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:23 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Mar 29, 2007 10:30 pm
Posts: 1510
Location: Virginia, USA
Google Talk: hpmccloud@gmail.com
Never use And's :( They're slow.

_________________
Nean wrote:
Yes harold. Give it to me.

Image
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:24 pm 
Offline
Pro
User avatar

Joined: Tue Nov 13, 2007 2:42 pm
Posts: 509
William wrote:
Dugor wrote:
I don't see anything different from mine?


Code:
If IsPlaying(i) And GetPlayerMap(i) = MapNum And GetPlayerAccess(i) <= ADMIN_MONITOR Then

Etc..


I separated those on purpose. VB6 doesn't do short circuit evaluations.

Let's say one of those is false, it will still try to evaluate the other expressions in that if then statement. If you separate them then you won't have that issue.


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:33 pm 
Offline
Community Leader
User avatar

Joined: Mon May 29, 2006 1:00 pm
Posts: 2538
Location: Sweden
Google Talk: johansson_tk@hotmail.com
Mind checking the speed difference? I don't think it's noticeable in less than 1000loops.

_________________
I'm on Facebook!My Youtube Channel Send me an email
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:35 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Mar 29, 2007 10:30 pm
Posts: 1510
Location: Virginia, USA
Google Talk: hpmccloud@gmail.com
viewtopic.php?f=120&t=4398&start=0

_________________
Nean wrote:
Yes harold. Give it to me.

Image
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:40 pm 
Offline
Community Leader
User avatar

Joined: Mon May 29, 2006 1:00 pm
Posts: 2538
Location: Sweden
Google Talk: johansson_tk@hotmail.com
10 million cycles 8secs :p It's a good enough reason to skip the And. But really, these changes won't make any difference.

_________________
I'm on Facebook!My Youtube Channel Send me an email
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:40 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Mar 29, 2007 10:30 pm
Posts: 1510
Location: Virginia, USA
Google Talk: hpmccloud@gmail.com
18 seconds versus 10 seconds.

Anyways, it's still a loss of speed, no matter the difference it shouldn't be ignored.

_________________
Nean wrote:
Yes harold. Give it to me.

Image
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:43 pm 
Offline
Community Leader
User avatar

Joined: Mon May 29, 2006 1:00 pm
Posts: 2538
Location: Sweden
Google Talk: johansson_tk@hotmail.com
How long time does it take to run 10million loop cycles?

_________________
I'm on Facebook!My Youtube Channel Send me an email
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:45 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Mar 29, 2007 10:30 pm
Posts: 1510
Location: Virginia, USA
Google Talk: hpmccloud@gmail.com
1276 milliseconds.

_________________
Nean wrote:
Yes harold. Give it to me.

Image
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:56 pm 
Offline
Community Leader
User avatar

Joined: Mon May 29, 2006 1:00 pm
Posts: 2538
Location: Sweden
Google Talk: johansson_tk@hotmail.com
How lond does it take for you to loop 10million cycles in your head?

_________________
I'm on Facebook!My Youtube Channel Send me an email
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:58 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Mar 29, 2007 10:30 pm
Posts: 1510
Location: Virginia, USA
Google Talk: hpmccloud@gmail.com
What? :|

_________________
Nean wrote:
Yes harold. Give it to me.

Image
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 5:59 pm 
Offline
Pro
User avatar

Joined: Tue Nov 13, 2007 2:42 pm
Posts: 509
Giaken, if you're bored compare the old UpdateNPCAI with this new one and post the results.


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 6:10 pm 
Offline
Community Leader
User avatar

Joined: Mon May 29, 2006 1:00 pm
Posts: 2538
Location: Sweden
Google Talk: johansson_tk@hotmail.com
Dugor wrote:
Giaken, if you're bored compare the old UpdateNPCAI with this new one and post the results.

Yeah that would be interesting to see.

_________________
I'm on Facebook!My Youtube Channel Send me an email
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 6:38 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Mar 29, 2007 10:30 pm
Posts: 1510
Location: Virginia, USA
Google Talk: hpmccloud@gmail.com
Code:
%Faster     2.9|     1.6|     2.5|     0.4|    -1.1|     1.4|     0.6|     1.7|     0.4|    -0.7
Test1      1248|    1230|    1233|    1222|    1216|    1219|    1223|    1232|    1226|    1213
Test2      1213|    1211|    1203|    1217|    1230|    1202|    1216|    1212|    1221|    1221


Test1 = Dugor's NPC AI
Test2 = Old NPC AI

Code:
%Faster     2.4|     0.8|     1.1|     1.1|     0.2|     0.7|     9.4|     0.6|     0.7|     2.2
Test1      1242|    1224|    1229|    1228|    1309|    1314|    1332|    1226|    1233|    1249
Test2      1213|    1214|    1216|    1215|    1307|    1305|    1217|    1219|    1224|    1222


And that's with William's NPC AI.

So basically the new AIs are slower? I don't know if I can trust this test or not. I had to add a bunch of undeclared shit...I'll run the tests through the actual server soon.

_________________
Nean wrote:
Yes harold. Give it to me.

Image
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 6:54 pm 
Offline
Pro
User avatar

Joined: Tue Nov 13, 2007 2:42 pm
Posts: 509
I tried this
Code:
Do While ServerOnline
        Tick = GetTickCount
       
        For i = 1 To 10000
            UpdateNpcAI
        Next
       
        Debug.Print "test1", GetTickCount - Tick
       
        Tick = GetTickCount
       
        For i = 1 To 10000
            UpdateNPCAI2
        Next
       
        Debug.Print "test2", GetTickCount - Tick

        Sleep 1
        DoEvents
       
    Loop


Code:
test1          1312
test2          1235
test1          1468
test2          1235
test1          1219
test2          1235
test1          1296
test2          1407
test1          1657
test2          1828
test1          1657
test2          1828
test1          1656
test2          1812
test1          1672
test2          1828
test1          1641
test2          1843
test1          1688
test2          1344
test1          1328
test2          1250


Test1 - My code
Test2 - The original

I tested with 1 player and 3 npcs with attack on sight. It seems when nothing is happening that the original code is a little bit faster. But when attacking players, my code is faster.


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 6:56 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Mar 29, 2007 10:30 pm
Posts: 1510
Location: Virginia, USA
Google Talk: hpmccloud@gmail.com
So it's slower then faster then slower?

I think we need to completely rewrite the NPC AI.

_________________
Nean wrote:
Yes harold. Give it to me.

Image
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 7:00 pm 
Offline
Pro
User avatar

Joined: Tue Nov 13, 2007 2:42 pm
Posts: 509
The beginning, I hadn't logged in yet.

Then I logged in and was attacked,
Code:
test1          1657
test2          1828
test1          1657
test2          1828
test1          1656
test2          1812
test1          1672
test2          1828
test1          1641
test2          1843


My code is faster here.

... and get on msn.


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 7:24 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Mar 29, 2007 10:30 pm
Posts: 1510
Location: Virginia, USA
Google Talk: hpmccloud@gmail.com
I'll get on later. I have to do some chores.

_________________
Nean wrote:
Yes harold. Give it to me.

Image
Image


Top
 Profile  
 
PostPosted: Tue Mar 17, 2009 7:28 pm 
Offline
Pro
User avatar

Joined: Tue Nov 13, 2007 2:42 pm
Posts: 509
Haha. Ok.

I did a little bit more testing, depending on which sub I call first, that one will be a tad bit slower. I need to setup a better testbed.


Top
 Profile  
 
PostPosted: Thu Mar 19, 2009 4:41 pm 
Offline
Persistant Poster
User avatar

Joined: Thu Mar 29, 2007 10:30 pm
Posts: 1510
Location: Virginia, USA
Google Talk: hpmccloud@gmail.com
Here's mine so far :P

Code:
Private Sub UpdateNPCAI()
Dim MapNum As Long
Dim MapNpcNum As Long
Dim NpcNum As Long
Dim WalkDir As Long
Dim CorrectDir As Boolean

    For MapNum = 1 To MAX_MAPS
        If PlayersOnMap(MapNum) Then
            For MapNpcNum = 1 To MAX_MAP_NPCS
           
                NpcNum = MapNpc(MapNum, MapNpcNum).Num
               
                If NpcNum > 0 Then
               
                    WalkDir = Int(Rnd * 5)
                   
                    CorrectDir = True
                   
                    Select Case WalkDir
                   
                        Case DIR_UP
                        Case DIR_DOWN
                        Case DIR_LEFT
                        Case DIR_RIGHT
                        Case Else
                            CorrectDir = False
                   
                    End Select
                   
                    If CorrectDir Then
                        If CanNpcMove(MapNum, MapNpcNum, WalkDir) Then
                            NpcMove MapNum, MapNpcNum, WalkDir, 1
                        End If
                    End If
               
                End If
           
            Next
        End If
    Next

End Sub


All it does is randomly move the NPCs around. We need to write the CanNpcMove and NpcMove functions from scratch, too. The whole NPC system should be worked on.

_________________
Nean wrote:
Yes harold. Give it to me.

Image
Image


Top
 Profile  
 
PostPosted: Thu Mar 19, 2009 7:52 pm 
Offline
Pro
User avatar

Joined: Tue Nov 13, 2007 2:42 pm
Posts: 509
If you comment out the DoEvents near the bottom of the sub, it runs much faster.
SPOILER: (click to show)
Code:
Testing results              47            47
Testing results              47            31
Testing results              47            47
Testing results              47            31
Testing results              47            47
Testing results              47            31
Testing results              47            47
Testing results              47            31
Testing results              47            454
Testing results              609           437
Testing results              594           422
Testing results              593           422
Testing results              610           422
Testing results              593           438
Testing results              594           421
Testing results              594           422
Testing results              594           422
Testing results              594           422
Testing results              594           437
Testing results              594           438
Testing results              625           31
Testing results              47            47
Testing results              47            31
Testing results              47            47
Testing results              47            31
Testing results              47            47
Testing results              47            31
Testing results              47            47
Testing results              46            32
Testing results              47            46
Testing results              47            32
Testing results              46            47
Testing results              47            31
Testing results              63            47
Testing results              47            31
Testing results              47            47
Testing results              46            32
Testing results              47            46
Testing results              47            32
Testing results              46            47
Testing results              47            31
Testing results              47            47
Testing results              47            31
Testing results              47            47
Testing results              47            31
Testing results              47            47
Testing results              47            31


The first number is the old npc ai code, the second number is my code.

The higher numbers are when i logged in and the npcs attacked. 3 npcs set on aggresive and 1 non admin player.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 26 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group