project-navigation
Personal tools

Author Topic: Enhancing civilians' behavior (proposition of code)  (Read 4908 times)

alexis

  • Guest
Enhancing civilians' behavior (proposition of code)
« on: June 20, 2008, 02:21:30 pm »
I have a code suggestions to modify civilians' behavior. This concerns the AI_CivilianCalcBestAction function defined in the g_ai.c file.

AI_CivilianCalcBestAction is called to test each square were a civilian can go, and returns a number estimating the benefit of the move (higher value = best move). for now, this number is the sum of three factors:
- the distance to the nearest alien
- a laziness factor (to encourage civilians to consume the more TU they can)
- a random factor

The first factor (distance to the nearest alien) is taken into account only for distance <RUN_AWAY_DIST = 5 cells!! This must be modified.

I made some modifications, but I didn't have tested them much (I tried few maps only). Maybe other people involved in ufoai development can adapt my suggestion to have better results.

Here is what my modified code does:
1 - the civilian reaction is different when the distance to the nearest alien is small or big.
2 - civilians are encouraged a little to regroup when they are close
3 - moving close to a fighter is encouraged a little, but not too close to avoid figthers being blocked.
4 - civilians are encouraged to find places were aliens don't see them.

Here is my source code of AI_CivilianCalcBestAction:
Code: [Select]
static float AI_CivilianCalcBestAction (edict_t * ent, pos3_t to, aiAction_t *aia)
{
edict_t *check;
int i, move, tu;
float dist, minDist, minDistCivilian, minDistFighter;
float bestActionPoints;

/* set basic parameters */
bestActionPoints = 0.0;
memset(aia, 0, sizeof(*aia));
VectorCopy(to, ent->pos);
VectorCopy(to, aia->to);
VectorCopy(to, aia->stop);
gi.GridPosToVec(gi.routingMap, to, ent->origin);

move = gi.MoveLength(gi.routingMap, to, qtrue);
tu = ent->TU - move;

/* test for time */
if (tu < 0)
return AI_ACTION_NOTHING_FOUND;

/* check whether this civilian can use weapons */
if (ent->chr.teamDef) {
const teamDef_t* teamDef = ent->chr.teamDef;
if (ent->state & ~STATE_PANIC && teamDef->weapons)
return AI_FighterCalcBestAction(ent, to, aia);
} else
Com_Printf("AI_FighterCalcBestAction: Error - civilian team with no teamdef\n");

/* run away */
minDist = RUN_AWAY_DIST*UNIT_SIZE;
minDistCivilian=RUN_AWAY_DIST*UNIT_SIZE;
minDistFighter=RUN_AWAY_DIST*UNIT_SIZE;
for (i = 0, check = g_edicts; i < globals.num_edicts; i++, check++){
if (check->inuse && check->team == TEAM_ALIEN && !(check->state & STATE_DEAD) && ent != check) {
dist = VectorDist(ent->origin, check->origin);
if (dist && dist < minDist)
minDist = dist;
}
if (check->inuse && check->team == TEAM_CIVILIAN && !(check->state & STATE_DEAD) && ent != check) {
dist = VectorDist(ent->origin, check->origin);
if (dist && dist < minDistCivilian)
minDistCivilian = dist;
}
if (check->inuse && check->team == TEAM_PHALANX && !(check->state & STATE_DEAD) && ent != check) {
dist = VectorDist(ent->origin, check->origin);
if (dist && dist < minDistFighter)
minDistFighter = dist;
}

}
float delta=0.0;/*GUETE_RUN_AWAY * minDist / RUN_AWAY_DIST;*/
minDist/=UNIT_SIZE;
minDistCivilian/=UNIT_SIZE;
minDistFighter/=UNIT_SIZE;
if(minDist<8.0){
/*very near an alien: run away fast*/
delta=4.0 * minDist;
}else if(minDist<16.0){
/*near an alien: run away*/
delta=24.0+minDist;
}else if(minDist<24.0){
/*near an alien: run away slower*/
delta=40.0+(minDist-16)/4;
}else{
delta=42.0;
}
/*near a civilian: join him (1/3)*/
if(minDistCivilian<10.0)
delta+=(10.0-minDistCivilian)/3.0;
/*near a fighter: join him (1/5)*/
if(minDistFighter<15.0)
delta+=(15.0-minDistFighter)/5.0;
/*don't go close to a fighter to let him move*/
if(minDistFighter<2.0)
delta/=10.0;

/*try to hide*/
float reaction_trap=0.0;
for (i = 0, check = g_edicts; i < globals.num_edicts; i++, check++)
if (check->inuse && G_IsLivingActor(check) && ent != check
&& (check->team == TEAM_ALIEN || ent->state & STATE_INSANE) && G_ActorVis(check->origin, ent, qtrue) > 0.25)
reaction_trap+=25.0;
delta-=reaction_trap;
bestActionPoints += delta;

/* add laziness */
if (ent->TU)
bestActionPoints += GUETE_CIV_LAZINESS * tu / ent->TU;
/* add random effects */
bestActionPoints += GUETE_CIV_RANDOM * frand();

return bestActionPoints;
}
« Last Edit: June 20, 2008, 02:34:07 pm by BTAxis »

Offline BTAxis

  • Administrator
  • PHALANX Commander
  • *******
  • Posts: 2607
    • View Profile
Re: Enhancing civilians' behavior (proposition of code)
« Reply #1 on: June 20, 2008, 02:35:09 pm »
Note that bobbens is in the process of rewriting the AI. It might be some time before he's finished, so maybe this can function as a stopgap measure, but I don't know.

Offline Mattn

  • Administrator
  • PHALANX Commander
  • *****
  • Posts: 4831
  • https://github.com/mgerhardy/vengi
    • View Profile
    • Vengi Voxel Tools
Re: Enhancing civilians' behavior (proposition of code)
« Reply #2 on: June 20, 2008, 05:50:21 pm »
Note that bobbens is in the process of rewriting the AI. It might be some time before he's finished, so maybe this can function as a stopgap measure, but I don't know.

thanks for the patch - i will have a look. if you plan further improvements, feel free to send them, because bobbens changes won't make it into 2.3

but please have a look at the coding guidellines ;)

Offline Mattn

  • Administrator
  • PHALANX Commander
  • *****
  • Posts: 4831
  • https://github.com/mgerhardy/vengi
    • View Profile
    • Vengi Voxel Tools
Re: Enhancing civilians' behavior (proposition of code)
« Reply #3 on: June 20, 2008, 06:06:01 pm »
i've applied your patch to our svn for public testing, feedback is welcome - and as i said - if you have further improvements, let me know...

alexis

  • Guest
Re: Enhancing civilians' behavior (proposition of code)
« Reply #4 on: June 20, 2008, 07:40:29 pm »
Thanks for reacting so fast.

You have rewritten the code relatively to your coding guidelines before feeding the svn and that's cool, but you put an "assert(dist)" that can fail (I don't known why VectorDist return 0.0 but sometimes it does!). Please replace this line by an "if(idist)continue;" (before the switch statement).

NB: of course the code I submitted is a workaround to wait for a better AI, I hope so :)

Offline Mattn

  • Administrator
  • PHALANX Commander
  • *****
  • Posts: 4831
  • https://github.com/mgerhardy/vengi
    • View Profile
    • Vengi Voxel Tools
Re: Enhancing civilians' behavior (proposition of code)
« Reply #5 on: June 20, 2008, 08:22:02 pm »
You have rewritten the code relatively to your coding guidelines before feeding the svn and that's cool, but you put an "assert(dist)" that can fail (I don't known why VectorDist return 0.0 but sometimes it does!). Please replace this line by an "if(idist)continue;" (before the switch statement).

that's why there is an assert - this should not happen, there should not be a zero distance, because there should never more than one actor on the same grid field. i've added a G_IsLivingActor check to the loop - i hope that fixes it.

alexis

  • Guest
Re: Enhancing civilians' behavior (proposition of code)
« Reply #6 on: June 20, 2008, 09:01:48 pm »
G_IsLivingActor seems to fix the crash - Thanks.