| require "story" |
| require "advanced-signals" |
|
|
| function on_player_created(event) |
| local player = game.players[event.player_index] |
| player.game_view_settings = |
| { |
| show_side_menu = false, |
| show_research_info = false, |
| show_alert_gui = false, |
| show_minimap = false |
| } |
| game.permissions.get_group(0).set_allows_action(defines.input_action.remove_cables, false) |
| game.permissions.get_group(0).set_allows_action(defines.input_action.open_production_gui, false) |
| game.permissions.get_group(0).set_allows_action(defines.input_action.open_tips_and_tricks_gui, false) |
| game.permissions.get_group(0).set_allows_action(defines.input_action.open_logistic_gui, false) |
| game.permissions.get_group(0).set_allows_action(defines.input_action.open_technology_gui, false) |
| player.force.disable_all_prototypes() |
| end |
|
|
| local clear_vis = function() |
| |
| for _, id in pairs(global.render_ids) do |
| rendering.destroy(id) |
| end |
| end |
|
|
| local add_train_label = function(backer_tag,label_text,color) |
| local loco = nil |
| for _, train in pairs(surface().find_entities_filtered({name='locomotive'})) do |
| if train.backer_name == backer_tag then |
| loco = train |
| end |
| end |
| if loco then |
| loco.color = {r=1,g=0.6,b=0,a=0.5} |
| game.print('adding label') |
| local label_id = rendering.draw_text({ |
| surface = loco.surface, |
| target = loco, |
| color = {1,1,1}, |
| text = "red train", |
| offset = {0,-2} |
| }) |
| table.insert(global.render_ids,label_id) |
| end |
| end |
|
|
| local add_train_labels = function(trains) |
| for _, train in pairs(trains) do |
| local ent = surface().find_entities_filtered({name='locomotive',position=train.position}) |
| if ent then |
| game.print('adding label') |
| local label_id = rendering.draw_text({ |
| surface = surface(), |
| target = ent, |
| color = {1,1,1}, |
| text = "red train", |
| offset = {0,-2} |
| }) |
| table.insert(global.render_ids,label_id) |
| end |
| end |
| end |
|
|
| local add_labels = function(label_data) |
| for _, data in pairs(label_data) do |
| local matching_ents = surface().find_entities_filtered({name=data.entity,position=data.position}) |
| if #matching_ents>0 then |
| for _, ent in pairs(matching_ents) do |
| local label_id = rendering.draw_text({ |
| surface = surface(), |
| target = ent, |
| color = {1,1,1}, |
| text = {"label."..data.locale}, |
| target_offset = {0,1}, |
| alignment = 'center' |
| }) |
| table.insert(global.render_ids,label_id) |
| end |
| end |
| end |
| end |
|
|
| story_table = |
| { |
| { |
| { |
| init = function() |
| global.render_ids = {} |
| for k, entity in pairs (surface().find_entities()) do |
| if entity.name == "locomotive" then |
| entity.insert"coal" |
| end |
| entity.minable = false |
| entity.operable = false |
| entity.rotatable = false |
| end |
| player().character.destroy() |
| player().set_quick_bar_slot(1,'rail-chain-signal') |
| player().set_quick_bar_slot(2,'rail-signal') |
| player().game_view_settings = {show_rail_block_visualisation = true} |
| end |
| }, |
| { |
| init = function() |
| clear_vis() |
| set_goal("", false) |
| set_info({text = {"chain-green"}}) |
| set_info({custom_function = add_run_trains_button, append = true}) |
| find_gui_recursive(player().gui, "reset_all").destroy() |
| set_continue_button_style(function (button) |
| if button.valid then |
| button.enabled = true |
| end |
| end) |
| clear_surface() |
| global.this_puzzle = setup.chain_green.entities |
| global.this_puzzle_param = nil |
| global.this_puzzle_labels = {} |
| global.this_puzzle_trains = {} |
| for k, entity in pairs (global.this_puzzle) do |
| entity.minable = false |
| entity.operable = false |
| if entity.name == "locomotive" then |
| if entity.schedule then |
| entity.manual_mode = true |
| end |
| table.insert(global.this_puzzle_trains, entity) |
| end |
| if entity.label then |
| print("found ent with label "..entity.name) |
| table.insert(global.this_puzzle_labels,{ |
| name = entity.name, |
| position = entity.position, |
| locale = entity.label |
| }) |
| end |
| end |
| recreate_entities(global.this_puzzle) |
| loop_trains(0) |
| add_labels(global.this_puzzle_labels) |
| end, |
| condition = function() |
| return global.continue |
| end |
| }, |
| { |
| init = function() |
| set_goal("", false) |
| set_info({text = {"chain-blue-go"}}) |
| set_info({custom_function = add_run_trains_button, append = true}) |
| find_gui_recursive(player().gui, "reset_all").destroy() |
| set_continue_button_style(function (button) |
| if button.valid then |
| button.enabled = true |
| end |
| end) |
| clear_surface() |
| global.this_puzzle = setup.chain_blue_go.entities |
| global.this_puzzle_param = nil |
| global.this_puzzle_trains = {} |
| for k, entity in pairs (global.this_puzzle) do |
| entity.minable = false |
| entity.operable = false |
| if entity.name == "locomotive" then |
| if entity.schedule then |
| entity.manual_mode = true |
| end |
| table.insert(global.this_puzzle_trains, entity) |
| end |
| end |
| recreate_entities(global.this_puzzle) |
| loop_trains(0) |
| end, |
| condition = function() |
| return global.continue |
| end |
| }, |
| { |
| init = function() |
| set_goal("", false) |
| set_info({text = {"chain-blue-stop"}}) |
| set_info({custom_function = add_run_trains_button, append = true}) |
| find_gui_recursive(player().gui, "reset_all").destroy() |
| set_continue_button_style(function (button) |
| if button.valid then |
| button.enabled = true |
| end |
| end) |
| clear_surface() |
| global.this_puzzle = setup.chain_blue_stop.entities |
| global.this_puzzle_param = nil |
| global.this_puzzle_trains = {} |
| for k, entity in pairs (global.this_puzzle) do |
| entity.minable = false |
| entity.operable = false |
| if entity.name == "locomotive" then |
| if entity.schedule then |
| entity.manual_mode = true |
| end |
| table.insert(global.this_puzzle_trains, entity) |
| end |
| end |
| recreate_entities(global.this_puzzle) |
| loop_trains(0) |
| end, |
| condition = function() |
| return global.continue |
| end |
| }, |
| { |
| init = function() |
| set_goal("", false) |
| set_info({text = {"chain-red"}}) |
| set_info({custom_function = add_run_trains_button, append = true}) |
| find_gui_recursive(player().gui, "reset_all").destroy() |
| set_continue_button_style(function (button) |
| if button.valid then |
| button.enabled = true |
| end |
| end) |
| clear_surface() |
| global.this_puzzle = setup.chain_red.entities |
| global.this_puzzle_param = nil |
| global.this_puzzle_trains = {} |
| for k, entity in pairs (global.this_puzzle) do |
| entity.minable = false |
| entity.operable = false |
| if entity.name == "locomotive" then |
| if entity.schedule then |
| entity.manual_mode = true |
| end |
| table.insert(global.this_puzzle_trains, entity) |
| end |
| end |
| recreate_entities(global.this_puzzle) |
| loop_trains(0) |
| end, |
| condition = function() |
| return global.continue |
| end |
| }, |
| { |
| init = function() |
| clear_surface() |
| set_goal("", false) |
| set_info({text = {"deadlock-1"}}) |
| set_info({text = {"deadlock-2"}, append = true}) |
| set_info({custom_function = add_button, append = true}) |
| global.this_puzzle_trains = {} |
| for k, entity in pairs (setup.deadlock_1.entities) do |
| if entity.name == "locomotive" or entity.name == "fluid-wagon" then |
| table.insert(global.this_puzzle_trains, entity) |
| elseif entity.name == "rail-signal" then |
| entity.minable = true |
| end |
| end |
| global.this_puzzle = setup.deadlock_1.entities |
| global.this_puzzle_param = setup.deadlock_1.param |
| recreate_entities(global.this_puzzle, global.this_puzzle_param) |
| loop_trains(9*60) |
| end, |
| condition = function() |
| return global.continue |
| end |
| }, |
| { |
| init = function() |
| clear_surface() |
| global.this_puzzle = setup.deadlock_1.entities |
| global.this_puzzle_param = setup.deadlock_1.param |
| global.this_puzzle_trains = {} |
| global.this_puzzle_labels = {} |
| clear_vis() |
| for k, entity in pairs (global.this_puzzle) do |
| if entity.name == "locomotive" or entity.name == "fluid-wagon" then |
| table.insert(global.this_puzzle_trains, entity) |
| elseif entity.name == "rail-signal" then |
| entity.minable = true |
| end |
| end |
| for k, entity in pairs (recreate_entities(global.this_puzzle, global.this_puzzle_param)) do |
| if entity.name == "rail-signal" and |
| ( |
| ( |
| entity.position.x == -4.5 and |
| entity.position.y == 2.5 |
| ) |
| or |
| ( |
| entity.position.x == -2.5 and |
| entity.position.y == -2.5 |
| ) |
| ) |
| then |
| entity.minable = true |
| local X = entity.position.x |
| local Y = entity.position.y |
| local D = entity.direction |
| entity.destroy() |
| surface().create_entity{name = "rail-chain-signal", position = {X,Y}, direction = D} |
| table.insert(global.this_puzzle_labels,{ |
| name = 'rail-chain-signal', |
| position = {X,Y}, |
| locale = 'rail-chain-signal' |
| }) |
| end |
| end |
| add_labels(global.this_puzzle_labels) |
| set_goal() |
| set_info({text = {"chain-signal-1"}}) |
| set_info({text = {"chain-signal-2"}, append = true}) |
| set_info({custom_function = add_button, append = true}) |
| loop_trains(8*60) |
| end, |
| condition = function() |
| return global.continue |
| end |
| }, |
| { |
| init = function() |
| clear_surface() |
| global.required_chain_signals = 4 |
| global.required_rail_signals = 0 |
| set_goal({"fix-intersection"}) |
| set_info({custom_function = add_run_trains_button}) |
| player().game_view_settings = {show_rail_block_visualisation = false} |
| global.this_puzzle_trains = {} |
| for k, entity in pairs (setup.deadlock_2.entities) do |
| if entity.name == "locomotive" or entity.name == "fluid-wagon" then |
| entity.manual_mode = true |
| table.insert(global.this_puzzle_trains, entity) |
| elseif entity.name == "rail-signal" then |
| entity.minable = true |
| end |
| end |
| global.this_puzzle = setup.deadlock_2.entities |
| global.this_puzzle_param = setup.deadlock_2.param |
| recreate_entities(global.this_puzzle, global.this_puzzle_param) |
| end, |
| condition = function() |
| return puzzle_condition_red() |
| end |
| }, |
| { |
| init = function() |
| clear_surface() |
| global.required_chain_signals = 8 |
| set_goal({"fix-intersection"}) |
| set_info({custom_function = add_run_trains_button}) |
| global.this_puzzle_trains = {} |
| for k, entity in pairs (setup.intersection_1.entities) do |
| if entity.name == "locomotive" or entity.name == "fluid-wagon" then |
| entity.manual_mode = true |
| table.insert(global.this_puzzle_trains, entity) |
| elseif entity.name == "rail-signal" then |
| entity.minable = true |
| end |
| end |
| global.this_puzzle = setup.intersection_1.entities |
| global.this_puzzle_param = setup.intersection_1.param |
| recreate_entities(global.this_puzzle, global.this_puzzle_param) |
| end, |
| condition = function() |
| return puzzle_condition_red() |
| end |
| }, |
| { |
| init = function() |
| clear_surface() |
| global.required_chain_signals = 4 |
| set_goal({"fix-intersection"}) |
| set_info({custom_function = add_run_trains_button}) |
| global.this_puzzle_trains = {} |
| for k, entity in pairs (setup.intersection_2.entities) do |
| if entity.name == "locomotive" or entity.name == "fluid-wagon" then |
| entity.manual_mode = true |
| table.insert(global.this_puzzle_trains, entity) |
| elseif entity.name == "rail-signal" then |
| entity.minable = true |
| end |
| end |
| global.this_puzzle = setup.intersection_2.entities |
| global.this_puzzle_param = setup.intersection_2.param |
| recreate_entities(global.this_puzzle, global.this_puzzle_param) |
| end, |
| condition = function() |
| return puzzle_condition_red() |
| end |
| }, |
| { |
| init = function() |
| clear_surface() |
| global.required_chain_signals = 12 |
| global.required_rail_signals = 12 |
| set_goal({"fix-intersection-2"}) |
| set_info({custom_function = add_run_trains_button}) |
| global.this_puzzle_trains = {} |
| global.this_puzzle = setup.intersection_3.entities |
| global.this_puzzle_param = setup.intersection_3.param |
| for k, entity in pairs (global.this_puzzle) do |
| if entity.name == "locomotive" or entity.name == "fluid-wagon" then |
| entity.manual_mode = true |
| table.insert(global.this_puzzle_trains, entity) |
| elseif entity.name == "rail-signal" then |
| entity.minable = true |
| end |
| end |
| recreate_entities(global.this_puzzle, global.this_puzzle_param) |
| end, |
| condition = function() |
| return puzzle_condition_all() |
| end |
| }, |
| { |
| init = function() |
| player().set_controller{type = defines.controllers.god} |
| for k, entity in pairs (surface().find_entities()) do |
| entity.minable = true |
| entity.operable = true |
| entity.rotatable = true |
| end |
| player().insert({name='rail',count=1000}) |
| player().insert({name='rail-signal',count=30}) |
| player().insert({name='rail-chain-signal',count=30}) |
| player().insert({name='train-stop',count=10}) |
| player().insert({name='locomotive',count=3}) |
| player().insert({name='cargo-wagon',count=3}) |
| player().insert({name='coal',count=100}) |
| player().set_quick_bar_slot(2,'rail-signal') |
| player().set_quick_bar_slot(3,'rail') |
| player().set_quick_bar_slot(4,'train-stop') |
| player().set_quick_bar_slot(5,'locomotive') |
| player().set_quick_bar_slot(6,'cargo-wagon') |
| set_info{text = {"finish-info"}} |
| set_info{custom_function = function(flow) add_button(flow).caption = {"finish"} end, append = true} |
| set_goal(nil, false) |
| end, |
| condition = function() |
| return global.continue |
| end |
| } |
| } |
| } |
|
|
| story_init_helpers(story_table) |
|
|
| script.on_init(function() |
| surface().always_day = true |
| game.forces.player.manual_mining_speed_modifier = 4 |
| game.forces.player.disable_all_prototypes() |
| global.story = story_init() |
| end) |
|
|
| script.on_event(defines.events.on_tick, function(event) |
| story_update(global.story, event, "") |
| limit_camera({0,0}, 20) |
| loop_trains() |
| end) |
|
|
| script.on_event(defines.events.on_gui_click, function (event) |
| story_update(global.story, event, "") |
| end) |
|
|
| script.on_event(defines.events.on_player_created, on_player_created) |
|
|
| story_gui_click = function(event) |
| local element = event.element |
| if not element.valid then return end |
| local player = game.players[event.player_index] |
| local name = element.name |
|
|
| if name == "start_trains" then |
| if not element.enabled then return end |
| for k, train in pairs (surface().find_entities_filtered{name = "locomotive"}) do |
| if train.train.schedule then |
| train.train.manual_mode = false |
| end |
| end |
| element.enabled = false |
| global.save_inventory = game.create_inventory(100) |
| player.clear_cursor() |
| for name, count in pairs (player.get_main_inventory().get_contents()) do |
| global.save_inventory.insert({name = name, count = count}) |
| end |
| player.clear_items_inside() |
|
|
| player.set_controller{type = defines.controllers.ghost} |
| return |
| end |
|
|
| if name == "reset_trains" then |
| for k, train in pairs (surface().find_entities_filtered{name = "locomotive"}) do |
| train.destroy() |
| end |
| for k, train in pairs (surface().find_entities_filtered{name = "fluid-wagon"}) do |
| train.destroy() |
| end |
| recreate_entities(global.this_puzzle_trains, global.this_puzzle_param) |
| for k, child in pairs (element.parent.children) do |
| if child.name ~= "story_continue_button" then |
| child.enabled = true |
| end |
| end |
| if player.controller_type ~= defines.controllers.god then |
| player.set_controller{type = defines.controllers.god} |
| if global.save_inventory then |
| for name, count in pairs (global.save_inventory.get_contents()) do |
| player.insert({name = name, count = count}) |
| end |
| global.save_inventory.destroy() |
| global.save_inventory = nil |
| end |
| end |
| return |
| end |
|
|
| if name == "reset_all" then |
| clear_surface() |
| recreate_entities(global.this_puzzle, global.this_puzzle_param) |
| for k, child in pairs (element.parent.children) do |
| if child.name ~= "story_continue_button" then |
| child.enabled = true |
| end |
| end |
|
|
| if player.controller_type ~= defines.controllers.god then |
| player.set_controller{type = defines.controllers.god} |
| end |
|
|
| player.clear_items_inside() |
| if global.required_chain_signals > 0 then player.insert{name = "rail-chain-signal", count = global.required_chain_signals} end |
| if global.required_rail_signals > 0 then player.insert{name = "rail-signal", count = global.required_rail_signals} end |
| return |
| end |
|
|
| end |
|
|
| function clear_surface() |
| local entities = surface().find_entities() |
| for k, entity in pairs (entities) do |
| if entity.valid and entity.name ~= "character" then |
| entity.destroy() |
| end |
| end |
| for k, entity in pairs (surface().find_entities()) do |
| if entity.valid and entity.name ~= "character" then |
| entity.destroy() |
| end |
| end |
| end |
|
|
| function add_run_trains_button(gui) |
| gui.add{type = "line", direction = "horizontal"} |
| local flow = gui.add{type = "table", column_count = 2} |
| flow.style.horizontal_spacing = 2 |
| flow.style.vertical_spacing = 2 |
| flow.style.horizontally_stretchable = true |
| local button = flow.add{type = "button", name = "start_trains", caption = {"start-trains"}} |
| button.style.horizontally_stretchable = true |
| local button = flow.add{type = "button", name = "reset_trains", caption = {"reset-trains"}} |
| button.style.horizontally_stretchable = true |
| local button = flow.add{type = "button", name = "reset_all", caption = {"reset-all"}} |
| button.style.horizontally_stretchable = true |
| local button = add_button(flow) |
| button.style.horizontally_stretchable = true |
| set_continue_button_style(function (button) |
| if button.valid then |
| button.enabled = false |
| end |
| end) |
| local player = player() |
| player.set_controller{type = defines.controllers.god} |
| player.remove_item"rail-chain-signal" |
| if global.required_chain_signals and global.required_chain_signals > 0 then |
| player.insert{name = "rail-chain-signal", count = global.required_chain_signals} |
| end |
| if global.required_rail_signals and global.required_rail_signals > 0 then |
| player.insert{name = "rail-signal", count = global.required_rail_signals} |
| end |
| global.intermission = 0 |
| global.loop_interval = 0 |
| global.loop_tick = nil |
| end |
|
|
| function puzzle_condition_red() |
| if global.continue then return true end |
| for k, train in pairs (surface().find_entities_filtered{name = "locomotive"}) do |
| if train.train.speed ~= 0 then |
| return false |
| end |
| if train.color == nil then |
| if train.train.state ~= defines.train_state.wait_station then |
| return false |
| end |
| if train.health ~= 1000 then |
| return false |
| end |
| end |
| if train.train.state == defines.train_state.no_path then |
| return false |
| end |
| end |
| for k, wagon in pairs (surface().find_entities_filtered{name = "fluid-wagon"}) do |
| if wagon.health ~= 600 then |
| return false |
| end |
| end |
| global.intermission = global.intermission + 1 |
| if global.intermission == 90 then |
| flash_goal() |
| set_continue_button_style(function (button) |
| if button.valid then |
| button.enabled = true |
| end |
| end) |
| end |
| end |
|
|
| function puzzle_condition_all() |
| if global.continue then return true end |
| for k, train in pairs (surface().find_entities_filtered{name = "locomotive"}) do |
| if train.train.speed ~= 0 then |
| return false |
| end |
|
|
| if train.train.state ~= defines.train_state.wait_station then |
| return false |
| end |
| if train.health ~= 1000 then |
| return false |
| end |
|
|
| if train.train.state == defines.train_state.no_path then |
| return false |
| end |
| end |
| for k, wagon in pairs (surface().find_entities_filtered{name = "fluid-wagon"}) do |
| if wagon.health ~= 600 then |
| return false |
| end |
| end |
| global.intermission = global.intermission + 1 |
| if global.intermission == 90 then |
| flash_goal() |
| set_continue_button_style(function (button) |
| if button.valid then |
| button.enabled = true |
| end |
| end) |
| end |
| end |
|
|
| function loop_trains(interval) |
| if interval then |
| global.loop_interval = interval |
| global.loop_tick = game.tick + global.loop_interval |
| return |
| end |
| if not global.loop_tick then return end |
| if game.tick ~= global.loop_tick then return end |
| for k, train in pairs (surface().find_entities_filtered{name = "locomotive"}) do |
| train.destroy() |
| end |
| for k, train in pairs (surface().find_entities_filtered{name = "fluid-wagon"}) do |
| train.destroy() |
| end |
| recreate_entities(global.this_puzzle_trains, global.this_puzzle_param) |
| global.loop_tick = game.tick + global.loop_interval |
| end |
|
|