hoes.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  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. -- am I going to hoe the top of a dirt node?
  53. if not pt or pt.type ~= "node"
  54. or pt.above.y ~= pt.under.y + 1 then
  55. return
  56. end
  57. local under = minetest.get_node(pt.under)
  58. local upos = pointed_thing.under
  59. if minetest.is_protected(upos, user:get_player_name()) then
  60. minetest.record_protection_violation(upos, user:get_player_name())
  61. return
  62. end
  63. local p = {x = pt.under.x, y = pt.under.y + 1, z = pt.under.z}
  64. local above = minetest.get_node(p)
  65. -- return if any of the nodes is not registered
  66. if not minetest.registered_nodes[under.name]
  67. or not minetest.registered_nodes[above.name] then
  68. return
  69. end
  70. -- check if the node above the pointed thing is air
  71. if above.name ~= "air" then
  72. return
  73. end
  74. -- check if pointing at dirt
  75. if minetest.get_item_group(under.name, "soil") ~= 1 then
  76. return
  77. end
  78. -- turn the node into soil, wear out item and play sound
  79. minetest.set_node(pt.under, {name = "farming:soil"})
  80. minetest.sound_play("default_dig_crumbly", {pos = pt.under, gain = 0.5})
  81. local wdef = itemstack:get_definition()
  82. local wear = 65535 / (uses - 1)
  83. if farming.is_creative(user:get_player_name()) then
  84. if tr then
  85. wear = 1
  86. else
  87. wear = 0
  88. end
  89. end
  90. if tr then
  91. itemstack = toolranks.new_afteruse(itemstack, user, under, {wear = wear})
  92. else
  93. itemstack:add_wear(wear)
  94. end
  95. if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then
  96. minetest.sound_play(wdef.sound.breaks, {pos = pt.above,
  97. gain = 0.5}, true)
  98. end
  99. return itemstack
  100. end
  101. -- Define Hoes
  102. farming.register_hoe(":farming:hoe_wood", {
  103. description = S("Wooden Hoe"),
  104. inventory_image = "farming_tool_woodhoe.png",
  105. max_uses = 30,
  106. material = "group:wood"
  107. })
  108. minetest.register_craft({
  109. type = "fuel",
  110. recipe = "farming:hoe_wood",
  111. burntime = 5,
  112. })
  113. farming.register_hoe(":farming:hoe_stone", {
  114. description = S("Stone Hoe"),
  115. inventory_image = "farming_tool_stonehoe.png",
  116. max_uses = 90,
  117. material = "group:stone"
  118. })
  119. farming.register_hoe(":farming:hoe_steel", {
  120. description = S("Steel Hoe"),
  121. inventory_image = "farming_tool_steelhoe.png",
  122. max_uses = 200,
  123. material = "default:steel_ingot"
  124. })
  125. farming.register_hoe(":farming:hoe_bronze", {
  126. description = S("Bronze Hoe"),
  127. inventory_image = "farming_tool_bronzehoe.png",
  128. max_uses = 500,
  129. groups = {not_in_creative_inventory = 1},
  130. })
  131. farming.register_hoe(":farming:hoe_mese", {
  132. description = S("Mese Hoe"),
  133. inventory_image = "farming_tool_mesehoe.png",
  134. max_uses = 350,
  135. groups = {not_in_creative_inventory = 1},
  136. })
  137. farming.register_hoe(":farming:hoe_diamond", {
  138. description = S("Diamond Hoe"),
  139. inventory_image = "farming_tool_diamondhoe.png",
  140. max_uses = 500,
  141. groups = {not_in_creative_inventory = 1},
  142. })
  143. -- Toolranks support
  144. if tr then
  145. minetest.override_item("farming:hoe_wood", {
  146. original_description = "Wood Hoe",
  147. description = toolranks.create_description("Wood Hoe")})
  148. minetest.override_item("farming:hoe_stone", {
  149. original_description = "Stone Hoe",
  150. description = toolranks.create_description("Stone Hoe")})
  151. minetest.override_item("farming:hoe_steel", {
  152. original_description = "Steel Hoe",
  153. description = toolranks.create_description("Steel Hoe")})
  154. minetest.override_item("farming:hoe_bronze", {
  155. original_description = "Bronze Hoe",
  156. description = toolranks.create_description("Bronze Hoe")})
  157. minetest.override_item("farming:hoe_mese", {
  158. original_description = "Mese Hoe",
  159. description = toolranks.create_description("Mese Hoe")})
  160. minetest.override_item("farming:hoe_diamond", {
  161. original_description = "Diamond Hoe",
  162. description = toolranks.create_description("Diamond Hoe")})
  163. end
  164. -- hoe bomb function
  165. local function hoe_area(pos, player)
  166. -- check for protection
  167. if minetest.is_protected(pos, player:get_player_name()) then
  168. minetest.record_protection_violation(pos, player:get_player_name())
  169. return
  170. end
  171. local r = 5 -- radius
  172. -- remove flora (grass, flowers etc.)
  173. local res = minetest.find_nodes_in_area(
  174. {x = pos.x - r, y = pos.y - 1, z = pos.z - r},
  175. {x = pos.x + r, y = pos.y + 2, z = pos.z + r},
  176. {"group:flora"})
  177. for n = 1, #res do
  178. minetest.swap_node(res[n], {name = "air"})
  179. end
  180. -- replace dirt with tilled soil
  181. res = nil
  182. res = minetest.find_nodes_in_area_under_air(
  183. {x = pos.x - r, y = pos.y - 1, z = pos.z - r},
  184. {x = pos.x + r, y = pos.y + 2, z = pos.z + r},
  185. {"group:soil"})
  186. for n = 1, #res do
  187. minetest.swap_node(res[n], {name = "farming:soil"})
  188. end
  189. end
  190. -- throwable hoe bomb
  191. minetest.register_entity("farming:hoebomb_entity", {
  192. physical = true,
  193. visual = "sprite",
  194. visual_size = {x = 1.0, y = 1.0},
  195. textures = {"farming_hoe_bomb.png"},
  196. collisionbox = {0,0,0,0,0,0},
  197. lastpos = {},
  198. player = "",
  199. on_step = function(self, dtime)
  200. if not self.player then
  201. self.object:remove()
  202. return
  203. end
  204. local pos = self.object:get_pos()
  205. if self.lastpos.x ~= nil then
  206. local vel = self.object:getvelocity()
  207. -- only when potion hits something physical
  208. if vel.x == 0
  209. or vel.y == 0
  210. or vel.z == 0 then
  211. if self.player ~= "" then
  212. -- round up coords to fix glitching through doors
  213. self.lastpos = vector.round(self.lastpos)
  214. hoe_area(self.lastpos, self.player)
  215. end
  216. self.object:remove()
  217. return
  218. end
  219. end
  220. self.lastpos = pos
  221. end
  222. })
  223. -- actual throwing function
  224. local function throw_potion(itemstack, player)
  225. local playerpos = player:get_pos()
  226. local obj = minetest.add_entity({
  227. x = playerpos.x,
  228. y = playerpos.y + 1.5,
  229. z = playerpos.z
  230. }, "farming:hoebomb_entity")
  231. local dir = player:get_look_dir()
  232. local velocity = 20
  233. obj:setvelocity({
  234. x = dir.x * velocity,
  235. y = dir.y * velocity,
  236. z = dir.z * velocity
  237. })
  238. obj:setacceleration({
  239. x = dir.x * -3,
  240. y = -9.5,
  241. z = dir.z * -3
  242. })
  243. obj:get_luaentity().player = player
  244. end
  245. -- hoe bomb item
  246. minetest.register_craftitem("farming:hoe_bomb", {
  247. description = S("Hoe Bomb (use or throw on grassy areas to hoe land"),
  248. inventory_image = "farming_hoe_bomb.png",
  249. groups = {flammable = 2, not_in_creative_inventory = 1},
  250. on_use = function(itemstack, user, pointed_thing)
  251. if pointed_thing.type == "node" then
  252. hoe_area(pointed_thing.above, user)
  253. else
  254. throw_potion(itemstack, user)
  255. if not farming.is_creative(user:get_player_name()) then
  256. itemstack:take_item()
  257. return itemstack
  258. end
  259. end
  260. end,
  261. })
  262. -- Mithril Scythe (special item)
  263. farming.scythe_not_drops = {"farming:trellis", "farming:beanpole"}
  264. farming.add_to_scythe_not_drops = function(item)
  265. table.insert(farming.scythe_not_drops, item)
  266. end
  267. minetest.register_tool("farming:scythe_mithril", {
  268. description = S("Mithril Scythe (Use to harvest and replant crops)"),
  269. inventory_image = "farming_scythe_mithril.png",
  270. sound = {breaks = "default_tool_breaks"},
  271. on_use = function(itemstack, placer, pointed_thing)
  272. if pointed_thing.type ~= "node" then
  273. return
  274. end
  275. local pos = pointed_thing.under
  276. local name = placer:get_player_name()
  277. if minetest.is_protected(pos, name) then
  278. return
  279. end
  280. local node = minetest.get_node_or_nil(pos)
  281. if not node then
  282. return
  283. end
  284. local def = minetest.registered_nodes[node.name]
  285. if not def then
  286. return
  287. end
  288. if not def.drop then
  289. return
  290. end
  291. if not def.groups
  292. or not def.groups.plant then
  293. return
  294. end
  295. local drops = minetest.get_node_drops(node.name, "")
  296. if not drops
  297. or #drops == 0
  298. or (#drops == 1 and drops[1] == "") then
  299. return
  300. end
  301. -- get crop name
  302. local mname = node.name:split(":")[1]
  303. local pname = node.name:split(":")[2]
  304. local sname = tonumber(pname:split("_")[2])
  305. pname = pname:split("_")[1]
  306. if not sname then
  307. return
  308. end
  309. -- add dropped items
  310. for _, dropped_item in pairs(drops) do
  311. -- dont drop items on this list
  312. for _, not_item in pairs(farming.scythe_not_drops) do
  313. if dropped_item == not_item then
  314. dropped_item = nil
  315. end
  316. end
  317. if dropped_item then
  318. local obj = minetest.add_item(pos, dropped_item)
  319. if obj then
  320. obj:set_velocity({
  321. x = math.random(-10, 10) / 9,
  322. y = 3,
  323. z = math.random(-10, 10) / 9,
  324. })
  325. end
  326. end
  327. end
  328. -- Run script hook
  329. for _, callback in pairs(core.registered_on_dignodes) do
  330. callback(pos, node, placer)
  331. end
  332. -- play sound
  333. minetest.sound_play("default_grass_footstep", {pos = pos, gain = 1.0})
  334. local replace = mname .. ":" .. pname .. "_1"
  335. if minetest.registered_nodes[replace] then
  336. local p2 = minetest.registered_nodes[replace].place_param2 or 1
  337. minetest.set_node(pos, {name = replace, param2 = p2})
  338. else
  339. minetest.set_node(pos, {name = "air"})
  340. end
  341. if not farming.is_creative(name) then
  342. itemstack:add_wear(65535 / 150) -- 150 uses
  343. return itemstack
  344. end
  345. end,
  346. })
  347. if minetest.get_modpath("moreores") then
  348. minetest.register_craft({
  349. output = "farming:scythe_mithril",
  350. recipe = {
  351. {"", "moreores:mithril_ingot", "moreores:mithril_ingot"},
  352. {"moreores:mithril_ingot", "", "group:stick"},
  353. {"", "", "group:stick"}
  354. }
  355. })
  356. farming.register_hoe(":moreores:hoe_silver", {
  357. description = S("%s Hoe"):format(S("Silver")),
  358. inventory_image = "moreores_tool_silverhoe.png",
  359. max_uses = 300,
  360. material = "moreores:silver_ingot",
  361. })
  362. farming.register_hoe(":moreores:hoe_mithril", {
  363. description = S("%s Hoe"):format(S("Mithril")),
  364. inventory_image = "moreores_tool_mithrilhoe.png",
  365. max_uses = 1000,
  366. material = "moreores:mithril_ingot",
  367. })
  368. -- Toolranks support
  369. if tr then
  370. minetest.override_item("moreores:hoe_silver", {
  371. original_description = S("%s Hoe"):format(S("Silver")),
  372. description = toolranks.create_description("Silver Hoe")})
  373. minetest.override_item("moreores:hoe_mithril", {
  374. original_description = S("%s Hoe"):format(S("Mithril")),
  375. description = toolranks.create_description("Mithril Hoe")})
  376. end
  377. end