How would this 'decision tree' look like in pawn ?
#1

Hello there,

I am working on a small A.I. for npc behavior. With the knowledge i have now i would end up
having alot of
pawn Код:
if(blabla
and
pawn Код:
case : blabla
and so on..anything i can find in wiki's 'Control Structures' page actualy.

Obviously i want to script this as short as possible so the npc doesnt take to much time to 'decide' something.

My question is, how would a decision tree like below look like in pawn ? How would you do it ? and like i stated before without too many unnecessary structures.



Note: Dont get me wrong im not being lazy here waiting for someone to write an entire script. Just an opinion
and/or good basic structure shouldnt be too much to ask.

Thanks in advance.

your Artificial Intelligence pedestrian
Reply
#2

Well, it wont be easy but I thought of something quick.


Perhaps you could use OnPlayerUpdate, or any other timer you want to do per 250-300 ms, however let's move on. You check if the player is in range of the NPC, he is? Determine between the player's facing angle and the NPC's. if NPC Angle+180 = PlayerAngle. Then the player is facing the NPC. This wont work only if the player is FACING the NPC though.
Reply
#3

Quote:
Originally Posted by DaniceMcHarley
Посмотреть сообщение
Well, it wont be easy but I thought of something quick.


Perhaps you could use OnPlayerUpdate, or any other timer you want to do per 250-300 ms, however let's move on. You check if the player is in range of the NPC, he is? Determine between the player's facing angle and the NPC's. if NPC Angle+180 = PlayerAngle. Then the player is facing the NPC. This wont work only if the player is FACING the NPC though.
Well we dont have to worry about the way of 'how to check if a player is in range' I just used a 'well known' streamer and attached an area per npc.
onplayerenterarea will do the rest with a few if statements.

The fact of me wanting to check many things keeps me wondering how to do it in a most efficient way.

and not end up to something like this for example;
pawn Код:
if(isnpcinvehicle
if(npc is cop && player is cop

else if(

else if(
else if(
else if(
else if(
else if(

else
{
if(npc is civilian
else if(

else if(
else if(
else if(
else if(
else if(

else
{
if(npc is gangmember

if(!isplayerinvehicle)

bla bla bla
Reply
#4

Since we don't have 100 cases and ifs, I think the if-structure is good. With indentation you can clearly see what's where + an editor with more than just standard functions would make it well organzized (letting you snap in single functions/areas).

But I'm just saying that because I don't think there is another efficient way
A switch-case wouldn't work out because you don't have only numbers here, but conditions (except the 'states').

The only alternative are jumps, but they will make it a chaos.


Problem is, you don't have all the information you need at one place (e.g. in one timer callback), meaning you get some information from callbacks (like shots) but some are only accessible through a timer.

So splitting it up to as many callbacks as possible is the most efficient way, but not that easy.
Reply
#5

Quote:

Problem is, you don't have all the information you need at one place (e.g. in one timer callback), meaning you get some information from callbacks (like shots) but some are only accessible through a timer.

So splitting it up to as many callbacks as possible is the most efficient way, but not that easy.

I see..and would hooking callbacks be an option to get anything in order ?
Reply
#6

Quote:
Originally Posted by AIped
Посмотреть сообщение
I see..and would hooking callbacks be an option to get anything in order ?
Yea that could be useful for some things.
Reply
#7

Mate, I'm using Finite State Machine method. All conditions controlled by PVar's. It's the most simple and effective enough way to do something. Many of the games used it early, but I think many of the games still using it=) get me in skype for more details=) But in general for this things I'm using the main NPC timer with 100 ms checking. Your NPC has a conditions which changed when something happens. For example, after spawn your NPC has SetPVar(npcid,"Condition",0); - it will the first check of your timer, the most easier check - to get the closest player. If(TheClosestPlayerDistance < 40.0) SetPVar(npcid,"Condition",1); next you should to write what will happens if condition will be = 1. For example
If(GetPVar(npcid,"Condition")==1)
{
if(FCNPC_GetAmmo(npcid)==0)
{
SetPVar(npcid,"Condition",2);
}
if(FCNPC_GetAmmo(npcid)!=0)
{
SetPVar(npcid,"Condition",3);
}
}
If(GetPVar(npcid,"Condition")==2)
{
FCNPC_GoTo(npcid,escape_x,escape_y,escape_z,MOVE_T YPE_SPRINT,0.0,0.0);
SetPVar(npcid,"Condition",4); // that this PVar does not be called early that we need
}
If(GetPVar(npcid,"Condition")==3)
{
new Float, Float:y, Float:z;
GetPlayerPos(TheClosestPlayer,x,y,z);
FCNPC_AimAt(npcid,x,y,z,1.0);
}
public FCNPC_OnReachDestination(npcid)
{
If(GetPVar(npcid,"Condition")==4)
{
SetPVar(npcid,"Condition",0);
}
}
So it's just an example, if you need something specific just ask me about it=)
Reply
#8

better use switch case: combination for that dude
Reply
#9

https://sampforum.blast.hk/showthread.php?tid=216730

Tried using a ternary operator?
Reply
#10

Quote:
Originally Posted by Satori_Komeiji
Посмотреть сообщение
I dont think so and i never saw that thread thank you very much.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)