abm.lua 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. minetest.register_abm({
  2. -- change wetness of soil by time
  3. label = "Farming soil",
  4. nodenames = {"group:field"},
  5. interval = 15,
  6. chance = 4,
  7. action = function(pos, node)
  8. local starttime=os.clock()
  9. local n_def = minetest.registered_nodes[node.name] or nil
  10. if not n_def then
  11. return
  12. end
  13. local wet = n_def.soil.wet or nil
  14. local base = n_def.soil.base or nil
  15. local dry = n_def.soil.dry or nil
  16. if not n_def.soil or not wet or not base or not dry then
  17. return
  18. end
  19. -- pos.y = pos.y + 1
  20. local nn = minetest.get_node_or_nil({x=pos.x,y=pos.y+1,z=pos.z})
  21. if not nn or not nn.name then
  22. return
  23. end
  24. local nn_def = minetest.registered_nodes[nn.name] or nil
  25. -- pos.y = pos.y - 1
  26. if nn_def and nn_def.walkable and minetest.get_item_group(nn.name, "plant") == 0 then
  27. minetest.set_node(pos, {name = base})
  28. return
  29. end
  30. -- check if there is water nearby
  31. local wet_lvl = minetest.get_item_group(node.name, "wet")
  32. if minetest.find_node_near(pos, 3, {"group:water"}) then
  33. -- if it is dry soil and not base node, turn it into wet soil
  34. if wet_lvl == 0 then
  35. minetest.set_node(pos, {name = wet})
  36. end
  37. else
  38. -- only turn back if there are no unloaded blocks (and therefore
  39. -- possible water sources) nearby
  40. if not minetest.find_node_near(pos, 3, {"ignore"}) then
  41. -- turn it back into base if it is already dry
  42. if wet_lvl == 0 then
  43. -- only turn it back if there is no plant/seed on top of it
  44. if minetest.get_item_group(nn.name, "plant") == 0 and minetest.get_item_group(nn.name, "seed") == 0 then
  45. minetest.set_node(pos, {name = base})
  46. end
  47. -- if its wet turn it back into dry soil
  48. elseif wet_lvl == 1 then
  49. minetest.set_node(pos, {name = dry})
  50. end
  51. end
  52. end
  53. -- table.insert(farming.time_farming,1000*(os.clock()-starttime))
  54. end,
  55. })
  56. minetest.register_abm({
  57. -- infect plants
  58. label="crops getting ill",
  59. nodenames="group:infectable",
  60. intervall = 120,
  61. change=50,
  62. action = function(pos)
  63. local starttime=os.clock()
  64. local node=minetest.get_node(pos)
  65. if node.name == "air" or node.name == "ignore" then
  66. return
  67. end
  68. local ndef = minetest.registered_nodes[node.name]
  69. if ndef.groups.infectable == nil then
  70. return
  71. end
  72. local meta = minetest.get_meta(pos)
  73. local ill_rate=meta:get_int("farming:weakness")
  74. if ill_rate == nil then
  75. return
  76. else
  77. if ill_rate >0 then
  78. else
  79. ill_rate = 5
  80. end
  81. end
  82. if math.random(1,ill_rate)==1 then
  83. farming.plant_infect(pos)
  84. end
  85. -- table.insert(farming.time_ill,1000*(os.clock()-starttime))
  86. end
  87. })
  88. minetest.register_abm({
  89. label="Planting crops",
  90. nodenames = farming.change_soil,
  91. neighbors = {"air","group:grass","group:dry_grass"},
  92. interval = farming.abm_planting+math.random(-1,1), -- little noise
  93. chance = farming.abm_planting_chance,
  94. action = function(pos)
  95. -- local starttime=os.clock()
  96. local ptabove={x=pos.x,y=pos.y+1,z=pos.z}
  97. local above = minetest.get_node(ptabove)
  98. if above.name ~= "air" then
  99. if (minetest.get_item_group(above.name, "grass")==0) or (minetest.get_item_group(above.name, "dry_grass")==0) then
  100. return
  101. end
  102. end
  103. local ptlight=minetest.get_node_light(ptabove)
  104. if ptlight < farming.min_light then
  105. return
  106. end
  107. local ptlight=minetest.get_node_light(ptabove,.5)
  108. if ptlight < farming.min_light then
  109. return
  110. end
  111. -- only for positions, where not too many plants are nearby
  112. -- first check if any crops are nearby, because the counting
  113. -- of nearby crops is time consuming
  114. if minetest.find_node_near(pos,4,"group:farming") ~= nil then
  115. local count_crops=farming.abm_near_rarity*#minetest.find_nodes_in_area(vector.subtract(pos,4),vector.add(pos,4),"group:farming")
  116. if math.random(1,math.ceil(count_crops)) > 1 then
  117. return
  118. end
  119. end
  120. local node_y=pos.y
  121. local sc={}
  122. for _,line in ipairs(farming.spreading_crops) do
  123. if line.y_min<=node_y and line.y_max>=node_y then
  124. local node_temp=minetest.get_heat(pos)
  125. if line.temp_min<=node_temp and line.temp_max>=node_temp then
  126. local node_hum=minetest.get_humidity(pos)
  127. if line.hum_min<=node_hum and line.hum_max>=node_hum then
  128. if line.light_min<ptlight and line.light_max >= ptlight then
  129. for k=1,line.base_rate do
  130. table.insert(sc,line.name)
  131. end
  132. end
  133. end
  134. end
  135. end
  136. end
  137. if #sc > 0 then
  138. local setplant=sc[math.random(1,#sc)]
  139. minetest.add_node(ptabove, {name=setplant,param2=1})
  140. minetest.get_node_timer(ptabove):start(math.random(10, 15))
  141. farming.set_node_metadata(ptabove)
  142. end
  143. -- table.insert(farming.time_planting,1000*(os.clock()-starttime))
  144. end,
  145. })
  146. -- for optimisation only
  147. --minetest.register_on_shutdown(function()
  148. --[[
  149. for _,colu in ipairs({"time_plantinfect","time_plantcured","time_plantpunch","time_planting","time_ill","time_farming",
  150. "time_digharvest","time_steptimer","time_infect","time_seedtimer","time_wilttimer",
  151. "time_tooldig","time_usehook","time_calclight","time_placeseed","time_setmeta"}) do
  152. if (#farming[colu] > 0 ) then
  153. local tv=farming[colu]
  154. table.sort(tv)
  155. print(colu.." "..tv[math.ceil(#tv*0.25)].." - "..tv[math.ceil(#tv*0.5)].." - "..tv[math.ceil(#tv*0.75)])
  156. end
  157. end
  158. ]]
  159. --end)
  160. --[[
  161. for _,colu in ipairs({"time_plantinfect","time_plantcured","time_plantpunch","time_planting","time_ill","time_farming",
  162. "time_digharvest","time_steptimer","time_infect","time_seedtimer","time_wilttimer",
  163. "time_tooldig","time_usehook","time_placeseed","time_calclight","time_setmeta"}) do
  164. farming[colu]={}
  165. end
  166. ]]