repairman.lua 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. local function repairman_overview(obj)
  2. local formspec =
  3. kobo.unit_inv..
  4. 'textarea[3.25,0;7.5,1;;;repairman]'..
  5. 'image[0,0;3,3;kobo_repairman_snap.png]'..
  6. 'textarea[3.25,.75;7.5,2.25;;;repairman state: '..obj.state..'.]'..
  7. 'image[0,4.5;3,.25;kobo_inv_fg.png]'
  8. return formspec
  9. end
  10. core.register_entity('kobo:repairman', {
  11. initial_properties = {
  12. visual = 'mesh',
  13. mesh = 'kobo_worker.obj',
  14. visual_size = {x=10, y=10},
  15. physical = true,
  16. collide_with_objects = false,
  17. collisionbox = {-.125, -.5, -.125, .125, 0, .125},
  18. textures = {'kobo_repairman.png'},
  19. automatic_face_movement_dir = 0.0,
  20. },
  21. on_activate = function(self, staticdata, dtime_s)
  22. local data = core.deserialize(staticdata)
  23. if data then
  24. self.node_timer = data.node_timer
  25. self.owner = data.owner
  26. self.home = data.home
  27. self.state = data.state
  28. self.path = data.path
  29. self.step = data.step
  30. self.last_job = data.last_job
  31. end
  32. end,
  33. get_staticdata = function(self)
  34. local data ={}
  35. data.node_timer = self.node_timer
  36. data.owner = self.owner
  37. data.home = self.home
  38. data.state = self.state
  39. data.path = self.path
  40. data.step = self.step
  41. data.last_job = self.last_job
  42. return core.serialize(data)
  43. end,
  44. on_step = function(self, dtime, moveresults)
  45. self.node_timer = (self.node_timer or 0) + dtime
  46. if self.node_timer > 1 then
  47. self.node_timer = 0
  48. if self.state == 'idle' then --Find the lazybones some work.
  49. local self_pos = self.object:get_pos()
  50. local node = core.get_node(self_pos)
  51. local repair = core.find_node_near(self_pos, 10, 'kobo:repair')
  52. if repair then
  53. local def = core.registered_nodes[node.name]
  54. if def.walkable then
  55. self_pos = vector.add(self_pos, {x=0, y=1, z=0})
  56. end
  57. local path = core.find_path(self_pos, repair, 5, 1, 1)
  58. if path then
  59. self.path = path
  60. self.step = 2
  61. self.state = 'traveling'
  62. else --Make the unit wander around for a while.
  63. self.state = 'idle'
  64. end
  65. else
  66. local buildings = core.find_node_near(self_pos, 10, 'group:storage')
  67. if buildings then
  68. local def = core.registered_nodes[node.name]
  69. if def.walkable then
  70. self_pos = vector.add(self_pos, {x=0, y=1, z=0})
  71. end
  72. local path = core.find_path(self_pos, vector.add(buildings, {x=0, y=1, z=0}), 5, 1, 1)
  73. if path then
  74. self.path = path
  75. self.step = 2
  76. self.state = 'traveling'
  77. end
  78. else
  79. self.state = 'idle'
  80. end
  81. end
  82. elseif self.state == 'traveling' then
  83. if #self.path > (self.step - 1) then
  84. local pos = self.object:get_pos()
  85. local perhaps = vector.direction(pos, self.path[self.step])
  86. self.object:set_velocity({x = perhaps.x, y = 0, z = perhaps.z})
  87. self.step = self.step + 1
  88. else
  89. local self_pos = vector.round(self.object:get_pos())
  90. local repair = core.find_node_near(self_pos, 1, 'kobo:repair', true)
  91. if repair then
  92. self.object:set_velocity({x=0, y=0, z=0})
  93. self.state = 'working'
  94. self.last_job = repair
  95. else
  96. self.state = 'idle'
  97. end
  98. end
  99. elseif self.state == 'working' then
  100. local node = core.get_node(self.last_job)
  101. if core.get_item_group(node.name, 'player_building') > 0 then
  102. local meta = core.get_meta(self.last_job)
  103. local health = meta:get_int('health')
  104. local def = core.registered_nodes[node.name]
  105. local max_health = def._health
  106. if health < max_health then
  107. local resources = kobo.resources[self.owner]
  108. if resources.metal >= 1 then
  109. meta:set_int('health', math.min(health + 5, max_health))
  110. resources.metal = resources.metal - 1
  111. local player = core.get_player_by_name(self.owner)
  112. kobo.hud_refresh(player)
  113. end
  114. else
  115. self.state = 'idle'
  116. end
  117. else
  118. local repair_pos = vector.add(self.last_job, {x=0, y=1, z=0})
  119. core.remove_node(self.last_job)
  120. self.state = 'idle'
  121. end
  122. end
  123. elseif moveresults.collides then
  124. local hit_node = moveresults.collisions[1] and moveresults.collisions[1].type == 'node'
  125. if hit_node then
  126. local node_pos = moveresults.collisions[1].node_pos
  127. local node = core.get_node(node_pos)
  128. if core.get_item_group(node.name, 'player_building') > 0 then
  129. local meta = core.get_meta(node_pos)
  130. local health = meta:get_int('health')
  131. local def = core.registered_nodes[node.name]
  132. local max_health = def._health
  133. if health < max_health then
  134. self.last_job = node_pos
  135. self.state = 'working'
  136. self.object:set_velocity({x=0, y=0, z=0})
  137. else
  138. local repair_pos = vector.add(node_pos, {x=0, y=1, z=0})
  139. core.remove_node(repair_pos)
  140. end
  141. end
  142. end
  143. end
  144. end,
  145. on_rightclick = function(self, clicker)
  146. local player_name = clicker:get_player_name()
  147. if self.owner == player_name or core.check_player_privs(clicker, {server = true}) then
  148. core.show_formspec(player_name, 'kobo:repairman_overview', repairman_overview(self))
  149. end
  150. end,
  151. })