|
local util = require("new-hope-util") |
|
local final_screen = require("final_screen") |
|
require("story") |
|
|
|
local car_supplies = |
|
{ |
|
["piercing-rounds-magazine"] = 200, |
|
["steel-plate"] = 200, |
|
["iron-gear-wheel"] = 250, |
|
["electronic-circuit"] = 500, |
|
["solar-panel"] = 200 |
|
} |
|
|
|
local get_car_contents = function() |
|
local cars = global.cars |
|
local contents = {} |
|
for k, car in pairs (cars) do |
|
if not car.valid then |
|
cars[k] = nil |
|
else |
|
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 |
|
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(car_supplies) 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 (car_supplies) do |
|
if not car_contents[item] then return end |
|
if car_contents[item] < count then return end |
|
end |
|
return true |
|
end |
|
|
|
local researched_technology_list = |
|
{ |
|
["automation-2"] = true, |
|
["automation"] = true, |
|
["automobilism"] = true, |
|
["electronics"] = true, |
|
["engine"] = true, |
|
["fast-inserter"] = true, |
|
["heavy-armor"] = true, |
|
["logistic-science-pack"] = true, |
|
["logistics-2"] = true, |
|
["logistics"] = true, |
|
["military"] = true, |
|
["optics"] = true, |
|
["physical-projectile-damage-1"] = true, |
|
["steel-axe"] = true, |
|
["steel-processing"] = true, |
|
["stone-wall"] = true, |
|
["gun-turret"] = true, |
|
["weapon-shooting-speed-1"] = true |
|
} |
|
|
|
local enabled_technology_list = |
|
{ |
|
["advanced-material-processing"] = true, |
|
["automated-rail-transportation"] = true, |
|
["concrete"] = true, |
|
["electronics"] = true, |
|
["electric-energy-distribution-1"] = true, |
|
["engine"] = true, |
|
["gate"] = true, |
|
["landfill"] = true, |
|
["military-2"] = true, |
|
["physical-projectile-damage-2"] = true, |
|
["rail-signals"] = true, |
|
["railway"] = true, |
|
["research-speed-1"] = true, |
|
["research-speed-2"] = true, |
|
["solar-energy"] = true, |
|
["stronger-explosives-1"] = true, |
|
["toolbelt"] = true, |
|
["weapon-shooting-speed-2"] = true |
|
} |
|
|
|
local spawn_position = {-23, 5} |
|
|
|
script.on_init(function() |
|
global.story = story_init() |
|
game.forces.player.set_spawn_position(spawn_position, 1) |
|
end) |
|
|
|
local set_remnants_permament = function() |
|
for k, remnant in pairs (game.surfaces[1].find_entities_filtered{type = {"corpse", "rail-remnants"}}) do |
|
if remnant.name:find("remnant") then |
|
remnant.corpse_expires = false |
|
end |
|
end |
|
end |
|
|
|
local chart_areas = function() |
|
local surface = game.surfaces[1] |
|
local force = game.forces.player |
|
for k, entity in pairs (surface.find_entities_filtered{force = force, area = {{-500, -250},{500, 250}}}) do |
|
local position = entity.position |
|
force.chart(surface, {{position.x - 16, position.y - 16}, {position.x + 16, position.y + 16}}) |
|
end |
|
force.chart(surface, {{spawn_position[1] - 200, spawn_position[2] - 200}, {spawn_position[1] + 200, spawn_position[2] + 200}}) |
|
end |
|
|
|
local init = function() |
|
|
|
game.map_settings.enemy_expansion.enabled = false |
|
game.map_settings.enemy_evolution.enabled = false |
|
game.forces.enemy.evolution_factor = 0 |
|
game.surfaces[1].daytime = 0.8 |
|
|
|
local force = game.forces.player |
|
force.reset_recipes() |
|
force.disable_all_prototypes() |
|
|
|
util.set_technologies_enabled(force, enabled_technology_list) |
|
util.set_technologies_researched(force, researched_technology_list) |
|
|
|
force.reset_technology_effects() |
|
force.clear_chart() |
|
force.maximum_following_robot_count = 10 |
|
|
|
util.verify_techs(force) |
|
|
|
global.cars = global.cars or {} |
|
game.players[1].clear_recipe_notifications() |
|
end |
|
|
|
local player_item_list = |
|
{ |
|
["assembling-machine-1"] = 10, |
|
["coal"] = 40, |
|
["copper-plate"] = 100, |
|
["electric-mining-drill"] = 5, |
|
["electronic-circuit"] = 100, |
|
["submachine-gun"] = 1, |
|
["firearm-magazine"] = 40, |
|
["shotgun"] = 1, |
|
["shotgun-shell"] = 20, |
|
["heavy-armor"] = 1, |
|
["inserter"] = 20, |
|
["iron-gear-wheel"] = 50, |
|
["iron-plate"] = 200, |
|
["lab"] = 5, |
|
["long-handed-inserter"] = 10, |
|
["pipe"] = 40, |
|
["small-electric-pole"] = 20, |
|
["small-lamp"] = 20, |
|
["stone"] = 200, |
|
["transport-belt"] = 50, |
|
["wood"] = 50 |
|
} |
|
|
|
local car_item_list = |
|
{ |
|
["iron-plate"] = 400, |
|
["copper-plate"] = 200, |
|
["gun-turret"] = 20, |
|
["firearm-magazine"] = 200, |
|
["steel-plate"] = 50, |
|
["coal"] = 100 |
|
} |
|
|
|
local train_stop_locale = |
|
{ |
|
dropoff_stop = {"iron-processing-stop"}, |
|
mine_stop = {"iron-mine-stop"} |
|
} |
|
|
|
local translate_stops = function(player) |
|
player.request_translation(train_stop_locale.dropoff_stop) |
|
player.request_translation(train_stop_locale.mine_stop) |
|
end |
|
|
|
local on_player_created = function(event) |
|
local player = game.get_player(event.player_index) |
|
util.insert_safe(player.character, player_item_list) |
|
if event.player_index == 1 then |
|
translate_stops(player) |
|
end |
|
end |
|
|
|
local on_string_translated = function(event) |
|
if not event.translated then return end |
|
if event.localised_string[1] == train_stop_locale.dropoff_stop[1] then |
|
local train_stop = game.surfaces[1].find_entity("train-stop", {-29, -7}) |
|
if train_stop then |
|
train_stop.backer_name = event.result |
|
end |
|
return |
|
end |
|
if event.localised_string[1] == train_stop_locale.mine_stop[1] then |
|
local train_stop = game.surfaces[1].find_entity("train-stop", {-423, -145}) |
|
if train_stop then |
|
train_stop.backer_name = event.result |
|
end |
|
return |
|
end |
|
end |
|
|
|
local get_angle = function(position_1, position_2) |
|
local d_x = (position_2[1] or position_2.x) - (position_1[1] or position_1.x) |
|
local d_y = (position_2[2] or position_2.y) - (position_1[2] or position_1.y) |
|
return math.atan2(d_y, d_x) |
|
end |
|
|
|
local get_orientation = function(source_position, target_position) |
|
|
|
|
|
local angle = get_angle(target_position, source_position) |
|
|
|
|
|
local orientation = (angle / (2 * math.pi)) - 0.25 |
|
if orientation < 0 then orientation = orientation + 1 end |
|
if orientation > 1 then orientation = orientation - 1 end |
|
|
|
return orientation |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local car_waypoints = |
|
{ |
|
{-200, 20}, |
|
{-165, -6}, |
|
{-122, -5}, |
|
{-95, -5}, |
|
{-88, -0}, |
|
{-82, 0}, |
|
{-50, 3}, |
|
{-25, 5} |
|
} |
|
|
|
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 update_car_driving = function() |
|
|
|
local car = global.car |
|
local waypoint = global.car_waypoints[1] |
|
|
|
if not waypoint then |
|
car.speed = car.speed * 0.95 |
|
car.riding_state = |
|
{ |
|
acceleration = defines.riding.acceleration.braking, |
|
direction = defines.riding.direction.straight |
|
} |
|
return |
|
end |
|
|
|
local distance = util.distance(car.position, {x = waypoint[1], y = waypoint[2]}) |
|
if distance < 2 then |
|
table.remove(global.car_waypoints, 1) |
|
return |
|
end |
|
|
|
local direction |
|
|
|
local target_orientation = get_orientation(car.position, waypoint) |
|
if math.abs(car.orientation - target_orientation) <= 1/128 then |
|
car.orientation = target_orientation |
|
direction = defines.riding.direction.straight |
|
else |
|
|
|
local change = car.orientation - target_orientation |
|
if change > 0.5 then |
|
change = -1 + change |
|
end |
|
if change < -0.5 then |
|
change = 1 + change |
|
end |
|
|
|
if change > 0 then |
|
|
|
car.orientation = car.orientation - (0.08 * change) |
|
else |
|
car.orientation = car.orientation - (0.08 * change) |
|
|
|
end |
|
|
|
end |
|
|
|
car.riding_state = |
|
{ |
|
acceleration = defines.riding.acceleration.accelerating, |
|
direction = defines.riding.direction.straight |
|
} |
|
end |
|
|
|
story_table = |
|
{ |
|
{ |
|
{ |
|
init = function() |
|
init() |
|
end |
|
}, |
|
{ |
|
init = function() |
|
global.car_waypoints = car_waypoints |
|
for k, waypoint in pairs (car_waypoints) do |
|
|
|
|
|
end |
|
for k, player in pairs (game.players) do |
|
if player.character then player.character.destroy() end |
|
end |
|
local start_position = global.car_waypoints[1] |
|
table.remove(global.car_waypoints, 1) |
|
local driving_car = game.surfaces[1].create_entity{name = "car", position = start_position, force = "player"} |
|
global.cars = |
|
{ |
|
[driving_car.unit_number] = driving_car |
|
} |
|
local dude = game.surfaces[1].create_entity{name = "character", force = "player", position = start_position} |
|
driving_car.set_passenger(dude) |
|
global.dude = dude |
|
global.car = driving_car |
|
global.car.orientation = get_orientation(global.car.position, global.car_waypoints[1]) |
|
global.car.speed = 0.3 |
|
util.insert_safe(global.car, car_item_list) |
|
global.car.color = { r = 0.869, g = 0.5 , b = 0.130, a = 0.5 } |
|
for k, player in pairs (game.players) do |
|
player.set_controller |
|
{ |
|
type = defines.controllers.cutscene, |
|
waypoints = |
|
{ |
|
{ |
|
target = global.car, |
|
transition_time = 0, |
|
time_to_wait = 1000, |
|
zoom = 1.5 |
|
} |
|
}, |
|
start_position = global.car.position, |
|
start_zoom = 1.5 |
|
} |
|
end |
|
end, |
|
update = update_car_driving, |
|
condition = function(event) |
|
if event.tick % 60 ~= 0 then return end |
|
return global.car.speed == 0 |
|
end |
|
}, |
|
{ |
|
init = function() |
|
chart_areas() |
|
if global.dude and global.dude.valid then |
|
global.dude.destroy() |
|
end |
|
for k, player in pairs (game.players) do |
|
if player.controller_type == defines.controllers.cutscene then |
|
player.exit_cutscene() |
|
end |
|
if player.character then player.character.destroy() end |
|
player.teleport({x = global.car.position.x + 1, y = global.car.position.y - 1}) |
|
player.create_character() |
|
util.insert_safe(player, player_item_list) |
|
player.zoom = 0.75 |
|
player.set_controller |
|
{ |
|
type = defines.controllers.cutscene, |
|
waypoints = |
|
{ |
|
{ |
|
target = player.character, |
|
transition_time = 150, |
|
time_to_wait = 30, |
|
zoom = 0.75 |
|
} |
|
}, |
|
start_position = global.car.position, |
|
start_zoom = 1.5 |
|
} |
|
end |
|
end, |
|
condition = story_elapsed_check(3) |
|
}, |
|
think_with_delay({"think-arrived-1"}, 2), |
|
think_with_delay({"think-arrived-2"}, 6), |
|
think_with_delay({"think-arrived-3"}, 7), |
|
think_with_delay({"think-arrived-4"}, 8), |
|
think_with_delay({"think-arrived-5"}, 7), |
|
{ |
|
condition = story_elapsed_check(2) |
|
}, |
|
{ |
|
init = function() |
|
set_goal({"goal-repair-base-and-research-railway"}) |
|
end, |
|
condition = function(event) |
|
if event.tick % 60 ~= 0 then return end |
|
local force = game.forces.player |
|
return force.technologies["automated-rail-transportation"].researched == true |
|
end, |
|
action = function() |
|
set_goal("") |
|
end |
|
}, |
|
think_with_delay({"think-recover-railway"}), |
|
{ |
|
condition = story_elapsed_check(6) |
|
}, |
|
{ |
|
init = function(event) |
|
set_goal({"goal-set-up-train"}) |
|
end, |
|
condition = function(event) |
|
if event.name ~= defines.events.on_train_changed_state then return end |
|
local train = event.train |
|
if not (train and train.valid) then return end |
|
if train.manual_mode then return end |
|
if train.state ~= defines.train_state.wait_station then return end |
|
if #train.cargo_wagons == 0 then return end |
|
local schedule = train.schedule |
|
if not schedule then return end |
|
return #schedule.records >= 2 |
|
end, |
|
action = function(event) |
|
set_goal() |
|
end |
|
}, |
|
think_with_delay({"think-gather-supplies-1"}, 5), |
|
think_with_delay({"think-gather-supplies-2"}, 6), |
|
think_with_delay({"think-gather-supplies-3"}, 7), |
|
think_with_delay({"think-gather-supplies-4"}, 7), |
|
{ |
|
condition = story_elapsed_check(5) |
|
}, |
|
{ |
|
init = function(event) |
|
set_goal({"goal-get-supplies"}) |
|
set_info({custom_function = update_materials_gui}) |
|
end, |
|
condition = function(event) |
|
if event.tick % 60 ~= 0 then return end |
|
set_info({custom_function = update_materials_gui}) |
|
return car_content_check() |
|
end, |
|
action = function() |
|
set_goal("") |
|
set_info() |
|
end |
|
}, |
|
think_with_delay({"think-ready-to-go"}, 5), |
|
{ |
|
condition = story_elapsed_check(5) |
|
}, |
|
{ |
|
init = function() |
|
if not game.is_multiplayer() then |
|
game.tick_paused = true |
|
end |
|
for k, player in pairs (game.connected_players) do |
|
final_screen.create(player) |
|
end |
|
game.play_sound({path = "utility/game_won"}) |
|
end, |
|
condition = function() |
|
return false |
|
end |
|
} |
|
} |
|
} |
|
|
|
skippity = function() |
|
for k, player in pairs (game.connected_players) do |
|
final_screen.create(player) |
|
end |
|
end |
|
|
|
story_init_helpers(story_table) |
|
|
|
local story_events = |
|
{ |
|
defines.events.on_tick, |
|
defines.events.on_train_changed_state |
|
} |
|
|
|
local build_events = |
|
{ |
|
defines.events.on_built_entity, |
|
defines.events.on_robot_built_entity, |
|
defines.events.script_raised_built, |
|
defines.events.script_raised_revive |
|
} |
|
|
|
local on_built_entity = function(event) |
|
|
|
local entity = event.entity or event.created_entity |
|
if not (entity and entity.valid) then return end |
|
|
|
if entity.name == "car" then |
|
global.cars[entity.unit_number] = entity |
|
end |
|
|
|
end |
|
|
|
local on_player_driving_changed_state = function(event) |
|
|
|
local car = event.entity |
|
if not (car and car.valid) then return end |
|
|
|
if car.name ~= "car" then return end |
|
|
|
global.cars[car.unit_number] = car |
|
|
|
end |
|
|
|
script.on_event(story_events, function(event) |
|
story_update(global.story, event) |
|
end) |
|
|
|
script.on_event(defines.events.on_player_created, on_player_created) |
|
|
|
script.on_event(build_events, on_built_entity) |
|
script.on_event(defines.events.on_player_driving_changed_state, on_player_driving_changed_state) |
|
script.on_event(defines.events.on_gui_click, final_screen.on_gui_click) |
|
script.on_event(defines.events.on_gui_closed, final_screen.on_gui_closed) |
|
script.on_event(defines.events.on_string_translated, on_string_translated) |
|
|