require "story" local setups = require "ghost-rails" required_count = 10 through_wall_path = 40 local no_deconstruction_markers = function() local all_ents = game.surfaces[1].find_entities() for _, entity in pairs(all_ents) do if entity.to_be_deconstructed() then return false end end return true end local reset_deconstruction = function() local all_ents = game.surfaces[1].find_entities() for _, entity in pairs(all_ents) do if entity.to_be_deconstructed() then entity.cancel_deconstruction('player') end end end local remove_all_rail_ghosts = function() local rail_ghosts = game.surfaces[1].find_entities_filtered({ghost_name={'straight-rail','curved-rail'}}) for _, ghost in pairs(rail_ghosts) do ghost.destroy() end end local set_continue_button_state = function(state) set_continue_button_style(function (button) if button.valid then button.enabled = state end end) global.completed = state end 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_tutorials_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 intermission = { init = function() player().clean_cursor() flying_congrats(global.last_built_position) set_goal() set_info() end, condition = story_elapsed_check(1) } story_table = { { {condition = story_elapsed_check(1)}, { init = function() global.built_rail = 0 set_goal({"place-ghost-rail", global.built_rail, 4}) set_info({text = {"place-ghost-rail-info"}}) player().insert{name = "rail", count = 1000} player().set_quick_bar_slot(1,'rail') end, update = function(event) set_goal({"place-ghost-rail", surface().count_entities_filtered{name = "entity-ghost"}, 4}, true) end, condition = function(event) if event.name == defines.events.on_tick then return surface().count_entities_filtered{name = "entity-ghost"} >= 4 end end, action = function() end }, intermission, { init = function() set_goal({"start-ghost-rail-planning", 0, required_count}) set_info( { text = {"start-ghost-rail-planning-info"}, pictures = { "file/ghost-plan-1.png", "file/ghost-plan-2.png", {path = "file/ghost-plan-3.png", split = true} } }) global.initial = surface().count_entities_filtered{type = "entity-ghost"} end, condition = function(event) if event.name == defines.events.on_tick then local count = 0 for k, entity in pairs (surface().find_entities_filtered{type = "entity-ghost"}) do if entity.ghost_name == "curved-rail" then count = count + 1 end end local count = count - global.initial set_goal({"start-ghost-rail-planning", math.max(count, 0), required_count}, true) return count >= required_count end end, action = function() player().clean_cursor() end }, intermission, { init = function() deconstruct_on_tick(surface().find_entities_filtered{name = "entity-ghost"}) end, condition = function() return deconstruct_on_tick() end }, { init = function() set_goal({"rotate-rail"}) set_info({text = {"rotate-rail-info"}, picture = "file/rotate-rail.png"}) local surface = surface() for k, v in pairs (surface.find_entities_filtered{name = "entity-ghost"}) do v.destroy() end surface.create_entity { name = "entity-ghost", inner_name = "straight-rail", direction = 2, position = {-7, -3}, force = "player", expires = false }.minable = false surface.create_entity { name = "entity-ghost", inner_name = "straight-rail", direction = 2, position = {9,3}, force = "player", expires = false }.minable = false end, condition = function(event) if event.name ~= defines.events.on_tick then return end local rails = { {position = {-2, -2}, area = {{-3, -3}, {-1,-1}}, direction = 3}, {position = {4, 2}, area = {{5, 1}, {3, 3}}, direction = 7} } local surface = surface() count = 0 for k, ghost in pairs (surface.find_entities_filtered({name = "entity-ghost"})) do for j, rail in pairs (rails) do if ghost.ghost_name == "curved-rail" and ghost.position.x == rail.position[1] and ghost.position.y == rail.position[2] and ghost.direction == rail.direction then count = count + 1 break end end end if count >= 2 then return true end local any_destroyed = false for k, rail in pairs (surface.find_entities_filtered({name = "entity-ghost"})) do if rail.name ~= "character" and rail.minable then rail.destroy() any_destroyed = true end end if any_destroyed then game.print({"rotate-rail-not-1-tick"}) player().clean_cursor() end end }, intermission, { init = function() deconstruct_on_tick(surface().find_entities_filtered{name = "entity-ghost"}) end, condition = function() return deconstruct_on_tick() end }, { init = function() recreate_entities_on_tick(setups.plan_through_trees, nil, 1) end, condition = function() return recreate_entities_on_tick() end }, { init = function() set_goal() set_info({text={"trace-path"}}) set_info({text={"automatic-deconstruction"},append = true}) set_info{custom_function = function(flow) add_button(flow).caption = {"continue"} end, append = true} set_continue_button_state(false) local surface = surface() global.text = { surface.create_entity{name = "tutorial-flying-text", text = {"connect-start"}, position = {-15, -12}}, surface.create_entity{name = "tutorial-flying-text", text = {"connect-end"}, position = {-15, 10}} } for k, text in pairs (global.text) do text.active = false end end, update = function() local surface = surface() local count = 0 for k, entity in pairs (setups.rails) do local ghost = surface.find_entity("entity-ghost", entity.position) if ghost then count = count + 1 else local area = {{entity.position.x-2, entity.position.y-2}, {entity.position.x+2, entity.position.y+2}} for j, ghost in pairs (surface.find_entities_filtered{area = area, name = "entity-ghost"}) do if ((ghost.position.x == entity.position.x) and (ghost.position.y == entity.position.y) and (ghost.ghost_name == entity.name)) then count = count + 1 break end end end end if count >= #setups.rails then set_continue_button_state(true) end end, condition = function() return global.continue end, action = function() for k, arrow in pairs (global.text) do if arrow.valid then arrow.destroy() end end global.arrows = nil player().clean_cursor() global.continue = false end }, intermission, { init = function() local entities = {} for k, entity in pairs (surface().find_entities()) do if entity.name ~= "character" then entities[k] = entity end end deconstruct_on_tick(entities) end, condition = function() return deconstruct_on_tick() end }, { init = function() local entities = {} local rand = math.random local list = {} for k, entity in pairs (setups.trees) do entity.force = "neutral" entity.minable = true table.insert(entities,entity) end --for k, entity in pairs (game.entity_prototypes) do -- if entity.type == "tree" then -- table.insert(list, entity.name) -- end --end --for k = 1, 350 do -- local position = {x = rand(-52,51), y = rand(-51,52)} -- entities[k] = {name = list[rand(#list)], position = position, force = "neutral", minable = true} --end entities[351] = {name = 'assembling-machine-1', position = {x=0,y=-10}, force = "neutral", minable = false} recreate_entities_on_tick(entities, {check_can_place = true}, 1) print(serpent.block(export_entities())) end, condition = function() return recreate_entities_on_tick() end }, { init = function() set_goal({"crazy-rail", surface().count_entities_filtered{area = {{-50, -50}, {50, 50}}, name = "entity-ghost"}, through_wall_path}) set_info({text = {"crazy-rail-info"}}) set_info({custom_function = function(flow) add_button(flow).caption = {"reset"} end, append = true}) player().insert({name='rail',count=1}) local surface = surface() surface.create_entity{name = "entity-ghost", inner_name = "straight-rail", direction = 2, position = {-59, -9}, force = "player", expires = false} surface.create_entity{name = "entity-ghost", inner_name = "straight-rail", direction = 2, position = {59, -9}, force = "player", expires = false} end, update = function(event) if global.continue then remove_all_rail_ghosts() reset_deconstruction() local surface = surface() surface.create_entity{name = "entity-ghost", inner_name = "straight-rail", direction = 2, position = {-59, -9}, force = "player", expires = false} surface.create_entity{name = "entity-ghost", inner_name = "straight-rail", direction = 2, position = {59, -9}, force = "player", expires = false} global.continue = false set_continue_button_state(true) end end, condition = function(event) local count = surface().count_entities_filtered{name = "entity-ghost"} set_goal({"crazy-rail", count, through_wall_path}, true) return count >= through_wall_path end, }, intermission, { init = function() remove_all_rail_ghosts() reset_deconstruction() set_goal({"crazy-rail-no-tree-loss", surface().count_entities_filtered{area = {{-50, -50}, {50, 50}}, name = "entity-ghost"}, through_wall_path}) set_info({text = {"crazy-rail-no-tree-loss-info"}}) set_info({custom_function = function(flow) add_button(flow).caption = {"reset"} end, append = true}) local surface = surface() surface.create_entity{name = "entity-ghost", inner_name = "straight-rail", direction = 2, position = {-59, -9}, force = "player", expires = false} surface.create_entity{name = "entity-ghost", inner_name = "straight-rail", direction = 2, position = {59, -9}, force = "player", expires = false} end, update = function(event) if global.continue then remove_all_rail_ghosts() reset_deconstruction() local surface = surface() surface.create_entity{name = "entity-ghost", inner_name = "straight-rail", direction = 2, position = {-59, -9}, force = "player", expires = false} surface.create_entity{name = "entity-ghost", inner_name = "straight-rail", direction = 2, position = {59, -9}, force = "player", expires = false} global.continue = false set_continue_button_state(true) end end, condition = function(event) local count = surface().count_entities_filtered{name = "entity-ghost"} set_goal({"crazy-rail-no-tree-loss", count, through_wall_path}, true) local no_markers = no_deconstruction_markers() return count >= through_wall_path and no_markers end, }, intermission, { init = function() 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() game.forces.player.manual_mining_speed_modifier = 4 game.forces.player.disable_all_prototypes() surface().always_day = true global.story = story_init() end) script.on_event(defines.events, function(event) check_built_real_rail(event) story_update(global.story, event, "") if event.name == defines.events.on_player_created then on_player_created(event) end end) function check_built_real_rail(event) if event.name ~= defines.events.on_tick then return end local surface = surface() local player = player() local create = false for k, rail in pairs (surface.find_entities_filtered{type = "straight-rail"}) do if rail.minable then rail.destroy() player.clean_cursor() player.insert{name = "rail", count = 1} create = true end end for k, rail in pairs (surface.find_entities_filtered{type = "curved-rail"}) do if rail.minable then rail.destroy() player.clean_cursor() player.insert{name = "rail", count = 4} create = true end end if create then surface.create_entity{ name = "tutorial-flying-text", position = {player.position.x, player.position.y - 2}, text = {"built-real-rail"}, color = {r = 1, g = 0.1, b = 0.1} } end end function current_ghosts_count(area) if area then return surface().count_entities_filtered{area = area, name = "entity-ghost"} else return surface().count_entities_filtered{name = "entity-ghost"} end end