/* bool cCombatManager::CommandTrap(const int& unitID, UnitInfo* U, const float& EDis) { if( !U->E->inLOS || U->ud->transportMass < U->E->ud->mass ) return false; if( U->ud->transportCapacity == 0 ) return false; Command c; c.id = CMD_LOAD_UNITS; c.params.push_back(U->enemyID); cb->GiveOrder(unitID, &c); return true; } */ bool cCombatManager::CommandManeuver(const int& unitID, UnitInfo *U, const float& EDis) { if( U->ud->canfly || U->E->ud == 0 || !U->E->inLOS || U->enemyEff->BestRange <= 1.15*cb->GetUnitMaxRange(U->enemyID) || EDis > 3500.0 || int(G->UMobile.size()) > 60 ) return false; float3 Pos=cb->GetUnitPos(unitID); float3 EPos=GetEnemyPosition(U->enemyID,U->E); if( U->ud->minWaterDepth < 0 && Pos.y <= 0 && U->udr->WeaponSeaEff.BestRange == 0 ) { int iS=G->TM->GetSectorIndex(EPos); if( G->TM->IsSectorValid(iS) ) { Pos = G->TM->GetClosestSector(G->TM->landSectorType,iS)->position; Pos.x+=128-rand()%256; Pos.z+=128-rand()%256; G->CorrectPosition(Pos); Command c; c.id = CMD_MOVE; c.params.push_back(Pos.x); c.params.push_back(Pos.y); c.params.push_back(Pos.z); cb->GiveOrder(unitID, &c); G->UpdateEventAdd(1,int(GetNextUpdate(EDis,U)),unitID,U); return true; } } if( EDis < 0.70*U->enemyEff->BestRange || EDis > U->enemyEff->BestRange ) { float distanceAway=(0.87*U->enemyEff->BestRange-EDis); Pos.x+=(Pos.x-EPos.x)*(distanceAway/EDis); Pos.z+=(Pos.z-EPos.z)*(distanceAway/EDis); G->CorrectPosition(Pos); if( !G->TM->CanMoveToPos(U->area,Pos) ) return false; Command c; c.id = CMD_MOVE; c.params.push_back(Pos.x); c.params.push_back(cb->GetElevation(Pos.x,Pos.z)); c.params.push_back(Pos.z); cb->GiveOrder(unitID, &c); G->UpdateEventAdd(1,int(GetNextUpdate(EDis,U)),unitID,U); return true; } return false; }
void cCombatManager::UnitIdle(const int& unit, UnitInfo *U) { //*l<<"(cui) -eID="<<U->enemyID; if( ValidateEnemy(unit,U) && CanAttack(U,U->E,GetEnemyPosition(U->enemyID,U->E)) == 0 ) U->enemyID=-1; float3 fPos=cb->GetUnitPos(unit); if( U->enemyID == -1 ) while( (U->enemyID=GetClosestEnemy(fPos,U)) > 0 && !ValidateEnemy(unit,U) ) {} float distance = -1; if( U->enemyID >= 0 ) { distance = fPos.distance(GetEnemyPosition(U->enemyID,U->E)); if( distance == 0 ) distance = 1; } if( U->enemyID == -1 || (U->udrBL->task != TASK_ASSAULT && distance > 2.5*8*U->ud->losRadius) ) { U->inCombat=false; G->UpdateEventAdd(1,0,unit,U); return; } else if( CommandDGun(unit,U) ) return; else if( U->enemyEff == 0 || (U->udrBL->task != TASK_ASSAULT && distance > 1.75*U->enemyEff->BestRange ) || (U->ud->isCommander && cb->GetUnitHealth(unit)/U->ud->health <= 0.66 ) ) // || G->Enemies.find(U->enemyID)->second.ud->kamikazeDist > distance { float3 EPos = GetEnemyPosition(U->enemyID,U->E); CommandRun(unit,U,EPos); return; } else if( CommandCapture(unit,U,distance) || CommandManeuver(unit,U,distance) ) return; else { float3 EPos = GetEnemyPosition(U->enemyID,U->E); Command c; if( U->ud->canAttack && (U->E->inLOS || U->E->inRadar) ) { c.id = CMD_ATTACK; c.params.push_back(U->enemyID); } else if( U->ud->canAttack && (U->udr->IsBomber && U->E->posLocked) ) { c.id = CMD_ATTACK; c.params.push_back(EPos.x); c.params.push_back(EPos.y); c.params.push_back(EPos.z); } else // cant see enemy or Mod Workaround: Combat Lords - cant be given attack orders { c.id = CMD_MOVE; c.params.push_back(EPos.x -100.0 +rand()%201 ); c.params.push_back(EPos.y); c.params.push_back(EPos.z -100.0 +rand()%201 ); } cb->GiveOrder(unit, &c); G->UpdateEventAdd(1,int(GetNextUpdate(distance,U)),unit,U); } }