Epic/mods/tunneltest/tunneler.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 } )