Exemple #1
0
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);
}
Exemple #2
0
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);
	}
}