couriers.lua 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. local function courier_overview(obj)
  2. local scale = (obj.inv/30) * 3
  3. local formspec =
  4. kobo.unit_inv..
  5. 'textarea[3.25,0;7.5,1;;;Courier]'..
  6. 'image[0,0;3,3;kobo_courier_snap.png]'..
  7. 'textarea[3.25,.75;7.5,2.25;;;Courier state: '..obj.state..'.\n'..
  8. 'Courier inventory: '..obj.inv..' '..obj.mat..'.]'..
  9. 'image[0,4.5;'..scale..',.25;kobo_inv_fg.png]'
  10. return formspec
  11. end
  12. core.register_entity('kobo:courier', {
  13. initial_properties = {
  14. visual = 'mesh',
  15. mesh = 'kobo_worker.obj',
  16. visual_size = {x=10, y=10},
  17. physical = true,
  18. collide_with_objects = false,
  19. collisionbox = {-.125, -.5, -.125, .125, 0, .125},
  20. textures = {'kobo_courier.png'},
  21. automatic_face_movement_dir = 0.0,
  22. },
  23. on_activate = function(self, staticdata, dtime_s)
  24. local data = core.deserialize(staticdata)
  25. if data then
  26. self.node_timer = data.node_timer
  27. self.owner = data.owner
  28. self.home = data.home
  29. self.state = data.state
  30. self.path = data.path
  31. self.step = data.step
  32. self.inv = data.inv
  33. self.last_job = data.last_job
  34. self.mat = data.mat
  35. end
  36. end,
  37. get_staticdata = function(self)
  38. local data ={}
  39. data.node_timer = self.node_timer
  40. data.owner = self.owner
  41. data.home = self.home
  42. data.state = self.state
  43. data.path = self.path
  44. data.step = self.step
  45. data.inv = self.inv
  46. data.last_job = self.last_job
  47. data.mat = self.mat
  48. return core.serialize(data)
  49. end,
  50. on_step = function(self, dtime, moveresults)
  51. self.node_timer = (self.node_timer or 0) + dtime
  52. if self.node_timer > 1 then
  53. self.node_timer = 0
  54. if self.state == 'idle' then --Find the lazybones some work.
  55. if self.inv >= 1 then
  56. local self_pos = self.object:get_pos()
  57. local node = core.get_node(self_pos)
  58. local def = core.registered_nodes[node.name]
  59. if def.walkable then
  60. self_pos = vector.add(self_pos, {x=0, y=1, z=0})
  61. end
  62. local storage_point = core.find_node_near(self_pos, 10, 'group:storage')
  63. if storage_point then
  64. local path = core.find_path(self_pos, vector.add(storage_point, {x=0, y=1, z=0}), 5, 1, .75)
  65. if path then
  66. self.path = path
  67. self.step = 2
  68. self.state = 'traveling'
  69. end
  70. end
  71. else
  72. local last_job = self.last_job
  73. if not last_job then
  74. local self_pos = self.object:get_pos()
  75. local pos1 = vector.add(self_pos, {x=-10, y=0, z=-10})
  76. local pos2 = vector.add(self_pos, {x=10, y=0, z=10})
  77. local col_point = core.find_nodes_in_area(pos1, pos2, 'group:collector')
  78. if #col_point >= 1 then
  79. local pick = math.random(1, #col_point)
  80. local meta = core.get_meta(col_point[pick])
  81. local inventory = meta:get_int('inventory')
  82. if inventory >= 30 then
  83. local node = core.get_node(self_pos)
  84. local def = core.registered_nodes[node.name]
  85. if def.walkable then
  86. self_pos = vector.add(self_pos, {x=0, y=1, z=0})
  87. end
  88. local path = core.find_path(self_pos, vector.add(col_point[pick], {x=0, y=1, z=0}), 5, 1, 1)
  89. if path then
  90. self.path = path
  91. self.step = 2
  92. self.state = 'traveling'
  93. end
  94. else --Make the unit wander around for a while.
  95. self.state = 'idle'
  96. end
  97. end
  98. else
  99. local meta = core.get_meta(last_job)
  100. local inventory = meta:get_int('inventory')
  101. if inventory >= 30 then
  102. local self_pos = self.object:get_pos()
  103. local node = core.get_node(self_pos)
  104. local def = core.registered_nodes[node.name]
  105. if def.walkable then
  106. self_pos = vector.add(self_pos, {x=0, y=1, z=0})
  107. end
  108. local path = core.find_path(self_pos, vector.add(last_job, {x=0, y=1, z=0}), 5, 1, 1)
  109. if path then
  110. self.path = path
  111. self.step = 1
  112. self.state = 'traveling'
  113. end
  114. else --Make the unit wander around for a while.
  115. self.last_job = nil
  116. self.state = 'idle'
  117. end
  118. end
  119. end
  120. elseif self.state == 'traveling' then
  121. if #self.path > (self.step - 1) then
  122. local pos = self.object:get_pos()
  123. local perhaps = vector.direction(pos, self.path[self.step])
  124. self.object:set_velocity({x = perhaps.x, y = 0, z = perhaps.z})
  125. self.step = self.step + 1
  126. else
  127. local self_pos = vector.round(self.object:get_pos())
  128. local collection_spot = core.find_node_near(self_pos, 1, 'group:collector', true)
  129. if collection_spot then
  130. local node = core.get_node(collection_spot)
  131. local def = core.registered_nodes[node.name]
  132. local material = def._material
  133. self.object:set_velocity({x=0, y=0, z=0})
  134. self.last_job = collection_spot
  135. self.mat = material
  136. self.state = 'working'
  137. elseif core.find_node_near(self_pos, 1, 'group:storage', true) then
  138. local resources = kobo.resources[self.owner]
  139. if self.mat == 'food' then
  140. resources.food = resources.food + self.inv
  141. elseif self.mat == 'lumber' then
  142. resources.lumber = resources.lumber + self.inv
  143. elseif self.mat == 'metal' then
  144. resources.metal = resources.metal + self.inv
  145. elseif self.mat == 'stone' then
  146. resources.stone = resources.stone + self.inv
  147. end
  148. self.inv = 0
  149. local player = core.get_player_by_name(self.owner)
  150. kobo.hud_refresh(player)
  151. self.state = 'idle'
  152. else
  153. self.state = 'idle'
  154. end
  155. end
  156. elseif self.state == 'working' then
  157. local inventory_count = self.inv
  158. if inventory_count <= 20 then
  159. local pos = self.last_job
  160. local meta = core.get_meta(pos)
  161. local inventory = meta:get_int('inventory')
  162. if inventory >= 10 then
  163. meta:set_int('inventory', inventory - 10)
  164. self.inv = self.inv + 10
  165. elseif inventory == 0 then
  166. self.state = 'idle'
  167. end
  168. else
  169. local self_pos = self.object:get_pos()
  170. local storage_point = core.find_node_near(self_pos, 10, 'group:storage')
  171. if storage_point then
  172. local node = core.get_node(self_pos)
  173. local def = core.registered_nodes[node.name]
  174. if def.walkable then
  175. self_pos = vector.add(self_pos, {x=0, y=1, z=0})
  176. end
  177. local path = core.find_path(self_pos, vector.add(storage_point, {x=0, y=1, z=0}), 5, 1, 1)
  178. if path then
  179. self.path = path
  180. self.step = 2
  181. self.state = 'traveling'
  182. else --Make the unit wander around for a while.
  183. self.state = 'idle'
  184. end
  185. else
  186. self.state = 'idle'
  187. end
  188. end
  189. end
  190. elseif moveresults.collides then
  191. local hit_node = moveresults.collisions[1] and moveresults.collisions[1].type == 'node'
  192. if hit_node then
  193. local node_pos = moveresults.collisions[1].node_pos
  194. local node = core.get_node(node_pos)
  195. if core.get_item_group(node.name, 'storage') > 0 then
  196. local resources = kobo.resources[self.owner]
  197. if self.mat == 'food' then
  198. resources.food = resources.food + self.inv
  199. elseif self.mat == 'lumber' then
  200. resources.lumber = resources.lumber + self.inv
  201. elseif self.mat == 'metal' then
  202. resources.metal = resources.metal + self.inv
  203. elseif self.mat == 'stone' then
  204. resources.stone = resources.stone + self.inv
  205. end
  206. self.inv = 0
  207. self.state = 'idle'
  208. local player = core.get_player_by_name(self.owner)
  209. kobo.hud_refresh(player)
  210. elseif core.get_item_group(node.name, 'collector') > 0 then
  211. local node_pos = moveresults.collisions[1].node_pos
  212. local node = core.get_node(node_pos)
  213. local def = core.registered_nodes[node.name]
  214. local material = def._material
  215. self.object:set_velocity({x=0, y=0, z=0})
  216. self.last_job = node_pos
  217. self.mat = material
  218. self.state = 'working'
  219. end
  220. end
  221. end
  222. end,
  223. on_rightclick = function(self, clicker)
  224. local player_name = clicker:get_player_name()
  225. if self.owner == player_name or core.check_player_privs(clicker, {server = true}) then
  226. core.show_formspec(player_name, 'kobo:courier_overview', courier_overview(self))
  227. end
  228. end,
  229. })