if (AI_HideNeeded(ent) || !(G_TestVis(hidingTeam, ent, VT_PERISH | VT_NOFRUSTUM) & VIS_YES)) {
/* is a hiding spot */
//bestActionPoints += GUETE_HIDE + (aia->target ? GUETE_CLOSE_IN : 0);
bestActionPoints += guete_hide->integer + (aia->target ? guete_close_in->integer : 0); //AI TESTING MODIFICATION FROM NONICKCH
}
I dug through the archive and i figured out whats wrong.
first occurence is ok
/* hide */
if (!(G_TestVis(-ent->team, ent, VT_PERISH | VT_NOFRUSTOM) & VIS_YES)) {
/* is a hiding spot */
guete += GUETE_HIDE + (aia->target ? GUETE_CLOSE_IN : 0);
} else if (aia->target && tu >= 2) {
then a todo was added:
/* hide */
/** @todo Only hide if the visible actors have long range weapons in their hands
* otherwise make it depended on the mood (or some skill) of the alien whether
* it tries to attack by trying to get as close as possible or to try to hide */
if (!(G_TestVis(-ent->team, ent, VT_PERISH | VT_NOFRUSTUM) & VIS_YES)) {
/* is a hiding spot */
bestActionPoints += GUETE_HIDE + (aia->target ? GUETE_CLOSE_IN : 0);
/** @todo What is this 2? */
} else if (aia->target && tu >= 2) {
the next step is an implementon of the todo:
/* hide */
/** @todo Only hide if the visible actors have long range weapons in their hands
* otherwise make it depended on the mood (or some skill) of the alien whether
* it tries to attack by trying to get as close as possible or to try to hide */
if (!(G_TestVis(-ent->team, ent, VT_PERISH | VT_NOFRUSTUM) & VIS_YES) || AI_NoHideNeeded(ent)) {
/* is a hiding spot */
bestActionPoints += GUETE_HIDE + (aia->target ? GUETE_CLOSE_IN : 0);
} else if (aia->target && tu >= TU_MOVE_STRAIGHT) {
this code is ok,
but if you look at the AI_NoHideNeeded
/**
* @param ent The alien edict that checks whether it should hide
* @return true if hide is needed or false if the alien thinks that it is not needed
*/
static qboolean AI_NoHideNeeded (edict_t *ent)
you realize that the description of the @return and the function name don't match. So AI_NoHideNeeded changed to
/**
* @brief Checks whether the given alien should try to hide because there are enemies close
* enough to shoot the alien.
* @param ent The alien edict that should (maybe) hide
* @return @c true if hide is needed or @c false if the alien thinks that it is not needed
*/
static qboolean AI_HideNeeded (edict_t *ent)
and our hiding code now is:
/* hide */
if (AI_HideNeeded(ent) || !(G_TestVis(-ent->team, ent, VT_PERISH | VT_NOFRUSTUM) & VIS_YES)) {
/* is a hiding spot */
bestActionPoints += GUETE_HIDE + (aia->target ? GUETE_CLOSE_IN : 0);
} else if (aia->target && tu >= TU_MOVE_STRAIGHT) {
and that is error, the name of the function in this context was right. So now there is a "!" missing. The code realy should look like:
/* hide */
if (!AI_HideNeeded(ent) || !(G_TestVis(-ent->team, ent, VT_PERISH | VT_NOFRUSTUM) & VIS_YES)) {
/* is a hiding spot */
bestActionPoints += GUETE_HIDE + (aia->target ? GUETE_CLOSE_IN : 0);
} else if (aia->target && tu >= TU_MOVE_STRAIGHT) {
the last change has no problems so the code
should be
/* hide */
if (!AI_HideNeeded(ent) || !(G_TestVis(hidingTeam, ent, VT_PERISH | VT_NOFRUSTUM) & VIS_YES)) {
/* is a hiding spot */
bestActionPoints += GUETE_HIDE + (aia->target ? GUETE_CLOSE_IN : 0);
} else if (aia->target && tu >= TU_MOVE_STRAIGHT) {
---------------------------------------------------------------------------------------------------------------------------
Now let's take a closer look at AI_HideNeeded
/**
* @brief Checks whether the given alien should try to hide because there are enemies close
* enough to shoot the alien.
* @param ent The alien edict that should (maybe) hide
* @return @c true if hide is needed or @c false if the alien thinks that it is not needed
*/
static qboolean AI_HideNeeded (edict_t *ent)
{
/* only brave aliens are trying to stay on the field if no dangerous actor is visible */
if (ent->morale > mor_brave->integer) {
edict_t *from = NULL;
/* test if check is visible */
while ((from = G_EdictsGetNextLivingActor(from))) {
if (from->team == ent->team)
continue;
if (G_IsCivilian(from))
continue;
if (G_IsVisibleForTeam(from, ent->team)) {
const invList_t *invlist = RIGHT(from);
const fireDef_t *fd = NULL;
if (invlist && invlist->item.t) {
fd = FIRESH_FiredefForWeapon(&invlist->item);
} else {
invlist = LEFT(from);
if (invlist && invlist->item.t)
fd = FIRESH_FiredefForWeapon(&invlist->item);
}
/* search the (visible) inventory (by just checking the weapon in the hands of the enemy */
if (fd != NULL && fd->range * fd->range >= VectorDistSqr(ent->origin, from->origin)) {
const int damage = max(0, fd->damage[0] + (fd->damage[1] * crand()));
if (damage >= ent->HP / 3) {
const int hidingTeam = AI_GetHidingTeam(ent);
/* now check whether this enemy is visible for this alien */
if (G_Vis(hidingTeam, ent, from, VT_NOFRUSTUM))
return qtrue;
}
}
}
}
}
return qfalse;
}
If I am right only brave aliens (when they are threatened by enemy fire) ever feel the urge to hide.
It looks like the code is stuck somewhere between the implementation of AI_HideNeeded and AI_NoHideNeeded.
This code should work fine.
/**
* @brief Checks whether the given alien should try to hide because there are enemies close
* enough to shoot the alien.
* @param ent The alien edict that should (maybe) hide
* @return @c true if hide is needed or @c false if the alien thinks that it is not needed
*/
static qboolean AI_HideNeeded (edict_t *ent)
{
/* only brave aliens are trying to stay on the field if no dangerous actor is visible */
if (ent->morale > mor_brave->integer) {
edict_t *from = NULL;
/* test if check is visible */
while ((from = G_EdictsGetNextLivingActor(from))) {
if (from->team == ent->team)
continue;
if (G_IsCivilian(from))
continue;
if (G_IsVisibleForTeam(from, ent->team)) {
const invList_t *invlist = RIGHT(from);
const fireDef_t *fd = NULL;
if (invlist && invlist->item.t) {
fd = FIRESH_FiredefForWeapon(&invlist->item);
} else {
invlist = LEFT(from);
if (invlist && invlist->item.t)
fd = FIRESH_FiredefForWeapon(&invlist->item);
}
/* search the (visible) inventory (by just checking the weapon in the hands of the enemy */
if (fd != NULL && fd->range * fd->range >= VectorDistSqr(ent->origin, from->origin)) {
const int damage = max(0, fd->damage[0] + (fd->damage[1] * crand()));
if (damage >= ent->HP / 3) {
const int hidingTeam = AI_GetHidingTeam(ent);
/* now check whether this enemy is visible for this alien */
if (G_Vis(hidingTeam, ent, from, VT_NOFRUSTUM))
return qtrue;
}
}
}
}
return qfalse;
}
return qtrue;
}
What do you think?
It's quite late and I hope there are not too many errors in this post.