lock_picking.lua 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. doors.player_picking_answer = {}
  2. doors.lock_pick_timer = {}
  3. minetest.register_craftitem('doors:lock_pick', {
  4. description = 'Lock Picking Tool',
  5. inventory_image = 'doors_lock_pick.png',
  6. stack_max = 1,
  7. groups = {not_in_creative_inventory=1, stashable=1},
  8. on_use = function(itemstack, user, pointed_thing)
  9. local pos = minetest.get_pointed_thing_position(pointed_thing)
  10. local meta = minetest.get_meta(pos)
  11. local status = meta:get_int('lock_s')
  12. if status >= 3 then
  13. local name = user:get_player_name()
  14. doors.player_config[name] = pos
  15. doors.pick_lock(user, status)
  16. end
  17. end,
  18. on_drop = lobby.no_drop
  19. })
  20. for i = 0,9 do
  21. minetest.register_craftitem('doors:key_wedge_'..i, {
  22. description = 'Key Wedge',
  23. inventory_image = 'doors_key_wedge_'..i..'.png',
  24. stack_max = 1,
  25. groups = {not_in_creative_inventory=1}
  26. })
  27. end
  28. local wedges = {'doors:key_wedge_0', 'doors:key_wedge_1', 'doors:key_wedge_2', 'doors:key_wedge_3', 'doors:key_wedge_4', 'doors:key_wedge_5', 'doors:key_wedge_6', 'doors:key_wedge_7', 'doors:key_wedge_8', 'doors:key_wedge_9'}
  29. local function shuffle_table(table)
  30. for i = #table, 2 , -1 do
  31. local j = math.random(i)
  32. table[i], table[j] = table[j], table[i]
  33. end
  34. return table
  35. end
  36. function doors.pick_lock(player, difficulty)
  37. local pname = player:get_player_name()
  38. local player_attributes = player:get_meta()
  39. local luck = player_attributes:get_int('luck')
  40. local grid_inv = minetest.create_detached_inventory('lock_picking_wedges_'..pname, {
  41. allow_take = function()
  42. return -1
  43. end,
  44. allow_put = function()
  45. return -1
  46. end,
  47. })
  48. grid_inv:set_size('wedges', 10)
  49. grid_inv:set_list('wedges', shuffle_table(wedges))
  50. local solution_inv = minetest.create_detached_inventory('lock_picking_solution_'..pname, {})
  51. solution_inv:set_size('pattern', 5)
  52. local timer = 20-difficulty+luck
  53. local sequence = math.random(11111, 99999)
  54. doors.player_picking_answer[pname] = sequence
  55. doors.lock_pick_timer[pname] = timer
  56. doors.lock_picking_wrapper(player, timer)
  57. end
  58. function doors.lock_picking_wrapper(player, timer)
  59. local pname = player:get_player_name()
  60. local timer = doors.lock_pick_timer[pname] - 1
  61. doors.lock_pick_timer[pname] = timer
  62. if timer <= 0 then
  63. minetest.close_formspec(pname, 'doors:lock_picking')
  64. elseif timer > 0 then
  65. minetest.show_formspec(pname, 'doors:lock_picking', doors.lock_picking_formspec(player, timer))
  66. local looping = minetest.after(1, function()
  67. doors.lock_picking_wrapper(player, timer)
  68. end)
  69. end
  70. end
  71. function doors.lock_picking_formspec(player, timer)
  72. local pname = player:get_player_name()
  73. local sequence = doors.player_picking_answer[pname]
  74. local val1 = string.sub(sequence, 1, 1)
  75. local val2 = string.sub(sequence, 2, 2)
  76. local val3 = string.sub(sequence, 3, 3)
  77. local val4 = string.sub(sequence, 4, 4)
  78. local val5 = string.sub(sequence, 5, 5)
  79. local formspec =
  80. 'formspec_version[3]'..
  81. 'size[8,8]'..
  82. 'textarea[.5,3;7,2;;;Is breaking and entering your thing? If you don\'t break the lock is it technically breaking and entering???]'..
  83. 'textarea[.25,.1;8,1;;;The timer is running, '..timer..' seconds remain.]'..
  84. 'list[detached:lock_picking_wedges_'..pname..';wedges;1,.5;5,2;]'..
  85. 'image[0.5,4.5;1,1;doors_key_profile_'..val1..'.png]'..
  86. 'image[1.5,4.5;1,1;doors_key_profile_'..val2..'.png]'..
  87. 'image[2.5,4.5;1,1;doors_key_profile_'..val3..'.png]'..
  88. 'image[3.5,4.5;1,1;doors_key_profile_'..val4..'.png]'..
  89. 'image[4.5,4.5;1,1;doors_key_profile_'..val5..'.png]'..
  90. 'button[5.75,4.5;2,1;check;Check]'..
  91. 'button_exit[3,7.125;2,.75;exit;Exit]'..
  92. 'list[detached:lock_picking_solution_'..pname..';pattern;1,6;5,1;]'..
  93. 'listring[]'
  94. return formspec
  95. end
  96. minetest.register_on_player_receive_fields(function(player, formname, fields)
  97. local name = player:get_player_name()
  98. if formname == 'doors:lock_picking' then
  99. if fields.exit then
  100. doors.lock_pick_timer[name] = 0
  101. end
  102. if fields.check then
  103. local inv = minetest.get_inventory({type = 'detached', name = 'lock_picking_solution_'..name})
  104. local slot1 = inv:get_stack('pattern', 1)
  105. local key1 = string.sub(slot1:get_name(), -1)
  106. local slot2 = inv:get_stack('pattern', 2)
  107. local key2 = string.sub(slot2:get_name(), -1)
  108. local slot3 = inv:get_stack('pattern', 3)
  109. local key3 = string.sub(slot3:get_name(), -1)
  110. local slot4 = inv:get_stack('pattern', 4)
  111. local key4 = string.sub(slot4:get_name(), -1)
  112. local slot5 = inv:get_stack('pattern', 5)
  113. local key5 = string.sub(slot5:get_name(), -1)
  114. local solution = tonumber(key1..key2..key3..key4..key5)
  115. local answer = doors.player_picking_answer[name]
  116. if solution == answer then
  117. local pos = doors.player_config[name]
  118. minetest.chat_send_player(name, 'nice work!')
  119. doors.lock_pick_timer[name] = 0
  120. minetest.close_formspec(name, 'doors:lock_picking')
  121. local node = minetest.get_node(pos)
  122. if minetest.get_item_group(node.name, 'door') == 1 then --Standard door
  123. doors.door_toggle(pos, nil, player, true)
  124. minetest.after(3, function()
  125. doors.door_toggle(pos, nil, player, true)
  126. end)
  127. else --Trapdoor
  128. doors.trapdoor_toggle(pos, nil, player, true)
  129. minetest.after(3, function()
  130. doors.trapdoor_toggle(pos, nil, player, true)
  131. end)
  132. end
  133. else
  134. minetest.chat_send_player(name, 'Try again!')
  135. end
  136. end
  137. end
  138. end)