Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Quick Cleanup of the UpdateNPCAI
#1
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
Reply


Messages In This Thread

Forum Jump:


Users browsing this thread: 1 Guest(s)