new version

This commit is contained in:
Sokomine 2015-06-22 02:51:59 +02:00
parent edc676a2b9
commit 504ae82df0
3 changed files with 157 additions and 118 deletions

View File

@ -46,3 +46,13 @@ mines_with_shafts.deco_average_distance = 15;
-- set to true in order to get meselamps in vertical shafts all 20 nodes
mines_with_shafts.place_meselamps = false;
-- some tunnels are above ground;
-- they may require a bridge in order to reach further parts of the network;
-- the entrances also become better visible that way
mines_with_shafts.MIN_BRIDGE_LENGTH = 5
-- bridges can never grow longer than this size
mines_with_shafts.MAX_BRIDGE_LENGTH = 12
-- put a mese lamp where a tunnel would be placed above ground (only for debugging purposes)
mines_with_shafts.MARK_TUNNELS = nil; --minetest.get_content_id('default:meselamp');

View File

@ -24,7 +24,9 @@ cid_mines.c_cobble = minetest.get_content_id('default:cobble');
mines_with_shafts.get_mines_at = function( minp, maxp, check_range )
if( true ) then return {{x=100,y=5,z=100, seed=100*64000+100}}; end
local mine_positions = {};
if(true) then return {{x=-72,y=5,z=168, seed=-72*64000+168}}; end
local chunk_size = maxp.x - minp.x;
-- for now: no check for chunks in y direction
@ -58,6 +60,8 @@ mines_with_shafts.create_mine = function( minp, maxp, data, param2_data, a, heig
local surface_level_at = pr:next( 20,30 );
surface_level_at = surface_level_at - (surface_level_at%10) +5;
local chunksize = maxp.x - minp.x + 1;
-- this is a mapchunk that contains part of the vertical shaft
if( pos.x >= minp.x and pos.x <= maxp.x
and pos.z >= minp.z and pos.z <= maxp.z) then
@ -69,18 +73,24 @@ mines_with_shafts.create_mine = function( minp, maxp, data, param2_data, a, heig
local count = 0;
for ax=pos.x-1,pos.x+1 do
for az=pos.z-1,pos.z+1 do
local height = heightmap[(az-minp.z)*80+(ax-minp.x)+1];
if( height ) then
sum_height = sum_height + height;
local height = 1;
if( heightmap ) then
height = heightmap[(az-minp.z)*chunksize+(ax-minp.x)+1];
-- TODO: add alternate way in case of heightmap not defined
end
if( height and ax>=minp.x and ax<=maxp.x and az>=minp.z and az<=maxp.z) then
if( height > 0 ) then
sum_height = sum_height + height;
end
count = count+1;
end
end
end
if( count>0 and sum_height>0
if( count>0 and sum_height>=0
and data[ a:index( pos.x, minp.y, pos.z)] ~= cid_mines.c_rope
and data[ a:index( pos.x, minp.y, pos.z)] ~= cid_mines.c_fence) then
surface_height = math.max(1, sum_height/count);
surface_height = surface_height - (surface_height%10)+9;
surface_height = surface_height - (surface_height%10)+4;
--print('SURFACE HEIGHT: '..tostring( surface_height )..' COUNT: '..tostring(count)..' sum: '..tostring(sum_height));
local spos = {x=pos.x, y=surface_height, z=pos.z};
-- the schematic for the mining tower will be placed later on (after voxelmanip has been dealt with)
@ -106,7 +116,9 @@ mines_with_shafts.create_mine = function( minp, maxp, data, param2_data, a, heig
local npos = {x=pos.x, y=main_level_at; z=pos.z};
if( surface_level_at > 15 ) then
surface_level_at = surface_level_at - 5;
end
for i=5,-5,-1 do
local iteration_depth = 0;
if( i==0 ) then
@ -120,7 +132,7 @@ mines_with_shafts.create_mine = function( minp, maxp, data, param2_data, a, heig
npos.y = surface_level_at+i*5;
mines_with_shafts.create_branches_at_level( minp, maxp, data, param2_data, a, cid_mines, npos, extra_calls_mines, pr, 1, iteration_depth, heightmap );
end
if( pr:next(1,5)<4 ) then
if( pr:next(1,5)<3 ) then
npos.y = main_level_at+25+i*5;
mines_with_shafts.create_branches_at_level( minp, maxp, data, param2_data, a, cid_mines, npos, extra_calls_mines, pr, 1, iteration_depth, heightmap );
end
@ -163,9 +175,10 @@ mines_with_shafts.create_branch = function( minp, maxp, data, param2_data, a, ci
length = length+(4+3);
end
local material = 'default:wood';
if( iteration_depth == 1 ) then material = 'default:meselamp'; elseif (iteration_depth==2 ) then material = 'wool:pink'; end
-- create the main tunnel
mines_with_shafts.place_minetunnel_horizontal(minp, maxp, data, param2_data, a, cid_mines, pos, d1*length, d2, extra_calls_mines, heightmap );
mines_with_shafts.place_minetunnel_horizontal(minp, maxp, data, param2_data, a, cid_mines, pos, d1*length, d2, extra_calls_mines, heightmap, material );
-- if we went into z direction before, let the branches go into x direction (and vice versa)
local nd2 = 0;
@ -201,32 +214,6 @@ mines_with_shafts.create_branch = function( minp, maxp, data, param2_data, a, ci
last_right = true;
last_left = false;
elseif( p==6 ) then
-- crossings are places where shafts may go up and/or down
local dir = pr:next(1,5);
local y_start = npos.y;
local y_end = npos.y;
if( dir==1 and dist_last_shaft>2) then
y_start = y_start + pr:next(1,5)*5;
elseif( dir==2 and dist_last_shaft>2) then
y_end = y_end - pr:next(1,5)*5;
elseif( dir==3 and dist_last_shaft>2) then
y_start = y_start + pr:next(1,5)*5;
y_end = y_end - pr:next(1,5)*5;
end
-- make sure the vertical shaft does not go up higher than the surface
local height = heightmap[(npos.z-minp.z)*80+(npos.x-minp.x)+1];
if( not( height )) then
height = 1;
end
y_start = math.min( height, y_start );
if( y_start > y_end ) then
local vlength = y_start - y_end +2;
local vpos = {x=npos.x, y=y_start+2, z=npos.z};
mines_with_shafts.place_mineshaft_vertical(minp, maxp, data, param2_data, a, cid_mines, vpos, vlength, extra_calls_mines );
dist_last_shaft = 0;
end
elseif( pr:next(1,6)>3 ) then
last_right = false;
last_left = false;
@ -237,7 +224,57 @@ mines_with_shafts.create_branch = function( minp, maxp, data, param2_data, a, ci
last_right = false;
last_left = false;
end
dist_last_shaft = dist_last_shaft + 1;
if false and (pr:next(1,10)==1 or (dist_last_shaft>3 and iteration_depth==0 and pr:next(1,3)==1)) then
local dir = pr:next(1,5);
local y_start = npos.y;
local y_end = npos.y;
local h_max = 5;
if( iteration_depth==0 ) then
h_max = 8;
end
if( dir==1 and dist_last_shaft>2) then
y_start = y_start + pr:next(1,h_max)*5;
elseif( dir==2 and dist_last_shaft>2) then
y_end = y_end - pr:next(1,h_max)*5;
elseif( dir==3 and dist_last_shaft>2) then
y_start = y_start + pr:next(1,h_max)*5;
y_end = y_end - pr:next(1,h_max)*5;
end
-- make sure the vertical shaft does not go up higher than the surface
local height = 1;
if( heightmap ) then
height = heightmap[(npos.z-minp.z)*( maxp.x - minp.x + 1)+(npos.x-minp.x)+1];
else
light = minetest.get_node_light({x=npos.x, y=npos.y+2, z=npos.z}, 0.5);
if( not(light) or light<14 ) then
height = pos.y+3;
end
end
if( not( height )) then
height = 1;
-- TODO: add alternate way in case heightmap not defined
end
y_start = math.min( height, y_start );
if( y_start > y_end ) then
local vlength = y_start - y_end +2;
local vpos = {x=npos.x, y=y_start+2, z=npos.z};
mines_with_shafts.place_mineshaft_vertical(minp, maxp, data, param2_data, a, cid_mines, vpos, vlength, extra_calls_mines );
dist_last_shaft = 0;
if( height and y_start >= height and height>=minp.y and height<=maxp.y and height>=0
and npos.x>=minp.x and npos.x<=maxp.x and npos.z>=minp.z and npos.z<=maxp.z) then
-- TODO: make that configurable
local schems = { 'mine_shaft_entrance_basic_1_90',
'mine_shaft_entrance_stonebrick_1_90',
'mine_shaft_entrance_simple_1_90'};
local i = pr:next(1,#schems);
table.insert( extra_calls_mines.schems, {x=npos.x-2, y=math.max(1,height), z=npos.z-2, file=schems[i]});
end
end
else
dist_last_shaft = dist_last_shaft + 1;
end
end
end
@ -257,6 +294,7 @@ mines_with_shafts.handle_metadata = function( extra_calls )
local path = mines_with_shafts.modpath..'/schems/';
for _,v in pairs( extra_calls.schems ) do
if( v.file ) then
print('PLACING SCHEM '..tostring( v.file )..' AT '..minetest.pos_to_string( v )); -- TODO
minetest.place_schematic( {x=v.x, y=v.y, z=v.z}, path..v.file..".mts", "0", {}, true);
end
end

View File

@ -7,103 +7,94 @@
-- returns the length of the new tunnel
mines_with_shafts.place_minetunnel_horizontal = function(minp, maxp, data, param2_data, a, cid, pos, length, parallel_to_x_axis, extra_calls, heightmap )
-- exclude those tunnels that are not part of this mapchunk
-- we are only responsible for this tunnel if the central part of it is contained in this mapchunk;
-- that way, there will always be exactly one mapchunk responsible for each tunnel,
-- and the heightmap can be used as well;
-- further boundary checks are not necessary as the tunnel will be smaller than the shell
if( ( ( pos.y < minp.y or pos.y > maxp.y))
or (parallel_to_x_axis==0 and ( pos.x < minp.x or pos.x > maxp.x))
or (parallel_to_x_axis==1 and ( pos.z < minp.z or pos.z > maxp.z))
-- eliminate wrong parameters
or (parallel_to_x_axis~=0 and parallel_to_x_axis~=1)
or (not(heightmap))) then
return 0;
if( pos.y < minp.y or pos.y > maxp.y
or (parallel_to_x_axis==1 and ((pos.z < minp.z or pos.z > maxp.z) or (length>0 and pos.x>maxp.x) or (length<0 and pos.x<minp.x)))
or (parallel_to_x_axis~=1 and ((pos.x < minp.x or pos.x > maxp.x) or (length>0 and pos.z>maxp.z) or (length<0 and pos.z<minp.z)))) then
return;
end
local step = 1;
if( length<0 ) then
step = -1;
local px = 0;
local pz = 0;
if(parallel_to_x_axis==1) then
px = 1;
pz = 0;
else
px = 0;
pz = 1;
end
if( length<0 ) then
px = px*-1;
pz = pz*-1;
end
local vector_quer = {x=math.abs(pz),z=math.abs(px)};
local chunksize = maxp.x-minp.x+1;
local ax = pos.x;
local az = pos.z;
local vector_quer = {x=0,z=0};
if( parallel_to_x_axis==0 ) then
if( pos.x < minp.x and step>0) then
ax = minp.x;
length = length-( minp.x-pos.x );
elseif( pos.x > maxp.x and step<0) then
ax = maxp.x;
length = length-( pos.x-maxp.x );
end
vector_quer = {x=1,z=0};
elseif( parallel_to_x_axis==1 ) then
if( pos.z < minp.z and step>0) then
az = minp.z;
length = length-( minp.z-pos.z );
elseif( pos.z > maxp.z and step<0) then
az = maxp.z;
length = length-( pos.z-maxp.z );
end
vector_quer = {x=0,z=1};
end
local candidates = {};
for i=1,length,step do
local height = heightmap[(az-minp.z)*80+(ax-minp.x)+1];
if( height and ax>=minp.x and ax<=maxp.x and az>=minp.z and az<=maxp.z) then
-- data[ a:index( ax, height, az )] = minetest.get_content_id('wool:pink');
local d = 5; -- distance to the last slice of the tunnel that was definitely below ground
for i=1,math.abs(length) do
local seq_nr = 0;
if( az==pos.z ) then
seq_nr = (ax+2)%4;
elseif( ax==pos.x ) then
seq_nr = (az+2)%4;
end
if( ax >= minp.x and ax <= maxp.x and az >= minp.z and az <= maxp.z and pos.y >= minp.y and pos.y <= maxp.y) then
local is_below_ground = false;
if( height>pos.y+2 or maxp.y<0) then
is_below_ground = true;
if( pos.y < 0 ) then
d = 0;
else
local height = 1;
if( heightmap ) then
height = heightmap[(az-minp.z)*chunksize+(ax-minp.x)+1];
else
light = minetest.get_node_light({x=ax, y=pos.y+2, z=az}, 0.5);
if( not(light) or light<14 ) then
height = pos.y+3;
end
end
if( height and height > minp.y and height < maxp.y ) then
if( height <= pos.y+1 ) then
if( mines_with_shafts.MARK_TUNNELS ) then
data[ a:index( ax, height, az )] = mines_with_shafts.MARK_TUNNELS;
end
d = d+1;
if( d>=5) then
candidates[ #candidates+1 ] = {ax,az,seq_nr};
end
elseif( height > pos.y+1 ) then
d = 0;
end
else
candidates[ #candidates+1 ] = {ax,az,seq_nr};
end
end
local seq_nr = 0;
if( az==pos.z ) then
seq_nr = (ax+2)%4;
elseif( ax==pos.x ) then
seq_nr = (az+2)%4;
end
candidates[ #candidates+1 ] = {x=ax,y=pos.y,z=az,seq_nr=seq_nr,is_below_ground=is_below_ground};
end
if( parallel_to_x_axis==1 ) then
ax = ax + step;
else
az = az + step;
end
end
-- add some open mineshafts for the entrances
local change_occoured = true;
for i=1,#candidates do
if( i>1 and candidates[i].is_below_ground and not(candidates[i-1].is_below_ground)) then
for j=i-1,math.max(1,i-6) do
candidates[j].is_below_ground = true;
if( d<5 ) then
local res = mines_with_shafts.do_minetunnel_horizontal_slice( minp, maxp, data, param2_data, a, cid,
{x=ax, y=pos.y, z=az}, vector_quer, seq_nr, (length<0), extra_calls);
-- place the last 5 slices so that the entrance looks better
if( #candidates > 0 ) then
local bridge_length = mines_with_shafts.MIN_BRIDGE_LENGTH;
if( #candidates <= mines_with_shafts.MAX_BRIDGE_LENGTH ) then
bridge_length = #candidates;
end
for j=math.max(1,#candidates-bridge_length),#candidates do
local res = mines_with_shafts.do_minetunnel_horizontal_slice( minp, maxp, data, param2_data, a, cid,
{x=candidates[j][1], y=pos.y, z=candidates[j][2]}, vector_quer, candidates[j][3], (length<0), extra_calls);
end
candidates = {};
end
end
end
ax = ax+px;
az = az+pz;
end
for i=#candidates,2,-1 do
if( i<#candidates and candidates[i-1].is_below_ground and not(candidates[i].is_below_ground)) then
for j=i,math.min(#candidates,i+5) do
candidates[j].is_below_ground = true;
end
end
end
-- TODO: just for visualization
local id_wood = minetest.get_content_id('default:wood');
local id_mese = minetest.get_content_id('default:pinewood');
for i,v in ipairs( candidates ) do
if( v and v.is_below_ground==true ) then
cid.c_wood = id_wood;
local res = mines_with_shafts.do_minetunnel_horizontal_slice( minp, maxp, data, param2_data, a, cid,
{x=v.x, y=v.y, z=v.z}, vector_quer, v.seq_nr, (length<0), extra_calls);
else
cid.c_wood = id_mese;
end
end
cid.c_wood = id_wood;
return math.abs(length);
end
@ -149,7 +140,7 @@ mines_with_shafts.do_minetunnel_horizontal_slice = function( minp, maxp, data, p
local az = pos.z+(vector.z*i );
local old_node = data[ a:index( ax, pos.y-1, az)];
-- if there is air at the bottom, place some wood to walk on (even if the tunnel will later be aborted)
if( old_node==cid.c_air or old_node==cid.c_fence) then
if( old_node==cid.c_air or old_node==cid.c_fence or old_node==cid.c_ignore) then
data[ a:index( ax, pos.y-1, az)] = cid.c_wood;
end
if( beam_seq_nr==0 and i~=0) then