Minetest mod that adds scifi themed nodes https://content.minetest.net/packages/D00Med/scifi_nodes/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
4.8KB

  1. --------------
  2. -- Digicode --
  3. --------------
  4. local has_mesecons = minetest.get_modpath("mesecons")
  5. local secret_code = "1234"
  6. local allowed_chars = "0123456789"
  7. local code_length = 4
  8. local digicode_context = {}
  9. -- after_place_node, use by digicode and palm_scanner
  10. -- placer is a player object
  11. local function set_owner(pos, placer, itemstack, pointed_thing)
  12. local meta = minetest.get_meta(pos)
  13. meta:set_string("owner", placer:get_player_name())
  14. meta:set_string("code", secret_code)
  15. end
  16. local function toggle_digicode(pos)
  17. local node = minetest.get_node(pos)
  18. local name = node.name
  19. if name == "scifi_nodes:digicode_off" then
  20. minetest.swap_node(pos, {name="scifi_nodes:digicode_on", param2=node.param2})
  21. mesecon.receptor_on(pos, scifi_nodes.get_switch_rules(node.param2))
  22. minetest.get_node_timer(pos):start(2)
  23. elseif name == "scifi_nodes:digicode_on" then
  24. minetest.swap_node(pos, {name="scifi_nodes:digicode_off", param2=node.param2})
  25. mesecon.receptor_off(pos, scifi_nodes.get_switch_rules(node.param2))
  26. end
  27. end
  28. local function code_is_valid(code)
  29. local valid = false
  30. if type(code) == "string" and #code == code_length then
  31. valid = true
  32. end
  33. for i=1, #code do
  34. if not string.find(allowed_chars, string.sub(code,i,i)) then
  35. valid = false
  36. end
  37. end
  38. return valid
  39. end
  40. local function update_code(pos, code)
  41. local meta = minetest.get_meta(pos)
  42. meta:set_string("code", code)
  43. end
  44. local function show_digicode_formspec(pos, node, player, itemstack, pointed_thing)
  45. local meta = minetest.get_meta(pos)
  46. local owner = meta:get_string("owner")
  47. local current_code = meta:get_string("code")
  48. local current_player = player:get_player_name()
  49. -- Gathering datas that will be used by callback function
  50. digicode_context[current_player] = {code = current_code, pos = pos}
  51. if current_player == owner then
  52. minetest.show_formspec(current_player, "digicode_formspec",
  53. "size[6,3]"..
  54. "field[1,1;3,1;code;Code;]".. -- type, position, size, name, label
  55. "button_exit[1,2;2,1;change;Change code]"..
  56. "button_exit[3,2;2,1;open;Open door]")
  57. else
  58. minetest.show_formspec(current_player, "digicode_formspec",
  59. "size[6,3]"..
  60. "field[2,1;3,1;code;Code;]"..
  61. "button_exit[2,2;3,1;open;Open door]")
  62. end
  63. end
  64. -- Process datas from digicode_formspec
  65. minetest.register_on_player_receive_fields(function(player, formname, fields)
  66. if formname ~= "digicode_formspec" then
  67. return false
  68. end
  69. local sounds = {"scifi_nodes_scanner_granted","scifi_nodes_scanner_refused",
  70. "scifi_nodes_digicode_granted","scifi_nodes_digicode_refused"
  71. }
  72. local sound_index
  73. -- We have the right formspec so we can proceed it.
  74. -- Let's retrieve the datas we need :
  75. local context = digicode_context[player:get_player_name()]
  76. if fields.change and code_is_valid(fields.code) then
  77. update_code(context.pos, fields.code)
  78. sound_index = 1
  79. elseif
  80. fields.change and not code_is_valid(fields.code) then
  81. sound_index = 2
  82. elseif
  83. fields.open and fields.code == context.code then
  84. toggle_digicode(context.pos)
  85. sound_index = 3
  86. elseif
  87. fields.open and fields.code ~= context.code then
  88. sound_index = 4
  89. end
  90. -- play sound at context position
  91. minetest.sound_play(sounds[sound_index], {
  92. pos = context.pos,
  93. max_hear_distance = 10
  94. })
  95. context[player:get_player_name()] = nil -- we don't need it anymore
  96. end)
  97. minetest.register_node("scifi_nodes:digicode_on", {
  98. description = "Digicode",
  99. sunlight_propagates = true,
  100. buildable_to = false,
  101. tiles = {"scifi_nodes_digicode_on.png",},
  102. inventory_image = "scifi_nodes_digicode_on.png",
  103. wield_image = "scifi_nodes_digicode_on.png",
  104. drawtype = "signlike",
  105. node_box = {type = "wallmounted",},
  106. selection_box = {type = "wallmounted",},
  107. paramtype = "light",
  108. paramtype2 = "wallmounted",
  109. light_source = 5,
  110. groups = {cracky=1, oddly_breakable_by_hand=1, not_in_creative_inventory=1, mesecon_needs_receiver = 1},
  111. drop = {items = {"scifi_nodes:digicode_off"}},
  112. mesecons = {
  113. receptor = {
  114. state = (has_mesecons and mesecon.state.on)
  115. }
  116. },
  117. on_timer = toggle_digicode,
  118. sounds = default.node_sound_glass_defaults(),
  119. })
  120. minetest.register_node("scifi_nodes:digicode_off", {
  121. description = "Digicode",
  122. tiles = {"scifi_nodes_digicode_off.png",},
  123. inventory_image = "scifi_nodes_digicode_off.png",
  124. wield_image = "scifi_nodes_digicode_off.png",
  125. drawtype = "signlike",
  126. sunlight_propagates = true,
  127. buildable_to = false,
  128. node_box = {type = "wallmounted",},
  129. selection_box = {type = "wallmounted",},
  130. paramtype = "light",
  131. paramtype2 = "wallmounted",
  132. groups = {cracky=1, oddly_breakable_by_hand=1, mesecon_needs_receiver = 1},
  133. mesecons = {
  134. receptor = {
  135. state = (has_mesecons and mesecon.state.off)
  136. }
  137. },
  138. after_place_node = set_owner,
  139. on_rightclick = show_digicode_formspec,
  140. sounds = default.node_sound_glass_defaults(),
  141. })
  142. minetest.register_craft({
  143. output = "scifi_nodes:digicode_off 2",
  144. recipe = {{"mesecons_switch:mesecon_switch_off", "scifi_nodes:grey", ""}}
  145. })