init.lua 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. -- Minetest mod "City block"
  2. -- City block disables use of water/lava buckets and also sends aggressive players to jail
  3. -- 2016.02 - improvements suggested by rnd. removed spawn_jailer support. some small fixes and improvements.
  4. -- This library is free software; you can redistribute it and/or
  5. -- modify it under the terms of the GNU Lesser General Public
  6. -- License as published by the Free Software Foundation; either
  7. -- version 2.1 of the License, or (at your option) any later version.
  8. if not minetest.global_exists("city_block") then city_block = {} end
  9. city_block.blocks = city_block.blocks or {}
  10. city_block.filename = minetest.get_worldpath() .. "/city_blocks.txt"
  11. city_block.modpath = minetest.get_modpath("city_block")
  12. city_block.formspecs = city_block.formspecs or {}
  13. -- Cityblocks take 6 hours to become "active".
  14. -- This prevents certain classes of exploits (such as using them offensively
  15. -- during PvP). This also strongly discourages constantly moving them around
  16. -- for trivial reasons.
  17. city_block.CITYBLOCK_DELAY_TIME = 60*60*6
  18. -- Localize for performance.
  19. local vector_distance = vector.distance
  20. local vector_round = vector.round
  21. local vector_add = vector.add
  22. local vector_equals = vector.equals
  23. local math_random = math.random
  24. local CITYBLOCK_DELAY_TIME = city_block.CITYBLOCK_DELAY_TIME
  25. function city_block.time_active(t1, t2)
  26. return (math.abs(t2 - t1) > CITYBLOCK_DELAY_TIME)
  27. end
  28. local time_active = city_block.time_active
  29. dofile(city_block.modpath .. "/beacon.lua")
  30. dofile(city_block.modpath .. "/formspec.lua")
  31. dofile(city_block.modpath .. "/queries.lua")
  32. dofile(city_block.modpath .. "/functions.lua")
  33. dofile(city_block.modpath .. "/file.lua")
  34. dofile(city_block.modpath .. "/pvp.lua")
  35. dofile(city_block.modpath .. "/inv.lua")
  36. function city_block.on_punch(pos, node, puncher, pt)
  37. if not pos or not node or not puncher or not pt then
  38. return
  39. end
  40. local pname = puncher:get_player_name()
  41. local wielded = puncher:get_wielded_item()
  42. if wielded:get_name() == "rosestone:head" and wielded:get_count() >= 8 then
  43. -- Only if area is not protected against this player.
  44. if not minetest.test_protection(pos, pname) then
  45. for i, v in ipairs(city_block.blocks) do
  46. if vector_equals(v.pos, pos) then
  47. if not v.is_jail then
  48. local p1 = vector_add(pos, {x=-1, y=0, z=-1})
  49. local p2 = vector_add(pos, {x=1, y=0, z=1})
  50. local positions, counts = minetest.find_nodes_in_area(p1, p2, "griefer:grieferstone")
  51. if counts["griefer:grieferstone"] == 8 then
  52. v.is_jail = true
  53. local meta = minetest.get_meta(pos)
  54. local infotext = meta:get_string("infotext")
  55. infotext = infotext .. "\nJail Marker"
  56. meta:set_string("infotext", infotext)
  57. city_block:save()
  58. wielded:take_item(8)
  59. puncher:set_wielded_item(wielded)
  60. minetest.chat_send_player(pname, "# Server: Jail position marked!")
  61. return
  62. end
  63. end
  64. end
  65. end
  66. end
  67. end
  68. -- Duel activation.
  69. -- Can be done even if player doesn't have access to protection.
  70. if wielded:get_name() == "default:gold_ingot" and wielded:get_count() > 0 then
  71. local targetpos = pos
  72. -- Check for config device, and try to use that.
  73. -- Note: configured target pos might not be valid.
  74. local meta = minetest.get_meta(pos)
  75. local owner = meta:get_string("owner")
  76. local inv = meta:get_inventory()
  77. local config = inv:get_stack("config", 1)
  78. if config:get_name() == "cfg:dev" and config:get_count() == 1 then
  79. local cmeta = config:get_meta()
  80. local s1 = cmeta:get_string("p1")
  81. local p1 = minetest.string_to_pos(s1)
  82. if s1 and s1 ~= "" and p1 then
  83. p1 = vector_round(p1)
  84. if vector_distance(p1, pos) <= armor.DUEL_MAX_RADIUS then
  85. targetpos = p1
  86. else
  87. minetest.chat_send_player(pname, "# Server: Target too far.")
  88. return
  89. end
  90. else
  91. minetest.chat_send_player(pname, "# Server: Invalid configuration.")
  92. return
  93. end
  94. end
  95. local block = city_block.get_block(targetpos)
  96. if block and block.pvp_arena then
  97. local target_meta = minetest.get_meta(targetpos)
  98. local target_owner = target_meta:get_string("owner")
  99. if target_owner == owner then
  100. if armor.is_valid_arena(targetpos) then
  101. if armor.add_dueling_player(puncher, targetpos) then
  102. wielded:take_item()
  103. puncher:set_wielded_item(wielded)
  104. else
  105. if armor.dueling_players[pname] then
  106. minetest.chat_send_player(pname, "# Server: You are already in a duel!")
  107. end
  108. end
  109. else
  110. minetest.chat_send_player(pname, "# Server: This is not a working dueling arena! You need city blocks, protection, and at least 2 public beds.")
  111. end
  112. else
  113. minetest.chat_send_player(pname, "# Server: Invalid configuration.")
  114. end
  115. else
  116. minetest.chat_send_player(pname, "# Server: Target is not an arena marker.")
  117. end
  118. end
  119. end
  120. function city_block.on_rightclick(pos, node, clicker, itemstack)
  121. if not clicker or not clicker:is_player() then
  122. return
  123. end
  124. local pname = clicker:get_player_name()
  125. local meta = minetest.get_meta(pos)
  126. -- Player must be owner of city block.
  127. if meta:get_string("owner") ~= pname then
  128. return
  129. end
  130. -- Create formspec context.
  131. city_block.formspecs[pname] = pos
  132. local blockdata = city_block.get_block(pos)
  133. local formspec = city_block.create_formspec(pos, pname, blockdata)
  134. minetest.show_formspec(pname, "city_block:main", formspec)
  135. end
  136. function city_block.on_leaveplayer(player, timed_out)
  137. city_block.disable_beacons_for_player(player:get_player_name())
  138. end
  139. if not city_block.run_once then
  140. city_block:load()
  141. minetest.register_on_player_receive_fields(function(...)
  142. return city_block.on_receive_fields(...) end)
  143. minetest.register_node("city_block:cityblock", {
  144. description = "Lawful Zone Marker [Marks a 45x45x45 area as a city.]\n\nSaves your bed respawn position, if someone killed you within the city area.\nMurderers and trespassers will be sent to jail if caught in a city.\nPrevents the use of ore leeching equipment within 100 meters radius.\nPrevents mining with TNT nearby.",
  145. tiles = {"moreblocks_circle_stone_bricks.png^default_tool_mesepick.png"},
  146. is_ground_content = false,
  147. groups = utility.dig_groups("obsidian", {
  148. immovable=1,
  149. }),
  150. is_ground_content = false,
  151. sounds = default.node_sound_stone_defaults(),
  152. stack_max = 1,
  153. on_rightclick = function(...)
  154. return city_block.on_rightclick(...)
  155. end,
  156. after_place_node = function(...)
  157. return city_block.after_place_node(...)
  158. end,
  159. -- We don't need an `on_blast` func because TNT calls `on_destruct` properly!
  160. on_destruct = function(...)
  161. return city_block.on_destruct(...)
  162. end,
  163. -- Called by rename LBM.
  164. _on_update_infotext = function(...)
  165. return city_block._on_update_infotext(...)
  166. end,
  167. on_punch = function(...)
  168. return city_block.on_punch(...)
  169. end,
  170. allow_metadata_inventory_move = function(...)
  171. return city_block.allow_metadata_inventory_move(...)
  172. end,
  173. allow_metadata_inventory_put = function(...)
  174. return city_block.allow_metadata_inventory_put(...)
  175. end,
  176. allow_metadata_inventory_take = function(...)
  177. return city_block.allow_metadata_inventory_take(...)
  178. end,
  179. on_metadata_inventory_move = function(...)
  180. return city_block.on_metadata_inventory_move(...)
  181. end,
  182. on_metadata_inventory_put = function(...)
  183. return city_block.on_metadata_inventory_put(...)
  184. end,
  185. on_metadata_inventory_take = function(...)
  186. return city_block.on_metadata_inventory_take(...)
  187. end,
  188. })
  189. minetest.register_craft({
  190. output = 'city_block:cityblock',
  191. recipe = {
  192. {'default:pick_mese', 'farming:hoe_mese', 'default:sword_diamond'},
  193. {'chests:chest_locked', 'default:goldblock', 'default:sandstone'},
  194. {'default:obsidianbrick', 'default:mese', 'cobble_furnace:inactive'},
  195. }
  196. })
  197. minetest.register_privilege("disable_pvp", {
  198. description = "Players cannot damage players with this priv by punching.",
  199. give_to_singleplayer = false,
  200. })
  201. minetest.register_on_punchplayer(function(...)
  202. return city_block.on_punchplayer(...)
  203. end)
  204. minetest.register_on_leaveplayer(function(...)
  205. return city_block.on_leaveplayer(...)
  206. end)
  207. city_block.update_beacons()
  208. local c = "city_block:core"
  209. local f = city_block.modpath .. "/init.lua"
  210. reload.register_file(c, f, false)
  211. city_block.run_once = true
  212. end