forth_combinator/control.lua
2024-11-24 23:43:23 -05:00

198 lines
5.7 KiB
Lua

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,
-- })