Vision Emulation
How a bot sees.
My concept of a vision emulation for a bot in Quake 2 would be based on the following assumptions.
1) The bot's eyes are only infront of him and on his face.
2) The bot cannot see something hidden behind a wall or door that isn't open
3) The has trouble seeing something cast in the shadows of a level.
Identifing if an entity is in front of you, is actually quite simple as has already been accomplished. In the g_ai.c souce released by id Software, you will find a routine that is called infront() and visibility(), All infront happens to do is returns true if an entity is in its field of view, false if it isn't. This is why you can sneak up behind some of the enemies in quake 2.
qboolean infront (edict_t *self, edict_t *other)
{
vec3_t vec;
float dot;
vec3_t forward;
AngleVectors (self->s.angles, forward, NULL, NULL);
VectorSubtract (other->s.origin, self->s.origin, vec);
VectorNormalize (vec);
dot = DotProduct (vec, forward);
if (dot > 0.3)
return true;
return false;
}
thats is the subroutine that checks if something is infront.
Client side bots have a built in way of this aspect with the visibility table the Server sends, Server side bots have a much more inherently complex approach to this problem. However this also has been accomplished again in g_ai.c As for the exact lines that accomplish this I haven't really chewed through the code quite enough to find it. I'll look into it in the future.
What I would envision for something is if a entity passes the infront check, it then sends range checks to see if he is close enough to see, and also if a solid object is in the way, both must be passed for a bot to see the entity.
Again this has already been accomplished, so careful checking of the Quake2 DLL or soem of the old QuakeC bots should allow someone to easily generate a routine.
note: I believe this will be found in the Visible() definition. Correct me if I am wrong.
For a bot not to be able to see someone well in the dark required a decent amount of creativity and some good programming but it can be done. This reference will be based on the B.I.P at inside 3D. Since it is the most easily found example and can also be adapted into C quite easily. id Software also has this built into Quake 2 supposedly, I don't have a good example you can try to check it but I am assuming it is in there.
void () botSetNearLight =
{
local entity e;
local entity targ;
targ = self.enemy;
e = findradius (targ.origin,200);
if (e.classname == "light")
nearlight = TRUE;
};
That is the subroutine that check to see if the bot is in a decent amount of light
botSetNearLight();
if (!(nearlight) && (random() < 0.7)) return;
That was the check to see if he will be able to see a player. Nothing really strange in this code. The findradius simply check for a "light" near the entity.
This routine also assumes you have all sources of light has a classname assigned as light when they are spawned.
self.classname = "light";
Other notes.
That is generally what a bot requires to have somewhat realistic vision. I personally believe a field of view of about 140 degrees would be the most accurate and useful. Also the bot should be able to deal with a target that is firing behind, all be it not well since were attempting to generate a bot that is not distinguishable from a human opponent. Say it changes direction if a Rocket sound goes off. Not flawless but a natural human reaction.
This also allows one to use tactics to get a bot. Not just brute fire fight skills. A long range sniper has a pretty good shot at ths guy, bot no more then a real player.
}