182 lines
5.6 KiB
Lua
182 lines
5.6 KiB
Lua
--load settings
|
|
local settings = dofile( minetest.get_modpath("tunneltest") .. "/tunneltest.conf" )
|
|
|
|
--store all active hud elements for all players
|
|
local tunneler_huds = {}
|
|
|
|
local function tunneler_config( tunneler, player, point )
|
|
|
|
--get parameters of the configured tool
|
|
local meta = tunneler:get_meta()
|
|
local meta_table = meta:to_table()
|
|
local N = tunneler:get_definition()["_N"]
|
|
local M = tunneler:get_definition()["_M"]
|
|
|
|
--set up huds for the player
|
|
tunneler_huds[ player:get_player_name() ] = {}
|
|
local player_hud = tunneler_huds[ player:get_player_name() ]
|
|
|
|
--tabble to store nodes to dig
|
|
--TODO is it needed? we only ever use one square at a time
|
|
local digtable = {}
|
|
for i = 1,N do
|
|
digtable[ #digtable + 1 ] = {}
|
|
player_hud[ #player_hud + 1 ] = {}
|
|
end
|
|
|
|
--setting up formspec, and hud
|
|
local formspec = "size["..N..","..M.."]position[1,1]anchor[1,1]background[-1,-1;"..(N+2)..","..(M+2)..";digbg2.png;]"
|
|
for i = 1,N do
|
|
for j = 1,M do
|
|
--fill digtable
|
|
--fields might not exist, if tool has not been used yet
|
|
--if meta_table[ "b"..i.."-"..j ] == nil then
|
|
-- meta:set_int( "b"..i.."-"..j, 0 )
|
|
--end
|
|
digtable[i][j] = ( meta:get_int("b"..i.."-"..j) == 1 )
|
|
|
|
--setting up formspec
|
|
local img = "digformspec.png"
|
|
--middle is always dug out, have special texture
|
|
if (i == math.ceil( N/2 )) and (j == math.ceil( M/2 )) then
|
|
img = img .. "^dig_mid.png"
|
|
end
|
|
|
|
formspec = formspec .. "image_button["..(i-1)..","..(j-1)..";1,1;"..img..";b"..i.."-"..j..";;;;digpressed.png]"
|
|
|
|
--setting up hud
|
|
--TODO look into huds using overlays (not possible?)
|
|
local s = "dig.png"
|
|
if not digtable[i][j] then
|
|
s = "nodig.png"
|
|
end
|
|
if (i == math.ceil( N/2 )) and (j == math.ceil( M/2 )) then
|
|
s = "middig.png"
|
|
end
|
|
|
|
--store all the huds for each player
|
|
tunneler_huds[ player:get_player_name() ][i][j] = player:hud_add({
|
|
hud_elem_type = "image",
|
|
position = settings.hud.pos,
|
|
offset = { x=i*settings.hud.x_offset, y=j*settings.hud.y_offset },
|
|
text = s,
|
|
scale = settings.hud.scale,
|
|
alignment = settings.hud.alignment
|
|
})
|
|
end
|
|
end
|
|
|
|
--show the formspec
|
|
minetest.show_formspec( player:get_player_name(), "tunneltest:tunneler_config", formspec )
|
|
return( tunneler)
|
|
end
|
|
|
|
local function tunneler_field_handler( player, formname, fields )
|
|
|
|
-- only handle our own forms
|
|
if formname ~= "tunneltest:tunneler_config" then
|
|
return false
|
|
end
|
|
|
|
--get player/tool data
|
|
local tunneler = player:get_wielded_item()
|
|
local meta = tunneler:get_meta()
|
|
local N = tunneler:get_definition()["_N"]
|
|
local M = tunneler:get_definition()["_M"]
|
|
|
|
--if quitting, remove hud
|
|
if fields["quit"] == "true" then
|
|
for i = 1,N do
|
|
for j = 1,M do
|
|
player:hud_remove( tunneler_huds[ player:get_player_name() ][i][j] )
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
--if not quitting, save new values
|
|
for i,j in pairs(fields) do
|
|
|
|
--flip flag for field
|
|
meta:set_int( i, 1-meta:get_int(i) )
|
|
|
|
--update hud
|
|
local _, _, x, y = string.find( i, "b(%d+)-(%d+)" )
|
|
x = tonumber(x)
|
|
y = tonumber(y)
|
|
local s = "nodig.png"
|
|
if meta:get_int(i) == 1 then
|
|
s = "dig.png"
|
|
end
|
|
if (x == math.ceil( N/2 )) and (y == math.ceil( M/2 )) then
|
|
s = "middig.png"
|
|
end
|
|
player:hud_change( tunneler_huds[ player:get_player_name() ][x][y], "text", s )
|
|
end
|
|
|
|
--reset original dig flag (should be 0 already, just to make sure)
|
|
meta:set_int("used",0)
|
|
--set new wield item
|
|
player:set_wielded_item( tunneler )
|
|
end
|
|
|
|
local function tunneler_on_dig( pos, node, player )
|
|
|
|
--when sand falls on a troch digging happens without a player
|
|
if player == nil then
|
|
return
|
|
end
|
|
|
|
--see if it's a tunneler
|
|
if string.find(player:get_wielded_item():get_name(), "tunneltest:.*_tunneler") == nil then
|
|
return
|
|
end
|
|
|
|
--set up player/tunneler
|
|
local tunneler = player:get_wielded_item()
|
|
local meta = tunneler:get_meta()
|
|
local N = tunneler:get_definition()["_N"]
|
|
local M = tunneler:get_definition()["_M"]
|
|
|
|
--if not original dig, return
|
|
if meta:get_int("used") == 1 then
|
|
return
|
|
end
|
|
|
|
--all other digs will be nonoriginal
|
|
meta:set_int( "used", 1 )
|
|
--need to reset, before calling dig on other nodes
|
|
player:set_wielded_item( tunneler )
|
|
|
|
--calcualte directions
|
|
--TODO do it with dit_to_facedir facedir_to_dir -> propably more robust
|
|
local look_dir = player:get_look_dir()
|
|
local horizontal = vector.new(0,0,0)
|
|
if math.abs( look_dir.x ) < math.abs( look_dir.z ) then
|
|
horizontal.x = -look_dir.z / math.abs( look_dir.z )
|
|
else
|
|
horizontal.z = look_dir.x / math.abs( look_dir.x )
|
|
end
|
|
|
|
local dh = math.floor( N/2 ) + 1
|
|
local dv = math.floor( M/2 ) + 1
|
|
|
|
--dig everything else
|
|
for i = 1,N do
|
|
for j = 1,M do
|
|
if meta:get_int( "b"..i.."-"..j ) == 1 then
|
|
local newpos = vector.new( pos )
|
|
newpos = vector.add( newpos, vector.multiply( horizontal, (dh-i)))
|
|
newpos = vector.add(newpos, vector.multiply(vector.new(0,1,0), (dv-j)))
|
|
minetest.node_dig( newpos, minetest.get_node(newpos), player )
|
|
end
|
|
end
|
|
end
|
|
|
|
--reset original dig flag
|
|
meta:set_int("used",0)
|
|
player:set_wielded_item( tunneler )
|
|
end
|
|
|
|
return( { config=tunneler_config, field_handler=tunneler_field_handler, on_dig=tunneler_on_dig } )
|