|
local util = require("new-hope-util") |
|
require("story") |
|
|
|
local researched_technology_list = |
|
{ |
|
["automation"] = true, |
|
["gun-turret"] = true, |
|
["military"] = true, |
|
["optics"] = true |
|
} |
|
|
|
local enabled_technology_list = |
|
{ |
|
["automation-2"] = true, |
|
["automobilism"] = true, |
|
["electronics"] = true, |
|
["engine"] = true, |
|
["fast-inserter"] = true, |
|
["heavy-armor"] = true, |
|
["logistic-science-pack"] = true, |
|
["logistics-2"] = true, |
|
["logistics"] = true, |
|
["physical-projectile-damage-1"] = true, |
|
["steel-axe"] = true, |
|
["steel-processing"] = true, |
|
["stone-wall"] = true, |
|
["weapon-shooting-speed-1"] = true |
|
} |
|
|
|
local spawn_position = {-0.5, 44} |
|
|
|
script.on_init(function() |
|
global.story = story_init() |
|
end) |
|
|
|
local init = function() |
|
|
|
game.map_settings.enemy_expansion.enabled = false |
|
game.map_settings.enemy_evolution.enabled = false |
|
game.map_settings.unit_group.min_group_gathering_time = 60 * 60 |
|
game.map_settings.unit_group.max_group_gathering_time = 120 * 60 |
|
game.map_settings.unit_group.max_unit_group_size = 15 |
|
game.map_settings.pollution.enabled = true |
|
game.map_settings.pollution.enemy_attack_pollution_consumption_modifier = 8 |
|
|
|
game.forces.enemy.evolution_factor = 0 |
|
|
|
local force = game.forces.player |
|
force.reset() |
|
force.clear_chart() |
|
force.disable_all_prototypes() |
|
force.reset_recipes() |
|
|
|
local surface = game.surfaces[1] |
|
force.set_spawn_position(spawn_position, surface) |
|
surface.always_day = false |
|
surface.daytime = 0.4 |
|
|
|
util.set_technologies_researched(force, researched_technology_list) |
|
util.set_technologies_enabled(force, enabled_technology_list) |
|
force.reset_technology_effects() |
|
|
|
util.verify_techs(force) |
|
|
|
global.delayed_messages = {} |
|
game.players[1].clear_recipe_notifications() |
|
game.players[1].add_recipe_notification("lab"); |
|
end |
|
|
|
local item_list = |
|
{ |
|
["iron-plate"] = 10, |
|
["copper-plate"] = 10, |
|
["coal"] = 40, |
|
["transport-belt"] = 100, |
|
["inserter"] = 20, |
|
["small-electric-pole"] = 20, |
|
["electric-mining-drill"] = 5, |
|
["pistol"] = 1, |
|
["firearm-magazine"] = 20, |
|
["electronic-circuit"] = 40 |
|
} |
|
|
|
local on_player_created = function(event) |
|
local player = game.get_player(event.player_index) |
|
util.insert_safe(player.character, item_list) |
|
end |
|
|
|
local default_delay = 5 |
|
local think_with_delay = function(string, seconds) |
|
return |
|
{ |
|
condition = story_elapsed_check(seconds or default_delay), |
|
action = function() |
|
game.print(util.think_string(string)) |
|
end |
|
} |
|
end |
|
|
|
local car_distance_goal = 200 |
|
|
|
local update_car_progress = function(gui) |
|
local progress = gui.progress |
|
if not progress then |
|
progress = gui.add{type = "progressbar", name = "progress"} |
|
progress.style.horizontally_stretchable = true |
|
progress.parent.style.padding = 0 |
|
end |
|
progress.value = math.min(1, global.distance_travelled / car_distance_goal) |
|
end |
|
|
|
local finish_materials = |
|
{ |
|
["iron-plate"] = 400, |
|
["copper-plate"] = 200, |
|
["gun-turret"] = 20, |
|
["firearm-magazine"] = 200, |
|
["steel-plate"] = 50, |
|
["coal"] = 100 |
|
} |
|
|
|
local get_car_contents = function() |
|
local cars = game.surfaces[1].find_entities_filtered{name = "car"} |
|
if not cars[1] then return {} end |
|
local contents = {} |
|
for k, car in pairs (cars) do |
|
for name, count in pairs(car.get_inventory(defines.inventory.car_trunk).get_contents()) do |
|
contents[name] = (contents[name] or 0) + count |
|
end |
|
for name, count in pairs(car.get_inventory(defines.inventory.car_ammo).get_contents()) do |
|
contents[name] = (contents[name] or 0) + count |
|
end |
|
end |
|
return contents |
|
end |
|
|
|
local update_materials_gui = function(gui) |
|
local contents = get_car_contents() |
|
local table = gui.holding_table |
|
if not table then |
|
table = gui.add{type = "table", column_count = 3, style = "bordered_table", name = "holding_table"} |
|
end |
|
|
|
local items = game.item_prototypes |
|
|
|
for item, count in pairs(finish_materials) do |
|
if items[item] then |
|
local count_label = table[item] |
|
if not count_label then |
|
local sprite = table.add{type = "sprite", sprite = "item/"..item} |
|
sprite.style.width = 32 |
|
sprite.style.height = 32 |
|
local item_label = table.add{type = "label", caption = items[item].localised_name, style = "bold_label"} |
|
item_label.style.horizontally_stretchable = false |
|
count_label = table.add{type = "label", name = item} |
|
end |
|
local current_count = contents[item] or 0 |
|
count_label.caption = current_count.."/"..count |
|
if current_count >= count then |
|
count_label.style = "bold_green_label" |
|
else |
|
count_label.style = "label" |
|
end |
|
end |
|
end |
|
|
|
end |
|
|
|
local car_content_check = function() |
|
local car_contents = get_car_contents() |
|
for item, count in pairs (finish_materials) do |
|
if not car_contents[item] then return end |
|
if car_contents[item] < count then return end |
|
end |
|
return true |
|
end |
|
|
|
local story_table = |
|
{ |
|
{ |
|
{ |
|
init = function() |
|
init() |
|
end |
|
}, |
|
{ |
|
init = function() |
|
global.radar = game.surfaces[1].find_entities_filtered{name = "radar", limit = 1}[1] |
|
if global.radar then |
|
for k, player in pairs (game.players) do |
|
player.set_controller |
|
{ |
|
type = defines.controllers.cutscene, |
|
waypoints = |
|
{ |
|
{ |
|
target = global.radar, |
|
transition_time = 300, |
|
time_to_wait = 100, |
|
zoom = 2 |
|
}, |
|
{ |
|
target = player.character, |
|
transition_time = 100, |
|
time_to_wait = 0, |
|
zoom = 1 |
|
} |
|
}, |
|
start_position = global.radar.position, |
|
start_zoom = 4 |
|
} |
|
end |
|
end |
|
end, |
|
condition = story_elapsed_check(6) |
|
}, |
|
{ |
|
action = function() |
|
story_show_message_dialog{text = {"msg-sector-scan-completed"}} |
|
story_show_message_dialog{text = {"msg-detected-distress-beacon"}} |
|
end |
|
}, |
|
think_with_delay({"think-track-distress-beacon-1"}, 5), |
|
think_with_delay({"think-track-distress-beacon-2"}, 8), |
|
think_with_delay({"think-track-distress-beacon-3"}, 7), |
|
think_with_delay({"think-track-distress-beacon-4"}, 9), |
|
{ |
|
condition = story_elapsed_check(5) |
|
}, |
|
{ |
|
init = function() |
|
set_goal({"goal-build-lab"}) |
|
end, |
|
condition = function(event) |
|
if event.tick % 60 ~= 0 then return end |
|
|
|
if game.forces.player.get_entity_count("lab") == 0 then return end |
|
|
|
local lab = game.surfaces[1].find_entities_filtered{name = "lab", limit = 1}[1] |
|
if not lab then return end |
|
|
|
lab.energy = 1 |
|
story_show_message_dialog{text = {"msg-research-labs-1"}, point_to = {type = "entity", entity = lab}} |
|
story_show_message_dialog{text = {"msg-research-labs-2"}, point_to = {type = "entity", entity = lab}} |
|
return true |
|
end |
|
}, |
|
{ |
|
init = function() |
|
set_goal() |
|
end, |
|
condition = story_elapsed_check(3) |
|
}, |
|
{ |
|
init = function() |
|
set_goal({"goal-research-walls"}) |
|
end, |
|
condition = function() return game.forces.player.technologies["stone-wall"].researched end, |
|
action = function() |
|
set_goal() |
|
end |
|
}, |
|
think_with_delay({"think-research-car-1"}, 8), |
|
think_with_delay({"think-research-car-2"}, 8), |
|
think_with_delay({"think-research-car-3"}, 8), |
|
{ |
|
condition = story_elapsed_check(5) |
|
}, |
|
{ |
|
init = function() |
|
set_goal({"goal-research-automobilism"}) |
|
end, |
|
condition = function() |
|
return game.forces.player.technologies["automobilism"].researched |
|
end |
|
}, |
|
{ |
|
init = function() |
|
set_goal({"goal-build-car"}) |
|
end, |
|
condition = function(event) |
|
if event.tick % 60 ~= 0 then return end |
|
local car_count = game.surfaces[1].count_entities_filtered{name = "car", limit = 1} |
|
return car_count > 0 |
|
end, |
|
action = function() |
|
set_goal() |
|
end |
|
}, |
|
{ |
|
condition = story_elapsed_check(5) |
|
}, |
|
{ |
|
init = function() |
|
set_goal({"goal-drive-car"}) |
|
global.distance_travelled = 0 |
|
set_info({custom_function = update_car_progress}) |
|
end, |
|
condition = function(event) |
|
if event.tick % 60 ~= 0 then return end |
|
local car = game.surfaces[1].find_entities_filtered{name = "car", limit = 1}[1] |
|
if not car then return end |
|
if car.energy == 0 then return end |
|
global.car = car |
|
global.last_car_position = car.position |
|
return true |
|
end |
|
}, |
|
{ |
|
condition = function(event) |
|
if not global.car.valid then return true end |
|
if global.distance_travelled >= car_distance_goal then return true end |
|
end, |
|
update = function(event) |
|
if not global.car.valid then return end |
|
local new_position = global.car.position |
|
local distance = util.distance(new_position, global.last_car_position) |
|
global.distance_travelled = global.distance_travelled + distance |
|
global.last_car_position = new_position |
|
set_info{custom_function = update_car_progress} |
|
end, |
|
action = function() |
|
set_goal() |
|
set_info() |
|
end |
|
}, |
|
think_with_delay({"think-stop-messing-around-1"}, 5), |
|
think_with_delay({"think-stop-messing-around-2"}, 8), |
|
{ |
|
condition = story_elapsed_check(5) |
|
}, |
|
{ |
|
init = function() |
|
set_goal({"goal-prepare-materials"}) |
|
set_info({ |
|
custom_function = update_materials_gui |
|
}) |
|
end, |
|
update = function(event) |
|
if event.tick % 60 ~= 0 then return end |
|
set_info({ |
|
custom_function = update_materials_gui |
|
}) |
|
end, |
|
condition = function(event) |
|
if event.tick % 60 ~= 0 then return end |
|
return car_content_check() |
|
end, |
|
action = function() |
|
set_goal() |
|
set_info() |
|
end |
|
}, |
|
think_with_delay({"think-lets-go"}, 5), |
|
{ |
|
condition = story_elapsed_check(5), |
|
action = function() |
|
game.set_game_state({game_finished=true, player_won=true, can_continue=false, next_level = "level-05"}) |
|
end |
|
} |
|
} |
|
} |
|
|
|
local check_automate_science_packs_advice = function(event) |
|
if not global.science_packs_crafted then |
|
global.science_packs_crafted = 0 |
|
end |
|
if event.item_stack.name == "automation-science-pack" then |
|
global.science_packs_crafted = global.science_packs_crafted + event.item_stack.count |
|
end |
|
if global.science_packs_crafted > 15 and global.automate_science_packs_advice == nil then |
|
game.print(util.think_string({"think-automate-science-pack-crafting"})) |
|
global.automate_science_packs_advice = true |
|
end |
|
end |
|
|
|
local group_notice_count = 3 |
|
local go_kill_group_count = 8 |
|
local bump_biter_difficulty_group_count = 12 |
|
local on_unit_group_finished_gathering = function(event) |
|
|
|
|
|
global.gathered_group_count = (global.gathered_group_count or 0) + 1 |
|
|
|
if not global.showed_pollution_tip and global.gathered_group_count >= group_notice_count then |
|
global.showed_pollution_tip = true |
|
global.delayed_messages[game.tick + (20 * 60)] = util.think_string({"think-pollution-tip"}) |
|
end |
|
|
|
if not global.showed_murder_tip and global.gathered_group_count >= go_kill_group_count then |
|
global.showed_murder_tip = true |
|
global.delayed_messages[game.tick + (20 * 60)] = util.think_string({"think-kill-bases-tip"}) |
|
end |
|
|
|
if not global.bumped_biter_difficulty and global.gathered_group_count >= bump_biter_difficulty_group_count then |
|
game.map_settings.pollution.enemy_attack_pollution_consumption_modifier = 1 |
|
end |
|
|
|
end |
|
|
|
local minimum_delay_between_messages = 60 * 10 |
|
local check_delayed_message = function(event) |
|
|
|
if event.tick < ((global.last_message_tick or 0) + minimum_delay_between_messages) then |
|
|
|
return |
|
end |
|
|
|
for tick, message in pairs (global.delayed_messages) do |
|
if event.tick >= tick then |
|
game.print(message) |
|
global.delayed_messages[tick] = nil |
|
global.last_message_tick = event.tick |
|
return |
|
end |
|
end |
|
end |
|
|
|
local check_low_power = function() |
|
if global.showed_power_tip then return end |
|
local test_entities = game.surfaces[1].find_entities_filtered{type = {"mining-drill", "inserter", "assembling-machine", "radar", "lab", "lamp"}, force = "player"} |
|
for k, entity in pairs (test_entities) do |
|
if entity.is_connected_to_electric_network() then |
|
local buffer_size = entity.electric_buffer_size |
|
if buffer_size then |
|
if entity.energy < (buffer_size * 0.6) then |
|
global.showed_power_tip = true |
|
global.delayed_messages[game.tick + (5 * 60)] = util.think_string({"think-low-power"}) |
|
end |
|
end |
|
end |
|
end |
|
end |
|
|
|
story_init_helpers(story_table) |
|
|
|
local story_events = |
|
{ |
|
defines.events.on_tick |
|
} |
|
|
|
script.on_event(story_events, function(event) |
|
story_update(global.story, event, "level-05") |
|
end) |
|
|
|
script.on_event(defines.events.on_player_crafted_item, check_automate_science_packs_advice) |
|
|
|
script.on_event(defines.events.on_player_created, on_player_created) |
|
|
|
script.on_event(defines.events.on_unit_group_finished_gathering, on_unit_group_finished_gathering) |
|
|
|
script.on_nth_tick(103, check_delayed_message) |
|
|
|
script.on_nth_tick(269, check_low_power) |
|
|