palantiri.lua 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. lottblocks.palantiri = {}
  2. local tmp
  3. local file = io.open(minetest.get_worldpath().."/"..SAVEDIR.."/palantiri", "r")
  4. if file then
  5. tmp = minetest.deserialize(file:read("*all"))
  6. file:close()
  7. end
  8. if tmp ~= nil then
  9. lottblocks.palantiri = tmp[1]
  10. end
  11. local function save_palantiri()
  12. minetest.mkdir(minetest.get_worldpath().."/"..SAVEDIR)
  13. local file = io.open(minetest.get_worldpath().."/"..SAVEDIR.."/palantiri", "w")
  14. if file then
  15. file:write(minetest.serialize({lottblocks.palantiri}))
  16. file:close()
  17. end
  18. end
  19. local function check_blocks(pos)
  20. local minp = {x = pos.x - 2, y = pos.y - 2, z = pos.z - 2}
  21. local maxp = {x = pos.x + 2, y = pos.y + 2, z = pos.z + 2}
  22. local _, tilkal = minetest.find_nodes_in_area(minp, maxp, "lottores:tilkal")
  23. local _, mithril = minetest.find_nodes_in_area(minp, maxp, "lottores:mithril_block")
  24. if tilkal["lottores:tilkal"] < 6 or mithril["lottores:mithril_block"] < 16 then
  25. return false
  26. end
  27. return true
  28. end
  29. minetest.register_on_shutdown(function()
  30. save_palantiri()
  31. end)
  32. local purple = "#6d54dd"
  33. local function formspec_update(meta)
  34. local network = meta:get_string("network")
  35. local palantir = meta:get_string("name")
  36. local form = "size[6,5]" ..
  37. "background[5,5;1,1;gui_elfbg.png;true]"..
  38. "label[1.5,1;Network Name: " .. network .. "]" ..
  39. "label[1.5,1.5;Palantir Name: " .. palantir .. "]" ..
  40. "dropdown[1.5,2.5;3;teleports;Teleport to..."
  41. for i,v in pairs(lottblocks.palantiri[network]) do
  42. if i ~= palantir and i ~= "options" and i ~= "owner" then
  43. form = form .. "," .. i
  44. end
  45. end
  46. form = form .. ";1]"
  47. local n = 1
  48. local h = 3.5
  49. for i,v in pairs(lottblocks.palantiri[network]["options"]) do
  50. local c = "red"
  51. if v == "true" then
  52. c = "green"
  53. end
  54. form = form .. "label[" .. n .. "," .. h .. ";" .. minetest.colorize(c, i) .. "]"
  55. n = n + 1.5
  56. if n == 5.5 then
  57. n = 1
  58. h = 4
  59. end
  60. end
  61. return form
  62. end
  63. local races = {
  64. {"dwarves", "GAMEdwarf"},
  65. {"elves", "GAMEelf"},
  66. {"men", "GAMEman"},
  67. {"orcs", "GAMEorc"},
  68. {"hobbits", "GAMEhobbit"}
  69. }
  70. local function options_form(network)
  71. local checkbox_pos = 1
  72. local options = "size[5,5]" ..
  73. "background[5,5;1,1;gui_elfbg.png;true]" ..
  74. "label[1,0.5;Allowed races:]" ..
  75. "button[1,4;2,1;exit;Proceed]"
  76. for _, race in pairs(races) do
  77. options = options .. "checkbox[1," .. checkbox_pos .. ";" .. race[1] ..
  78. ";" .. race[1]:gsub("^%l", string.upper) .. ";" ..
  79. tostring(lottblocks.palantiri[network].options[race[1]]) .. "]"
  80. checkbox_pos = checkbox_pos + 0.5
  81. end
  82. return options
  83. end
  84. minetest.register_privilege("palantiri", {
  85. description = "Allows editing palantiri",
  86. give_to_singleplayer = false,
  87. })
  88. minetest.register_node("lottblocks:palantir", {
  89. description = "Palantir",
  90. tiles = {"default_obsidian.png"},
  91. paramtype = "light",
  92. drawtype = "mesh",
  93. mesh = "lottblocks_palantir.obj",
  94. node_placement_prediction = "",
  95. on_punch = function(pos)
  96. local meta = minetest.get_meta(pos)
  97. if meta:get_int("configured") == 2 then
  98. meta:set_string("formspec", formspec_update(meta))
  99. end
  100. end,
  101. on_rightclick = function(pos)
  102. local meta = minetest.get_meta(pos)
  103. if meta:get_int("configured") == 2 then
  104. meta:set_string("formspec", formspec_update(meta))
  105. end
  106. end,
  107. on_place = function(itemstack, placer, pointed_thing)
  108. if check_blocks(pointed_thing.above) == false then
  109. minetest.chat_send_player(placer:get_player_name(),
  110. minetest.colorize(purple, "One does not simply set down a palantir..."))
  111. return
  112. end
  113. return minetest.item_place(itemstack, placer, pointed_thing)
  114. end,
  115. after_place_node = function(pos, placer)
  116. local meta = minetest.get_meta(pos)
  117. meta:set_int("configured", 0)
  118. meta:set_string("owner", placer:get_player_name())
  119. meta:set_string("formspec", "size[8,5]" ..
  120. "background[8,5;1,1;gui_elfbg.png;true]"..
  121. "button[2.75,3.5;3,1;exit;Proceed]" ..
  122. "field[3,1;3,1;network;Network Name;]" ..
  123. "field[3,2.5;3,1;palantir;Palantir Name;]")
  124. end,
  125. on_receive_fields = function(pos, formname, fields, sender)
  126. local meta = minetest.get_meta(pos)
  127. local configured = meta:get_int("configured")
  128. local player_name = sender:get_player_name()
  129. if configured == 0 then
  130. if not fields.network or not fields.palantir
  131. or fields.network == "" or fields.palantir == "" then
  132. minetest.chat_send_player(player_name,
  133. minetest.colorize("red", "Both the network and the palantir must have a name!!"))
  134. return
  135. end
  136. if fields.palantir == "owner" or fields.palantir == "options" then
  137. minetest.chat_send_player(player_name,
  138. minetest.colorize("red", "Palantir cannot use reserved name!"))
  139. return
  140. end
  141. if not lottblocks.palantiri[fields.network] then
  142. lottblocks.palantiri[fields.network] = {}
  143. lottblocks.palantiri[fields.network].owner = player_name
  144. else
  145. if lottblocks.palantiri[fields.network].owner ~= player_name
  146. and not minetest.check_player_privs(sender, "palantiri") then
  147. minetest.chat_send_player(player_name,
  148. minetest.colorize("red", "Someone else has a network with this name!"))
  149. return
  150. end
  151. end
  152. if not lottblocks.palantiri[fields.network][fields.palantir] then
  153. lottblocks.palantiri[fields.network][fields.palantir] = pos
  154. else
  155. minetest.chat_send_player(player_name,
  156. minetest.colorize("red", "A palantir already exists on this network with the same name!"))
  157. return
  158. end
  159. if not lottblocks.palantiri[fields.network].options then
  160. lottblocks.palantiri[fields.network].options = {}
  161. local options = lottblocks.palantiri[fields.network].options
  162. for _, race in pairs(races) do
  163. options[race[1]] = "true"
  164. end
  165. end
  166. meta:set_string("network", fields.network)
  167. meta:set_string("name", fields.palantir)
  168. meta:set_string("formspec", options_form(fields.network))
  169. save_palantiri()
  170. meta:set_int("configured", 1)
  171. elseif meta:get_int("configured") == 1 then
  172. local network = meta:get_string("network")
  173. if player_name == meta:get_string("owner") then
  174. for _, race in pairs(races) do
  175. if fields[race[1]] ~= nil then
  176. lottblocks.palantiri[network].options[race[1]] = tostring(fields[race[1]])
  177. end
  178. end
  179. end
  180. if fields.exit then
  181. meta:set_string("formspec", formspec_update(meta))
  182. meta:set_int("configured", 2)
  183. end
  184. else
  185. if check_blocks(pos) == false then
  186. minetest.chat_send_player(player_name,
  187. minetest.colorize(purple, "The palantiri is no longer anchored to the world!"))
  188. minetest.remove_node(pos)
  189. minetest.add_item(pos, "lottblocks:palantir")
  190. return
  191. end
  192. local can_tp = true
  193. local network = meta:get_string("network")
  194. local allowed_races = {}
  195. for race, allowed in pairs(lottblocks.palantiri[network].options) do
  196. if allowed == "true" then
  197. allowed_races[race] = true
  198. end
  199. end
  200. if player_name ~= meta:get_string("owner") and
  201. minetest.check_player_privs(player_name, {palantiri = true}) ~= true then
  202. for _, race in pairs(races) do
  203. if allowed_races[race[1]] == true then
  204. can_tp = minetest.check_player_privs(player_name, {[race[2]] = true})
  205. if can_tp == true then
  206. break
  207. end
  208. end
  209. end
  210. local c = 0
  211. for i,v in pairs(allowed_races) do c = c + 1 end
  212. if c == 0 then
  213. can_tp = false
  214. end
  215. end
  216. if can_tp == true then
  217. if fields.teleports == "Teleport to..." then
  218. sender:setpos({x = pos.x, y = pos.y + 1, z = pos.z})
  219. return
  220. elseif fields.teleports == nil or
  221. lottblocks.palantiri[meta:get_string("network")][fields.teleports] == nil then
  222. return
  223. end
  224. local p = lottblocks.palantiri[meta:get_string("network")][fields.teleports]
  225. sender:setpos({x = p.x, y = p.y + 1, z = p.z})
  226. elseif can_tp == false then
  227. if not fields.teleports == "Teleport to..." then
  228. sender:setpos({
  229. x = pos.x + math.random(-50, 50),
  230. y = pos.y + math.random(20, 50),
  231. z = pos.z + math.random(-50, 50)
  232. })
  233. sender:set_hp(math.random(1,10))
  234. end
  235. end
  236. end
  237. end,
  238. on_destruct = function(pos)
  239. local meta = minetest.get_meta(pos)
  240. if meta:get_int("configured") >= 1 then
  241. lottblocks.palantiri[meta:get_string("network")][meta:get_string("name")] = nil
  242. end
  243. end,
  244. groups = {forbidden = 1, very_hard = 1},
  245. })
  246. minetest.register_craft({
  247. output = "lottblocks:palantir",
  248. recipe = {
  249. {"default:obsidian", "lottores:tilkal", "default:obsidian"},
  250. {"lottores:tilkal", "default:obsidian", "lottores:tilkal"},
  251. {"default:obsidian", "lottores:tilkal", "default:obsidian"}
  252. }
  253. })