//This function is called each time it is your turn. //Return true to end your turn, return false to ask the server for updated information. bool AI::run() { cout<<"Turn: "<<turnNumber()<<endl; vector<int> builders, uncombined, actors; for(unsigned int b=0;b<bots.size();b++) { // if it is my bot if(bots[b].owner()==playerID() && bots[b].partOf()==0) { bots[b].talk( "Hi there, I'm you're robot" ); if(bots[b].buildRate()>0 && builders.size()<4 && bots[b].size()==1) { builders.push_back(b); } else if(bots[b].size()==1) { uncombined.push_back(b); } else { actors.push_back(b); } } } // starting builders if(builders.size()<4) { for(unsigned int b=0;b<builders.size();b++) { int x=bots[builders[b]].x()+xMod[playerID()*2 +1]; int y=bots[builders[b]].y()+yMod[playerID()*2 +1]; bots[builders[b]].build(types[1], x, y, 1); } } // if there are 4 builders if(builders.size()==4) { // check if the builders are in their correct locations for(unsigned int b=0;b<builders.size();b++) { int dir=1; if(bots[builders[b]].y()==9) { bots[builders[b]].move("up"); } else if(bots[builders[b]].y()==10) { bots[builders[b]].move("down"); } if(bots[builders[b]].y()==8) { dir = 2; } else if(bots[builders[b]].y()==11) { dir = 0; } int x=bots[builders[b]].x()+xMod[dir]; int y=bots[builders[b]].y()+yMod[dir]; if(bots[builders[b]].actions()>0) { // builds 4 different guys bots[builders[b]].build(types[(built/4+b)%types.size()], x, y, 1); built++; } } } if(uncombined.size()==4) { /* for(unsigned int b=0;b<uncombined.size();b++) { if(bots[uncombined[b]].y()==9) { bots[uncombined[b]].move("down"); } else if(bots[builders[b]].y()==10) { bots[builders[b]].move("down"); } } */ bots[uncombined[0]].combine(bots[uncombined[1]],bots[uncombined[2]],bots[uncombined[3]]); } // Handles all of the non builders for(unsigned int b=0;b<actors.size();b++) { Unit* target = findNearestTarget(bots[actors[b]]); moveTowardsTarget(bots[actors[b]], *target); if(inRange(bots[actors[b]], *target)) { cout<<"In RANGE!"<<endl; unload(bots[actors[b]],*target); } } return true; }
/** 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