bool EnemySoldier::_tryAttack() { WalkerList enemies = _findEnemiesInRange( attackDistance() ); if( !enemies.empty() ) { _setSubAction( Soldier::fightEnemy ); setTarget( enemies.front()->pos() ); fight(); } else { ConstructionList constructions = _findContructionsInRange( attackDistance() ); if( !constructions.empty() ) { _setSubAction( Soldier::destroyBuilding ); setTarget( constructions.front()->pos() ); fight(); } } if( action() == acFight ) { bool needMeMove = false; _city()->statistic().map.isTileBusy<EnemySoldier>( pos(), this, needMeMove ); if( needMeMove ) { _move2freePos( target() ); } } return action() == acFight; }
void RomeArcher::timeStep(const unsigned long time) { Soldier::timeStep( time ); switch( _subAction() ) { case Soldier::fightEnemy: { WalkerList enemies = _findEnemiesInRange( attackDistance() ); if( !enemies.empty() ) { WalkerPtr p = enemies.front(); turn( p->pos() ); if( _animationRef().index() == (int)(_animationRef().frameCount()-1) ) { _fire( p->pos() ); _updateAnimation( time+1 ); } } else { //_check4attack(); send2patrol(); } } break; case Soldier::destroyBuilding: { ConstructionList constructions = _findContructionsInRange( attackDistance() ); if( !constructions.empty() ) { ConstructionPtr b = constructions.front(); turn( b->pos() ); if( _animationRef().index() == (int)(_animationRef().frameCount()-1) ) { _fire( b->pos() ); _updateAnimation( time+1 ); } } else { //_check4attack(); send2patrol(); } } case Soldier::patrol: if( game::Date::current().day() % 2 == 0 ) { _tryAttack(); } break; default: break; } // end switch( _d->action ) }
ConstructionList EnemySoldier::_findContructionsInRange( unsigned int range ) { ConstructionList ret; Tilemap& tmap = _map(); for( unsigned int k=0; k <= range; k++ ) { ConstructionList blds = tmap.rect( k, pos() ) .overlays() .select<Construction>(); for( auto b : blds ) { if( !_atExclude.count( b->group() ) ) { ret.push_back( b ); } } } if( ret.empty() ) return ret; switch( _atPriority ) { case attackFood: case attackCitizen: case attackIndustry: { ConstructionList tmpRet; object::Group needGroup; switch( _atPriority ) { case attackIndustry: needGroup = object::group::industry; break; case attackFood: needGroup = object::group::food; break; case attackCitizen: needGroup = object::group::house; break; case attackSenate: needGroup = object::group::administration; break; default: needGroup = object::group::unknown; break; } for( auto bld : ret ) { if( bld->group() == needGroup ) { tmpRet << bld; } } if( !tmpRet.empty() ) return tmpRet; } break; case attackBestBuilding: { ConstructionPtr maxBuilding = ret.front(); unsigned int maxCost = __getCost( maxBuilding ); foreach( it, ret ) { unsigned int cost = __getCost( *it ); if( cost > maxCost ) { maxCost = cost; maxBuilding = *it; } } if( maxBuilding.isValid() ) { ret.clear(); ret << maxBuilding; return ret; } } break; default: break; }