//An easy to use, do-everything-in-one-call sort of function commandList GalconAI::update(std::list<Planet> & planets, const std::list<Fleet> & fleets, const std::vector<ShipStats> & shipstats, std::vector<std::list<Building*> > buildRules) { //Set up the list of commands commandList rb; //See if we have waited long enough and the AI is active int time = SDL_GetTicks(); if ((time - updateTime_ < set_.delay && updateTime_ != -1) || !active_) return rb; updateTime_ = time; std::cout << "Update) Attack: " << attTotal_ << " Defense: " << defTotal_ << std::endl; //Compute the best target computeTarget(planets, fleets, shipstats); //Get the commands from rebalancing, attacking, and building rb = rebalance(fleets, shipstats); commandList at = attack(shipstats); commandList bd = build(buildRules, shipstats); //Append at to rb for (commandList::iterator i = at.begin(); i != at.end(); i++) { rb.push_back(*i); } for (commandList::iterator i = bd.begin(); i != bd.end(); i++) { rb.push_back(*i); } //Return the combined list of commands return rb; }
RubberBall::RubberBall(AbstractKart *kart) : Flyable(kart, PowerupManager::POWERUP_RUBBERBALL, 0.0f /* mass */), TrackSector() { // For debugging purpose: pre-fix each debugging line with the id of // the ball so that it's easy to collect all debug output for one // particular ball only. m_next_id++; m_id = m_next_id; // Don't let Flyable update the terrain information, since this object // has to do it earlier than that. setDoTerrainInfo(false); float forw_offset = 0.5f*kart->getKartLength() + m_extend.getZ()*0.5f+5.0f; createPhysics(forw_offset, btVector3(0.0f, 0.0f, m_speed*2), new btSphereShape(0.5f*m_extend.getY()), -70.0f /*gravity*/, true /*rotates*/); // Do not adjust the up velocity setAdjustUpVelocity(false); m_max_lifespan = 9999; m_target = NULL; m_aiming_at_target = false; m_fast_ping = false; // At the start the ball aims at quads till it gets close enough to the // target: m_height_timer = 0.0f; m_interval = m_st_interval; m_current_max_height = m_max_height; m_ping_sfx = sfx_manager->createSoundSource("ball_bounce"); // Just init the previoux coordinates with some value that's not getXYZ() m_previous_xyz = m_owner->getXYZ(); m_previous_height = 2.0f; // // A negative value indicates that the timer is not active m_delete_timer = -1.0f; m_tunnel_count = 0; LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld()); // FIXME: what does the rubber ball do in case of battle mode?? if(!world) return; computeTarget(); // initialises the current graph node TrackSector::update(getXYZ()); TerrainInfo::update(getXYZ()); initializeControlPoints(m_owner->getXYZ()); } // RubberBall
/** Updates the rubber ball. * \param dt Time step size. * \returns True if the rubber ball should be removed. */ bool RubberBall::updateAndDelete(float dt) { LinearWorld *world = dynamic_cast<LinearWorld*>(World::getWorld()); // FIXME: what does the rubber ball do in case of battle mode?? if(!world) return true; if(m_delete_timer>0) { m_delete_timer -= dt; if(m_delete_timer<=0) { hit(NULL); #ifdef PRINT_BALL_REMOVE_INFO Log::debug("RubberBall", "ball %d deleted.", m_id); #endif return true; } } // Update the target in case that the first kart was overtaken (or has // finished the race). computeTarget(); updateDistanceToTarget(); // Determine the new position. This new position is only temporary, // since it still needs to be adjusted for the height of the terrain. Vec3 next_xyz; if(m_aiming_at_target) moveTowardsTarget(&next_xyz, dt); else interpolate(&next_xyz, dt); // If the ball is close to the ground, we have to start the raycast // slightly higher (to avoid that the ball tunnels through the floor). // But if the ball is close to the ceiling of a tunnel and we would // start the raycast slightly higher, the ball might end up on top // of the ceiling. // The ball is considered close to the ground if the height above the // terrain is less than half the current maximum height. bool close_to_ground = 2.0*m_previous_height < m_current_max_height; float vertical_offset = close_to_ground ? 4.0f : 2.0f; // Note that at this stage getHoT still reports the height at // the previous location (since TerrainInfo wasn't updated). On // the other hand, we can't update TerrainInfo without having // at least a good estimation of the height. next_xyz.setY(getHoT() + vertical_offset); // Update height of terrain (which isn't done as part of // Flyable::update for rubber balls. TerrainInfo::update(next_xyz); m_height_timer += dt; float height = updateHeight()+m_extend.getY()*0.5f; float new_y = getHoT()+height; if(UserConfigParams::logFlyable()) printf("ball %d: %f %f %f height %f new_y %f gethot %f ", m_id, next_xyz.getX(), next_xyz.getY(), next_xyz.getZ(), height, new_y, getHoT()); // No need to check for terrain height if the ball is low to the ground if(height > 0.5f) { float terrain_height = getMaxTerrainHeight(vertical_offset) - m_extend.getY(); if(new_y>terrain_height) new_y = terrain_height; } if(UserConfigParams::logFlyable()) Log::verbose("RubberBall", "newy2 %f gmth %f", new_y, getMaxTerrainHeight(vertical_offset)); next_xyz.setY(new_y); m_previous_xyz = getXYZ(); m_previous_height = next_xyz.getY()-getHoT(); setXYZ(next_xyz); if(checkTunneling()) return true; // Determine new distance along track TrackSector::update(next_xyz); // Ball squashing: // =============== if(height<1.5f*m_extend.getY()) m_node->setScale(core::vector3df(1.0f, height/m_extend.getY(),1.0f)); else m_node->setScale(core::vector3df(1.0f, 1.0f, 1.0f)); return Flyable::updateAndDelete(dt); } // updateAndDelete