tunneler.lua 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. --load settings
  2. local settings = dofile( minetest.get_modpath("tunneltest") .. "/tunneltest.conf" )
  3. --store all active hud elements for all players
  4. local tunneler_huds = {}
  5. local function tunneler_config( tunneler, player, point )
  6. --get parameters of the configured tool
  7. local meta = tunneler:get_meta()
  8. local meta_table = meta:to_table()
  9. local N = tunneler:get_definition()["_N"]
  10. local M = tunneler:get_definition()["_M"]
  11. --set up huds for the player
  12. tunneler_huds[ player:get_player_name() ] = {}
  13. local player_hud = tunneler_huds[ player:get_player_name() ]
  14. --tabble to store nodes to dig
  15. --TODO is it needed? we only ever use one square at a time
  16. local digtable = {}
  17. for i = 1,N do
  18. digtable[ #digtable + 1 ] = {}
  19. player_hud[ #player_hud + 1 ] = {}
  20. end
  21. --setting up formspec, and hud
  22. local formspec = "size["..N..","..M.."]position[1,1]anchor[1,1]background[-1,-1;"..(N+2)..","..(M+2)..";digbg2.png;]"
  23. for i = 1,N do
  24. for j = 1,M do
  25. --fill digtable
  26. --fields might not exist, if tool has not been used yet
  27. --if meta_table[ "b"..i.."-"..j ] == nil then
  28. -- meta:set_int( "b"..i.."-"..j, 0 )
  29. --end
  30. digtable[i][j] = ( meta:get_int("b"..i.."-"..j) == 1 )
  31. --setting up formspec
  32. local img = "digformspec.png"
  33. --middle is always dug out, have special texture
  34. if (i == math.ceil( N/2 )) and (j == math.ceil( M/2 )) then
  35. img = img .. "^dig_mid.png"
  36. end
  37. formspec = formspec .. "image_button["..(i-1)..","..(j-1)..";1,1;"..img..";b"..i.."-"..j..";;;;digpressed.png]"
  38. --setting up hud
  39. --TODO look into huds using overlays (not possible?)
  40. local s = "dig.png"
  41. if not digtable[i][j] then
  42. s = "nodig.png"
  43. end
  44. if (i == math.ceil( N/2 )) and (j == math.ceil( M/2 )) then
  45. s = "middig.png"
  46. end
  47. --store all the huds for each player
  48. tunneler_huds[ player:get_player_name() ][i][j] = player:hud_add({
  49. hud_elem_type = "image",
  50. position = settings.hud.pos,
  51. offset = { x=i*settings.hud.x_offset, y=j*settings.hud.y_offset },
  52. text = s,
  53. scale = settings.hud.scale,
  54. alignment = settings.hud.alignment
  55. })
  56. end
  57. end
  58. --show the formspec
  59. minetest.show_formspec( player:get_player_name(), "tunneltest:tunneler_config", formspec )
  60. return( tunneler)
  61. end
  62. local function tunneler_field_handler( player, formname, fields )
  63. -- only handle our own forms
  64. if formname ~= "tunneltest:tunneler_config" then
  65. return false
  66. end
  67. --get player/tool data
  68. local tunneler = player:get_wielded_item()
  69. local meta = tunneler:get_meta()
  70. local N = tunneler:get_definition()["_N"]
  71. local M = tunneler:get_definition()["_M"]
  72. --if quitting, remove hud
  73. if fields["quit"] == "true" then
  74. for i = 1,N do
  75. for j = 1,M do
  76. player:hud_remove( tunneler_huds[ player:get_player_name() ][i][j] )
  77. end
  78. end
  79. return
  80. end
  81. --if not quitting, save new values
  82. for i,j in pairs(fields) do
  83. --flip flag for field
  84. meta:set_int( i, 1-meta:get_int(i) )
  85. --update hud
  86. local _, _, x, y = string.find( i, "b(%d+)-(%d+)" )
  87. x = tonumber(x)
  88. y = tonumber(y)
  89. local s = "nodig.png"
  90. if meta:get_int(i) == 1 then
  91. s = "dig.png"
  92. end
  93. if (x == math.ceil( N/2 )) and (y == math.ceil( M/2 )) then
  94. s = "middig.png"
  95. end
  96. player:hud_change( tunneler_huds[ player:get_player_name() ][x][y], "text", s )
  97. end
  98. --reset original dig flag (should be 0 already, just to make sure)
  99. meta:set_int("used",0)
  100. --set new wield item
  101. player:set_wielded_item( tunneler )
  102. end
  103. local function tunneler_on_dig( pos, node, player )
  104. --when sand falls on a troch digging happens without a player
  105. if player == nil then
  106. return
  107. end
  108. --see if it's a tunneler
  109. if string.find(player:get_wielded_item():get_name(), "tunneltest:.*_tunneler") == nil then
  110. return
  111. end
  112. --set up player/tunneler
  113. local tunneler = player:get_wielded_item()
  114. local meta = tunneler:get_meta()
  115. local N = tunneler:get_definition()["_N"]
  116. local M = tunneler:get_definition()["_M"]
  117. --if not original dig, return
  118. if meta:get_int("used") == 1 then
  119. return
  120. end
  121. --all other digs will be nonoriginal
  122. meta:set_int( "used", 1 )
  123. --need to reset, before calling dig on other nodes
  124. player:set_wielded_item( tunneler )
  125. --calcualte directions
  126. --TODO do it with dit_to_facedir facedir_to_dir -> propably more robust
  127. local look_dir = player:get_look_dir()
  128. local horizontal = vector.new(0,0,0)
  129. if math.abs( look_dir.x ) < math.abs( look_dir.z ) then
  130. horizontal.x = -look_dir.z / math.abs( look_dir.z )
  131. else
  132. horizontal.z = look_dir.x / math.abs( look_dir.x )
  133. end
  134. local dh = math.floor( N/2 ) + 1
  135. local dv = math.floor( M/2 ) + 1
  136. --dig everything else
  137. for i = 1,N do
  138. for j = 1,M do
  139. if meta:get_int( "b"..i.."-"..j ) == 1 then
  140. local newpos = vector.new( pos )
  141. newpos = vector.add( newpos, vector.multiply( horizontal, (dh-i)))
  142. newpos = vector.add(newpos, vector.multiply(vector.new(0,1,0), (dv-j)))
  143. minetest.node_dig( newpos, minetest.get_node(newpos), player )
  144. end
  145. end
  146. end
  147. --reset original dig flag
  148. meta:set_int("used",0)
  149. player:set_wielded_item( tunneler )
  150. end
  151. return( { config=tunneler_config, field_handler=tunneler_field_handler, on_dig=tunneler_on_dig } )