hoes.lua 11 KB

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