/** * @brief Moves the actor into a position in which he can hide. * @note @c team (parameter is passed through the lua stack) means that the AI tries to find * a hide position from the @c team members, if parameter is empty - from any enemy */ static int AIL_positionhide (lua_State *L) { pos3_t save; int tus = G_ActorUsableTUs(AIL_ent); int hidingTeam; VectorCopy(AIL_ent->pos, save); hidingTeam = AI_GetHidingTeam(AIL_ent); /* parse parameter */ if (lua_gettop(L)) { if (lua_isstring(L, 1)) { const char* s = lua_tostring(L, 1); hidingTeam = AIL_toTeamInt(s); if (hidingTeam == TEAM_ALL) AIL_invalidparameter(1); } else { AIL_invalidparameter(1); } } if (AI_FindHidingLocation(hidingTeam, AIL_ent, AIL_ent->pos, &tus)) { /* Return the spot. */ lua_pushpos3(L, &AIL_ent->pos); } else { lua_pushboolean(L, 0); } G_EdictSetOrigin(AIL_ent, save); return 1; }
/** * @brief Shoots the actor. */ static int actorL_shoot (lua_State *L) { int tu, shots; shoot_types_t shootType; const item_t *item; const fireDef_t *fdArray; assert(lua_isactor(L, 1)); /* Target */ aiActor_t *target = lua_toactor(L, 1); /* Number of TU to spend shooting, fire mode will adjust to that. */ if (lua_gettop(L) > 1) { assert(lua_isnumber(L, 2)); /* Must be a number. */ tu = (int) lua_tonumber(L, 2); } else { tu = G_ActorUsableTUs(AIL_ent); } shootType = ST_RIGHT; item = AI_GetItemForShootType(shootType, AIL_ent); if (item == NULL) { shootType = ST_LEFT; item = AI_GetItemForShootType(shootType, AIL_ent); } /* Failure - no weapon. */ if (item == NULL) { lua_pushboolean(L, 0); return 1; } /** @todo Choose fire mode based on TU available - currently the first one is used. */ fdArray = FIRESH_FiredefForWeapon(item); if (fdArray == NULL) { /* Failure - no weapon. */ lua_pushboolean(L, 0); return 1; } shots = tu / G_GetActorTimeForFiredef(AIL_ent, fdArray, false); while (shots > 0) { shots--; /** @todo actually handle fire modes */ G_ClientShoot(AIL_player, AIL_ent, target->ent->pos, shootType, 0, NULL, true, 0); } /* Success. */ lua_pushboolean(L, 1); return 1; }
/** * @brief Makes the actor head to the position. */ static int pos3L_goto (lua_State *L) { pos3_t *pos; assert(lua_ispos3(L, 1)); /* Calculate move table. */ G_MoveCalc(0, AIL_ent, AIL_ent->pos, G_ActorUsableTUs(AIL_ent)); gi.MoveStore(level.pathingMap); /* Move. */ pos = lua_topos3(L, 1); G_ClientMove(*AIL_player, 0, AIL_ent, *pos); lua_pushboolean(L, 1); return 1; }
/** * @brief Checks whether the requested action is possible for the current active team * @param[in] player Which player (human player) is trying to do the action * @param[in] ent Which of his units is trying to do the action. * @param[in] TU The time units to check against the ones ent has. * the action with */ bool G_ActionCheckForCurrentTeam (const player_t *player, edict_t *ent, int TU) { /* don't check for a player - but maybe a server action */ if (!player) return true; /* a generic tester if an action could be possible */ if (level.activeTeam != player->pers.team) { G_ClientPrintf(player, PRINT_HUD, _("Can't perform action - it is not your turn!")); return false; } if (TU > G_ActorUsableTUs(ent)) { return false; } return G_ActionCheck(player, ent); }
/** * @brief Determine the position where actor is more closer to the target and * locate behind the target from enemy * @note @c target (parameter is passed through the lua stack) The actor * to which AI tries to become closer */ static int AIL_positionherd (lua_State *L) { pos3_t save; aiActor_t* target; /* check parameter */ if (!(lua_gettop(L) && lua_isactor(L, 1))) { AIL_invalidparameter(1); lua_pushboolean(L, 0); return 1; } VectorCopy(AIL_ent->pos, save); target = lua_toactor(L, 1); if (AI_FindHerdLocation(AIL_ent, AIL_ent->pos, target->ent->origin, G_ActorUsableTUs(AIL_ent))) { lua_pushpos3(L, &AIL_ent->pos); } else { lua_pushboolean(L, 0); } G_EdictSetOrigin(AIL_ent, save); return 1; }
/** * @brief Moves the actor into a position in which he can shoot his target. */ static int AIL_positionshoot (lua_State *L) { pos3_t to, bestPos; vec3_t check; edict_t *ent; int dist; int xl, yl, xh, yh; int min_tu; aiActor_t *target; const byte crouchingState = G_IsCrouched(AIL_ent) ? 1 : 0; /* We need a target. */ assert(lua_isactor(L, 1)); target = lua_toactor(L, 1); /* Make things more simple. */ ent = AIL_ent; dist = G_ActorUsableTUs(ent); /* Calculate move table. */ G_MoveCalc(0, ent, ent->pos, crouchingState, G_ActorUsableTUs(ent)); gi.MoveStore(level.pathingMap); /* set borders */ xl = (int) ent->pos[0] - dist; if (xl < 0) xl = 0; yl = (int) ent->pos[1] - dist; if (yl < 0) yl = 0; xh = (int) ent->pos[0] + dist; if (xh > PATHFINDING_WIDTH) xl = PATHFINDING_WIDTH; yh = (int) ent->pos[1] + dist; if (yh > PATHFINDING_WIDTH) yh = PATHFINDING_WIDTH; /* evaluate moving to every possible location in the search area, * including combat considerations */ min_tu = INT_MAX; for (to[2] = 0; to[2] < PATHFINDING_HEIGHT; to[2]++) for (to[1] = yl; to[1] < yh; to[1]++) for (to[0] = xl; to[0] < xh; to[0]++) { pos_t tu; /* Can we see the target? */ gi.GridPosToVec(gi.routingMap, ent->fieldSize, to, check); tu = G_ActorMoveLength(ent, level.pathingMap, to, true); if (tu > G_ActorUsableTUs(ent) || tu == ROUTING_NOT_REACHABLE) continue; /* Better spot (easier to get to). */ if (tu < min_tu) { if (G_ActorVis(check, ent, target->ent, true) > 0.3) { VectorCopy(to, bestPos); min_tu = tu; } } } /* No position found in range. */ if (min_tu > G_ActorUsableTUs(ent)) { lua_pushboolean(L, 0); return 1; } /* Return the spot. */ lua_pushpos3(L, &bestPos); return 1; }