Dungeongen: Add and improve parameters
Add: Bool for 'only_in_ground'. Min and max corridor length. Min and max room size with X, Y, Z components. Min and max large room size with X, Y, Z components. 'only_in_ground = false' allows core mapgens to create structures in air and water using dungeongen. Corridor length parameters replace a fixed random range. Room size parameters replace the former system where one parameter 'roomsize' was added to fixed random ranges. All parameters are set for no change to current dungeon behaviour. Remove some now-redundant and long-unused code.master
parent
4d634ef675
commit
a901a56859
|
@ -52,6 +52,7 @@ DungeonGen::DungeonGen(INodeDefManager *ndef,
|
|||
if (dparams) {
|
||||
memcpy(&dp, dparams, sizeof(dp));
|
||||
} else {
|
||||
// Default dungeon parameters
|
||||
dp.seed = 0;
|
||||
|
||||
dp.c_water = ndef->getId("mapgen_water_source");
|
||||
|
@ -63,14 +64,20 @@ DungeonGen::DungeonGen(INodeDefManager *ndef,
|
|||
if (dp.c_river_water == CONTENT_IGNORE)
|
||||
dp.c_river_water = ndef->getId("mapgen_water_source");
|
||||
|
||||
dp.diagonal_dirs = false;
|
||||
dp.holesize = v3s16(1, 2, 1);
|
||||
dp.roomsize = v3s16(0, 0, 0);
|
||||
dp.rooms_min = 2;
|
||||
dp.rooms_max = 16;
|
||||
dp.y_min = -MAX_MAP_GENERATION_LIMIT;
|
||||
dp.y_max = MAX_MAP_GENERATION_LIMIT;
|
||||
dp.notifytype = GENNOTIFY_DUNGEON;
|
||||
dp.diagonal_dirs = false;
|
||||
dp.only_in_ground = true;
|
||||
dp.holesize = v3s16(1, 2, 1);
|
||||
dp.corridor_len_min = 1;
|
||||
dp.corridor_len_max = 13;
|
||||
dp.room_size_min = v3s16(4, 4, 4);
|
||||
dp.room_size_max = v3s16(8, 6, 8);
|
||||
dp.room_size_large_min = v3s16(8, 8, 8);
|
||||
dp.room_size_large_max = v3s16(16, 16, 16);
|
||||
dp.rooms_min = 2;
|
||||
dp.rooms_max = 16;
|
||||
dp.y_min = -MAX_MAP_GENERATION_LIMIT;
|
||||
dp.y_max = MAX_MAP_GENERATION_LIMIT;
|
||||
dp.notifytype = GENNOTIFY_DUNGEON;
|
||||
|
||||
dp.np_density = nparams_dungeon_density;
|
||||
dp.np_alt_wall = nparams_dungeon_alt_wall;
|
||||
|
@ -97,16 +104,19 @@ void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax)
|
|||
// Dungeon generator doesn't modify places which have this set
|
||||
vm->clearFlag(VMANIP_FLAG_DUNGEON_INSIDE | VMANIP_FLAG_DUNGEON_PRESERVE);
|
||||
|
||||
// Set all air and water to be untouchable
|
||||
// to make dungeons open to caves and open air
|
||||
for (s16 z = nmin.Z; z <= nmax.Z; z++) {
|
||||
for (s16 y = nmin.Y; y <= nmax.Y; y++) {
|
||||
u32 i = vm->m_area.index(nmin.X, y, z);
|
||||
for (s16 x = nmin.X; x <= nmax.X; x++) {
|
||||
content_t c = vm->m_data[i].getContent();
|
||||
if (c == CONTENT_AIR || c == dp.c_water || c == dp.c_river_water)
|
||||
vm->m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
|
||||
i++;
|
||||
if (dp.only_in_ground) {
|
||||
// Set all air and water to be untouchable
|
||||
// to make dungeons open to caves and open air
|
||||
for (s16 z = nmin.Z; z <= nmax.Z; z++) {
|
||||
for (s16 y = nmin.Y; y <= nmax.Y; y++) {
|
||||
u32 i = vm->m_area.index(nmin.X, y, z);
|
||||
for (s16 x = nmin.X; x <= nmax.X; x++) {
|
||||
content_t c = vm->m_data[i].getContent();
|
||||
if (c == CONTENT_AIR || c == dp.c_water ||
|
||||
c == dp.c_river_water)
|
||||
vm->m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,21 +152,25 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
|
|||
v3s16 roomplace;
|
||||
|
||||
/*
|
||||
Find place for first room
|
||||
Find place for first room.
|
||||
There is a 1 in 4 chance of the first room being 'large',
|
||||
all other rooms are not 'large'.
|
||||
*/
|
||||
bool fits = false;
|
||||
for (u32 i = 0; i < 100 && !fits; i++) {
|
||||
bool is_large_room = ((random.next() & 3) == 1);
|
||||
if (is_large_room) {
|
||||
roomsize.Z = random.range(8, 16);
|
||||
roomsize.Y = random.range(8, 16);
|
||||
roomsize.X = random.range(8, 16);
|
||||
roomsize.Z = random.range(
|
||||
dp.room_size_large_min.Z, dp.room_size_large_max.Z);
|
||||
roomsize.Y = random.range(
|
||||
dp.room_size_large_min.Y, dp.room_size_large_max.Y);
|
||||
roomsize.X = random.range(
|
||||
dp.room_size_large_min.X, dp.room_size_large_max.X);
|
||||
} else {
|
||||
roomsize.Z = random.range(4, 8);
|
||||
roomsize.Y = random.range(4, 6);
|
||||
roomsize.X = random.range(4, 8);
|
||||
roomsize.Z = random.range(dp.room_size_min.Z, dp.room_size_max.Z);
|
||||
roomsize.Y = random.range(dp.room_size_min.Y, dp.room_size_max.Y);
|
||||
roomsize.X = random.range(dp.room_size_min.X, dp.room_size_max.X);
|
||||
}
|
||||
roomsize += dp.roomsize;
|
||||
|
||||
// start_padding is used to disallow starting the generation of
|
||||
// a dungeon in a neighboring generation chunk
|
||||
|
@ -246,10 +260,9 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
|
|||
makeCorridor(doorplace, doordir, corridor_end, corridor_end_dir);
|
||||
|
||||
// Find a place for a random sized room
|
||||
roomsize.Z = random.range(4, 8);
|
||||
roomsize.Y = random.range(4, 6);
|
||||
roomsize.X = random.range(4, 8);
|
||||
roomsize += dp.roomsize;
|
||||
roomsize.Z = random.range(dp.room_size_min.Z, dp.room_size_max.Z);
|
||||
roomsize.Y = random.range(dp.room_size_min.Y, dp.room_size_max.Y);
|
||||
roomsize.X = random.range(dp.room_size_min.X, dp.room_size_max.X);
|
||||
|
||||
m_pos = corridor_end;
|
||||
m_dir = corridor_end_dir;
|
||||
|
@ -397,13 +410,8 @@ void DungeonGen::makeCorridor(v3s16 doorplace, v3s16 doordir,
|
|||
makeHole(doorplace);
|
||||
v3s16 p0 = doorplace;
|
||||
v3s16 dir = doordir;
|
||||
u32 length;
|
||||
/*if (random.next() % 2)
|
||||
length = random.range(1, 13);
|
||||
else
|
||||
length = random.range(1, 6);*/
|
||||
length = random.range(1, 13);
|
||||
u32 partlength = random.range(1, 13);
|
||||
u32 length = random.range(dp.corridor_len_min, dp.corridor_len_max);
|
||||
u32 partlength = random.range(dp.corridor_len_min, dp.corridor_len_max);
|
||||
u32 partcount = 0;
|
||||
s16 make_stairs = 0;
|
||||
|
||||
|
@ -556,7 +564,6 @@ bool DungeonGen::findPlaceForRoomDoor(v3s16 roomsize, v3s16 &result_doorplace,
|
|||
continue;
|
||||
v3s16 roomplace;
|
||||
// X east, Z north, Y up
|
||||
#if 1
|
||||
if (doordir == v3s16(1, 0, 0)) // X+
|
||||
roomplace = doorplace +
|
||||
v3s16(0, -1, random.range(-roomsize.Z + 2, -2));
|
||||
|
@ -569,17 +576,6 @@ bool DungeonGen::findPlaceForRoomDoor(v3s16 roomsize, v3s16 &result_doorplace,
|
|||
if (doordir == v3s16(0, 0, -1)) // Z-
|
||||
roomplace = doorplace +
|
||||
v3s16(random.range(-roomsize.X + 2, -2), -1, -roomsize.Z + 1);
|
||||
#endif
|
||||
#if 0
|
||||
if (doordir == v3s16(1, 0, 0)) // X+
|
||||
roomplace = doorplace + v3s16(0, -1, -roomsize.Z / 2);
|
||||
if (doordir == v3s16(-1, 0, 0)) // X-
|
||||
roomplace = doorplace + v3s16(-roomsize.X+1,-1,-roomsize.Z / 2);
|
||||
if (doordir == v3s16(0, 0, 1)) // Z+
|
||||
roomplace = doorplace + v3s16(-roomsize.X / 2, -1, 0);
|
||||
if (doordir == v3s16(0, 0, -1)) // Z-
|
||||
roomplace = doorplace + v3s16(-roomsize.X / 2, -1, -roomsize.Z + 1);
|
||||
#endif
|
||||
|
||||
// Check fit
|
||||
bool fits = true;
|
||||
|
|
|
@ -48,8 +48,14 @@ struct DungeonParams {
|
|||
content_t c_stair;
|
||||
|
||||
bool diagonal_dirs;
|
||||
bool only_in_ground;
|
||||
v3s16 holesize;
|
||||
v3s16 roomsize;
|
||||
u16 corridor_len_min;
|
||||
u16 corridor_len_max;
|
||||
v3s16 room_size_min;
|
||||
v3s16 room_size_max;
|
||||
v3s16 room_size_large_min;
|
||||
v3s16 room_size_large_max;
|
||||
u16 rooms_min;
|
||||
u16 rooms_max;
|
||||
s16 y_min;
|
||||
|
|
|
@ -845,47 +845,61 @@ void MapgenBasic::generateDungeons(s16 max_stone_y, MgStoneType stone_type)
|
|||
|
||||
DungeonParams dp;
|
||||
|
||||
dp.seed = seed;
|
||||
dp.c_water = c_water_source;
|
||||
dp.c_river_water = c_river_water_source;
|
||||
dp.rooms_min = 2;
|
||||
dp.rooms_max = 16;
|
||||
dp.y_min = -MAX_MAP_GENERATION_LIMIT;
|
||||
dp.y_max = MAX_MAP_GENERATION_LIMIT;
|
||||
dp.np_density = nparams_dungeon_density;
|
||||
dp.np_alt_wall = nparams_dungeon_alt_wall;
|
||||
dp.seed = seed;
|
||||
dp.c_water = c_water_source;
|
||||
dp.c_river_water = c_river_water_source;
|
||||
|
||||
dp.only_in_ground = true;
|
||||
dp.corridor_len_min = 1;
|
||||
dp.corridor_len_max = 13;
|
||||
dp.rooms_min = 2;
|
||||
dp.rooms_max = 16;
|
||||
dp.y_min = -MAX_MAP_GENERATION_LIMIT;
|
||||
dp.y_max = MAX_MAP_GENERATION_LIMIT;
|
||||
|
||||
dp.np_density = nparams_dungeon_density;
|
||||
dp.np_alt_wall = nparams_dungeon_alt_wall;
|
||||
|
||||
switch (stone_type) {
|
||||
default:
|
||||
case MGSTONE_STONE:
|
||||
dp.c_wall = c_cobble;
|
||||
dp.c_alt_wall = c_mossycobble;
|
||||
dp.c_stair = c_stair_cobble;
|
||||
dp.c_wall = c_cobble;
|
||||
dp.c_alt_wall = c_mossycobble;
|
||||
dp.c_stair = c_stair_cobble;
|
||||
|
||||
dp.diagonal_dirs = false;
|
||||
dp.holesize = v3s16(1, 2, 1);
|
||||
dp.roomsize = v3s16(0, 0, 0);
|
||||
dp.notifytype = GENNOTIFY_DUNGEON;
|
||||
dp.diagonal_dirs = false;
|
||||
dp.holesize = v3s16(1, 2, 1);
|
||||
dp.room_size_min = v3s16(4, 4, 4);
|
||||
dp.room_size_max = v3s16(8, 6, 8);
|
||||
dp.room_size_large_min = v3s16(8, 8, 8);
|
||||
dp.room_size_large_max = v3s16(16, 16, 16);
|
||||
dp.notifytype = GENNOTIFY_DUNGEON;
|
||||
break;
|
||||
case MGSTONE_DESERT_STONE:
|
||||
dp.c_wall = c_desert_stone;
|
||||
dp.c_alt_wall = CONTENT_IGNORE;
|
||||
dp.c_stair = c_stair_desert_stone;
|
||||
dp.c_wall = c_desert_stone;
|
||||
dp.c_alt_wall = CONTENT_IGNORE;
|
||||
dp.c_stair = c_stair_desert_stone;
|
||||
|
||||
dp.diagonal_dirs = true;
|
||||
dp.holesize = v3s16(2, 3, 2);
|
||||
dp.roomsize = v3s16(2, 5, 2);
|
||||
dp.notifytype = GENNOTIFY_TEMPLE;
|
||||
dp.diagonal_dirs = true;
|
||||
dp.holesize = v3s16(2, 3, 2);
|
||||
dp.room_size_min = v3s16(6, 9, 6);
|
||||
dp.room_size_max = v3s16(10, 11, 10);
|
||||
dp.room_size_large_min = v3s16(10, 13, 10);
|
||||
dp.room_size_large_max = v3s16(18, 21, 18);
|
||||
dp.notifytype = GENNOTIFY_TEMPLE;
|
||||
break;
|
||||
case MGSTONE_SANDSTONE:
|
||||
dp.c_wall = c_sandstonebrick;
|
||||
dp.c_alt_wall = CONTENT_IGNORE;
|
||||
dp.c_stair = c_stair_sandstonebrick;
|
||||
dp.c_wall = c_sandstonebrick;
|
||||
dp.c_alt_wall = CONTENT_IGNORE;
|
||||
dp.c_stair = c_stair_sandstonebrick;
|
||||
|
||||
dp.diagonal_dirs = false;
|
||||
dp.holesize = v3s16(2, 2, 2);
|
||||
dp.roomsize = v3s16(2, 0, 2);
|
||||
dp.notifytype = GENNOTIFY_DUNGEON;
|
||||
dp.diagonal_dirs = false;
|
||||
dp.holesize = v3s16(2, 2, 2);
|
||||
dp.room_size_min = v3s16(6, 4, 6);
|
||||
dp.room_size_max = v3s16(10, 6, 10);
|
||||
dp.room_size_large_min = v3s16(10, 8, 10);
|
||||
dp.room_size_large_max = v3s16(18, 16, 18);
|
||||
dp.notifytype = GENNOTIFY_DUNGEON;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -564,34 +564,47 @@ void MapgenV6::makeChunk(BlockMakeData *data)
|
|||
if ((flags & MG_DUNGEONS) && (stone_surface_max_y >= node_min.Y)) {
|
||||
DungeonParams dp;
|
||||
|
||||
dp.seed = seed;
|
||||
dp.c_water = c_water_source;
|
||||
dp.c_river_water = c_water_source;
|
||||
dp.rooms_min = 2;
|
||||
dp.rooms_max = 16;
|
||||
dp.y_min = -MAX_MAP_GENERATION_LIMIT;
|
||||
dp.y_max = MAX_MAP_GENERATION_LIMIT;
|
||||
dp.np_density = NoiseParams(0.9, 0.5, v3f(500.0, 500.0, 500.0), 0, 2, 0.8, 2.0);
|
||||
dp.np_alt_wall = NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0);
|
||||
dp.seed = seed;
|
||||
dp.c_water = c_water_source;
|
||||
dp.c_river_water = c_water_source;
|
||||
|
||||
dp.only_in_ground = true;
|
||||
dp.corridor_len_min = 1;
|
||||
dp.corridor_len_max = 13;
|
||||
dp.rooms_min = 2;
|
||||
dp.rooms_max = 16;
|
||||
dp.y_min = -MAX_MAP_GENERATION_LIMIT;
|
||||
dp.y_max = MAX_MAP_GENERATION_LIMIT;
|
||||
|
||||
dp.np_density
|
||||
= NoiseParams(0.9, 0.5, v3f(500.0, 500.0, 500.0), 0, 2, 0.8, 2.0);
|
||||
dp.np_alt_wall
|
||||
= NoiseParams(-0.4, 1.0, v3f(40.0, 40.0, 40.0), 32474, 6, 1.1, 2.0);
|
||||
|
||||
if (getBiome(0, v2s16(node_min.X, node_min.Z)) == BT_DESERT) {
|
||||
dp.c_wall = c_desert_stone;
|
||||
dp.c_alt_wall = CONTENT_IGNORE;
|
||||
dp.c_stair = c_stair_desert_stone;
|
||||
dp.c_wall = c_desert_stone;
|
||||
dp.c_alt_wall = CONTENT_IGNORE;
|
||||
dp.c_stair = c_stair_desert_stone;
|
||||
|
||||
dp.diagonal_dirs = true;
|
||||
dp.holesize = v3s16(2, 3, 2);
|
||||
dp.roomsize = v3s16(2, 5, 2);
|
||||
dp.notifytype = GENNOTIFY_TEMPLE;
|
||||
dp.diagonal_dirs = true;
|
||||
dp.holesize = v3s16(2, 3, 2);
|
||||
dp.room_size_min = v3s16(6, 9, 6);
|
||||
dp.room_size_max = v3s16(10, 11, 10);
|
||||
dp.room_size_large_min = v3s16(10, 13, 10);
|
||||
dp.room_size_large_max = v3s16(18, 21, 18);
|
||||
dp.notifytype = GENNOTIFY_TEMPLE;
|
||||
} else {
|
||||
dp.c_wall = c_cobble;
|
||||
dp.c_alt_wall = c_mossycobble;
|
||||
dp.c_stair = c_stair_cobble;
|
||||
dp.c_wall = c_cobble;
|
||||
dp.c_alt_wall = c_mossycobble;
|
||||
dp.c_stair = c_stair_cobble;
|
||||
|
||||
dp.diagonal_dirs = false;
|
||||
dp.holesize = v3s16(1, 2, 1);
|
||||
dp.roomsize = v3s16(0, 0, 0);
|
||||
dp.notifytype = GENNOTIFY_DUNGEON;
|
||||
dp.diagonal_dirs = false;
|
||||
dp.holesize = v3s16(1, 2, 1);
|
||||
dp.room_size_min = v3s16(4, 4, 4);
|
||||
dp.room_size_max = v3s16(8, 6, 8);
|
||||
dp.room_size_large_min = v3s16(8, 8, 8);
|
||||
dp.room_size_large_max = v3s16(16, 16, 16);
|
||||
dp.notifytype = GENNOTIFY_DUNGEON;
|
||||
}
|
||||
|
||||
DungeonGen dgen(ndef, &gennotify, &dp);
|
||||
|
|
Loading…
Reference in New Issue