//------------ begin of function World::plant_spread ------------// // // pSpread = probability of spreading, range from 0 to 1000 // void World::plant_spread(int pSpread) { if( plant_count > plant_limit) return; if( 5 * plant_count < 4 * plant_limit ) pSpread += pSpread; if(misc.random(1000) >= pSpread ) return; // ------- determine temperature short t = weather.temp_c(); // ------- randomly select a place to seed plant int y = 1+misc.random(max_y_loc-2); int x = 1+misc.random(max_x_loc-2); Location *l = get_loc(x,y); int build_flag = 1; char teraType = terrain_res[l->terrain_id]->average_type; // ------- all square around are the same terrain type and empty for( int y1 = y-1; y1 <= y+1; ++y1) for( int x1 = x-1; x1 <= x+1; ++x1) { l = get_loc(x1,y1); // #### begin Gilbert 6/3 #######// if( !l->can_add_plant() || terrain_res[l->terrain_id]->average_type != teraType) build_flag = 0; // #### end Gilbert 6/3 #######// } if( build_flag) { char climateZone = 0; short plantBitmap = 0; for( int retry=0; !climateZone && retry < 5; ++retry) { for( char j=0; j < 3; ++j) { if( misc.random(5) > abs(t- opt_temp[j]) ) { climateZone = j+1; plantBitmap = plant_res.scan( climateZone, teraType, 0); if( plantBitmap) { l = get_loc(x,y); l->set_plant( plantBitmap, rand_inner_x(), rand_inner_y() ); l->set_fire_src(100); plant_count++; } break; } } } } }
//------------ begin of function World::plant_init ------------// // randomly select a place and call plant_spray to enlarge the // forest // void World::plant_init() { plant_count = 0; int trial; for(trial = 50; trial > 0; --trial) { // ------- randomly select a place to seed plant int y = 1+m.random(max_y_loc-2); int x = 1+m.random(max_x_loc-2); Location *l = get_loc(x,y); int build_flag = TRUE; char teraType = terrain_res[l->terrain_id]->average_type; // ------- all square around are the same terrain type and empty for( int y1 = y-1; y1 <= y+1; ++y1) for( int x1 = x-1; x1 <= x+1; ++x1) { l = get_loc(x1,y1); // #### begin Gilbert 6/3 #######// if( !l->can_add_plant() || terrain_res[l->terrain_id]->average_type != teraType) build_flag = FALSE; // #### end Gilbert 6/3 #######// } if( build_flag ) { short plantBitmap = plant_res.scan( 0, teraType, 0); short plantArray[PLANT_ARRAY_SIZE]; for( int i = 0; i < PLANT_ARRAY_SIZE; ++i) { plantArray[i] = plant_res.plant_recno(plant_res.scan(0, teraType, 0)); } if( plantArray[0] ) { plant_spray(plantArray, 6+m.random(4), x, y); } } } plant_limit = plant_count * 3 / 2; // ------- kill some plant ----------// for(trial = 8; trial > 0; --trial) { plant_death(2); } }
//------------ begin of function World::plant_spray ------------// void World::plant_spray(short *plantArray, char area, char distance, short x, short y) { // #### begin Ban 8/10 #######// int i, j, tempi, tempj; Location *newl; char teraType; for (i=-area; i<=area; i++) { for (j=-area; j<=area; j++) { // ###### begin Gilbert 9/11 #####// tempi = misc.random(distance<<2) + i - (distance<<1); tempj = misc.random(distance<<2) + j - (distance<<1); // ###### end Gilbert 9/11 #####// if ( ((x+tempi)<(max_x_loc-1)) && ((y+tempj)<(max_y_loc-1)) && ((x+tempi)> 0) && ((y+tempj)> 0)) { newl = get_loc(x+tempi, y+tempj); short basePlantId = plantArray[misc.random(PLANT_ARRAY_SIZE)]; //get type of tree short plantSize = misc.random(plant_res[basePlantId]->bitmap_count); //get size of tree teraType = terrain_res[newl->terrain_id]->average_type; if( newl && newl->can_add_plant() && ((plant_res[basePlantId]->tera_type[0] == teraType) || (plant_res[basePlantId]->tera_type[1] == teraType) || (plant_res[basePlantId]->tera_type[2] == teraType))) { newl->set_plant(plant_res[basePlantId]->first_bitmap +plantSize, rand_inner_x(), rand_inner_y()); newl->set_fire_src(100); plant_count++; } else if( newl && newl->is_plant() && (newl->plant_id() - plant_res[plant_res.plant_recno(newl->plant_id())]->first_bitmap) > plantSize ) { newl->remove_plant(); newl->set_plant(plant_res[basePlantId]->first_bitmap +plantSize, rand_inner_x(), rand_inner_y() ); newl->set_fire_src(100); } } } } // #### end Ban 8/10 #######// }
//------------ begin of function World::plant_reprod --------// // // pReprod = prabability of reproduction, range from 0 to 20 // scanDensity = scan one square per scanDensity^2 // void World::plant_reprod(int pReprod, int scanDensity) { if( plant_count > plant_limit ) return; if( 5 * plant_count < 4 * plant_limit ) pReprod++; // higher probability to grow // determine the rainful, temperature and sunlight short t = weather.temp_c(); // scan the map for plant int yBase = misc.random(scanDensity); int xBase = misc.random(scanDensity); for( int y = yBase; y < max_y_loc; y += scanDensity) { for( int x = xBase; x < max_x_loc; x += scanDensity) { Location *l = get_loc(x,y); short bitmapId, basePlantId, plantGrade; // is a plant and grade > 3 if( l->is_plant() && (basePlantId = plant_res.plant_recno( bitmapId = l->plant_id())) != 0 && ((plantGrade = bitmapId - plant_res[basePlantId]->first_bitmap) >= 3 || plantGrade == plant_res[basePlantId]->bitmap_count-1)) { // find the optimal temperature for the plant short oTemp = opt_temp[plant_res[basePlantId]->climate_zone -1]; short tempEffect = 5 - abs( oTemp - t); tempEffect = tempEffect > 0 ? tempEffect : 0; if( misc.random(100) < tempEffect * pReprod) { // produce the same plant but grade 1, char trial = 2; Location *newl; while( trial --) { newl = NULL; switch(misc.random(8)) { case 0: // north square if( y > 0) newl = get_loc(x,y-1); break; case 1: // east square if( x < max_x_loc-1 ) newl = get_loc(x+1,y); break; case 2: // south square if( y < max_y_loc-1 ) newl = get_loc(x,y+1); break; case 3: // west square if( x > 0) newl = get_loc(x-1,y); break; case 4: // north west square if( y > 0 && x > 0) newl = get_loc(x-1,y-1); break; case 5: // north east square if( y > 0 && x < max_x_loc-1 ) newl = get_loc(x+1,y-1); break; case 6: // south east square if( y < max_y_loc-1 && x < max_x_loc-1) newl = get_loc(x+1,y+1); break; case 7: // south west square if( y < max_y_loc-1 && x > 0) newl = get_loc(x-1,y+1); break; } char teraType; // #### begin Gilbert 6/3 #######// if( newl && newl->can_add_plant() && (plant_res[basePlantId]->tera_type[0] == (teraType = terrain_res[newl->terrain_id]->average_type) || plant_res[basePlantId]->tera_type[1] == teraType || plant_res[basePlantId]->tera_type[2] == teraType) ) // #### end Gilbert 6/3 #######// { newl->set_plant(plant_res[basePlantId]->first_bitmap , rand_inner_x(), rand_inner_y() ); // ------- set flammability --------- newl->set_fire_src(100); plant_count++; //### begin alex 24/6 ###// //newl->set_power_off(); //newl->power_nation_recno = 0; //set_surr_power_off(x, y); //#### end alex 24/6 ####// break; } } } } } } }
//------------ begin of function World::plant_init ------------// // plantTrial = number of places that randomly selected to plant a forest // scanRadius = radius of the search area for killing a tree for subroutine plant_death() // remove a tree if the area has more than 3 trees // void World::plant_init(int plantTrial, int scanRadius) { plant_count = 0; for( int trial = plantTrial; trial > 0; --trial ) { // ------- randomly select a place to seed plant int y = 1+misc.random(max_y_loc-2); int x = 1+misc.random(max_x_loc-2); Location *l = get_loc(x,y); int build_flag = 1; char teraType = terrain_res[l->terrain_id]->average_type; // ------- all square around are the same terrain type and empty for( int y1 = y-1; y1 <= y+1; ++y1) for( int x1 = x-1; x1 <= x+1; ++x1) { l = get_loc(x1,y1); // #### begin Gilbert 6/3 #######// if( !l->can_add_plant() || terrain_res[l->terrain_id]->average_type != teraType) build_flag = 0; // #### end Gilbert 6/3 #######// } if( build_flag ) { short plantBitmap = plant_res.scan( 0, teraType, 0); short plantArray[PLANT_ARRAY_SIZE]; for( int i = 0; i < PLANT_ARRAY_SIZE; ++i) { plantArray[i] = plant_res.plant_recno(plant_res.scan(0, teraType, 0)); } if( plantArray[0] ) { plant_spray(plantArray, 1 + misc.random(3), 1 + misc.random(2), x, y); } } } int xLoc, yLoc; short plantBitmap = plant_res.scan( 0, 0, 0); short plantArray[PLANT_ARRAY_SIZE]; for( int i = 0; i < PLANT_ARRAY_SIZE; ++i) plantArray[i] = plant_res.plant_recno(plant_res.scan(0, 0, 0)); for( yLoc = 0; yLoc < max_y_loc; ++yLoc ) { for( xLoc = 0; xLoc < max_x_loc; ++xLoc ) { Location* locPtr = get_loc( xLoc, yLoc ); if(locPtr->has_dirt()) { Rock *dirtPtr = dirt_array[locPtr->dirt_recno()]; RockInfo *dirtInfo = rock_res.get_rock_info(dirtPtr->rock_recno); if (dirtInfo->rock_type == 'P') { if( plantArray[0] ) plant_spray(plantArray, 0, misc.random(3), xLoc, yLoc); } } } } // ------- kill some plant ----------// plant_death(1, scanRadius); }
//------------ begin of function World::plant_spray ------------// void World::plant_spray(short *plantArray, char strength, short x, short y) { if( strength <= 0) return; //---------- if the space is empty put a plant on it ----------// Location *newl = get_loc(x, y); short basePlantId = plantArray[m.random(PLANT_ARRAY_SIZE)]; short plantSize = m.random(plant_res[basePlantId]->bitmap_count); if( plantSize > strength) plantSize = strength; char teraType; if( newl && newl->can_add_plant() && (plant_res[basePlantId]->tera_type[0] == (teraType = terrain_res[newl->terrain_id]->average_type) || plant_res[basePlantId]->tera_type[1] == teraType || plant_res[basePlantId]->tera_type[2] == teraType) ) { newl->set_plant(plant_res[basePlantId]->first_bitmap +plantSize , rand_inner_x(), rand_inner_y() ); newl->set_fire_src(100); plant_count++; //### begin alex 24/6 ###// //newl->set_power_off(); //newl->power_nation_recno = 0; //set_surr_power_off(x, y); //#### end alex 24/6 ####// } else if( newl && newl->is_plant() && // 1. same type, large override small // newl->plant_id() >= plant_res[basePlantId]->first_bitmap && // newl->plant_id() < plant_res[basePlantId]->first_bitmap + plantSize) // 2. same type, small override large // newl->plant_id() > plant_res[basePlantId]->first_bitmap + plantSize && // newl->plant_id() < plant_res[basePlantId]->first_bitmap + plant_res[basePlantId]->bitmap_count) // 3. all types, small override large (newl->plant_id() - plant_res[plant_res.plant_recno(newl->plant_id())]->first_bitmap) > plantSize ) { // same kind of plant, but smaller, override by a smaller one newl->remove_plant(); newl->set_plant(plant_res[basePlantId]->first_bitmap +plantSize , rand_inner_x(), rand_inner_y() ); newl->set_fire_src(100); //### begin alex 24/6 ###// //newl->set_power_off(); //newl->power_nation_recno = 0; //set_surr_power_off(x, y); //#### end alex 24/6 ####// } else { plantSize = -1; } if( plantSize >= 0 && strength) { char trial = 3; while( trial--) { switch(m.random(8)) { case 0: // north square if( y > 0) plant_spray(plantArray, strength-1, x,y-1); break; case 1: // east square if( x < max_x_loc-1 ) plant_spray(plantArray, strength-1, x+1,y); break; case 2: // south square if( y < max_y_loc-1 ) plant_spray(plantArray, strength-1, x,y+1); break; case 3: // west square if( x > 0) plant_spray(plantArray, strength-1, x-1,y); break; case 4: // north west square if( y > 0 && x > 0) plant_spray(plantArray, strength-1, x-1,y-1); break; case 5: // north east square if( y > 0 && x < max_x_loc-1 ) plant_spray(plantArray, strength-1, x+1,y-1); break; case 6: // south east square if( y < max_y_loc-1 && x < max_x_loc-1) plant_spray(plantArray, strength-1, x+1,y+1); break; case 7: // south west square if( y < max_y_loc-1 && x > 0) plant_spray(plantArray, strength-1, x-1,y+1); break; } } } }