| Mirage Source http://miragesource.net/forums/ |
|
| Quick Cleanup of the UpdateNPCAI http://miragesource.net/forums/viewtopic.php?f=193&t=5269 |
Page 1 of 2 |
| Author: | Jacob [ Tue Mar 17, 2009 4:20 pm ] |
| Post subject: | Quick Cleanup of the UpdateNPCAI |
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 |
|
| Author: | William [ Tue Mar 17, 2009 4:27 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
I combined some too 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 |
|
| Author: | Jacob [ Tue Mar 17, 2009 5:16 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
I don't see anything different from mine? |
|
| Author: | GIAKEN [ Tue Mar 17, 2009 5:18 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
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. |
|
| Author: | William [ Tue Mar 17, 2009 5:20 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
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.. |
|
| Author: | GIAKEN [ Tue Mar 17, 2009 5:23 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
Never use And's |
|
| Author: | Jacob [ Tue Mar 17, 2009 5:24 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
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. |
|
| Author: | William [ Tue Mar 17, 2009 5:33 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
Mind checking the speed difference? I don't think it's noticeable in less than 1000loops. |
|
| Author: | GIAKEN [ Tue Mar 17, 2009 5:35 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
viewtopic.php?f=120&t=4398&start=0 |
|
| Author: | William [ Tue Mar 17, 2009 5:40 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
10 million cycles 8secs :p It's a good enough reason to skip the And. But really, these changes won't make any difference. |
|
| Author: | GIAKEN [ Tue Mar 17, 2009 5:40 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
18 seconds versus 10 seconds. Anyways, it's still a loss of speed, no matter the difference it shouldn't be ignored. |
|
| Author: | William [ Tue Mar 17, 2009 5:43 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
How long time does it take to run 10million loop cycles? |
|
| Author: | GIAKEN [ Tue Mar 17, 2009 5:45 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
1276 milliseconds. |
|
| Author: | William [ Tue Mar 17, 2009 5:56 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
How lond does it take for you to loop 10million cycles in your head? |
|
| Author: | GIAKEN [ Tue Mar 17, 2009 5:58 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
What? |
|
| Author: | Jacob [ Tue Mar 17, 2009 5:59 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
Giaken, if you're bored compare the old UpdateNPCAI with this new one and post the results. |
|
| Author: | William [ Tue Mar 17, 2009 6:10 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
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. |
|
| Author: | GIAKEN [ Tue Mar 17, 2009 6:38 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
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. |
|
| Author: | Jacob [ Tue Mar 17, 2009 6:54 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
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. |
|
| Author: | GIAKEN [ Tue Mar 17, 2009 6:56 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
So it's slower then faster then slower? I think we need to completely rewrite the NPC AI. |
|
| Author: | Jacob [ Tue Mar 17, 2009 7:00 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
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. |
|
| Author: | GIAKEN [ Tue Mar 17, 2009 7:24 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
I'll get on later. I have to do some chores. |
|
| Author: | Jacob [ Tue Mar 17, 2009 7:28 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
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. |
|
| Author: | GIAKEN [ Thu Mar 19, 2009 4:41 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
Here's mine so far 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. |
|
| Author: | Jacob [ Thu Mar 19, 2009 7:52 pm ] |
| Post subject: | Re: Quick Cleanup of the UpdateNPCAI |
If you comment out the DoEvents near the bottom of the sub, it runs much faster. SPOILER: (click to show)
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. |
|
| Page 1 of 2 | All times are UTC |
| Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |
|