/** * TransformPointCloud function * * This function takes a point cloud and transforms it according to the camera pose * @param normal_cloud the cloud with normals * @param camera_pose the camera pose * @return the cloud transformed */ pcl::PointCloud<pcl::PointNormal>::Ptr Functions3D::transformPointCloud(pcl::PointCloud<pcl::PointNormal>::Ptr normal_cloud, Eigen::Matrix4f camera_pose) { /** * Initialize a new point cloud to save the data */ pcl::PointCloud<pcl::PointNormal>::Ptr new_cloud(new pcl::PointCloud<pcl::PointNormal>); pcl::transformPointCloudWithNormals(*normal_cloud, *new_cloud, camera_pose); return new_cloud; }
//loading msg form collection and merge tables that may linked together bool merge_table_msg() { //load table shapes mongodb_store::MessageStoreProxy table_shape(*nh, "table_shapes"); std::vector< boost::shared_ptr<table_detection::Table> > result_tables; table_shape.query<table_detection::Table>(result_tables); //set or load checked_num std::vector< boost::shared_ptr<std_msgs::Int32> > checked_amount; table_shape.queryNamed<std_msgs::Int32>("checked_num", checked_amount); if(checked_amount.size() == 0){ std_msgs::Int32 tmp; tmp.data = checked_num; table_shape.insertNamed("checked_num",tmp); } else{ //load record form mongodb checked_num = checked_amount[0]->data; } ROS_INFO("Found %lu table shapes, already checked %d", result_tables.size(), checked_num); //extract points from msg pcl_cloud::Ptr new_cloud(new pcl_cloud()); for(int j=0;j<result_tables.size();j++){ for(int i=0;i<(*result_tables[j]).tabletop.points.size();i++){ Point tt; tt.x = (*result_tables[j]).tabletop.points[i].x; tt.y = (*result_tables[j]).tabletop.points[i].y; tt.z = (*result_tables[j]).tabletop.points[i].z; new_cloud->push_back(tt); } } return true; }
// This function destroys a non-core proc, and procs downlink of a non-core proc that has been destroyed. static void destroy_procs_recursively(struct core_struct* core, struct proc_struct* destroyed_pr, int destroyer_team) { int i; core->group_member[destroyed_pr->group_member_index].exists = 0; // core->group_members--; this is dealt with by set_basic_group_properties() destroy_a_proc(destroyed_pr, destroyer_team); procs_destroyed_in_this_explosion ++; // note loop starts at 1 for (i = 1; i < GROUP_CONNECTIONS; i++) { if (destroyed_pr->group_connection_exists[i]) { struct cloud_struct* cl = new_cloud(CLOUD_SUB_PROC_EXPLODE, 64, destroyed_pr->group_connection_ptr[i]->position.x, destroyed_pr->group_connection_ptr[i]->position.y); if (cl != NULL) { cl->angle = destroyed_pr->group_connection_ptr[i]->angle; cl->colour = destroyed_pr->player_index; //destroyer_team; cl->data [0] = destroyed_pr->group_connection_ptr[i]->shape; cl->data [1] = 1; cl->speed.x = 0; cl->speed.y = 0; cl->display_size_x1 = -200; cl->display_size_y1 = -200; cl->display_size_x2 = 200; cl->display_size_y2 = 200; } explosion_fragments(destroyed_pr->group_connection_ptr[i]->position.x, destroyed_pr->group_connection_ptr[i]->position.y, destroyed_pr->group_connection_ptr[i]->speed.x, destroyed_pr->group_connection_ptr[i]->speed.y, 6, destroyed_pr->player_index); destroy_procs_recursively(core, destroyed_pr->group_connection_ptr[i], destroyer_team); } } }
int main (int argc, char** argv) { PointCloudT::Ptr cloud (new PointCloudT); PointCloudT::Ptr new_cloud (new PointCloudT); bool new_cloud_available_flag = false; //pcl::Grabber* grab = new pcl::OpenNIGrabber (); PointCloudT::Ptr ddd; boost::function<void (const PointCloudT::ConstPtr&)> f = boost::bind(&grabberCallback, _1, cloud, &new_cloud_available_flag); grab->registerCallback (f); viewer->registerKeyboardCallback(keyboardEventOccurred); grab->start (); bool first_time = true; FILE* objects; objects = fopen ("objects.txt","a"); while(!new_cloud_available_flag) boost::this_thread::sleep(boost::posix_time::milliseconds(1)); new_cloud_available_flag=false; //////////////////// // invert correction //////////////////// Eigen::Matrix4f transMat = Eigen::Matrix4f::Identity(); transMat (1,1) = -1; //////////////////// // pass filter //////////////////// PointCloudT::Ptr passed_cloud; pcl::PassThrough<PointT> pass; passed_cloud = boost::shared_ptr<PointCloudT>(new PointCloudT); //////////////////// // voxel grid //////////////////// PointCloudT::Ptr voxelized_cloud; voxelized_cloud = boost::shared_ptr<PointCloudT>(new PointCloudT); pcl::VoxelGrid<PointT> vg; vg.setLeafSize (0.001, 0.001, 0.001); //////////////////// // sac segmentation //////////////////// PointCloudT::Ptr cloud_f; PointCloudT::Ptr cloud_plane; PointCloudT::Ptr cloud_filtered; cloud_f = boost::shared_ptr<PointCloudT>(new PointCloudT); cloud_plane = boost::shared_ptr<PointCloudT> (new PointCloudT); cloud_filtered = boost::shared_ptr<PointCloudT> (new PointCloudT); pcl::SACSegmentation<PointT> seg; pcl::PointIndices::Ptr inliers (new pcl::PointIndices); pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients); seg.setOptimizeCoefficients (true); seg.setModelType (pcl::SACMODEL_PLANE); seg.setMethodType (pcl::SAC_RANSAC); seg.setMaxIterations (100); seg.setDistanceThreshold (0.02); //////////////////// // euclidean clustering //////////////////// std::vector<pcl::PointIndices> cluster_indices; std::vector<PointCloudT::Ptr> extracted_clusters; pcl::search::KdTree<PointT>::Ptr eucl_tree (new pcl::search::KdTree<PointT>); pcl::EuclideanClusterExtraction<PointT> ec; ec.setClusterTolerance (0.04); ec.setMinClusterSize (100); ec.setMaxClusterSize (25000); ec.setSearchMethod (eucl_tree); PointCloudT::Ptr cloud_cluster; //////////////////// // vfh estimate //////////////////// pcl::NormalEstimation<PointT, pcl::Normal> ne; pcl::search::KdTree<PointT>::Ptr vfh_tree1 (new pcl::search::KdTree<PointT> ()); pcl::VFHEstimation<PointT, pcl::Normal, pcl::VFHSignature308> vfh; pcl::search::KdTree<PointT>::Ptr vfh_tree2 (new pcl::search::KdTree<PointT> ()); std::vector<pcl::PointCloud<pcl::VFHSignature308>::Ptr> computed_vfhs; ne.setSearchMethod (vfh_tree1); ne.setRadiusSearch (0.05); vfh.setSearchMethod (vfh_tree2); vfh.setRadiusSearch (0.05); pcl::PointCloud<pcl::Normal>::Ptr normals; pcl::PointCloud<pcl::VFHSignature308>::Ptr vfhs; //////////////////// // nearest neighbour //////////////////// int k = 6; std::string kdtree_idx_file_name = "kdtree.idx"; std::string training_data_h5_file_name = "training_data.h5"; std::string training_data_list_file_name = "training_data.list"; // std::vector<vfh_model> models; // flann::Matrix<float> data; // loadFileList (models, training_data_list_file_name); // flann::load_from_file (data, // training_data_h5_file_name, // "training_data"); // // flann::Index<flann::ChiSquareDistance<float> > index (data, // flann::SavedIndexParams // ("kdtree.idx")); //////////////////// // process nearest neighbour //////////////////// std::vector<hypothesis> final_hypothesis; final_hypothesis.clear(); double last = pcl::getTime(); while (! viewer->wasStopped()) { if (new_cloud_available_flag) { new_cloud_available_flag = false; double now = pcl::getTime(); //////////////////// // pass filter //////////////////// //passed_cloud = boost::shared_ptr<PointCloudT>(new PointCloudT); //////////////////// // voxel grid //////////////////// //voxelized_cloud = boost::shared_ptr<PointCloudT>(new PointCloudT); //////////////////// // sac segmentation //////////////////// //cloud_f = boost::shared_ptr<PointCloudT>(new PointCloudT); //cloud_plane = boost::shared_ptr<PointCloudT> (new PointCloudT); //cloud_filtered = boost::shared_ptr<PointCloudT> (new PointCloudT); //////////////////// // euclidean clustering //////////////////// extracted_clusters.clear(); cluster_indices.clear(); //////////////////// // vfh estimate //////////////////// computed_vfhs.clear(); //////////////////// // nearest neighbour //////////////////// cloud_mutex.lock(); //displayCloud(viewer,cloud); boost::thread displayCloud_(displayCloud,viewer,cloud); if(now-last > 13 || first_time) { first_time = false; last=now; //////////////////// // invert correction //////////////////// pcl::transformPointCloud(*cloud,*new_cloud,transMat); //////////////////// // pass filter //////////////////// pass.setInputCloud (new_cloud); pass.setFilterFieldName ("x"); pass.setFilterLimits (-0.5, 0.5); //pass.setFilterLimitsNegative (true); pass.filter (*passed_cloud); //////////////////// // voxel grid //////////////////// vg.setInputCloud (passed_cloud); vg.filter (*voxelized_cloud); //////////////////// // sac segmentation //////////////////// *cloud_filtered = *voxelized_cloud; int i=0, nr_points = (int) voxelized_cloud->points.size (); while (cloud_filtered->points.size () > 0.3 * nr_points) { // Segment the largest planar component from the remaining cloud seg.setInputCloud (cloud_filtered); seg.segment (*inliers, *coefficients); if (inliers->indices.size () == 0) { std::cout << "Couldnt estimate a planar model for the dataset.\n"; break; } // Extract the planar inliers from the input cloud pcl::ExtractIndices<PointT> extract; extract.setInputCloud (cloud_filtered); extract.setIndices (inliers); extract.setNegative (false); // Get the points associated with the planar surface extract.filter (*cloud_plane); // Remove the planar inliers, extract the rest extract.setNegative (true); extract.filter (*cloud_f); *cloud_filtered = *cloud_f; } //////////////////// // euclidean clustering //////////////////// // Creating the KdTree object for the search method of the extraction eucl_tree->setInputCloud (cloud_filtered); ec.setInputCloud (cloud_filtered); ec.extract (cluster_indices); for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it) { //PointCloudT::Ptr cloud_cluster (new PointCloudT); cloud_cluster = boost::shared_ptr<PointCloudT>(new PointCloudT); for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); pit++) cloud_cluster->points.push_back (cloud_filtered->points [*pit]); cloud_cluster->width = cloud_cluster->points.size (); cloud_cluster->height = 1; cloud_cluster->is_dense = true; extracted_clusters.push_back(cloud_cluster); } cloud_cluster.reset(); //////////////////// // vfh estimate //////////////////// for (int z=0; z<extracted_clusters.size(); ++z) { vfhs = boost::shared_ptr<pcl::PointCloud<pcl::VFHSignature308> > (new pcl::PointCloud<pcl::VFHSignature308>); normals = boost::shared_ptr<pcl::PointCloud<pcl::Normal> > (new pcl::PointCloud<pcl::Normal>); ne.setInputCloud (extracted_clusters.at(z)); ne.compute (*normals); vfh.setInputCloud (extracted_clusters.at(z)); vfh.setInputNormals (normals); vfh.compute (*vfhs); computed_vfhs.push_back(vfhs); } vfhs.reset(); normals.reset(); //////////////////// // nearest neighbour //////////////////// std::vector<vfh_model> models; flann::Matrix<int> k_indices; flann::Matrix<float> k_distances; flann::Matrix<float> data; loadFileList (models, training_data_list_file_name); flann::load_from_file (data, training_data_h5_file_name, "training_data"); flann::Index<flann::ChiSquareDistance<float> > index (data, flann::SavedIndexParams ("kdtree.idx")); for(int z=0; z<computed_vfhs.size(); ++z) { vfh_model histogram; histogram.second.resize(308); for (size_t i = 0; i < 308; ++i) { histogram.second[i] = computed_vfhs.at(z)->points[0].histogram[i]; } index.buildIndex (); nearestKSearch (index, histogram, k, k_indices, k_distances); hypothesis x; x.distance = k_distances[0][0]; size_t index = models.at(k_indices[0][0]).first.find("_v",5); x.object_name = models.at(k_indices[0][0]).first.substr(5,index-5); ddd = boost::shared_ptr<PointCloudT>(new PointCloudT); pcl::transformPointCloud(*extracted_clusters.at(z),*ddd,transMat); x.cluster = ddd; ddd.reset(); std::string filename =""; filename += "inputcloud_" + boost::lexical_cast<std::string>(j+1); filename += "_" + boost::lexical_cast<std::string>(z) + ".pcd"; x.cluster_name = filename.c_str(); final_hypothesis.push_back(x); x.cluster.reset(); //delete x; // std::string filename =""; // filename += "inputcloud_" + boost::lexical_cast<std::string>(j+1); // filename += "_" + boost::lexical_cast<std::string>(z) + ".pcd"; // const char* filen = filename.c_str(); // fprintf(objects,"%s",filen); // fprintf(objects,"::"); // fprintf(objects,models.at (k_indices[0][0]).first.c_str()); // fprintf(objects,"::"); // fprintf(objects,"%f",k_distances[0][0]); // fprintf(objects,"\n"); } delete[] k_indices.ptr (); delete[] k_distances.ptr (); delete[] data.ptr (); std::cout << final_hypothesis.size() << std::endl; viewer->removeAllShapes(); for(int z=0; z<final_hypothesis.size();++z) { if(final_hypothesis.at(z).distance < 100) { fprintf(objects,"%s",final_hypothesis.at(z).cluster_name.c_str()); fprintf(objects,"::"); fprintf(objects,"%s",final_hypothesis.at(z).object_name.c_str()); fprintf(objects,"::"); fprintf(objects,"%f",final_hypothesis.at(z).distance); fprintf(objects,"\n"); std::stringstream ddd; ddd << final_hypothesis.at(z).object_name; ddd << "\n" << "("; ddd << final_hypothesis.at(z).distance; ddd << ")"; viewer->addText3D(ddd.str().c_str(), final_hypothesis.at(z).cluster->points[0], 0.02,1,1,1, boost::lexical_cast<std::string>(z)); drawBoundingBox(final_hypothesis.at(z).cluster,viewer,z); } } //boost::thread allBoxes_(allBoxes,viewer,final_hypothesis); //allBoxes_.join(); viewer->spinOnce(); final_hypothesis.clear(); j++; } // for(int z=0; z<extracted_clusters.size(); ++z) // { // //viewer->addPointCloud<PointT>(extracted_clusters.at(z), // // boost::lexical_cast<std::string>(z)); // // std::string filename =""; // filename += "inputcloud_" + boost::lexical_cast<std::string>(j); // filename += "_" + boost::lexical_cast<std::string>(z) + ".pcd"; // pcl::io::savePCDFile(filename,*extracted_clusters.at(z),false); // } // for(int z=0; z<computed_vfhs.size(); ++z) // { // //viewer->addPointCloud<PointT>(extracted_clusters.at(z), // // boost::lexical_cast<std::string>(z)); // // std::string filename =""; // filename += "inputcloud_" + boost::lexical_cast<std::string>(j); // filename += "_" + boost::lexical_cast<std::string>(z) + "_vfhs.pcd"; // pcl::io::savePCDFileASCII<pcl::VFHSignature308> (filename, *computed_vfhs.at(z)); // } //viewer->removeAllShapes(); // viewer->removeAllPointClouds(); // viewer->setCameraPosition(0, 0, 0, 0, 0, 1, 0, -1, 0); // pcl::visualization::PointCloudColorHandlerRGBField<PointT> rgb(cloud); // viewer->addPointCloud<PointT>(cloud,rgb,"input_cloud"); // viewer->spinOnce(); //std::cout << final_hypothesis.at(0).cluster->points[0]; //boost::this_thread::sleep(boost::posix_time::milliseconds(10)); displayCloud_.join(); cloud_mutex.unlock(); } } grab->stop(); return 0; }
// wrapper around hurt_proc for cases where the damage is caused by something that can be caught by virtual interface. // damage sources that are not caught by virtual interface should call hurt_proc directly void apply_packet_damage_to_proc(struct proc_struct* pr, int damage, int cause_team, int cause_core_index, timestamp cause_core_timestamp) { struct core_struct* core = &w.core[pr->core_index]; core->damage_source_core_index = cause_core_index; core->damage_source_core_timestamp = cause_core_timestamp; core->damage_this_cycle += damage; // if (pr->interface_object_present // && pr->interface_on_process_set_on) // checks for core->interface_active just below if (pr->interface_protects) // checks for core->interface_active just below { if (core->interface_active) { if (pr->interface_stability) damage /= 2; core->interface_strength -= damage; if (core->interface_strength > 0) { pr->interface_hit_time = w.world_time; return; } // interface broken: // fpr("\n broken interface core %i", core->index); core->interface_active = 0; core->interface_broken_time = w.world_time; play_game_sound(SAMPLE_INT_BREAK, TONE_1G, 140, 1, pr->position.x, pr->position.y); int i; for (i = 0; i < core->group_members_max; i ++) { if (core->group_member[i].exists && w.proc[core->group_member[i].index].interface_protects) // && w.proc[core->group_member[i].index].interface_object_present // && w.proc[core->group_member[i].index].interface_on_process_set_on) { struct cloud_struct* cl = new_cloud(CLOUD_INTERFACE_BREAK, 32, w.proc[core->group_member[i].index].position.x, w.proc[core->group_member[i].index].position.y); if (cl != NULL) { cl->angle = w.proc[core->group_member[i].index].angle; cl->colour = w.proc[core->group_member[i].index].player_index; cl->data [0] = w.proc[core->group_member[i].index].shape; cl->speed.x = 0; cl->speed.y = 0; cl->display_size_x1 = -200; cl->display_size_y1 = -200; cl->display_size_x2 = 200; cl->display_size_y2 = 200; } } } /* struct cloud_struct* cl = new_cloud(CLOUD_INTERFACE_BREAK, 32, pr->position.x, pr->position.y); if (cl != NULL) { cl->angle = pr->angle; cl->colour = pr->player_index; cl->data [0] = pr->shape; cl->speed.x = 0; cl->speed.y = 0; cl->display_size_x1 = -200; cl->display_size_y1 = -200; cl->display_size_x2 = 200; cl->display_size_y2 = 200; } */ // after interface is broken strength may be -ve, in which case the interface may need to recharge for a while. return; } } /* if (pr->virtual_method != -1 && pr->method[pr->virtual_method].data [MDATA_PR_VIRTUAL_STATE] > 0) { if (damage >= pr->method[pr->virtual_method].data [MDATA_PR_VIRTUAL_STATE]) { damage -= pr->method[pr->virtual_method].data [MDATA_PR_VIRTUAL_STATE]; virtual_method_break(pr); } else { pr->method[pr->virtual_method].data [MDATA_PR_VIRTUAL_STATE] -= damage; pr->method[pr->virtual_method].data [MDATA_PR_VIRTUAL_PULSE] += (damage / 2); if (pr->method[pr->virtual_method].data [MDATA_PR_VIRTUAL_PULSE] > VIRTUAL_METHOD_PULSE_MAX) pr->method[pr->virtual_method].data [MDATA_PR_VIRTUAL_PULSE] = VIRTUAL_METHOD_PULSE_MAX; return; } } */ if (damage <= 0) return; pr->hit_pulse_time = w.world_time; hurt_proc(pr->index, damage, cause_team); }
// This function destroys a non-core process and everything downlinked from it static void noncore_proc_explodes(struct proc_struct* destroyed_pr, int destroyer_team) { /* struct cloud_struct* cl = new_cloud(CLOUD_PROC_EXPLODE, 32, destroyed_pr->position.x, destroyed_pr->position.y); if (cl != NULL) { cl->angle = destroyed_pr->angle; cl->colour = destroyer_team; cl->data [0] = destroyed_pr->shape; cl->speed.x = 0; cl->speed.y = 0; }*/ struct proc_struct* parent_pr = destroyed_pr->group_connection_ptr [0]; int parent_connection_index = destroyed_pr->connected_from [0]; // int parent_downlink_index = destroyed_pr->connected_from_link [0]; // parent_pr->group_connection [parent_connection_index] = NULL; parent_pr->group_connection_exists [parent_connection_index] = 0; procs_destroyed_in_this_explosion = w.core[destroyed_pr->core_index].group_members_current; // subtracted from below int i; for (i = 1; i < GROUP_CONNECTIONS; i++) // Note i starts at 1 (don't destroy uplink) { if (destroyed_pr->group_connection_exists [i]) { destroy_procs_recursively(&w.core[destroyed_pr->core_index], destroyed_pr->group_connection_ptr[i], destroyer_team); } } w.core[destroyed_pr->core_index].group_member[destroyed_pr->group_member_index].exists = 0; // core->group_members--; this is dealt with by set_basic_group_properties() destroy_a_proc(destroyed_pr, destroyer_team); play_game_sound(SAMPLE_BANG, TONE_2C, 60, 10, destroyed_pr->position.x, destroyed_pr->position.y); reset_group_after_composition_change(&w.core[destroyed_pr->core_index]); procs_destroyed_in_this_explosion -= w.core[destroyed_pr->core_index].group_members_current; // fpr("\n procs_destroyed_in_this_explosion %i", procs_destroyed_in_this_explosion); struct cloud_struct* cl = new_cloud(CLOUD_SUB_PROC_EXPLODE, 64, destroyed_pr->position.x, destroyed_pr->position.y); if (cl != NULL) { cl->angle = destroyed_pr->angle; cl->colour = destroyed_pr->player_index; //destroyer_team; cl->data [0] = destroyed_pr->shape; cl->data [1] = procs_destroyed_in_this_explosion; cl->speed.x = 0; cl->speed.y = 0; cl->display_size_x1 = -200; cl->display_size_y1 = -200; cl->display_size_x2 = 200; cl->display_size_y2 = 200; } explosion_fragments(destroyed_pr->position.x, destroyed_pr->position.y, destroyed_pr->speed.x, destroyed_pr->speed.y, 6, destroyed_pr->player_index); explosion_affects_block_nodes(destroyed_pr->position.x, destroyed_pr->position.y, 200 + (procs_destroyed_in_this_explosion * 20), destroyed_pr->player_index); shake_screen(destroyed_pr->position.x, destroyed_pr->position.y, 6 + procs_destroyed_in_this_explosion); }
// This function destroys an entire process from the core. // It then destroys group members using the group_member array rather than recursively through connections, // because the fact that the group no longer exists means that some steps involved in removing a proc from a group can be ignored. void core_proc_explodes(struct proc_struct* core_pr, int destroyer_team) { struct core_struct* core = &w.core[core_pr->core_index]; struct cloud_struct* cl = new_cloud(CLOUD_MAIN_PROC_EXPLODE, 64, core_pr->position.x, core_pr->position.y); if (cl != NULL) { cl->angle = core_pr->angle; cl->colour = core_pr->player_index; cl->data [0] = core_pr->shape; cl->data [1] = core->group_members_current; cl->speed.x = 0; cl->speed.y = 0; cl->display_size_x1 = -300; cl->display_size_y1 = -300; cl->display_size_x2 = 300; cl->display_size_y2 = 300; } explosion_fragments(core_pr->position.x, core_pr->position.y, core_pr->speed.x, core_pr->speed.y, 6, core_pr->player_index); explosion_affects_block_nodes(core_pr->position.x, core_pr->position.y, 200 + (core->group_members_current * 20), core_pr->player_index); int i; remove_core_from_selection(core_pr->core_index); if (templ[core->player_index][core->template_index].first_build_object_member != -1) clear_build_queue_for_core(core->player_index, core->index); if (core->special_AI_type != 0) special_AI_destroyed(core); // this may create a bubble that will be turned into a cloud below. core->exists = 0; core->destroyed_timestamp = w.world_time; if (core->bubble_text_time > w.world_time - BUBBLE_TOTAL_TIME) { // if the core had a bubble, it stays on as a cloud (and refers to bubble data in the core's core_struct, // which should still be usable because the core will be deallocating) struct cloud_struct* bubble_cl = new_cloud(CLOUD_BUBBLE_TEXT, BUBBLE_TOTAL_TIME, core_pr->position.x, core_pr->position.y); if (bubble_cl != NULL) { bubble_cl->created_timestamp = core->bubble_text_time; bubble_cl->destruction_timestamp = bubble_cl->created_timestamp + BUBBLE_TOTAL_TIME; bubble_cl->data [0] = core->index; bubble_cl->display_size_x1 = -300; bubble_cl->display_size_y1 = -40; bubble_cl->display_size_x2 = 300; bubble_cl->display_size_y2 = 40; } } destroy_a_proc(&w.proc[core->process_index], destroyer_team); w.proc[core->process_index].reserved = 0; for (i = 1; i < core->group_members_max; i++) // note for i = 1 { sancheck(core->group_member[i].index, 0, w.max_procs, "core_proc_explodes: core->group_member[i].index"); w.proc[core->group_member[i].index].reserved = 0; // core has been destroyed, so proc no longer reserved if (core->group_member[i].exists) { cl = new_cloud(CLOUD_SUB_PROC_EXPLODE, 64, w.proc[core->group_member[i].index].position.x, w.proc[core->group_member[i].index].position.y); if (cl != NULL) { cl->angle = w.proc[core->group_member[i].index].angle; cl->colour = core->player_index; cl->data [0] = w.proc[core->group_member[i].index].shape; cl->data [1] = 1; cl->speed.x = 0; cl->speed.y = 0; cl->display_size_x1 = -200; cl->display_size_y1 = -200; cl->display_size_x2 = 200; cl->display_size_y2 = 200; } procs_destroyed_in_this_explosion ++; explosion_fragments(w.proc[core->group_member[i].index].position.x, w.proc[core->group_member[i].index].position.y, w.proc[core->group_member[i].index].speed.x, w.proc[core->group_member[i].index].speed.y, 6, core->player_index); destroy_a_proc(&w.proc[core->group_member[i].index], destroyer_team); } } // play_game_sound(SAMPLE_BANG, TONE_2C - (procs_destroyed_in_this_explosion / 3), 100, 10, core->core_position.x, core->core_position.y); int bang_sample = SAMPLE_BANG; if (procs_destroyed_in_this_explosion > 1) bang_sample = SAMPLE_BANG2; play_game_sound(bang_sample, TONE_2C - (procs_destroyed_in_this_explosion / 3), 50, 10, core->core_position.x, core->core_position.y); shake_screen(core->core_position.x, core->core_position.y, 16 + procs_destroyed_in_this_explosion); }