worms.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. -----------------------------------------------------------------------------------------------
  2. -- Fishing - crabman77's version
  3. -- Rewrited from original Fishing - Mossmanikin's version - Worm 0.0.2
  4. -----------------------------------------------------------------------------------------------
  5. -- License (code & textures): WTFPL
  6. -- Contains code from: fishing (original), mobs
  7. -- Looked at code from: my_mobs
  8. -- Dependencies: default
  9. -----------------------------------------------------------------------------------------------
  10. -----------------------------------------------------------------------------------------------
  11. -- WORM ITEM
  12. -----------------------------------------------------------------------------------------------
  13. minetest.register_craftitem("fishing:bait_worm", {
  14. description = fishing_setting.func.S("Worm"),
  15. groups = { fishing_bait=1 },
  16. inventory_image = "fishing_bait_worm.png",
  17. on_place = function(itemstack, placer, pointed_thing)
  18. if not placer then -- can happen, e.g. if placed using minetest.place_node
  19. return itemstack
  20. end
  21. local pt = pointed_thing
  22. if not minetest.is_protected(pt.under, placer:get_player_name()) then
  23. minetest.add_entity({x=pt.under.x, y=pt.under.y+0.6, z=pt.under.z}, "fishing:bait_worm_entity")
  24. itemstack:take_item()
  25. end
  26. return itemstack
  27. end,
  28. on_drop = function(itemstack, dropper, pos)
  29. minetest.add_entity({x = pos.x, y = pos.y, z = pos.z}, "fishing:bait_worm_entity")
  30. itemstack:take_item()
  31. return itemstack
  32. end,
  33. })
  34. -----------------------------------------------------------------------------------------------
  35. -- WORM MOB
  36. -----------------------------------------------------------------------------------------------
  37. minetest.register_entity("fishing:bait_worm_entity", {
  38. hp_max = 300,
  39. damage_over_time = 1,
  40. collisionbox = {-3/16, -3/16, -3/16, 3/16, 3/16, 3/16},
  41. visual = "sprite",
  42. visual_size = {x=1/2, y=1/2},
  43. textures = { "fishing_bait_worm.png", "fishing_bait_worm.png"},
  44. view_range = 32,
  45. -- Don't punch this poor creature...
  46. on_punch = function(self, puncher)
  47. self.object:remove()
  48. end,
  49. -- ...softly take it into your hand.
  50. on_rightclick = function(self, clicker)
  51. if clicker:is_player() and clicker:get_inventory() then
  52. clicker:get_inventory():add_item("main", "fishing:bait_worm")
  53. self.object:remove()
  54. end
  55. end,
  56. -- AI :D
  57. on_step = function(self, dtime)
  58. local pos = self.object:getpos()
  59. -- despawn when no player in range
  60. local remove_entity = true
  61. for _,player in pairs(minetest.get_connected_players()) do
  62. local p = player:getpos()
  63. local dist = ((p.x-pos.x)^2 + (p.y-pos.y)^2 + (p.z-pos.z)^2)^0.5
  64. if dist < 25 then
  65. remove_entity = false
  66. break
  67. end
  68. end
  69. if remove_entity then
  70. self.object:remove()
  71. return
  72. end
  73. local n = minetest.get_node({x=pos.x,y=pos.y-0.3,z=pos.z})
  74. -- move in world
  75. local look_whats_up = function(self)
  76. self.object:set_hp(self.object:get_hp()-self.damage_over_time) -- creature is getting older
  77. if n.name == "air" then -- fall when in air
  78. self.object:moveto({x=pos.x,y=pos.y-0.5,z=pos.z})
  79. self.object:set_hp(self.object:get_hp()-75)
  80. --if n.name == "snappy" then -- fall when leaves or similar
  81. elseif minetest.get_item_group(n.name, "snappy") ~= 0 then
  82. self.object:moveto({x=pos.x+(0.001*(math.random(-32, 32))),y=pos.y-(0.001*(math.random(0, 64))),z=pos.z+(0.001*(math.random(-32, 32)))})
  83. elseif string.find(n.name, "default:water") then -- sink when in water
  84. self.object:moveto({x=pos.x,y=pos.y-0.25,z=pos.z})
  85. self.object:set_hp(self.object:get_hp()-37)
  86. elseif minetest.get_item_group(n.name, "soil") ~= 0 then
  87. if minetest.get_item_group(minetest.get_node({x=pos.x,y=pos.y-0.1,z=pos.z}).name, "soil") == 0 and self.object:get_hp() > 200 then
  88. self.object:set_hp(199)
  89. elseif self.object:get_hp() > 200 then -- leave dirt to see whats going on
  90. self.object:moveto({x=pos.x+(0.001*(math.random(-2, 2))),y=pos.y+0.003,z=pos.z+(0.001*(math.random(-2, 2)))})
  91. elseif self.object:get_hp() < 199 then -- no rain here, let's get outa here
  92. self.object:moveto({x=pos.x+(0.001*(math.random(-2, 2))),y=pos.y-0.001,z=pos.z+(0.001*(math.random(-2, 2)))})
  93. elseif self.object:get_hp() == 0 then
  94. self.object:remove()
  95. end
  96. else -- check if there's dirt anywhere (not finished)
  97. local check_group = minetest.get_item_group
  98. local goal_01 = check_group(minetest.get_node({x = pos.x + 1, y = pos.y-0.4, z = pos.z }).name, "soil")
  99. local goal_02 = check_group(minetest.get_node({x = pos.x, y = pos.y-0.4, z = pos.z + 1}).name, "soil")
  100. local goal_03 = check_group(minetest.get_node({x = pos.x - 1, y = pos.y-0.4, z = pos.z }).name, "soil")
  101. local goal_04 = check_group(minetest.get_node({x = pos.x, y = pos.y-0.4, z = pos.z - 1}).name, "soil")
  102. local goal_1a = check_group(minetest.get_node({x = pos.x + 1, y = pos.y+0.6, z = pos.z }).name, "soil")
  103. local goal_2a = check_group(minetest.get_node({x = pos.x, y = pos.y+0.6, z = pos.z + 1}).name, "soil")
  104. local goal_3a = check_group(minetest.get_node({x = pos.x - 1, y = pos.y+0.6, z = pos.z }).name, "soil")
  105. local goal_4a = check_group(minetest.get_node({x = pos.x, y = pos.y+0.6, z = pos.z - 1}).name, "soil")
  106. -- if there's dirt nearby, go there
  107. if goal_01 ~= 0 or goal_1a ~= 0 then
  108. self.object:moveto({x=pos.x+0.002,y=pos.y,z=pos.z+(0.001*(math.random(-2, 2)))})
  109. elseif goal_02 ~= 0 or goal_2a ~= 0 then
  110. self.object:moveto({x=pos.x+(0.001*(math.random(-2, 2))),y=pos.y,z=pos.z+0.002})
  111. elseif goal_03 ~= 0 or goal_3a ~= 0 then
  112. self.object:moveto({x=pos.x-0.002,y=pos.y,z=pos.z+(0.001*(math.random(-2, 2)))})
  113. elseif goal_04 ~= 0 or goal_4a ~= 0 then
  114. self.object:moveto({x=pos.x+(0.001*(math.random(-2, 2))),y=pos.y,z=pos.z-0.002})
  115. else -- I'm lost, no dirt
  116. self.object:moveto({x=pos.x+(0.001*(math.random(-8, 8))),y=pos.y,z=pos.z+(0.001*(math.random(-8, 8)))})
  117. end
  118. end
  119. end
  120. look_whats_up(self)
  121. end,
  122. })
  123. --- Bait Worm Entity
  124. minetest.register_craft({
  125. output = "fishing:bait_worm 8",
  126. recipe = {
  127. {"default:dirt"},
  128. {"default:dirt"},
  129. }
  130. })
  131. -----------------------------------------------------------------------------------------------
  132. -- GETTING WORMS
  133. -----------------------------------------------------------------------------------------------
  134. -- get worms from digging in dirt:
  135. if fishing_setting.settings["new_worm_source"] == false then
  136. minetest.register_node(":default:dirt", {
  137. description = fishing_setting.func.S("Dirt"),
  138. tiles = {"default_dirt.png"},
  139. is_ground_content = true,
  140. groups = {crumbly=3},
  141. sounds = default.node_sound_dirt_defaults(),
  142. after_dig_node = function (pos, oldnode, oldmetadata, digger)
  143. if math.random(1, 100) <= fishing_setting.settings["worm_chance"] then
  144. local tool_in_use = digger:get_wielded_item():get_name()
  145. if tool_in_use == "" or tool_in_use == "default:dirt" then
  146. if fishing_setting.settings["worm_is_mob"] == true then
  147. minetest.add_entity({x = pos.x, y = pos.y+0.4, z = pos.z}, "fishing:bait_worm_entity")
  148. else
  149. local inv = digger:get_inventory()
  150. if inv:room_for_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""}) then
  151. inv:add_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""})
  152. end
  153. end
  154. end
  155. end
  156. end,
  157. })
  158. else
  159. -- get worms from digging with hoes:
  160. -- turns nodes with group soil=1 into soil
  161. local function hoe_on_use(itemstack, user, pointed_thing, uses)
  162. local pt = pointed_thing
  163. -- check if pointing at a node
  164. if not pt or pt.type ~= "node" then
  165. return
  166. end
  167. local under = minetest.get_node(pt.under)
  168. local upos = pointed_thing.under
  169. if minetest.is_protected(upos, user:get_player_name()) then
  170. minetest.record_protection_violation(upos, user:get_player_name())
  171. return
  172. end
  173. local p = {x=pt.under.x, y=pt.under.y+1, z=pt.under.z}
  174. local above = minetest.get_node(p)
  175. -- return if any of the nodes is not registered
  176. if not minetest.registered_nodes[under.name]
  177. or not minetest.registered_nodes[above.name] then
  178. return
  179. end
  180. -- check if the node above the pointed thing is air
  181. if above.name ~= "air" then
  182. return
  183. end
  184. -- check if pointing at dirt
  185. if minetest.get_item_group(under.name, "soil") ~= 1 then
  186. return
  187. end
  188. -- turn the node into soil, wear out item and play sound
  189. minetest.set_node(pt.under, {name="farming:soil"})
  190. minetest.sound_play("default_dig_crumbly", {pos = pt.under, gain = 0.5,})
  191. if math.random(1, 100) < fishing_setting.settings["worm_chance"] then
  192. if fishing_setting.settings["worm_is_mob"] == true then
  193. minetest.add_entity({x=pt.under.x, y=pt.under.y+0.4, z=pt.under.z}, "fishing:bait_worm_entity")
  194. else
  195. local inv = user:get_inventory()
  196. if inv:room_for_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""}) then
  197. inv:add_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""})
  198. end
  199. end
  200. end
  201. if not minetest.setting_getbool("creative_mode") then
  202. local tool_name = itemstack:get_name()
  203. itemstack:add_wear(65535/(uses-1))
  204. if itemstack:get_wear() == 0 and minetest.get_modpath("invtweak") then
  205. local index = user:get_wield_index()
  206. minetest.sound_play("invtweak_tool_break", {pos = user:getpos(), gain = 0.9, max_hear_distance = 5})
  207. minetest.after(0.20, refill, user, tool_name, index)
  208. end
  209. end
  210. return itemstack
  211. end
  212. -- didn't change the hoes, just here because hoe_on_use is local
  213. minetest.register_tool(":farming:hoe_wood", {
  214. description = fishing_setting.func.S("Wooden Hoe"),
  215. inventory_image = "farming_tool_woodhoe.png",
  216. on_use = function(itemstack, user, pointed_thing)
  217. return hoe_on_use(itemstack, user, pointed_thing, 30)
  218. end,
  219. })
  220. minetest.register_tool(":farming:hoe_stone", {
  221. description = fishing_setting.func.S("Stone Hoe"),
  222. inventory_image = "farming_tool_stonehoe.png",
  223. on_use = function(itemstack, user, pointed_thing)
  224. return hoe_on_use(itemstack, user, pointed_thing, 90)
  225. end,
  226. })
  227. minetest.register_tool(":farming:hoe_steel", {
  228. description = fishing_setting.func.S("Steel Hoe"),
  229. inventory_image = "farming_tool_steelhoe.png",
  230. on_use = function(itemstack, user, pointed_thing)
  231. return hoe_on_use(itemstack, user, pointed_thing, 200)
  232. end,
  233. })
  234. minetest.register_tool(":farming:hoe_bronze", {
  235. description = fishing_setting.func.S("Bronze Hoe"),
  236. inventory_image = "farming_tool_bronzehoe.png",
  237. on_use = function(itemstack, user, pointed_thing)
  238. return hoe_on_use(itemstack, user, pointed_thing, 220)
  239. end,
  240. })
  241. end