seek.lua 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. function pm.seek_flammable_node(self, pos)
  2. local minp = vector.add(pos, {x=-8, y=-8, z=-8})
  3. local maxp = vector.add(pos, {x=8, y=8, z=8})
  4. local positions = minetest.find_nodes_in_area_under_air(minp, maxp, "group:flammable")
  5. if #positions > 0 then
  6. local p2 = positions[math.random(1, #positions)]
  7. if not minetest.test_protection(p2, "") then
  8. return p2, nil
  9. end
  10. end
  11. return nil, nil
  12. end
  13. function pm.seek_player_or_mob_or_item(self, pos)
  14. local all = pm.get_nearby_objects(self, pos, pm.sight_range)
  15. -- Filter out anything that isn't a player or mob or dropped item.
  16. local objects = {}
  17. for i=1, #all, 1 do
  18. if all[i]:is_player() and all[i]:get_hp() > 0 then
  19. if not gdac.player_is_admin(all[i]) then
  20. objects[#objects+1] = all[i]
  21. end
  22. else
  23. local ent = all[i]:get_luaentity()
  24. if ent then
  25. if ent.mob or ent.name == "__builtin:item" then
  26. objects[#objects+1] = all[i]
  27. end
  28. end
  29. end
  30. end
  31. if #objects > 0 then
  32. return nil, objects[math.random(1, #objects)]
  33. end
  34. return nil, nil
  35. end
  36. function pm.seek_player_or_mob(self, pos)
  37. local all = pm.get_nearby_objects(self, pos, pm.sight_range)
  38. -- Filter out anything that isn't a player or mob or dropped item.
  39. local objects = {}
  40. for i=1, #all, 1 do
  41. if all[i]:is_player() and all[i]:get_hp() > 0 then
  42. if not gdac.player_is_admin(all[i]) then
  43. objects[#objects+1] = all[i]
  44. end
  45. else
  46. local ent = all[i]:get_luaentity()
  47. if ent then
  48. if ent.mob then
  49. objects[#objects+1] = all[i]
  50. end
  51. end
  52. end
  53. end
  54. if #objects > 0 then
  55. return nil, objects[math.random(1, #objects)]
  56. end
  57. return nil, nil
  58. end
  59. function pm.seek_player_or_mob_not_wisp(self, pos)
  60. local all = pm.get_nearby_objects(self, pos, pm.sight_range)
  61. -- Filter out anything that isn't a player or mob or dropped item.
  62. local objects = {}
  63. for i=1, #all, 1 do
  64. if all[i]:is_player() and all[i]:get_hp() > 0 then
  65. if not gdac.player_is_admin(all[i]) then
  66. objects[#objects+1] = all[i]
  67. end
  68. else
  69. local ent = all[i]:get_luaentity()
  70. if ent then
  71. if ent.mob then
  72. if ent.name ~= "pm:follower" then
  73. objects[#objects+1] = all[i]
  74. end
  75. end
  76. end
  77. end
  78. end
  79. if #objects > 0 then
  80. return nil, objects[math.random(1, #objects)]
  81. end
  82. return nil, nil
  83. end
  84. function pm.seek_player_or_item(self, pos)
  85. local all = pm.get_nearby_objects(self, pos, pm.sight_range)
  86. -- Filter out anything that isn't a player or mob or dropped item.
  87. local objects = {}
  88. for i=1, #all, 1 do
  89. if all[i]:is_player() and all[i]:get_hp() > 0 then
  90. if not gdac.player_is_admin(all[i]) then
  91. objects[#objects+1] = all[i]
  92. end
  93. else
  94. local ent = all[i]:get_luaentity()
  95. if ent then
  96. if ent.name == "__builtin:item" then
  97. objects[#objects+1] = all[i]
  98. end
  99. end
  100. end
  101. end
  102. if #objects > 0 then
  103. return nil, objects[math.random(1, #objects)]
  104. end
  105. return nil, nil
  106. end
  107. function pm.seek_player(self, pos)
  108. local all = pm.get_nearby_objects(self, pos, pm.sight_range)
  109. -- Filter out anything that isn't a player or mob or dropped item.
  110. local objects = {}
  111. for i=1, #all, 1 do
  112. if all[i]:is_player() and all[i]:get_hp() > 0 then
  113. if not gdac.player_is_admin(all[i]) then
  114. objects[#objects+1] = all[i]
  115. end
  116. end
  117. end
  118. if #objects > 0 then
  119. return nil, objects[math.random(1, #objects)]
  120. end
  121. return nil, nil
  122. end
  123. function pm.seek_node_with_meta(self, pos)
  124. local minp = vector.add(pos, {x=-16, y=-8, z=-16})
  125. local maxp = vector.add(pos, {x=16, y=8, z=16})
  126. local positions = minetest.find_nodes_with_meta(minp, maxp)
  127. if positions then
  128. if #positions > 0 then
  129. local pos = positions[math.random(1, #positions)]
  130. local minp = vector.add(pos, {x=-1, y=-1, z=-1})
  131. local maxp = vector.add(pos, {x=1, y=1, z=1})
  132. local airs = minetest.find_nodes_in_area(minp, maxp, "air")
  133. if airs and #airs > 0 then
  134. return airs[math.random(1, #airs)], nil
  135. end
  136. end
  137. end
  138. return nil, nil
  139. end
  140. function pm.seek_wisp(self, pos)
  141. local all = pm.get_nearby_objects(self, pos, pm.sight_range)
  142. -- Filter out anything that isn't a player or mob or dropped item.
  143. local objects = {}
  144. for i=1, #all, 1 do
  145. local ent = all[i]:get_luaentity()
  146. if ent then
  147. if ent.mob and ent._name and ent._name == "pm:follower" then
  148. objects[#objects+1] = all[i]
  149. end
  150. end
  151. end
  152. if #objects > 0 then
  153. local wisp = objects[math.random(1, #objects)]
  154. local p = wisp:get_pos()
  155. p.y = p.y - 3 -- Keep communal wisps from following each other into the sky.
  156. return p, wisp
  157. end
  158. return nil, nil
  159. end
  160. function pm.seek_solitude(self, pos)
  161. local all = pm.get_nearby_objects(self, pos, pm.sight_range)
  162. -- Filter out anything that isn't a player or mob or dropped item.
  163. local objects = {}
  164. for i=1, #all, 1 do
  165. if all[i]:is_player() then
  166. objects[#objects+1] = all[i]
  167. else
  168. local ent = all[i]:get_luaentity()
  169. if ent then
  170. if ent.mob then
  171. objects[#objects+1] = all[i]
  172. end
  173. end
  174. end
  175. end
  176. if #objects > 0 then
  177. -- Calculate average center of the group.
  178. local center = {x=0, y=0, z=0}
  179. for k, v in ipairs(objects) do
  180. local p = v:get_pos()
  181. center.x = center.x + p.x
  182. center.y = center.y + p.y
  183. center.z = center.z + p.z
  184. end
  185. center.x = center.x / #objects
  186. center.y = center.y / #objects
  187. center.z = center.z / #objects
  188. -- Find/return position away from the center of the group.
  189. local dir = vector.subtract(pos, center)
  190. dir = vector.normalize(dir)
  191. dir = vector.multiply(dir, 10)
  192. local air = minetest.find_node_near(vector.add(pos, dir), 11, "air", true)
  193. -- Don't go flying when looking for solitude, stay near ground.
  194. if air then
  195. while minetest.get_node(vector.add(air, {x=0, y=-1, z=0})).name == "air" do
  196. air.y = air.y - 1
  197. end
  198. end
  199. return air, nil
  200. end
  201. return nil, nil
  202. end