123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- --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 } )
|