Mirage Source
Quick Cleanup of the UpdateNPCAI - Printable Version

+- Mirage Source (https://mirage-engine.uk/forums)
+-- Forum: Mirage Source (Nostalgia) (https://mirage-engine.uk/forums/forumdisplay.php?fid=61)
+--- Forum: Archive (2006-2011) (https://mirage-engine.uk/forums/forumdisplay.php?fid=18)
+---- Forum: Source Code Development (https://mirage-engine.uk/forums/forumdisplay.php?fid=51)
+----- Forum: Mirage Source 4 (Visual Basic 6) (https://mirage-engine.uk/forums/forumdisplay.php?fid=44)
+----- Thread: Quick Cleanup of the UpdateNPCAI (/showthread.php?tid=2625)

Pages: 1 2


Quick Cleanup of the UpdateNPCAI - Jacob - 17-03-2009

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



Re: Quick Cleanup of the UpdateNPCAI - William - 17-03-2009

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



Re: Quick Cleanup of the UpdateNPCAI - Jacob - 17-03-2009

I don't see anything different from mine?


Re: Quick Cleanup of the UpdateNPCAI - GIAKEN - 17-03-2009

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.


Re: Quick Cleanup of the UpdateNPCAI - William - 17-03-2009

Dugor Wrote:I don't see anything different from mine?

[code]If IsPlaying(i) And GetPlayerMap(i) = MapNum And GetPlayerAccess(i)


Re: Quick Cleanup of the UpdateNPCAI - GIAKEN - 17-03-2009

Never use And's Sad They're slow.


Re: Quick Cleanup of the UpdateNPCAI - Jacob - 17-03-2009

William Wrote:[quote="Dugor"]I don't see anything different from mine?

[code]If IsPlaying(i) And GetPlayerMap(i) = MapNum And GetPlayerAccess(i)


Re: Quick Cleanup of the UpdateNPCAI - William - 17-03-2009

Mind checking the speed difference? I don't think it's noticeable in less than 1000loops.


Re: Quick Cleanup of the UpdateNPCAI - GIAKEN - 17-03-2009

viewtopic.php?f=120&t=4398&start=0


Re: Quick Cleanup of the UpdateNPCAI - William - 17-03-2009

10 million cycles 8secs :p It's a good enough reason to skip the And. But really, these changes won't make any difference.


Re: Quick Cleanup of the UpdateNPCAI - GIAKEN - 17-03-2009

18 seconds versus 10 seconds.

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


Re: Quick Cleanup of the UpdateNPCAI - William - 17-03-2009

How long time does it take to run 10million loop cycles?


Re: Quick Cleanup of the UpdateNPCAI - GIAKEN - 17-03-2009

1276 milliseconds.


Re: Quick Cleanup of the UpdateNPCAI - William - 17-03-2009

How lond does it take for you to loop 10million cycles in your head?


Re: Quick Cleanup of the UpdateNPCAI - GIAKEN - 17-03-2009

What? :|


Re: Quick Cleanup of the UpdateNPCAI - Jacob - 17-03-2009

Giaken, if you're bored compare the old UpdateNPCAI with this new one and post the results.


Re: Quick Cleanup of the UpdateNPCAI - William - 17-03-2009

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.


Re: Quick Cleanup of the UpdateNPCAI - GIAKEN - 17-03-2009

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.


Re: Quick Cleanup of the UpdateNPCAI - Jacob - 17-03-2009

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.


Re: Quick Cleanup of the UpdateNPCAI - GIAKEN - 17-03-2009

So it's slower then faster then slower?

I think we need to completely rewrite the NPC AI.


Re: Quick Cleanup of the UpdateNPCAI - Jacob - 17-03-2009

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.


Re: Quick Cleanup of the UpdateNPCAI - GIAKEN - 17-03-2009

I'll get on later. I have to do some chores.


Re: Quick Cleanup of the UpdateNPCAI - Jacob - 17-03-2009

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.


Re: Quick Cleanup of the UpdateNPCAI - GIAKEN - 19-03-2009

Here's mine so far Tongue

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.


Re: Quick Cleanup of the UpdateNPCAI - Jacob - 19-03-2009

If you comment out the DoEvents near the bottom of the sub, it runs much faster.
[spoiler]
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
[/spoiler]

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.