hoes.lua 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. local S = farming.intllib
  2. local tr = minetest.get_modpath("toolranks")
  3. -- Hoe registration function
  4. farming.register_hoe = function(name, def)
  5. -- Check for : prefix (register new hoes in your mod's namespace)
  6. if name:sub(1,1) ~= ":" then
  7. name = ":" .. name
  8. end
  9. -- Check def table
  10. if def.description == nil then
  11. def.description = S("Hoe")
  12. end
  13. if def.inventory_image == nil then
  14. def.inventory_image = "unknown_item.png"
  15. end
  16. if def.max_uses == nil then
  17. def.max_uses = 30
  18. end
  19. -- add hoe group
  20. def.groups = def.groups or {}
  21. def.groups.hoe = 1
  22. -- Register the tool
  23. minetest.register_tool(name, {
  24. description = def.description,
  25. inventory_image = def.inventory_image,
  26. on_use = function(itemstack, user, pointed_thing)
  27. return farming.hoe_on_use(itemstack, user, pointed_thing, def.max_uses)
  28. end,
  29. groups = def.groups,
  30. sound = {breaks = "default_tool_breaks"},
  31. })
  32. -- Register its recipe
  33. if def.recipe then
  34. minetest.register_craft({
  35. output = name:sub(2),
  36. recipe = def.recipe
  37. })
  38. elseif def.material then
  39. minetest.register_craft({
  40. output = name:sub(2),
  41. recipe = {
  42. {def.material, def.material, ""},
  43. {"", "group:stick", ""},
  44. {"", "group:stick", ""}
  45. }
  46. })
  47. end
  48. end
  49. -- Turns dirt with group soil=1 into soil
  50. function farming.hoe_on_use(itemstack, user, pointed_thing, uses)
  51. local pt = pointed_thing
  52. -- check if pointing at a node
  53. if not pt or pt.type ~= "node" then
  54. return
  55. end
  56. local under = minetest.get_node(pt.under)
  57. local upos = pointed_thing.under
  58. if minetest.is_protected(upos, user:get_player_name()) then
  59. minetest.record_protection_violation(upos, user:get_player_name())
  60. return
  61. end
  62. local p = {x = pt.under.x, y = pt.under.y + 1, z = pt.under.z}
  63. local above = minetest.get_node(p)
  64. -- return if any of the nodes is not registered
  65. if not minetest.registered_nodes[under.name]
  66. or not minetest.registered_nodes[above.name] then
  67. return
  68. end
  69. -- check if the node above the pointed thing is air
  70. if above.name ~= "air" then
  71. return
  72. end
  73. -- check if pointing at dirt
  74. if minetest.get_item_group(under.name, "soil") ~= 1 then
  75. return
  76. end
  77. -- turn the node into soil, wear out item and play sound
  78. minetest.set_node(pt.under, {name = "farming:soil"})
  79. minetest.sound_play("default_dig_crumbly", {pos = pt.under, gain = 0.5})
  80. local wear = 65535 / (uses -1)
  81. if farming.is_creative(user:get_player_name()) then
  82. if tr then
  83. wear = 1
  84. else
  85. wear = 0
  86. end
  87. end
  88. if tr then
  89. itemstack = toolranks.new_afteruse(itemstack, user, under, {wear = wear})
  90. else
  91. itemstack:add_wear(wear)
  92. end
  93. return itemstack
  94. end
  95. -- Define Hoes
  96. farming.register_hoe(":farming:hoe_wood", {
  97. description = S("Wooden Hoe"),
  98. inventory_image = "farming_tool_woodhoe.png",
  99. max_uses = 30,
  100. material = "group:wood"
  101. })
  102. minetest.register_craft({
  103. type = "fuel",
  104. recipe = "farming:hoe_wood",
  105. burntime = 5,
  106. })
  107. farming.register_hoe(":farming:hoe_stone", {
  108. description = S("Stone Hoe"),
  109. inventory_image = "farming_tool_stonehoe.png",
  110. max_uses = 90,
  111. material = "group:stone"
  112. })
  113. farming.register_hoe(":farming:hoe_steel", {
  114. description = S("Steel Hoe"),
  115. inventory_image = "farming_tool_steelhoe.png",
  116. max_uses = 200,
  117. material = "default:steel_ingot"
  118. })
  119. farming.register_hoe(":farming:hoe_bronze", {
  120. description = S("Bronze Hoe"),
  121. inventory_image = "farming_tool_bronzehoe.png",
  122. max_uses = 500,
  123. groups = {not_in_creative_inventory = 1},
  124. })
  125. farming.register_hoe(":farming:hoe_mese", {
  126. description = S("Mese Hoe"),
  127. inventory_image = "farming_tool_mesehoe.png",
  128. max_uses = 350,
  129. groups = {not_in_creative_inventory = 1},
  130. })
  131. farming.register_hoe(":farming:hoe_diamond", {
  132. description = S("Diamond Hoe"),
  133. inventory_image = "farming_tool_diamondhoe.png",
  134. max_uses = 500,
  135. groups = {not_in_creative_inventory = 1},
  136. })
  137. -- hoe bomb function
  138. local function hoe_area(pos, player)
  139. -- check for protection
  140. if minetest.is_protected(pos, player:get_player_name()) then
  141. minetest.record_protection_violation(pos, player:get_player_name())
  142. return
  143. end
  144. local r = 5 -- radius
  145. -- remove flora (grass, flowers etc.)
  146. local res = minetest.find_nodes_in_area(
  147. {x = pos.x - r, y = pos.y - 1, z = pos.z - r},
  148. {x = pos.x + r, y = pos.y + 2, z = pos.z + r},
  149. {"group:flora"})
  150. for n = 1, #res do
  151. minetest.swap_node(res[n], {name = "air"})
  152. end
  153. -- replace dirt with tilled soil
  154. res = nil
  155. res = minetest.find_nodes_in_area_under_air(
  156. {x = pos.x - r, y = pos.y - 1, z = pos.z - r},
  157. {x = pos.x + r, y = pos.y + 2, z = pos.z + r},
  158. {"group:soil"})
  159. for n = 1, #res do
  160. minetest.swap_node(res[n], {name = "farming:soil"})
  161. end
  162. end
  163. -- throwable hoe bomb
  164. minetest.register_entity("farming:hoebomb_entity", {
  165. physical = true,
  166. visual = "sprite",
  167. visual_size = {x = 1.0, y = 1.0},
  168. textures = {"farming_hoe_bomb.png"},
  169. collisionbox = {0,0,0,0,0,0},
  170. lastpos = {},
  171. player = "",
  172. on_step = function(self, dtime)
  173. if not self.player then
  174. self.object:remove()
  175. return
  176. end
  177. local pos = self.object:get_pos()
  178. if self.lastpos.x ~= nil then
  179. local vel = self.object:getvelocity()
  180. -- only when potion hits something physical
  181. if vel.x == 0
  182. or vel.y == 0
  183. or vel.z == 0 then
  184. if self.player ~= "" then
  185. -- round up coords to fix glitching through doors
  186. self.lastpos = vector.round(self.lastpos)
  187. hoe_area(self.lastpos, self.player)
  188. end
  189. self.object:remove()
  190. return
  191. end
  192. end
  193. self.lastpos = pos
  194. end
  195. })
  196. -- actual throwing function
  197. local function throw_potion(itemstack, player)
  198. local playerpos = player:get_pos()
  199. local obj = minetest.add_entity({
  200. x = playerpos.x,
  201. y = playerpos.y + 1.5,
  202. z = playerpos.z
  203. }, "farming:hoebomb_entity")
  204. local dir = player:get_look_dir()
  205. local velocity = 20
  206. obj:setvelocity({
  207. x = dir.x * velocity,
  208. y = dir.y * velocity,
  209. z = dir.z * velocity
  210. })
  211. obj:setacceleration({
  212. x = dir.x * -3,
  213. y = -9.5,
  214. z = dir.z * -3
  215. })
  216. obj:get_luaentity().player = player
  217. end
  218. -- hoe bomb item
  219. minetest.register_craftitem("farming:hoe_bomb", {
  220. description = S("Hoe Bomb (use or throw on grassy areas to hoe land"),
  221. inventory_image = "farming_hoe_bomb.png",
  222. groups = {flammable = 2, not_in_creative_inventory = 1},
  223. on_use = function(itemstack, user, pointed_thing)
  224. if pointed_thing.type == "node" then
  225. hoe_area(pointed_thing.above, user)
  226. else
  227. throw_potion(itemstack, user)
  228. if not farming.is_creative(user:get_player_name()) then
  229. itemstack:take_item()
  230. return itemstack
  231. end
  232. end
  233. end,
  234. })
  235. -- Mithril Scythe (special item)
  236. farming.scythe_not_drops = {"farming:trellis", "farming:beanpole"}
  237. farming.add_to_scythe_not_drops = function(item)
  238. table.insert(farming.scythe_not_drops, item)
  239. end
  240. minetest.register_tool("farming:scythe", {
  241. description = "Scythe (Use to harvest and replant crops)",
  242. inventory_image = "farming_scythe.png",
  243. sound = {breaks = "default_tool_breaks"},
  244. on_use = function(itemstack, placer, pointed_thing)
  245. if pointed_thing.type ~= "node" then
  246. return
  247. end
  248. local pos = pointed_thing.under
  249. local name = placer:get_player_name()
  250. if minetest.is_protected(pos, name) then
  251. return
  252. end
  253. local node = minetest.get_node_or_nil(pos)
  254. if not node then
  255. return
  256. end
  257. local def = minetest.registered_nodes[node.name]
  258. if not def then
  259. return
  260. end
  261. if not def.drop then
  262. return
  263. end
  264. if not def.groups
  265. or not def.groups.plant then
  266. return
  267. end
  268. local drops = minetest.get_node_drops(node.name, "")
  269. if not drops
  270. or #drops == 0
  271. or (#drops == 1 and drops[1] == "") then
  272. return
  273. end
  274. -- get crop name
  275. local mname = node.name:split(":")[1]
  276. local pname = node.name:split(":")[2]
  277. local sname = tonumber(pname:split("_")[2])
  278. pname = pname:split("_")[1]
  279. if not sname then
  280. return
  281. end
  282. -- add dropped items
  283. for _, dropped_item in pairs(drops) do
  284. -- dont drop items on this list
  285. for _, not_item in pairs(farming.scythe_not_drops) do
  286. if dropped_item == not_item then
  287. dropped_item = nil
  288. end
  289. end
  290. if dropped_item then
  291. local player_inv = placer:get_inventory()
  292. if player_inv:room_for_item('main', dropped_item) then
  293. player_inv:add_item('main', dropped_item)
  294. else
  295. local obj = minetest.add_item(pos, dropped_item)
  296. if obj then
  297. obj:set_velocity({
  298. x = math.random(-10, 10) / 9,
  299. y = 3,
  300. z = math.random(-10, 10) / 9,
  301. })
  302. end
  303. end
  304. end
  305. end
  306. -- Run script hook
  307. for _, callback in pairs(core.registered_on_dignodes) do
  308. callback(pos, node, placer)
  309. end
  310. -- play sound
  311. minetest.sound_play("default_grass_footstep", {pos = pos, gain = 1.0})
  312. local replace = mname .. ":" .. pname .. "_1"
  313. if minetest.registered_nodes[replace] then
  314. local p2 = minetest.registered_nodes[replace].place_param2 or 1
  315. minetest.set_node(pos, {name = replace, param2 = p2})
  316. else
  317. minetest.set_node(pos, {name = "air"})
  318. end
  319. if not farming.is_creative(name) then
  320. itemstack:add_wear(65535 / 150) -- 150 uses
  321. return itemstack
  322. end
  323. end,
  324. })