void AAIGroup::Defend(int unit, float3 *enemy_pos, int importance) { Command cmd; if(enemy_pos) { cmd.id = CMD_FIGHT; cmd.params.push_back(enemy_pos->x); cmd.params.push_back(enemy_pos->y); cmd.params.push_back(enemy_pos->z); GiveOrder(&cmd, importance, DEFENDING, "Group::Defend"); target_sector = ai->Getmap()->GetSectorOfPos(enemy_pos); } else { cmd.id = CMD_GUARD; cmd.params.push_back(unit); GiveOrder(&cmd, importance, GUARDING, "Group::Defend"); float3 pos = ai->Getcb()->GetUnitPos(unit); target_sector = ai->Getmap()->GetSectorOfPos(&pos); } task = GROUP_DEFENDING; }
void AAIGroup::Defend(int unit, float3 enemy_pos, int importance) { Command cmd; if(enemy_pos.x > 0) { cmd.id = CMD_FIGHT; cmd.params.push_back(enemy_pos.x); cmd.params.push_back(enemy_pos.y); cmd.params.push_back(enemy_pos.z); GiveOrder(&cmd, importance, DEFENDING); target_sector = ai->map->GetSectorOfPos(enemy_pos); } else { cmd.id = CMD_GUARD; cmd.params.push_back(unit); GiveOrder(&cmd, importance, GUARDING); target_sector = ai->map->GetSectorOfPos(cb->GetUnitPos(unit)); } task = GROUP_DEFENDING; }
void AAIGroup::GetNewRallyPoint() { AAISector *sector; // delete old rally point (if there is any) if(rally_point.x > 0) { sector = ai->Getmap()->GetSectorOfPos(&rally_point); --sector->rally_points; } rally_point = ai->Getexecute()->GetRallyPoint(group_movement_type, continent, 1, 1); if(rally_point.x > 0) { //add new rally point to sector sector = ai->Getmap()->GetSectorOfPos(&rally_point); ++sector->rally_points; // send idle groups to new rally point if(task == GROUP_IDLE) { Command c; c.id = CMD_MOVE; c.params.push_back(rally_point.x); c.params.push_back(rally_point.y); c.params.push_back(rally_point.z); GiveOrder(&c, 90, HEADING_TO_RALLYPOINT, "Group::RallyPoint"); } } }
void UnitGroup::SetWaitingForGoal () { state = ugroup_WaitingForGoal; Command c; c.id = CMD_STOP; GiveOrder (&c); }
void AAIGroup::DefendAirSpace(float3 *pos) { Command c; c.id = CMD_PATROL; c.params.push_back(pos->x); c.params.push_back(pos->y); c.params.push_back(pos->z); GiveOrder(&c, 110, UNIT_ATTACKING, "Group::DefendAirSpace"); task = GROUP_PATROLING; }
void UnitGroup::SetGrouping () { state=ugroup_Grouping; Command c; c.id = CMD_MOVE; c.params.push_back (mid.x); c.params.push_back (0.0f); c.params.push_back (mid.y); GiveOrder (&c); }
void AAIGroup::AirRaidUnit(int unit_id) { Command c; c.id = CMD_ATTACK; c.params.push_back(unit_id); GiveOrder(&c, 110, UNIT_ATTACKING, "Group::AirRaidUnit"); ai->Getut()->AssignGroupToEnemy(unit_id, this); task = GROUP_ATTACKING; }
void UnitGroup::SetMoving () { state = ugroup_Moving; if (goal.x >= 0) { // go to next sector Command c; c.id = CMD_MOVE; c.params.push_back (globals->map->gblocksize * (goal.x + 0.5f)); c.params.push_back (0.0f); c.params.push_back (globals->map->gblocksize * (goal.y + 0.5f)); GiveOrder (&c); } else { Command c; c.id = CMD_STOP; GiveOrder (&c); } }
void AAIGroup::BombTarget(int target_id, float3 *target_pos) { Command c; c.id = CMD_ATTACK; c.params.push_back(target_pos->x); c.params.push_back(target_pos->y); c.params.push_back(target_pos->z); GiveOrder(&c, 110, UNIT_ATTACKING, "Group::BombTarget"); ai->Getut()->AssignGroupToEnemy(target_id, this); task = GROUP_BOMBING; }
void AAIGroup::Retreat(float3 *pos) { this->task = GROUP_RETREATING; Command c; c.id = CMD_MOVE; c.params.push_back(pos->x); c.params.push_back(pos->y); c.params.push_back(pos->z); GiveOrder(&c, 105, MOVING, "Group::Retreat"); // set new dest sector target_sector = ai->Getmap()->GetSectorOfPos(pos); }
void AAIGroup::TargetUnitKilled() { // behaviour of normal mods if(!cfg->AIR_ONLY_MOD) { // air groups retreat to rally point if(category == AIR_ASSAULT) { Command c; c.id = CMD_MOVE; c.params.push_back(rally_point.x); c.params.push_back(rally_point.y); c.params.push_back(rally_point.z); GiveOrder(&c, 90, MOVING, "Group::TargetUnitKilled"); } } }
void UnitGroup::SetPruning () { GameInfo *gi = globals->map->GetGameInfo (current); curTarget = SelectTarget (gi->enemies); if (curTarget >= 0) { // attack Command c; c.id = CMD_ATTACK; c.params.push_back (curTarget); GiveOrder (&c); } state = ugroup_Pruning; }
int CAICallback::SendUnits(const std::vector<int>& unitIds, int receivingTeamId) { typedef unsigned char ubyte; std::vector<short> sentUnitIDs; if (team != receivingTeamId) { if (receivingTeamId >= 0 && receivingTeamId < (MAX_TEAMS - 1)) { if (gs->Team(receivingTeamId) && gs->Team(team)) { if (!gs->Team(receivingTeamId)->isDead && !gs->Team(team)->isDead) { // we must iterate over the ID's to check if // all of them really belong to the AI's team for (std::vector<int>::const_iterator it = unitIds.begin(); it != unitIds.end(); it++ ) { const int unitID = *it; if (unitID > 0 && unitID < MAX_UNITS) { CUnit* unit = uh->units[unitID]; if (unit && unit->team == team) { // we own this unit, save it (note: safe cast // since MAX_UNITS currently fits in a short) sentUnitIDs.push_back(short(unitID)); // stop whatever this unit is doing Command c; c.id = CMD_STOP; GiveOrder(unitID, &c); } } } if (sentUnitIDs.size() > 0) { // we can't use SendShare() here either, since // AI's don't have a notion of "selected units" net->Send(CBaseNetProtocol::Get().SendAIShare(ubyte(gu->myPlayerNum), ubyte(team), ubyte(receivingTeamId), 0.0f, 0.0f, sentUnitIDs)); } } } } } // return how many units were actually put up for transfer return (sentUnitIDs.size()); }
int CAICallback::SendUnits(const std::vector<int>& unitIds, int receivingTeamId) { typedef unsigned char ubyte; std::vector<short> sentUnitIDs; if ((team != receivingTeamId) && teamHandler->IsValidTeam(receivingTeamId) && teamHandler->Team(receivingTeamId) && teamHandler->Team(team) && !teamHandler->Team(receivingTeamId)->isDead && !teamHandler->Team(team)->isDead) { // we must iterate over the ID's to check if // all of them really belong to the AI's team std::vector<int>::const_iterator uid; for (uid = unitIds.begin(); uid != unitIds.end(); ++uid) { const int unitId = *uid; const CUnit* unit = GetUnit(unitId); if (unit && unit->team == team) { // we own this unit, save it // (note: safe cast since MAX_UNITS currently fits in a short) sentUnitIDs.push_back(short(unitId)); // stop whatever this unit is doing Command c(CMD_STOP); GiveOrder(unitId, &c); } } if (!sentUnitIDs.empty()) { // we ca not use SendShare() here either, since // AIs do not have a notion of "selected units" net->Send(CBaseNetProtocol::Get().SendAIShare(ubyte(gu->myPlayerNum), skirmishAIHandler.GetCurrentAIID(), ubyte(team), ubyte(receivingTeamId), 0.0f, 0.0f, sentUnitIDs)); } } // return how many units were actually put up for transfer return (sentUnitIDs.size()); }
void AAIGroup::AttackSector(AAISector *dest, float importance) { float3 pos; Command c; c.id = CMD_FIGHT; c.params.resize(3); // get position of the group pos = GetGroupPos(); int group_x = pos.x/ai->Getmap()->xSectorSize; int group_y = pos.z/ai->Getmap()->ySectorSize; c.params[0] = (dest->left + dest->right)/2; c.params[2] = (dest->bottom + dest->top)/2; // choose location that way that attacking units must cross the entire sector if(dest->x > group_x) c.params[0] = (dest->left + 7 * dest->right)/8; else if(dest->x < group_x) c.params[0] = (7 * dest->left + dest->right)/8; else c.params[0] = (dest->left + dest->right)/2; if(dest->y > group_y) c.params[2] = (7 * dest->bottom + dest->top)/8; else if(dest->y < group_y) c.params[2] = (dest->bottom + 7 * dest->top)/8; else c.params[2] = (dest->bottom + dest->top)/2; c.params[1] = ai->Getcb()->GetElevation(c.params[0], c.params[2]); // move group to that sector GiveOrder(&c, importance + 8, UNIT_ATTACKING, "Group::AttackSector"); target_sector = dest; task = GROUP_ATTACKING; }
void AAIGroup::UnitIdle(int unit) { // special behaviour of aircraft in not air only mods if(category == AIR_ASSAULT && task != GROUP_IDLE && !cfg->AIR_ONLY_MOD) { Command c; c.id = CMD_MOVE; c.params.push_back(rally_point.x); c.params.push_back(rally_point.y); c.params.push_back(rally_point.z); GiveOrder(&c, 100, MOVING); task = GROUP_IDLE; } // behaviour of all other categories else if(attack) { //check if idle unit is in target sector float3 pos = cb->GetUnitPos(unit); AAISector *temp = ai->map->GetSectorOfPos(pos); if(temp == target_sector || !target_sector) { // combat groups if(group_type == ASSAULT_UNIT && attack->dest->enemy_structures <= 0) { ai->am->GetNextDest(attack); return; } // unit the aa groups was guarding has been killed else if(group_type == ANTI_AIR_UNIT) { if(!attack->combat_groups.empty()) { int unit = (*attack->combat_groups.begin())->GetRandomUnit(); if(unit >= 0) { Command c; c.id = CMD_GUARD; c.params.push_back(unit); GiveOrder(&c, 110, GUARDING); } } else attack->StopAttack(); } } } else if(task == GROUP_RETREATING) { //check if retreating units is in target sector float3 pos = cb->GetUnitPos(unit); AAISector *temp = ai->map->GetSectorOfPos(pos); if(temp == target_sector || !target_sector) task = GROUP_IDLE; } else if(task == GROUP_DEFENDING) { //check if retreating units is in target sector float3 pos = cb->GetUnitPos(unit); AAISector *temp = ai->map->GetSectorOfPos(pos); if(temp == target_sector || !target_sector) task = GROUP_IDLE; } }
void AAIGroup::UnitIdle(int unit) { if(ai->Getcb()->GetCurrentFrame() - lastCommandFrame < 10) return; // special behaviour of aircraft in non air only mods if(category == AIR_ASSAULT && task != GROUP_IDLE && !cfg->AIR_ONLY_MOD) { Command c; c.id = CMD_MOVE; c.params.push_back(rally_point.x); c.params.push_back(rally_point.y); c.params.push_back(rally_point.z); GiveOrder(&c, 100, MOVING, "Group::Idle_a"); task = GROUP_IDLE; } // behaviour of all other categories else if(attack) { //check if idle unit is in target sector float3 pos = ai->Getcb()->GetUnitPos(unit); AAISector *temp = ai->Getmap()->GetSectorOfPos(&pos); if(temp == target_sector || !target_sector) { // combat groups if(group_unit_type == ASSAULT_UNIT && attack->dest->enemy_structures <= 0) { ai->Getam()->GetNextDest(attack); return; } // unit the aa group was guarding has been killed else if(group_unit_type == ANTI_AIR_UNIT) { if(!attack->combat_groups.empty()) { int unit = (*attack->combat_groups.begin())->GetRandomUnit(); if(unit >= 0) { Command c; c.id = CMD_GUARD; c.params.push_back(unit); GiveOrder(&c, 110, GUARDING, "Group::Idle_b"); } } else attack->StopAttack(); } } else { // idle assault units are ordered to attack the current target sector if(group_unit_type == ASSAULT_UNIT) { Command c; c.id = CMD_FIGHT; c.params.resize(3); // get position of the group pos = ai->Getcb()->GetUnitPos(unit); int pos_x = pos.x/ai->Getmap()->xSectorSize; int pos_y = pos.z/ai->Getmap()->ySectorSize; c.params[0] = (target_sector->left + target_sector->right)/2; c.params[2] = (target_sector->bottom + target_sector->top)/2; // choose location that way that attacking units must cross the entire sector if(target_sector->x > pos_x) c.params[0] = (target_sector->left + 7 * target_sector->right)/8; else if(target_sector->x < pos_x) c.params[0] = (7 * target_sector->left + target_sector->right)/8; else c.params[0] = (target_sector->left + target_sector->right)/2; if(target_sector->y > pos_y) c.params[2] = (7 * target_sector->bottom + target_sector->top)/8; else if(target_sector->y < pos_y) c.params[2] = (target_sector->bottom + 7 * target_sector->top)/8; else c.params[2] = (target_sector->bottom + target_sector->top)/2; c.params[1] = ai->Getcb()->GetElevation(c.params[0], c.params[2]); // move group to that sector GiveOrder(&c, 110, UNIT_ATTACKING, "Group::Idle_c"); } } } else if(task == GROUP_RETREATING) { //check if retreating units is in target sector float3 pos = ai->Getcb()->GetUnitPos(unit); AAISector *temp = ai->Getmap()->GetSectorOfPos(&pos); if(temp == target_sector || !target_sector) task = GROUP_IDLE; } else if(task == GROUP_DEFENDING) { //check if retreating units is in target sector float3 pos = ai->Getcb()->GetUnitPos(unit); AAISector *temp = ai->Getmap()->GetSectorOfPos(&pos); if(temp == target_sector || !target_sector) task = GROUP_IDLE; } }