first basic version
This commit is contained in:
commit
c96859cf27
3
depends.txt
Normal file
3
depends.txt
Normal file
@ -0,0 +1,3 @@
|
||||
default
|
||||
cottages?
|
||||
tnt?
|
13
init.lua
Normal file
13
init.lua
Normal file
@ -0,0 +1,13 @@
|
||||
-- the namespace
|
||||
mines_with_shafts = {};
|
||||
|
||||
mines_with_shafts.modpath = minetest.get_modpath( "mines_with_shafts");
|
||||
|
||||
-- the mod comes with its own ladder and rope; both act as rails for carts
|
||||
dofile(mines_with_shafts.modpath.."/nodes.lua")
|
||||
|
||||
dofile(mines_with_shafts.modpath.."/mines_horizontal_tunnels.lua")
|
||||
dofile(mines_with_shafts.modpath.."/mines_create.lua")
|
||||
|
||||
-- TODO: give credits to the texture creator(s)
|
||||
-- TODO: add vertical shafts
|
96
mines_create.lua
Normal file
96
mines_create.lua
Normal file
@ -0,0 +1,96 @@
|
||||
|
||||
local cid_mines = {};
|
||||
|
||||
cid_mines.c_ignore = minetest.get_content_id('ignore');
|
||||
cid_mines.c_air = minetest.get_content_id('air');
|
||||
|
||||
-- basic material used for the tunnels
|
||||
cid_mines.c_wood = minetest.get_content_id('default:wood');
|
||||
cid_mines.c_fence = minetest.get_content_id('default:fence_wood');
|
||||
cid_mines.c_torch = minetest.get_content_id('default:torch');
|
||||
cid_mines.c_rail = minetest.get_content_id('default:rail');
|
||||
|
||||
-- basic additional material used for the shafts
|
||||
cid_mines.c_mineladder = minetest.get_content_id('mines_with_shafts:ladder');
|
||||
cid_mines.c_rope = minetest.get_content_id('mines_with_shafts:rope');
|
||||
|
||||
-- node types that force mine shafts to end there (floodings are still possible)
|
||||
cid_mines.c_lava = minetest.get_content_id('default:lava_source');
|
||||
cid_mines.c_lava_flowing = minetest.get_content_id('default:lava_flowing');
|
||||
cid_mines.c_water = minetest.get_content_id('default:water_source');
|
||||
|
||||
|
||||
-- nodes that may be found at the side of the tunnels randomly
|
||||
cid_mines.c_chest = minetest.get_content_id('default:chest');
|
||||
cid_mines.c_stone = minetest.get_content_id('default:stone');
|
||||
cid_mines.c_sand = minetest.get_content_id('default:sand');
|
||||
cid_mines.c_gravel = minetest.get_content_id('default:gravel');
|
||||
cid_mines.c_ladder = minetest.get_content_id('default:ladder');
|
||||
cid_mines.c_sign_wall = minetest.get_content_id('default:sign_wall');
|
||||
cid_mines.c_coalblock = minetest.get_content_id('default:coalblock');
|
||||
cid_mines.c_steelblock = minetest.get_content_id('default:steelblock');
|
||||
cid_mines.c_copperblock = minetest.get_content_id('default:copperblock');
|
||||
cid_mines.c_barrel = minetest.get_content_id('cottages:barrel');
|
||||
cid_mines.c_shelf = minetest.get_content_id('cottages:shelf');
|
||||
cid_mines.c_tnt = minetest.get_content_id('tnt:tnt');
|
||||
|
||||
|
||||
|
||||
-- TODO
|
||||
mines_with_shafts.create_mine = function( minp, maxp, data, param2_data, a )
|
||||
local npos = {x=minp.x+40,y=minp.y+40,z=minp.z+40,bsizex=100,bsizez=1};
|
||||
local backwards = false;
|
||||
local extra_calls_mines = {chests={}, signs={}};
|
||||
|
||||
mines_with_shafts.place_minetunnel_horizontal(minp, maxp, data, param2_data, a, cid_mines, npos, 100, 1, extra_calls_mines );
|
||||
mines_with_shafts.place_minetunnel_horizontal(minp, maxp, data, param2_data, a, cid_mines, npos, -100, 1, extra_calls_mines );
|
||||
mines_with_shafts.place_minetunnel_horizontal(minp, maxp, data, param2_data, a, cid_mines, npos, 100, 0, extra_calls_mines );
|
||||
mines_with_shafts.place_minetunnel_horizontal(minp, maxp, data, param2_data, a, cid_mines, npos, -100, 0, extra_calls_mines );
|
||||
end
|
||||
|
||||
|
||||
minetest.register_on_generated(function(minp, maxp, seed)
|
||||
|
||||
-- TODO: mines still float in the air
|
||||
-- limit height of the mines
|
||||
if( minp.y < -256 or minp.y > 64) then
|
||||
return;
|
||||
end
|
||||
|
||||
local vm;
|
||||
local a;
|
||||
local data;
|
||||
local param2_data;
|
||||
-- get the voxelmanip object
|
||||
local emin;
|
||||
local emax;
|
||||
-- if no voxelmanip data was passed on, read the data here
|
||||
if( not( vm ) or not( a) or not( data ) or not( param2_data ) ) then
|
||||
vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
if( not( vm )) then
|
||||
return;
|
||||
end
|
||||
|
||||
a = VoxelArea:new{
|
||||
MinEdge={x=emin.x, y=emin.y, z=emin.z},
|
||||
MaxEdge={x=emax.x, y=emax.y, z=emax.z},
|
||||
}
|
||||
|
||||
data = vm:get_data()
|
||||
param2_data = vm:get_param2_data()
|
||||
end
|
||||
|
||||
|
||||
-- actually create the mine
|
||||
mines_with_shafts.create_mine( emin, emax, data, param2_data, a );
|
||||
|
||||
|
||||
-- store the voxelmanip data
|
||||
vm:set_data(data)
|
||||
vm:set_param2_data(param2_data)
|
||||
|
||||
vm:calc_lighting( tmin, tmax);
|
||||
vm:write_to_map(data);
|
||||
vm:update_liquids();
|
||||
|
||||
end)
|
280
mines_horizontal_tunnels.lua
Normal file
280
mines_horizontal_tunnels.lua
Normal file
@ -0,0 +1,280 @@
|
||||
-----------------------------------------------------
|
||||
-- this creates the horizontal tunnels for the mines
|
||||
----------------------------------------------------
|
||||
|
||||
|
||||
-- if length is <0, the tunnel will go in the opposite direction
|
||||
mines_with_shafts.place_minetunnel_horizontal = function(minp, maxp, data, param2_data, a, cid, pos, length, parallel_to_x_axis, extra_calls )
|
||||
|
||||
-- minetunnels are not allowed to follow the borders of mapchunks while beeing only partly contained in that chunk
|
||||
-- as this would make consistent placement a lot harder and is not really needed for convincing mines
|
||||
if( (pos.y-2 < minp.y and pos.y+2 > minp.y )
|
||||
or (pos.y-2 < maxp.y and pos.y+2 > maxp.y )
|
||||
or (pos.z-2 < minp.z and pos.z+2 > minp.z and parallel_to_x_axis == 1)
|
||||
or (pos.z-2 < maxp.z and pos.z+2 > maxp.z and parallel_to_x_axis == 1)
|
||||
or (pos.x-2 < minp.x and pos.x+2 > minp.x and parallel_to_x_axis == 0)
|
||||
or (pos.x-2 < maxp.x and pos.x+2 > maxp.x and parallel_to_x_axis == 0)) then
|
||||
return;
|
||||
end
|
||||
|
||||
local vector = {x=0,y=0,z=0};
|
||||
local vector_quer = {x=0,y=0,z=0};
|
||||
-- the tunnel extends in x direction
|
||||
if( parallel_to_x_axis == 1 ) then
|
||||
if( length>0) then
|
||||
vector.x = 1;
|
||||
else
|
||||
vector.x = -1;
|
||||
end
|
||||
vector_quer.z = 1;
|
||||
elseif( parallel_to_x_axis == 0 ) then
|
||||
if( length>0) then
|
||||
vector.z = 1;
|
||||
else
|
||||
vector.z = -1;
|
||||
end
|
||||
vector_quer.x = 1;
|
||||
else
|
||||
-- wrong parameters
|
||||
return;
|
||||
end
|
||||
|
||||
-- the actual start position will be 2 nodes further in, thus creating nice crossings
|
||||
local ax = pos.x+vector.x;
|
||||
local az = pos.z+vector.z;
|
||||
for i=1,math.abs(length) do
|
||||
-- go one step further in eitzer x or z direction
|
||||
ax = ax+vector.x;
|
||||
az = az+vector.z;
|
||||
|
||||
-- make sure we do not exceed the boundaries of the mapchunk
|
||||
if( ax < minp.x or ax > maxp.x
|
||||
or az < minp.z or az > maxp.z ) then
|
||||
return;
|
||||
end
|
||||
|
||||
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, i%4, (length<0), extra_calls);
|
||||
-- abort if there is anything that prevents the mine from progressing in that direction
|
||||
if( res < 0 ) then
|
||||
return;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- internal function
|
||||
-- * go one node into the direction given by vector
|
||||
-- * place a support beam made from wood and fences if beam_seq_nr==0
|
||||
-- * place torches and random nodes at the sides otherwise
|
||||
-- * returns a value >= 0 if everything went fine
|
||||
-- * returns a value <0 if the mine has to end at this place (i.e. sunlight detected, or water/lava found
|
||||
mines_with_shafts.do_minetunnel_horizontal_slice = function( minp, maxp, data, param2_data, a, cid, pos, vector, beam_seq_nr, backwards, extra_calls )
|
||||
local p = {x=pos.x, y=pos.y, z=pos.y};
|
||||
|
||||
local ax=pos.x;
|
||||
local az=pos.z;
|
||||
|
||||
local no_daylight = true;
|
||||
-- check if there are any nodes that force an end to the tunnel
|
||||
for ax=pos.x+(vector.x*-2),pos.x+(vector.x*2) do
|
||||
for az=pos.z+(vector.z*-2),pos.z+(vector.z*2) do
|
||||
for y=-1,2 do
|
||||
local old_node = data[ a:index( ax, pos.y+y, az)];
|
||||
-- we have hit a vertical minetunnel
|
||||
if( old_node==cid.c_mineladder or old_node==cid.c_rope ) then
|
||||
-- the tunnel may still continue behind this vertical tunnel
|
||||
return 0;
|
||||
end
|
||||
|
||||
-- we do not want to build a tunnel through lava or water; though both may flow in if we digged too far
|
||||
-- (the poor inhabitants will have given up the tunnel)
|
||||
if( old_node==cid.c_lava or old_node==cid.c_lava_flowing or old_node==cid.c_water ) then
|
||||
-- the tunnel has to end here
|
||||
print('MINESHAFT abort due to water or lava at '..minetest.pos_to_string( pos));
|
||||
return -1;
|
||||
end
|
||||
|
||||
if( math.abs(ax-pos.x)<2 and math.abs(az-pos.z)<2 ) then
|
||||
-- as soon as any of the 3 topmost nodes receives no daylight, we do not need to check any longer
|
||||
if( y==2 and no_daylight) then
|
||||
local light = minetest.get_node_light({x=ax, y=pos.y+y, z=az}, 0.5);
|
||||
if( light and light==15 ) then
|
||||
no_daylight = false;
|
||||
end
|
||||
end
|
||||
|
||||
-- if there is air at the bottom, place some wood to walk on (even if the tunnel will later be aborted)
|
||||
if( y==-1 and old_node==cid.c_air) then
|
||||
data[ a:index( ax, pos.y+y, az)] = cid.c_wood;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- there will always be a rail on the ground
|
||||
data[ a:index( pos.x, pos.y, pos.z )] = cid.c_rail;
|
||||
-- ..and air directly above so that players can walk through
|
||||
data[ a:index( pos.x, pos.y+1, pos.z )] = cid.c_air;
|
||||
|
||||
-- if all three topmost nodes receive daylight, then it's time to end our tunnel
|
||||
if( not( no_daylight )) then
|
||||
print('MINESHAFT abort due to daylight at '..minetest.pos_to_string(pos));
|
||||
return -2;
|
||||
end
|
||||
|
||||
-- every 4th tunnel has a wooden support beam
|
||||
if( beam_seq_nr == 0 ) then
|
||||
-- either vector.x or vector.z is 0; the other value will be 1
|
||||
ax = vector.x;
|
||||
az = vector.z;
|
||||
-- place the four fences at the sides
|
||||
data[ a:index( pos.x-ax, pos.y, pos.z-az )] = cid.c_fence;
|
||||
data[ a:index( pos.x-ax, pos.y+1, pos.z-az )] = cid.c_fence;
|
||||
data[ a:index( pos.x+ax, pos.y, pos.z+az )] = cid.c_fence;
|
||||
data[ a:index( pos.x+ax, pos.y+1, pos.z+az )] = cid.c_fence;
|
||||
-- place the three wooden planks on top of the fences
|
||||
data[ a:index( pos.x, pos.y+2, pos.z )] = cid.c_wood;
|
||||
data[ a:index( pos.x-ax, pos.y+2, pos.z-az )] = cid.c_wood;
|
||||
data[ a:index( pos.x+ax, pos.y+2, pos.z+az )] = cid.c_wood;
|
||||
-- all has been placed successfully
|
||||
return 1;
|
||||
end
|
||||
|
||||
|
||||
-- create the tunnel as such
|
||||
for ax=pos.x+(vector.x*-1),pos.x+(vector.x*1) do
|
||||
for az=pos.z+(vector.z*-1),pos.z+(vector.z*1) do
|
||||
for ay = pos.y, pos.y+2 do
|
||||
if( (ax ~= pos.x or az ~= pos.z) and ( ay>pos.y or data[a:index(ax,ay,az)]~=cid.c_rail)) then
|
||||
data[ a:index( ax, ay, az )] = cid.c_air;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- attach a torch to the beam
|
||||
local p2 = -1;
|
||||
if( beam_seq_nr == 1 ) then
|
||||
if( vector.x ~= 0 and not(backwards )) then
|
||||
p2 = 5;
|
||||
elseif( vector.x ~= 0 and backwards ) then
|
||||
p2 = 4;
|
||||
elseif( vector.z ~= 0 and not(backwards )) then
|
||||
p2 = 3;
|
||||
elseif( vector.z ~= 0 and backwards ) then
|
||||
p2 = 2;
|
||||
end
|
||||
-- put air in the middle
|
||||
elseif( beam_seq_nr == 2 ) then
|
||||
data[ a:index( pos.x, pos.y+2, pos.z )] = cid.c_air;
|
||||
-- attach a torch to the beam
|
||||
elseif( beam_seq_nr == 3 ) then
|
||||
if( vector.x ~= 0 and not(backwards )) then
|
||||
p2 = 4;
|
||||
elseif( vector.x ~= 0 and backwards ) then
|
||||
p2 = 5;
|
||||
elseif( vector.z ~= 0 and not(backwards )) then
|
||||
p2 = 2;
|
||||
elseif( vector.z ~= 0 and backwards ) then
|
||||
p2 = 3;
|
||||
end
|
||||
end
|
||||
if( p2 > -1 ) then
|
||||
data[ a:index( pos.x, pos.y+2, pos.z )] = cid.c_torch;
|
||||
param2_data[ a:index( pos.x, pos.y+2, pos.z )] = p2;
|
||||
end
|
||||
|
||||
|
||||
mines_with_shafts.place_random_decoration( data, param2_data, a, cid, pos, vector, extra_calls );
|
||||
|
||||
-- the tunnel has been created successfully
|
||||
return 1;
|
||||
end
|
||||
|
||||
|
||||
-- internal function
|
||||
-- * place a random decoration at one of the sides (or dig a one-node-wide hole or water source into the floor)
|
||||
mines_with_shafts.place_random_decoration = function( data, param2_data, a, cid, pos, vector, extra_calls )
|
||||
-- get a random object for placing in the tunnel
|
||||
local new_id = cid.c_air;
|
||||
local c = math.random( 1,100 );
|
||||
if( c<5 ) then -- 1,2,3,4
|
||||
new_id = cid.c_chest;
|
||||
elseif( c<7 ) then -- 5,6
|
||||
new_id = cid.c_barrel;
|
||||
elseif( c<9 ) then -- 7,8
|
||||
new_id = cid.c_shelf;
|
||||
elseif( c<11 ) then -- 9,10
|
||||
new_id = cid.c_stone;
|
||||
elseif( c<13 ) then -- 11,12
|
||||
new_id = cid.c_sand;
|
||||
elseif( c<15 ) then -- 13,14
|
||||
new_id = cid.c_gravel;
|
||||
elseif( c<17 ) then -- 15,16
|
||||
new_id = cid.c_ladder;
|
||||
elseif( c<19 ) then -- 17,18
|
||||
new_id = cid.c_coalblock;
|
||||
elseif( c<20 ) then -- 20
|
||||
new_id = cid.c_tnt;
|
||||
elseif( c<21 ) then -- 21
|
||||
new_id = cid.c_sign_wall;
|
||||
elseif( c<22 ) then
|
||||
new_id = cid.c_steelblock;
|
||||
elseif( c<23 ) then
|
||||
new_id = cid.c_copperblock;
|
||||
-- small chance for a water hole at the side
|
||||
elseif( c==96 ) then
|
||||
data[ a:index( pos.x-vector.x, pos.y-1, pos.z-vector.z )]=cid.c_water;
|
||||
elseif( c==97 ) then
|
||||
data[ a:index( pos.x+vector.x, pos.y-1, pos.z+vector.z )]=cid.c_water;
|
||||
-- holes at the sides may also occour
|
||||
elseif( c==98 ) then
|
||||
data[ a:index( pos.x-vector.x, pos.y-1, pos.z-vector.z )]=cid.c_air;
|
||||
elseif( c==99 ) then
|
||||
data[ a:index( pos.x+vector.x, pos.y-1, pos.z+vector.z )]=cid.c_air;
|
||||
else
|
||||
return;
|
||||
end
|
||||
|
||||
|
||||
if( new_id == cid.c_ignore or new_id == cid.c_air ) then
|
||||
return;
|
||||
end
|
||||
|
||||
-- only one side of the tunnel gets an object
|
||||
local side = 1;
|
||||
if( math.random( 1,2 )==1 ) then
|
||||
side = -1;
|
||||
end
|
||||
ax = pos.x+vector.x*side;
|
||||
ay = pos.y;
|
||||
az = pos.z+vector.z*side;
|
||||
-- only place something there if the place is currently empty
|
||||
if( data[ a:index( ax, ay, az )]~=cid.c_air ) then
|
||||
return;
|
||||
end
|
||||
|
||||
data[ a:index( ax, ay, az )] = new_id;
|
||||
|
||||
-- rotate facedir nodes correctly
|
||||
local p2 = 0;
|
||||
if( side==-1 and vector.x~=0 ) then
|
||||
p2 = 3;
|
||||
elseif( side== 1 and vector.x~=0 ) then
|
||||
p2 = 1;
|
||||
elseif( side==-1 and vector.z~=0 ) then
|
||||
p2 = 2;
|
||||
elseif( side== 1 and vector.z~=0 ) then
|
||||
p2 = 0;
|
||||
end
|
||||
param2_data[ a:index( ax, ay, az )] = p2;
|
||||
|
||||
if( new_id == cid.c_chest ) then
|
||||
table.insert( extra_calls.chests, {x=ax, y=ay, z=az, typ=new_content, bpos_i=-1, typ_name='chest_in_mine'});
|
||||
elseif( new_id == cid.c_shelf ) then
|
||||
table.insert( extra_calls.chests, {x=ax, y=ay, z=az, typ=new_content, bpos_i=-1, typ_name='shelf_in_mine'});
|
||||
elseif( new_id == cid.c_sign_wall ) then
|
||||
table.insert( extra_calls.signs, {x=ax, y=ay, z=az, typ=new_content, bpos_i=-1, typ_name='sign_in_mine'});
|
||||
end
|
||||
end
|
66
nodes.lua
Normal file
66
nodes.lua
Normal file
@ -0,0 +1,66 @@
|
||||
|
||||
|
||||
---------------------------------------------------------------------------------------
|
||||
-- a rope that is of use to the mines
|
||||
---------------------------------------------------------------------------------------
|
||||
-- the rope can only be digged if there is no further rope above it;
|
||||
-- Note: This rope also counts as a rail node; thus, carts can move through it
|
||||
minetest.register_node("mines_with_shafts:rope", {
|
||||
description = "rope for climbing",
|
||||
tiles = {"mines_with_shafts_rope.png"},
|
||||
groups = {snappy=3,choppy=3,oddly_breakable_by_hand=3,rail=1,connect_to_raillike=1},--connect_to_raillike=minetest.raillike_group("rail")},
|
||||
walkable = false,
|
||||
climbable = true,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
drawtype = "plantlike",
|
||||
can_dig = function(pos, player)
|
||||
local below = minetest.get_node( {x=pos.x, y=pos.y-1, z=pos.z});
|
||||
if( below and below.name and below.name == "mines_with_shafts:rope" ) then
|
||||
if( player ) then
|
||||
minetest.chat_send_player( player:get_player_name(),
|
||||
'The entire rope would be too heavy. Start digging at its lowest end!');
|
||||
end
|
||||
return false;
|
||||
end
|
||||
return true;
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mines_with_shafts:rope",
|
||||
recipe = {
|
||||
{"default:cotton","default:cotton","default:cotton"}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
-- Note: This rope also counts as a rail node; thus, carts can move through it
|
||||
minetest.register_node("mines_with_shafts:ladder", {
|
||||
description = "Ladder with rail support",
|
||||
drawtype = "signlike",
|
||||
tiles = {"default_ladder.png^default_rail.png^mines_with_shafts_rope.png"},
|
||||
inventory_image = "default_ladder.png",
|
||||
wield_image = "default_ladder.png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
sunlight_propagates = true,
|
||||
walkable = false,
|
||||
climbable = true,
|
||||
is_ground_content = false,
|
||||
selection_box = {
|
||||
type = "wallmounted",
|
||||
},
|
||||
groups = {choppy=2,oddly_breakable_by_hand=3,rail=1,connect_to_raillike=1}, --connect_to_raillike=minetest.raillike_group("rail")},
|
||||
legacy_wallmounted = true,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mines_with_shafts:ladder 2",
|
||||
recipe = {
|
||||
{"default:ladder","default:rail"}
|
||||
}
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user