void CaveFractal::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) { node_min = nmin; node_max = nmax; main_direction = v3f(0, 0, 0); // Allowed route area size in nodes ar = node_max - node_min + v3s16(1, 1, 1); // Area starting point in nodes of = node_min; // Allow a bit more //(this should be more than the maximum radius of the tunnel) s16 insure = 10; s16 more = MYMAX(MAP_BLOCKSIZE - max_tunnel_diameter / 2 - insure, 1); ar += v3s16(1,0,1) * more * 2; of -= v3s16(1,0,1) * more; route_y_min = 0; // Allow half a diameter + 7 over stone surface route_y_max = -of.Y + max_stone_y + max_tunnel_diameter / 2 + 7; // Limit maximum to area route_y_max = rangelim(route_y_max, 0, ar.Y - 1); s16 min = 0; if (node_min.Y < water_level && node_max.Y > water_level) { min = water_level - max_tunnel_diameter/3 - of.Y; route_y_max = water_level + max_tunnel_diameter/3 - of.Y; } route_y_min = ps->range(min, min + max_tunnel_diameter); route_y_min = rangelim(route_y_min, 0, route_y_max); s16 route_start_y_min = route_y_min; s16 route_start_y_max = route_y_max; route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1); route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1); // Randomize starting position orp = v3f( (float)(ps->next() % ar.X) + 0.5, (float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5, (float)(ps->next() % ar.Z) + 0.5 ); // Add generation notify begin event v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN; mg->gennotify.addEvent(notifytype, abs_pos); // Generate some tunnel starting from orp for (u16 j = 0; j < tunnel_routepoints; j++) makeTunnel(j % dswitchint == 0); // Add generation notify end event abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); notifytype = GENNOTIFY_LARGECAVE_END; mg->gennotify.addEvent(notifytype, abs_pos); }
void CavesV6::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, PseudoRandom *ps, PseudoRandom *ps2, bool is_large_cave, int max_stone_height, s16 *heightmap) { assert(vm); assert(ps); assert(ps2); this->vm = vm; this->ps = ps; this->ps2 = ps2; this->node_min = nmin; this->node_max = nmax; this->heightmap = heightmap; this->large_cave = is_large_cave; this->ystride = nmax.X - nmin.X + 1; // Set initial parameters from randomness min_tunnel_diameter = 2; max_tunnel_diameter = ps->range(2, 6); int dswitchint = ps->range(1, 14); if (large_cave) { part_max_length_rs = ps->range(2, 4); tunnel_routepoints = ps->range(5, ps->range(15, 30)); min_tunnel_diameter = 5; max_tunnel_diameter = ps->range(7, ps->range(8, 24)); } else { part_max_length_rs = ps->range(2, 9); tunnel_routepoints = ps->range(10, ps->range(15, 30)); } large_cave_is_flat = (ps->range(0, 1) == 0); main_direction = v3f(0, 0, 0); // Allowed route area size in nodes ar = node_max - node_min + v3s16(1, 1, 1); // Area starting point in nodes of = node_min; // Allow a bit more //(this should be more than the maximum radius of the tunnel) const s16 max_spread_amount = MAP_BLOCKSIZE; const s16 insure = 10; s16 more = MYMAX(max_spread_amount - max_tunnel_diameter / 2 - insure, 1); ar += v3s16(1, 0, 1) * more * 2; of -= v3s16(1, 0, 1) * more; route_y_min = 0; // Allow half a diameter + 7 over stone surface route_y_max = -of.Y + max_stone_height + max_tunnel_diameter / 2 + 7; // Limit maximum to area route_y_max = rangelim(route_y_max, 0, ar.Y - 1); if (large_cave) { s16 minpos = 0; if (node_min.Y < water_level && node_max.Y > water_level) { minpos = water_level - max_tunnel_diameter / 3 - of.Y; route_y_max = water_level + max_tunnel_diameter / 3 - of.Y; } route_y_min = ps->range(minpos, minpos + max_tunnel_diameter); route_y_min = rangelim(route_y_min, 0, route_y_max); } s16 route_start_y_min = route_y_min; s16 route_start_y_max = route_y_max; route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1); route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1); // Randomize starting position orp.Z = (float)(ps->next() % ar.Z) + 0.5f; orp.Y = (float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5f; orp.X = (float)(ps->next() % ar.X) + 0.5f; // Add generation notify begin event if (gennotify != NULL) { v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); GenNotifyType notifytype = large_cave ? GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN; gennotify->addEvent(notifytype, abs_pos); } // Generate some tunnel starting from orp for (u16 j = 0; j < tunnel_routepoints; j++) makeTunnel(j % dswitchint == 0); // Add generation notify end event if (gennotify != NULL) { v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z); GenNotifyType notifytype = large_cave ? GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END; gennotify->addEvent(notifytype, abs_pos); } }