Joost Posted April 22, 2012 Author Share Posted April 22, 2012 **The current way things work**The NPC hits the last thing that attacked it. Whether this was the guy with the huge sword or the guy giving him a backrub is irrelevant, you touch me last, I kill you now. This also has the side-effect of the NPC spasming out while trying to attack every single one of the 4 people hitting him at the same time.**What this does**This gives all NPC's a list of a number between ~~3 and 5 targets~~ 15 targets and how much damage they did to that NPC. The NPC will always attack the person who did the most damage to it. This means that you can have a setup with one warrior class tank designed for keeping the NPC's attention while the mages and rogues do damage to the NPC. The WoW definition of threat (what this simulates) is"_Threat is a measure of an NPC's aggression (often called "aggro") towards a player. Each NPC has a threat table, and the character at the top of the list is usually the target of its aggression. In-game, this is known as having aggro from that particular NPC. The NPC will attack that character if possible, unless another character manages to change the NPC's target. The tanking role usually has to pay particular attention to threat and how to hold it_."**What is tested**Every possible scenario involving 2 players.**What's still missing**It doesn't take into account healing as a mechanic of getting threat.**The code**All of this stuff is server-side of course, since server handles everything AI-related.First of all, some subs```Sub CheckTarget(ByVal MapNum As Long, ByVal MapNpcNum As Long)Dim i As Byte, CurrentThreat As Long, y As ByteFor i = 0 To 14    'MsgBox (x)  If MapNpc(MapNum).Npc(MapNpcNum).threat(i) > CurrentThreat Then    CurrentThreat = MapNpc(MapNum).Npc(MapNpcNum).threat(i)    y = i  End IfNext iIf CurrentThreat = 0 Then  MapNpc(MapNum).Npc(MapNpcNum).Target = 0  MapNpc(MapNum).Npc(MapNpcNum).targetType = 0Else  MapNpc(MapNum).Npc(MapNpcNum).Target = MapNpc(MapNum).Npc(MapNpcNum).Posstarget(y)  MapNpc(MapNum).Npc(MapNpcNum).targetType = 1End IfEnd SubSub AdjustThreat(ByVal MapNum As Long, ByVal MapNpcNum As Long, ByVal Index As Long, ByVal Damage As Long)Dim i As Byte, Updated As Boolean'This is if you have like a warrior class that you want to have tanking'If GetPlayerClass(Index) = WARRIOR Then'  Damage = Damage * 1.3'  Damage = Damage + 50'End ifFor i = 0 To 14  If MapNpc(MapNum).Npc(MapNpcNum).Posstarget(i) = Index Then    'Check if player is already in threat list    MapNpc(MapNum).Npc(MapNpcNum).threat(i) = MapNpc(MapNum).Npc(MapNpcNum).threat(i) + Damage    Updated = True    Exit For  End IfNext iIf Updated = False Then  For i = 0 To 14    If MapNpc(MapNum).Npc(MapNpcNum).Posstarget(i) = 0 Then      MapNpc(MapNum).Npc(MapNpcNum).Posstarget(i) = Index      MapNpc(MapNum).Npc(MapNpcNum).threat(i) = Damage      Updated = True      Exit For    End If  Next iEnd IfEnd SubSub RemoveThreat(Index As Long, MapNum As Long, MapNpcNum As Long)Dim i As ByteFor i = 0 To 14  If MapNpc(MapNum).Npc(MapNpcNum).Posstarget(i) = Index Then    MapNpc(MapNum).Npc(MapNpcNum).Posstarget(i) = 0    MapNpc(MapNum).Npc(MapNpcNum).threat(i) = 0    Exit For  End IfNext iCall CheckTarget(MapNum, MapNpcNum)End SubSub ResetThreat(ByVal MapNum As Long, MapNpcNum As Long)Dim i As ByteFor i = 0 To 14  MapNpc(MapNum).Npc(MapNpcNum).Posstarget(i) = 0  MapNpc(MapNum).Npc(MapNpcNum).threat(i) = 0Next iEnd Sub```Let's go trough them one by one. Sub CheckTarget is just something that checks what target on the NPC's list is highest on the list and should be attacked next. Sub AdjustThreat gives a player his threat after doing damage. The threat given is equal to the damage done. RemoveThreat and ResetThreat are both ways of clearing the memory, ResetThreat is for players(logoff), RemoveThreat is for the entire list (npc dies).In the Private Type MapNpcRec, we need to define the new properties, so add the below code in there. This just defines the variables that keep track of all the aggro list for all NPC's```  Posstarget(0 To 15) As Long  threat(0 To 15) As Long```Now, onto the part that handles NPC attacking,```        ' /////////////////////////////////////////////        ' // This is used for npcs to attack targets //        ' /////////////////////////////////////////////```We need to change the code that sets the target there to :```        If Map(MapNum).Npc(x) > 0 And MapNpc(MapNum).Npc(x).Num > 0 Then          Call CheckTarget(MapNum, x)          Target = MapNpc(MapNum).Npc(x).Target          targetType = MapNpc(MapNum).Npc(x).targetType          ' Check if the npc can attack the targeted player player          If Target > 0 Then            If targetType = 1 Then ' player              ' Is the target playing and on the same map?              If IsPlaying(Target) And GetPlayerMap(Target) = MapNum Then                TryNpcAttackPlayer x, Target              Else                ' Player left map or game, set target to 0                Call RemoveThreat(Target, MapNum, x)                'MapNpc(MapNum).Npc(x).targetType = 0 ' clear              End If            Else              ' lol no npc combat :(            End If          End If        End If```In Public Sub SpawnNPC we need to add```    Call ResetThreat(MapNum, MapNpcNum)```And after that we only need to call the add threat sub when a player damages an NPC. Below```   ' send animation    If n > 0 Then      If Not overTime Then        If spellnum = 0 Then Call SendAnimation(MapNum, Item(GetPlayerEquipment(attacker, Weapon)).Animation, 0, 0, TARGET_TYPE_NPC, MapNpcNum)      End If    End If```You need to change whatever there's into```   'Adjust the threat    Call AdjustThreat(MapNum, MapNpcNum, attacker, Damage)    'If required, adjust target    Call CheckTarget(MapNum, MapNpcNum)    ' Set the NPC target to the player```And you're done. Pretty simple I guess.**EDIT**I knew I missed something. in Sub NpcAttackPlayer, change```    ' Set NPC target to 0    MapNpc(MapNum).Npc(MapNpcNum).Target = 0    MapNpc(MapNum).Npc(MapNpcNum).targetType = 0```into```    ' Set NPC target to 0      Call RemoveThreat(victim, MapNum, MapNpcNum)      Call CheckTarget(Mapnum, MapNpcNum)```The attachment has one small error server-side, just try running it. Obvious fix is changing it into```      Call CheckTarget(MapNum, MapNpcNum)``` Link to comment Share on other sites More sharing options...
Mr.LLoyd Posted April 22, 2012 Share Posted April 22, 2012 I like the idea but you will need to test everything before posting. Link to comment Share on other sites More sharing options...
Joost Posted April 22, 2012 Author Share Posted April 22, 2012 In that case it works 100%. Trust me. Link to comment Share on other sites More sharing options...
Justn Posted April 22, 2012 Share Posted April 22, 2012 @Anosora:> I like the idea but you will need to test everything before posting.Really? Do u think everything is fully tested before it is posted here? Absolutely not…Good job joost I like this keep us posted on anything that comes up :) Link to comment Share on other sites More sharing options...
Joost Posted April 23, 2012 Author Share Posted April 23, 2012 Updated the code a bit to make sure I never find out what happens if there are too many people on the threat list by increasing the threat list to 15\. The only problem that can arise atm is the list not being reset properly at some point (works when player leaves map, disconnects, or warps but there might be other reasons) and that would be easily fixable. I'd say this is ready to be added to any game, especially since it is such a major major improvement over the old AI. Link to comment Share on other sites More sharing options...
zenmen Posted April 23, 2012 Share Posted April 23, 2012 Soo where exactly i must add this pieces of code? in which mod's in which plases ? : ) Link to comment Share on other sites More sharing options...
Joost Posted April 23, 2012 Author Share Posted April 23, 2012 The subs you can just add to the bottom of the gamelogic module. The rest of the code needs to replace the default code for targetting, you should be able to figure it out. Link to comment Share on other sites More sharing options...
zenmen Posted April 23, 2012 Share Posted April 23, 2012 To me have this straight, what and where, instead of what, under what, etc. Is it possible simpler explanation? : D I would be very grateful! Aggro is a brilliant thing .. Link to comment Share on other sites More sharing options...
Joost Posted April 23, 2012 Author Share Posted April 23, 2012 Attached is the source code added into a vanilla version of EO. Just take a look at that if you want to know where things go in more detail. Link to comment Share on other sites More sharing options...
Joost Posted April 23, 2012 Author Share Posted April 23, 2012 Had to fix my fix, should be 100% working now. Link to comment Share on other sites More sharing options...
erkro1 Posted May 2, 2012 Share Posted May 2, 2012 I can't find anything about Taunting, can you please give me a hint where I can find it? Link to comment Share on other sites More sharing options...
Joost Posted May 2, 2012 Author Share Posted May 2, 2012 I am working on something really cool now, will maybe add a taunting tutorial after that. It is pretty easy to rip the code too, just find all instances of Taunt and copy them. Link to comment Share on other sites More sharing options...
erkro1 Posted May 2, 2012 Share Posted May 2, 2012 @Joost:> I am working on something really cool now, will maybe add a taunting tutorial after that. It is pretty easy to rip the code too, just find all instances of Taunt and copy them.Well, thats the problem, I can't find the word 'Taunt' in both client and server. Link to comment Share on other sites More sharing options...
Joost Posted May 2, 2012 Author Share Posted May 2, 2012 did you download the attachment from the first post or one of my later posts? You need the one from the main post, deleted the other one. Link to comment Share on other sites More sharing options...
erkro1 Posted May 2, 2012 Share Posted May 2, 2012 @Joost:> did you download the attachment from the first post or one of my later posts? You need the one from the main post, deleted the other one.I downloaded the one from the main post. Link to comment Share on other sites More sharing options...
Joost Posted May 2, 2012 Author Share Posted May 2, 2012 fuck, i must've lost it. Link to comment Share on other sites More sharing options...
dimz Posted May 3, 2012 Share Posted May 3, 2012 I like the idea but, im trying to understand what it does. You say you can set up a warrior tank class to be the meatshield and you set a 15 players list that can be potential targets for monsters. Still, i dont understand how it is supposed to work ? Monsters will still go for the player who did the most damage or there is some kind of ''threat'' related to a particuliar class ?Id like to add this system to my game but i cant figure out how it works.Thanks Link to comment Share on other sites More sharing options...
Justn Posted May 3, 2012 Share Posted May 3, 2012 You have it right a monster will attack whoever deals the most damage to it. He also included a taunt spell in his source for warrior classes..Joost I was wondering what happens when 4 players block a monster and another person stands from afar and attacks while the others just stand there. Will it not attack anyone cause it can't reach the attacking player or will it give up since it can't reach him and attack one of the 4 players blocking it? Link to comment Share on other sites More sharing options...
7Eleven Posted May 4, 2012 Share Posted May 4, 2012 Wow this looks awesome, great job! I'm going to check it out right now Link to comment Share on other sites More sharing options...
Owen F Posted May 4, 2012 Share Posted May 4, 2012 @Justn:> You have it right a monster will attack whoever deals the most damage to it. He also included a taunt spell in his source for warrior classes..> > Joost I was wondering what happens when 4 players block a monster and another person stands from afar and attacks while the others just stand there. Will it not attack anyone cause it can't reach the attacking player or will it give up since it can't reach him and attack one of the 4 players blocking it?Not joost's problem really, that would be a problem with EO's AI regardless of Joost's system.Not sure if Robin ever did anything to prevent this. Link to comment Share on other sites More sharing options...
Justn Posted May 4, 2012 Share Posted May 4, 2012 I know its not Joost's problem.. but he is trying to fix the ai targeting.. I think that classifies as ai targeting.. just trying to help improve things. I think the ai needs to be completely changed anyways gonna work on it. No sense in adding this to an ai with holes already in it. Someone also told me that this isn't good for bigger servers due to the messy code? Just thought I would share.. ill let u know Joost if I come up with any improvements to the rest of the ai Link to comment Share on other sites More sharing options...
Joost Posted May 4, 2012 Author Share Posted May 4, 2012 It adds 2x15 longs to every NPC that's on a map, to save the damage and the index of the player (15 poss. players) Besides that, I'm not sure what's messy about it. (well, it is messy but nothing that should slow anything down) From my point of view this is such a major improvement of the old targetting system (where you could "bounce" a mob between 2 players constantly) that it is worth that. It allows proper party systems with tanks and dps and healers and makes any game feel more online and also creates unique roles for classes.The thing you mention with 4 ppl surrounding and 1 person damaging is correct, it will constantly try to run to the 5th player and fail. But yeah, this is a problem w/ the original code and w/ mine.For the taunting, I just added an extra spell variable, taunt as boolean in the spellrec, added checkbox in spelleditor and in the sub castspell (or handlespell, i dunno, whatever) I did a check if spell = taunt then find highest aggro and set taunters aggro to 110% of that. Not really difficult to do and a good training for new programmers so not too worried about the code being lost. Link to comment Share on other sites More sharing options...
Joost Posted May 4, 2012 Author Share Posted May 4, 2012 @dimz:> I like the idea but, im trying to understand what it does. You say you can set up a warrior tank class to be the meatshield and you set a 15 players list that can be potential targets for monsters. Still, i dont understand how it is supposed to work ? Monsters will still go for the player who did the most damage or there is some kind of ''threat'' related to a particuliar class ?> > Id like to add this system to my game but i cant figure out how it works.> ThanksI lost my taunt code but re-doing it is easy, see my above post. For an easy workaround, you can just check if GetPlayerClass(index) = a warrior and then multiple his threat by 300%. There is some commented out code in the subs that will show you what I mean. Link to comment Share on other sites More sharing options...
Owen F Posted May 4, 2012 Share Posted May 4, 2012 Personally I don't think the 4 players surrounding a boss and a 5th player attacking it is a big deal, hell, I think Runescape has that problem.The most annoying part about AI in my opinion is the constant move-stop-move-stop when pathfinding or just idly moving around the map.Of course, this really has hardly any relevance as this thread is about AI targeting, not movement, but yeah. just saying.Uhh what can I say that's on topic so I don't get warned.Well it's a nice code, I'm not entirely sure if it's ever been done and **released** before, but it has been a common request, well, it used to be a few years ago.It's definitely an improvement over the previous AI and every game should probably include this, although alter it to suit the game if necessary.**PS**It's kinda funny that Joost hasn't even got 100 posts yet and is more of a contribution to the community than like at least 3/4 of all registered users, if not more. Link to comment Share on other sites More sharing options...
Justn Posted May 4, 2012 Share Posted May 4, 2012 Hey Owen there is a way of removing the walk stop walk stop thing.. I remember robin saying there is a 1/4 chance that the box won't move.. just remove that check Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now