/* ======================================================================================================================================= BotNearestVisibleItem ======================================================================================================================================= */ float BotNearestVisibleItem(bot_state_t *bs, char *itemname, bot_goal_t *goal) { int i; char name[64]; bot_goal_t tmpgoal; float dist, bestdist; vec3_t dir; bsp_trace_t trace; bestdist = 999999; i = -1; do { i = trap_BotGetLevelItemGoal(i, itemname, &tmpgoal); trap_BotGoalName(tmpgoal.number, name, sizeof(name)); if (Q_stricmp(itemname, name) != 0) { continue; } VectorSubtract(tmpgoal.origin, bs->origin, dir); dist = VectorLength(dir); if (dist < bestdist) { // trace from start to end BotAI_Trace(&trace, bs->eye, NULL, NULL, tmpgoal.origin, bs->client, CONTENTS_SOLID|CONTENTS_PLAYERCLIP); if (trace.fraction >= 1.0) { bestdist = dist; memcpy(goal, &tmpgoal, sizeof(bot_goal_t)); } } } while (i > 0); return bestdist; }
/* ================== BotValidChatPosition ================== */ int BotValidChatPosition( bot_state_t *bs ) { vec3_t point, start, end, mins, maxs; bsp_trace_t trace; //if the bot is dead all positions are valid if ( BotIsDead( bs ) ) { return qtrue; } //must be on the ground //if (bs->cur_ps.groundEntityNum != ENTITYNUM_NONE) return qfalse; //do not chat if in lava or slime VectorCopy( bs->origin, point ); point[2] -= 24; if ( trap_PointContents( point,bs->entitynum ) & ( CONTENTS_LAVA | CONTENTS_SLIME ) ) { return qfalse; } //do not chat if under water VectorCopy( bs->origin, point ); point[2] += 32; if ( trap_PointContents( point,bs->entitynum ) & MASK_WATER ) { return qfalse; } //must be standing on the world entity VectorCopy( bs->origin, start ); VectorCopy( bs->origin, end ); start[2] += 1; end[2] -= 10; trap_AAS_PresenceTypeBoundingBox( PRESENCE_CROUCH, mins, maxs ); BotAI_Trace( &trace, start, mins, maxs, end, bs->client, MASK_SOLID ); if ( trace.ent != ENTITYNUM_WORLD ) { return qfalse; } //the bot is in a position where it can chat return qtrue; }
/* ================== BotValidChatPosition ================== */ int BotValidChatPosition(bot_state_t *bs) { vec3_t point, start, end, mins, maxs; bsp_trace_t trace; //if the bot is dead all positions are valid if (BotIsDead(bs)) return qtrue; //never start chatting with a powerup if (bs->inventory[INVENTORY_QUAD] || bs->inventory[INVENTORY_ENVIRONMENTSUIT] || bs->inventory[INVENTORY_HASTE] || bs->inventory[INVENTORY_INVISIBILITY] || bs->inventory[INVENTORY_REGEN] || bs->inventory[INVENTORY_FLIGHT]) return qfalse; //must be on the ground //if (bs->cur_ps.groundEntityNum != ENTITYNUM_NONE) return qfalse; //do not chat if in lava or slime VectorCopy(bs->origin, point); point[2] -= 24; if (trap_PointContents(point,bs->entitynum) & (CONTENTS_LAVA|CONTENTS_SLIME)) return qfalse; //do not chat if under water VectorCopy(bs->origin, point); point[2] += 32; if (trap_PointContents(point,bs->entitynum) & MASK_WATER) return qfalse; //must be standing on the world entity VectorCopy(bs->origin, start); VectorCopy(bs->origin, end); start[2] += 1; end[2] -= 10; trap_AAS_PresenceTypeBoundingBox(PRESENCE_CROUCH, mins, maxs); BotAI_Trace(&trace, start, mins, maxs, end, bs->playernum, MASK_SOLID); if (trace.entityNum != ENTITYNUM_WORLD) return qfalse; //the bot is in a position where it can chat return qtrue; }