Advertisement
llVIU

infinity_chest_v1

Sep 19th, 2019
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.46 KB | None | 0 0
  1. local Event = require "utils.event"
  2. local Global = require "utils.global"
  3. local sizeof = require "utils.sizeof"
  4. local validate_player = require "utils.validate_player"
  5.  
  6. local infinity_chests_storage = {}
  7. local infinity_chests = {}
  8. local infinity_chests_modes = {}
  9. local infinity_chest_gui = {}
  10.  
  11. Global.register({
  12. infinity_chests = infinity_chests,
  13. infinity_chests_modes = infinity_chests_modes,
  14. infinity_chest_gui = infinity_chest_gui,
  15. infinity_chests_storage = infinity_chests_storage
  16. },function(global)
  17. infinity_chests = global.infinity_chests
  18. infinity_chest_gui = global.infinity_chest_gui
  19. infinity_chests_storage = global.infinity_chests_storage
  20. infinity_chests_modes = global.infinity_chests_modes
  21. end)
  22.  
  23. local function built_entity(event)
  24. local entity = event.created_entity
  25. if not entity.valid then return end
  26. if entity.name ~= "infinity-chest" then return end
  27. entity.active = false
  28. infinity_chests[entity.unit_number] = entity
  29. rendering.draw_text{
  30. text = "♾",
  31. surface = entity.surface,
  32. target = entity,
  33. target_offset = {0, -0.6},
  34. scale = 2,
  35. color = { r = 0, g = 0.6, b = 1},
  36. alignment = "center"
  37. }
  38. end
  39.  
  40. local function mined_entity(event)
  41. local entity = event.entity
  42. if entity.name ~= "infinity-chest" then return end
  43. infinity_chests[entity.unit_number] = nil
  44. infinity_chests_storage[entity.unit_number] = nil
  45. infinity_chests_modes[entity.unit_number] = nil
  46. end
  47.  
  48.  
  49. local function item(item_name, item_count, inv, unit_number)
  50.  
  51. local item_stack = game.item_prototypes[item_name].stack_size
  52. local diff = item_count - item_stack
  53.  
  54. if not infinity_chests_storage[unit_number] then
  55. infinity_chests_storage[unit_number] = {}
  56. end
  57. local storage = infinity_chests_storage[unit_number]
  58.  
  59. local mode = infinity_chests_modes[unit_number]
  60. if mode == 2 then
  61. diff = 2^31
  62. end
  63.  
  64. if diff > 0 then
  65. local count = inv.remove({ name = item_name, count = diff})
  66. if not storage[item_name] then
  67. infinity_chests_storage[unit_number][item_name] = count
  68. else
  69. infinity_chests_storage[unit_number][item_name] = storage[item_name] + count
  70. end
  71. elseif diff < 0 then
  72. if not storage[item_name] then return end
  73. if storage[item_name] > (diff * -1) then
  74. local inserted = inv.insert({ name = item_name, count = (diff * -1)})
  75. infinity_chests_storage[unit_number][item_name] = storage[item_name] - inserted
  76. else
  77. inv.insert({ name = item_name, count = storage[item_name]})
  78. infinity_chests_storage[unit_number][item_name] = nil
  79. end
  80. end
  81.  
  82. end
  83.  
  84. local function update_chest(chest)
  85. for unit_number, chest in pairs(infinity_chests) do
  86. if not chest.valid then goto continue end
  87. local inv = chest.get_inventory(defines.inventory.chest)
  88. local content = inv.get_contents()
  89.  
  90. local mode = infinity_chests_modes[chest.unit_number]
  91. if mode then
  92. if mode == 1 then
  93. inv.setbar()
  94. else
  95. inv.setbar(1)
  96. end
  97. end
  98.  
  99.  
  100.  
  101. if sizeof(content) == 0 then
  102. chest.destructible = true
  103. chest.minable = true
  104. else
  105. chest.destructible = false
  106. chest.minable = false
  107. end
  108.  
  109. for item_name, item_count in pairs(content) do
  110. item(item_name, item_count, inv, unit_number)
  111. end
  112.  
  113. local storage = infinity_chests_storage[unit_number]
  114. if not storage then goto continue end
  115. for item_name, item_count in pairs(infinity_chests_storage[unit_number]) do
  116. if not content[item_name] then
  117. item(item_name, 0, inv, unit_number)
  118. end
  119. end
  120.  
  121. ::continue::
  122. end
  123. end
  124.  
  125. local function gui_opened(event)
  126.  
  127. if not event.gui_type == defines.gui_type.entity then return end
  128. local entity = event.entity
  129. if not entity then return end
  130. if not entity.valid or entity.name ~= 'infinity-chest' then return end
  131. local player = game.players[event.player_index]
  132. local frame = player.gui.center.add{ type = "frame", caption = "Infinity Chest", direction = "vertical", name = entity.unit_number}
  133. local controls = frame.add{ type = "flow", direction = "horizontal"}
  134. local items = frame.add{ type = "flow", direction = "vertical"}
  135.  
  136. local mode = infinity_chests_modes[entity.unit_number]
  137. local selected = mode and mode or 1
  138.  
  139. local tbl = controls.add{ type = "table", column_count = 2}
  140. tbl.add{ type = "label", caption = "Mode: " }
  141. local drop_down = tbl.add{ type = "drop-down", items = {"Automatic", "Manual"}, selected_index = selected, name = entity.unit_number }
  142. infinity_chests_modes[entity.unit_number] = drop_down.selected_index
  143.  
  144. player.opened = frame
  145. infinity_chest_gui[player.name] = {
  146. item_frame = items,
  147. frame = frame,
  148. entity = entity,
  149. updated = false
  150. }
  151. end
  152.  
  153. local function update_gui()
  154. for _, player in pairs(game.connected_players) do
  155.  
  156. local chest_gui_data = infinity_chest_gui[player.name]
  157. if not chest_gui_data then goto continue end
  158. local frame = chest_gui_data.item_frame
  159. local entity = chest_gui_data.entity
  160. if not frame then goto continue end
  161. if not entity or not entity.valid then goto continue end
  162. local mode = infinity_chests_modes[entity.unit_number]
  163. if mode == 2 and infinity_chest_gui[player.name].updated then goto continue end
  164. frame.clear()
  165.  
  166. local tbl = frame.add{ type = "table", column_count = 10, name = "infinity_chest_inventory" }
  167. local total = 0
  168. local items = {}
  169.  
  170. local storage = infinity_chests_storage[entity.unit_number]
  171.  
  172. if not storage then goto no_storage end
  173. for item_name, item_count in pairs(storage) do
  174. total = total +1
  175. items[item_name] = item_count
  176. end
  177. ::no_storage::
  178.  
  179. local inv = entity.get_inventory(defines.inventory.chest)
  180. local content = inv.get_contents()
  181.  
  182. for item_name, item_count in pairs(content) do
  183. if not items[item_name] then
  184. total = total + 1
  185. items[item_name] = item_count
  186. else
  187. items[item_name] = items[item_name] + item_count
  188. end
  189. end
  190.  
  191.  
  192. for item_name, item_count in pairs(items) do
  193. local btn = tbl.add{ type = "sprite-button", sprite = "item/"..item_name ,style = "slot_button", number = item_count, name = item_name}
  194. end
  195.  
  196. while total < 48 do
  197.  
  198. local btn = tbl.add{ type = "sprite-button", style = "slot_button"}
  199. btn.enabled = false
  200.  
  201. total = total + 1
  202. end
  203.  
  204. infinity_chest_gui[player.name].updated = true
  205. ::continue::
  206. end
  207.  
  208. end
  209.  
  210.  
  211. local function gui_closed(event)
  212. local player = game.players[event.player_index]
  213. local type = event.gui_type
  214.  
  215. if type == defines.gui_type.custom then
  216. local data = infinity_chest_gui[player.name]
  217. if not data then return end
  218. data.frame.destroy()
  219. infinity_chest_gui[player.name] = nil
  220. end
  221. end
  222.  
  223. local function state_changed(event)
  224. local player = event.player
  225. local element = event.element
  226. local unit_number = tonumber(element.name)
  227. infinity_chests_modes[unit_number] = element.selected_index
  228. local chest = infinity_chests[unit_number]
  229. end
  230.  
  231. local function gui_click(event)
  232. local element = event.element
  233. local player = game.players[event.player_index]
  234. if not validate_player(player) then return end
  235. if not element.valid then return end
  236. local parent = element.parent
  237. if not parent then return end
  238. if parent.name ~= "infinity_chest_inventory" then return end
  239. local unit_number = tonumber(parent.parent.parent.name)
  240. if tonumber(element.name) == unit_number then return end
  241.  
  242.  
  243. local shift = event.shift
  244. local ctrl = event.control
  245. local name = element.name
  246. local storage = infinity_chests_storage[unit_number]
  247.  
  248. if ctrl then
  249. local count = storage[name]
  250. local inserted = player.insert{ name = name, count = count}
  251. if inserted == count then
  252. infinity_chests_storage[unit_number][name] = nil
  253. else
  254. infinity_chests_storage[unit_number][name] = infinity_chests_storage[unit_number][name] - inserted
  255. end
  256. elseif shift then
  257. local count = storage[name]
  258. local stack = game.item_prototypes[name].stack_size
  259.  
  260. if count > stack then
  261. local inserted = player.insert{ name = name, count = stack}
  262. infinity_chests_storage[unit_number][name] = infinity_chests_storage[unit_number][name] - inserted
  263. else
  264. player.insert{ name = name, count = count}
  265. infinity_chests_storage[unit_number][name] = nil
  266. end
  267. else
  268. player.insert{ name = name, count = 1 }
  269. infinity_chests_storage[unit_number][name] = infinity_chests_storage[unit_number][name] - 1
  270. if infinity_chests_storage[unit_number][name] <= 0 then
  271. infinity_chests_storage[unit_number][name] = nil
  272. end
  273. end
  274.  
  275.  
  276. for _, p in pairs(game.connected_players) do
  277. if infinity_chest_gui[p.name] then
  278. infinity_chest_gui[p.name].updated = false
  279. end
  280. end
  281. end
  282.  
  283. local function tick()
  284. update_chest()
  285. update_gui()
  286. end
  287.  
  288. Event.register(defines.events.on_tick, tick)
  289. Event.register(defines.events.on_gui_click, gui_click)
  290. Event.register(defines.events.on_gui_opened, gui_opened)
  291. Event.register(defines.events.on_gui_closed, gui_closed)
  292. Event.register(defines.events.on_built_entity, built_entity)
  293. Event.register(defines.events.on_robot_built_entity, built_entity)
  294. Event.register(defines.events.on_player_mined_entity, mined_entity)
  295. Event.register(defines.events.on_gui_selection_state_changed, state_changed)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement