Page 1 of 1

Some small ai changes i need help with.

Posted: Mon Apr 30, 2007 5:15 pm
by fps
I need some help changing some stuff in the ai script i am working on, its pretty basic but i still can't remember how i should do it.

first. my guys use radio commands to report certain things.
the order looks looks this.

{
PlaySound(RADIOCLICK);
random(0,5)
{
case0
{
PlaySound(NOTARGETS)
}
ect...

how should i make a delay between the radio click and the message?

also a slightly larger topic. I cant remember were to find this.
the whole idea behind this script is to work in squads soooo.... how would i go about making the pawns not shoot the pawns between themselves and the targeted pawns.

the pawn uses the targeting system from the post i did before this.

also yet again...
Is there a way to send orders directly from one pawn to another?
Like this

friendly_1 = on attack order, target visible.
CallBackup();
{
if(random(1,10) < 2)
{
for(FRIENDLYNUMBER 1 - 10)
if((friendly_ # FRIENDLYNUMBER) is within 1000 textels)
{
friendly_ # FRIENDLYNUMBER.think = backuptotargetpositionfriendly1
}

Then in the other pawn
friendly_2
BackupToTargetPositionfriendly1();
{
if(random(1,10) < 5)
{
Friendly_1.TargetX = TargetX
Friendly_1.TargetY = TargetY
Friendly_1.TargetZ = TargetZ
Then some orders to get friendly2 to go there and give supporting fire
}
}

what would i need to do to get some sort of system like this to work.
PS. i am thinking about making friendly_1 a commander pawn script in each level or i could use If(friendly_1.COMMANDER = true) then obey his orders.



one more question. I dont want pawns to attack dead bodies of targets.

will this work.
If(self.Target HEALTHATTRIB > 1)
{
Attack();
}
else
{
TargetEliminated();
}


thanks,
fps

Posted: Tue May 01, 2007 10:41 am
by Juutis
how should i make a delay between the radio click and the message?
You could add the click and a little delay to each message sound. That way you would only have to play one sound.
how would i go about making the pawns not shoot the pawns between themselves and the targeted pawns.
The only way I can think of is to use TraceToActor(). You could trace a line to the target and if it returns the name of the target or 'false', there's no pawns in between and the pawn can fire.


Code: Select all

friendly_ # FRIENDLYNUMBER.think = backuptotargetpositionfriendly1
I don't think this will work. I'm not sure though. Doing it by accessing the other pawn's variables should work, like this:

Code: Select all

friendly_ # FRIENDLYNUMBER.nextorder = StringCopy("BackUpToTargetPositionfriendly1");
friendly_ # FRIENDLYNUMBER.changeorder = true;
Then with the other pawn:

Code: Select all

if(changeorder)
{
    changeorder = false;
    self.think = nextorder;
}

i am thinking about making friendly_1 a commander pawn script in each level or i could use If(friendly_1.COMMANDER = true) then obey his orders.
I would make a seperate script for him. It's much easier and simpler that way. You would have to stuff everything into one script otherwise and the script would probably become huge!

will this work.
If(self.Target HEALTHATTRIB > 1)
Basically, yes. Though I think it would have to be "if(GetAttribute(HEALTHATTRIB,self.Target) > 1)".


Ugh, what an ugly looking post. Hope it doesn't bother you too much.

Posted: Thu May 03, 2007 2:54 pm
by Jay
Juutis wrote:

Code: Select all

friendly_ # FRIENDLYNUMBER.think = backuptotargetpositionfriendly1
I don't think this will work. I'm not sure though. Doing it by accessing the other pawn's variables should work, like this:

Code: Select all

friendly_ # FRIENDLYNUMBER.nextorder = StringCopy("BackUpToTargetPositionfriendly1");
friendly_ # FRIENDLYNUMBER.changeorder = true;
Both of this won't work, because '#' concates strings, and nothing else. So you could write "friendly_" # FRIENDLYNUMBER.changeorder=true;
but that would not work, because '#' also returns strings, so you would try to do that, for example:
"friendly_01".changeorder=true;
I had this problem too once i tried to do that:
MousSelect(true,true).STRATEGY=1;
which never worked.

Posted: Thu May 03, 2007 7:10 pm
by Juutis
Oh yes, you're absolutely right, Jay. I knew there was a problem with this thing when I was writing that post but couldn't remember what it was. So thanks for correcting me. :)

So other pawns' variables can't be accessed without knowing the name when writing the script. Strings won't work. However, there is a workaround I think. With a string that contains the name of an entity you can access other entities' attributes! You could add an attribute called 'ReceivedOrder', for example, and then modify it with the commander's script. You could do like, 0 = no order, 1 = attack enemy, 2 = take cover, etc... You could modify the attribute with this line:
SetAttribute("ReceivedOrder",1,friendly_ # FRIENDLYNUMBER);

Then the non-commander pawn would check if the 'ReceivedOrder' attribute is 1 and attack the enemy. You could also add several attributes, like 'enemy_x', 'enemy_y' and 'enemy_z' through which the commander could update the enemy position.

It's a bit more tricky, but I'm almost 100% certain it works.

Posted: Fri May 04, 2007 5:51 pm
by fps
I will get to trying some of this stuff this weekend.
thank you for all the help so far.
I will see if i get any more problems.

thanks,
fps

Posted: Sun May 13, 2007 9:09 pm
by fps
i am finally getting around to testing some of this stuff.

i am having trouble getting the pawn not to attack dead pawns.

im having toruble with the getattribute command and i tryed the "int enemyexist" command but both are giving me errors.

heres how i am trying it. this is not exact.

Code: Select all

AquireTargets[( 
for 1 - 10 = enemynumber
{
    if(entityisvisable = ("foe_" # enemynumber) and if(GetAttribute(HEALTHATTRIB,"foe_" # enemynumber) > 1) )
    {
    SetTarget("foe_" # enemynumber)
    }
}
)]
if i mess this bit of code up so it dosent read it right it just freezes the pawn. but if the code reads through it shuts the game down without writing anything to the RF.log.
The only part of the code i have changed to maake it not work is the

Code: Select all

and if(GetAttribute(HEALTHATTRIB,"foe_" # enemynumber) > 1)
part, the rest may look messed up here because i am working from memory.

can you guys tell me what i messed up?

thanks,
fps

Posted: Sun May 13, 2007 9:18 pm
by Juutis

Code: Select all

if(entityisvisable = ("foe_" # enemynumber) and if(GetAttribute(HEALTHATTRIB,"foe_" # enemynumber) > 1) )
Should be something like

Code: Select all

if(IsEntityVsible("foe_" # enemynumber) and (GetAttribute(HEALTHATTRIB,"foe_" # enemynumber) > 1))
You need only one if.

Posted: Sun May 13, 2007 9:39 pm
by fps
i think thats waht i have. but i will double check. it tryed it like 12 different ways. i ever divided it up like this.

Code: Select all

AquireTargets[( 
for 1 - 10 = enemynumber 
{ 
     
if(IsEntityVsible("foe_" # enemynumber) )
    {
        if(GetAttribute(HEALTHATTRIB,"foe_" # enemynumber) > 1) 
        { 
        SetTarget("foe_" # enemynumber) 
        } 
    }
} 
)] 
now i would have thought that that would have worked.
would there be a simple way to just not search for the enemynumber of those known to be dead or somthing.

i think i also need the target to be set to "none" if the pawn it tries to target has 0 for health.

also when i say HEALTHATTRIB should this refer to this HEALTHATTRIBUTE [health] or this HEALTH [100] ?

Posted: Mon May 14, 2007 2:16 pm
by Juutis
also when i say HEALTHATTRIB should this refer to this HEALTHATTRIBUTE [health] or this HEALTH [100]
It should be the health attribute of the enemy pawn. So if you're using different attributes for different teams (like health_friend and health_foe), it should be the attribute of the opposite team.

Posted: Wed May 16, 2007 10:09 am
by Juutis
i am having trouble getting the pawn not to attack dead pawns.

im having toruble with the getattribute command and i tryed the "int enemyexist" command but both are giving me errors.
Now that I reread the previous post of yours, I realized something.

Note that the command is 'EnemyExists()'. You can use it in the attacking order of your pawn to see if the target is dead.

Code: Select all

if(EnemyExists(ENEMY_HEALTH_ATTRIBUTE) < 3) //the target is dead, removed or doesn't have the right attribute
{
     self.think = TARGET_LOST;
     return 0;
}
... where ENEMY_HEALTH_ATTRIBUTE is the health attribute of your enemy and TARGET_LOST is the order you want the pawn to go to after killing the enemy.

Posted: Wed May 16, 2007 3:03 pm
by fps
thanks Juutis! :)
thats going to be really helpfull.
I just got a basic system for not shooting allied pawns in the back so this should help a lot. I was even working on a killed target order based on the lost target order so i already have a step completed.



is there a way to use that command in the AquireTargets order so that once a dead pawn has been targeted it will never target that specific pawn again. somthing like a list of pawns not to target or somthing?

i think (and may be wrong) that if i use that order you posted in the attack aquire targets (which is run very often) instead of the IsCurrentTargetDead command, that it will continually loop between Killed_Target and Aquire Target when it can see a dead enemy.

it might just keep looking back at the target and saying the GOTCHA 1- 5 stuff then turing away and back again.

if you already know that this wont happen, then i will not bother to change it. im just not entirely sure.

i allready made the mistake of generating 10 varriants of allied and enemy scripts with different weapons and voices, ect... but they all have the same or similar errors. so each time i need to test a script modification on a wide scale i need to modify all 10 scripts at once, otherwise i wouldent be able to see the modification run in all senerios and i would have to run the one test 10 times to compensate. so i have before managed to mess up 9 out of the 10 scripts just to pull them back to running condition. oh well... :roll:

I am at least getting closter to being compleated with your help. :)

thanks,
fps

Posted: Thu May 17, 2007 5:31 pm
by fps
I just realised that if i use the EnemyExists thing i already have to have a target picked. i must need to use the GetAttribute Command. I experimented with the EntityExist command yesterday but it dosent work right for what i am using it for. i can use that for somthing else but not this. i was testing it by seting the target on sight then if it had the attribute it would set the target again or else set the target to somthing else.
I was having trouble getting the GetAttribute command to work in the AquireTargets command but it was probably just me. i will try it again.
Thanks,
fps