hoes.lua 11 KB

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