require('forth') function init_storage() -- storage.valid = false if not storage.valid then storage.players = {} storage.computers = {} storage.guis = {} storage.valid = true end end function computer_for_ent(entity) for _, computer in pairs(storage.computers) do if computer.entity == entity then return computer end end return nil end script.on_event(defines.events.on_tick, function(event) init_storage() for _, computer in pairs(storage.computers) do for _=1,250 do local ok, result = pcall(forth_tick, computer.ctx) if ok and result then break end if not ok then game.print(result) computer.ctx = forth_initialize(computer.entity) end end if #computer.ctx.outbuf > 0 then local out = '' for i, v in pairs(computer.ctx.outbuf) do out = out..v end computer.screen = computer.screen..out computer.ctx.outbuf = {} end end for player_index, player in pairs(storage.players) do if player.opened_combinator then local computer = computer_for_ent(player.opened_combinator) local ui = game.get_player(player_index).gui.screen.forth_combinator_gui ui.forth_combinator_console.text = computer.screen end end end) script.on_event(defines.events.on_gui_text_changed, function(event) if not event.element or event.element.name ~= 'forth_combinator_editor' then return end local player = storage.players[event.player_index] player.curtext = event.element.text end) function create_ui(player, computer) local frame = player.gui.screen.add{type = "frame", name = "forth_combinator_gui", caption = "Console"} frame.force_auto_center() local editor = frame.add{type = 'text-box', name = 'forth_combinator_editor'} editor.style.minimal_height = 600 editor.style.minimal_width = 800 editor.style.maximal_height = 600 editor.style.maximal_width = 800 editor.text = computer.script local console = frame.add{type = 'text-box', name = 'forth_combinator_console'} console.style.minimal_height = 600 console.style.minimal_width = 400 console.style.maximal_height = 600 console.style.maximal_width = 400 console.text = computer.screen local run_button = frame.add{type = 'button', name = 'forth_combinator_run', caption = "Do Shit"} -- console.selectable = false return frame end script.on_event(defines.events.on_gui_opened, function(event) if not event.entity or event.entity.name ~= 'forth-combinator' then return end init_storage() local player = game.get_player(event.player_index) if not storage.players[event.player_index] then storage.players[event.player_index] = {} end if player.gui.screen.forth_combinator_gui then player.gui.screen.forth_combinator_gui.destroy() end if player.opened then player.opened = nil end player.opened = create_ui(player, computer_for_ent(event.entity)) storage.players[event.player_index].opened_combinator = event.entity end) script.on_event(defines.events.on_gui_closed, function(event) local player = game.get_player(event.player_index) if player.gui.screen.forth_combinator_gui then player.gui.screen.forth_combinator_gui.destroy() if storage.players[event.player_index] then storage.players[event.player_index].opened_combinator = nil end end end) script.on_event(defines.events.on_gui_click, function(event) local player = game.get_player(event.player_index) local entity = storage.players[event.player_index].opened_combinator if event.element.name == 'forth_combinator_run' then local computer = computer_for_ent(entity) if not computer then game.print('Invalid computer in gui click') return end computer.ctx = forth_initialize(entity) -- Hack, idc local text = storage.players[event.player_index].curtext for c in text:gmatch('.') do table.insert(computer.ctx.keybuf, string.byte(c)) end table.insert(computer.ctx.keybuf, 10) computer.screen = '' computer.script = text end end) function OnBuiltEntity(event) local entity = event.entity if entity.name ~= 'forth-combinator' then return end init_storage() local computer = { ctx = forth_initialize(entity), entity = entity, screen = '', script = '', } table.insert(storage.computers, computer) end function OnEntityDied(event) local entity = event.entity if entity.name ~= 'forth-combinator' then return end init_storage() local removals = {} for i, comp in pairs(storage.computers) do if comp.entity == entity then table.insert(removals, i) end end for _, i in pairs(removals) do table.remove(storage.computers, i) end end script.on_event(defines.events.on_built_entity, OnBuiltEntity) script.on_event(defines.events.on_robot_built_entity, OnBuiltEntity) -- script.on_event(defines.events.on_pre_ghost_deconstructed, OnPreGhostDeconstructed) script.on_event(defines.events.on_entity_died, OnEntityDied) script.on_event(defines.events.on_pre_player_mined_item, OnEntityDied) script.on_event(defines.events.on_robot_pre_mined, OnEntityDied) -- player.surface.create_entity({ -- name = 'laser-beam', -- position = entity.position, -- source_position = entity.position, -- target = player.position, -- })