local Chrono_table = require 'maps.chronosphere.table' local Balance = require 'maps.chronosphere.balance' local Public = {} local Upgrades = require "maps.chronosphere.upgrade_list" local math_floor = math.floor local math_random = math.random local function math_sgn(x) return (x<0 and -1) or 1 end function Public.locomotive_spawn(surface, position, wagons) surface.request_to_generate_chunks(position, 0.5) surface.force_generate_chunk_requests() local objective = Chrono_table.get_table() if objective.planet[1].type.id == 17 then --fish market position.x = position.x - 960 position.y = position.y - 64 end for y = -10, 18, 2 do local rail = {name = "straight-rail", position = {position.x, position.y + y}, force = "player", direction = 0} surface.create_entity({name = "straight-rail", position = {position.x, position.y + y}, force = "player", direction = 0}) end objective.locomotive = surface.create_entity({name = "locomotive", position = {position.x, position.y + -6}, force = "player"}) objective.locomotive.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 100}) for i = 1, 3, 1 do objective.locomotive_cargo[i] = surface.create_entity({name = "cargo-wagon", position = {position.x, position.y + math_floor((i - 1) * 6.5)}, force = "player"}) local inv = objective.locomotive_cargo[i].get_inventory(defines.inventory.cargo_wagon) if wagons[i].bar > 0 then inv.set_bar(wagons[i].bar) end for ii = 1, 40, 1 do inv.set_filter(ii, wagons[i].filters[ii]) if wagons[i].inventory[ii] then inv.insert(wagons[i].inventory[ii]) end end objective.locomotive_cargo[i].minable = false end objective.locomotive_cargo[1].operable = false objective.locomotive.color = {0, 255, 0} objective.locomotive.minable = false --if not objective.comfychests then objective.comfychests = {} end --if not objective.accumulators then objective.accumulators = {} end for i = 1, 24, 1 do local yi = 0 local xi = 5 if i > 20 then yi = 6 - 12 xi = 5 elseif i > 16 then yi = 6 - 15 xi = 5 elseif i > 12 then xi = 5 yi = 6 - 18 elseif i > 8 then yi = 6 xi = 0 elseif i > 4 then yi = 3 xi = 0 else yi = 0 xi = 0 end local comfychest = surface.create_entity({name = "blue-chest", position = {position.x - 2 + xi, position.y - 2 + yi + i}, force = "player"}) comfychest.minable = false --comfychest.destructible = false if not objective.comfychests[i] then table.insert(objective.comfychests, comfychest) else objective.comfychests[i] = comfychest end end rendering.draw_light({ sprite = "utility/light_medium", scale = 5.5, intensity = 1, minimum_darkness = 0, oriented = true, color = {255,255,255}, target = objective.locomotive, surface = surface, visible = true, only_in_alt_mode = false, }) rendering.draw_light({ sprite = "utility/light_medium", scale = 5.5, intensity = 1, minimum_darkness = 0, oriented = true, color = {255,255,255}, target = objective.locomotive_cargo[3], surface = surface, visible = true, only_in_alt_mode = false, }) end function Public.fish_tag() local objective = Chrono_table.get_table() if not objective.locomotive_cargo[1] then return end local cargo = objective.locomotive_cargo[1] if not cargo.valid then return end if not cargo.surface then return end if not cargo.surface.valid then return end if objective.locomotive_tag then if objective.locomotive_tag.valid then if objective.locomotive_tag.position.x == cargo.position.x and objective.locomotive_tag.position.y == cargo.position.y then return end objective.locomotive_tag.destroy() end end objective.locomotive_tag = cargo.force.add_chart_tag( cargo.surface, {icon = {type = 'item', name = 'raw-fish'}, position = cargo.position, text = " " }) end function Public.create_wagon_room() local objective = Chrono_table.get_table() local width = 64 local height = 384 objective.comfychests2 = {} objective.accumulators = {} local map_gen_settings = { ["width"] = width, ["height"] = height + 128, ["water"] = 0, ["starting_area"] = 1, ["cliff_settings"] = {cliff_elevation_interval = 0, cliff_elevation_0 = 0}, ["default_enable_all_autoplace_controls"] = true, ["autoplace_settings"] = { ["entity"] = {treat_missing_as_default = false}, ["tile"] = {treat_missing_as_default = true}, ["decorative"] = {treat_missing_as_default = false}, }, } if not game.surfaces["cargo_wagon"] then game.create_surface("cargo_wagon", map_gen_settings) end local surface = game.surfaces["cargo_wagon"] surface.freeze_daytime = true surface.daytime = 0.1 surface.request_to_generate_chunks({0,0}, 12) surface.force_generate_chunk_requests() local carfpos = { [1]={x=-33,y=-127},[2]={x=-33,y=-128},[3]={x=-33,y=-129},[4]={x=-33,y=-130},[5]={x=32,y=-127},[6]={x=32,y=-128},[7]={x=32,y=-129},[8]={x=32,y=-130}, [9]={x=-33,y=-2},[10]={x=-33,y=-1},[11]={x=-33,y=0},[12]={x=-33,y=1},[13]={x=32,y=-2},[14]={x=32,y=-1},[15]={x=32,y=0},[16]={x=32,y=1}, [17]={x=-33,y=126},[18]={x=-33,y=127},[19]={x=-33,y=128},[20]={x=-33,y=129},[21]={x=32,y=126},[22]={x=32,y=127},[23]={x=32,y=128},[24]={x=32,y=129} } for i = 1, 24, 1 do surface.set_tiles({{name = "tutorial-grid", position = {carfpos[i].x,carfpos[i].y}}}) end for x = width * -0.5, width * 0.5 - 1, 1 do for y = height * 0.5, height * 0.7, 1 do surface.set_tiles({{name = "out-of-map", position = {x,y}}}) end for y = height * -0.7, height * -0.5, 1 do surface.set_tiles({{name = "out-of-map", position = {x,y}}}) end for y = height * -0.5 + 3, height * 0.5 - 4, 1 do surface.set_tiles({{name = "tutorial-grid", position = {x,y}}}) end for y = height * -0.16 - 5, height * -0.16 + 0, 1 do surface.set_tiles({{name = "out-of-map", position = {x,y}}}) end for y = height * 0.16 - 0, height * 0.16 + 5, 1 do surface.set_tiles({{name = "out-of-map", position = {x,y}}}) end for y = height * -0.5, height * -0.5 + 2, 1 do surface.set_tiles({{name = "out-of-map", position = {x,y}}}) end for y = height * 0.5 - 3, height * 0.5, 1 do surface.set_tiles({{name = "out-of-map", position = {x,y}}}) end end for x = width * -0.2 + 1, width * 0.2 - 1, 1 do for y = height * -0.16 - 5, height * -0.16 + 0, 1 do surface.set_tiles({{name = "tutorial-grid", position = {x,y}}}) end for y = height * 0.16 -0, height * 0.16 + 5, 1 do surface.set_tiles({{name = "tutorial-grid", position = {x,y}}}) end --for y = height * -0.5 -5, height * -0.5 + 3, 1 do -- surface.set_tiles({{name = "tutorial-grid", position = {x,y}}}) --end end for x = width * -0.5 + 5, width * 0.5 - 6, 1 do for y = height * -0.7 + 18, height * -0.5 - 5, 1 do surface.set_tiles({{name = "tutorial-grid", position = {x,y}}}) end end for x = width * -0.5 - 6, width * -0.5 + 3, 1 do -- combinators for y = -251, -241, 1 do surface.set_tiles({{name = "tutorial-grid", position = {x,y}}}) end end for x = width * -0.4 + 6, width * 0.4 - 6, 1 do for y = height * -0.5 + 7, height * -0.5 + 10, 1 do local p = {x,y} surface.set_tiles({{name = "water", position = p}}) if math_random(1, 3) == 1 and (x ~= width * -0.4 + 6) and (y ~= height * -0.5 + 7) then surface.create_entity({name = "fish", position = p}) end end end local combinators = {} for x = width * -0.5 - 6, width * -0.5 + 3, 1 do for y = -250, -244, 2 do combinators[#combinators + 1] = {name = "arithmetic-combinator", position = {x, y}, force = "player", create_build_effect_smoke = false} end end local combimade = {} for i = 1, #combinators, 1 do combimade[i] = surface.create_entity(combinators[i]) combimade[i].minable = false combimade[i].destructible = false combimade[i].operable = false if i > 1 then combimade[i].connect_neighbour({wire = defines.wire_type.green, target_entity = combimade[i - 1], source_circuit_id = 2, target_circuit_id = 1}) local rule = combimade[i].get_or_create_control_behavior() rule.parameters = {parameters = {first_signal = {type = "virtual", name = "signal-A"}, second_constant = 0, operation = "+", output_signal = {type = "virtual", name = "signal-A"}}} else local rule2 = combimade[i].get_or_create_control_behavior() rule2.parameters = {parameters = {first_signal = {type = "virtual", name = "signal-A"}, second_constant = 0, operation = "+", output_signal = {type = "virtual", name = "signal-B"}}} end end local checker = surface.create_entity({name = "decider-combinator", position = {x = width * -0.5 - 6, y = -242}, force = "player", create_build_effect_smoke = false }) local rules3 = checker.get_or_create_control_behavior() rules3.parameters = {parameters = {first_signal = {type = "virtual", name = "signal-A"}, second_signal = {type = "virtual", name = "signal-B"}, comparator = ">", output_signal = {type = "virtual", name = "signal-C"}, copy_count_from_input = false }} local combipower = surface.create_entity({name = "substation", position = {x = width * -0.5 - 4, y = -242}, force="player", create_build_effect_smoke = false}) combipower.connect_neighbour({wire = defines.wire_type.green, target_entity = checker, target_circuit_id = 1}) combipower.connect_neighbour({wire = defines.wire_type.green, target_entity = combimade[#combimade], target_circuit_id = 1}) combimade[1].connect_neighbour({wire = defines.wire_type.green, target_entity = checker, source_circuit_id = 2, target_circuit_id = 1}) local speaker = surface.create_entity({name = "programmable-speaker", position = {x = width * -0.5 - 6, y = -241}, force = "player", create_build_effect_smoke = false, parameters = {playback_volume = 0.6, playback_globally = true, allow_polyphony = false}, alert_parameters = {show_alert = true, show_on_map = true, icon_signal_id = {type = "item", name = "accumulator"}, alert_message = "Train Is Charging!" }}) speaker.connect_neighbour({wire = defines.wire_type.green, target_entity = checker, target_circuit_id = 2}) local rules4 = speaker.get_or_create_control_behavior() rules4.circuit_condition = {condition = {first_signal = {type = "virtual", name = "signal-C"}, second_constant = 0, comparator = ">"}} rules4.circuit_parameters = {signal_value_is_pitch = false, instrument_id = 8, note_id = 5} local solar1 = surface.create_entity({name = "solar-panel", position = {x = width * -0.5 - 2, y = -242}, force="player", create_build_effect_smoke = false}) local solar2 = surface.create_entity({name = "solar-panel", position = {x = width * -0.5 + 1, y = -242}, force="player", create_build_effect_smoke = false}) solar1.destructible = false solar1.minable = false solar2.destructible = false solar2.minable = false combipower.destructible = false combipower.minable = false combipower.operable = false speaker.destructible = false speaker.minable = false speaker.operable = false checker.destructible = false checker.minable = false checker.operable = false for _, x in pairs({-1, 0}) do for i = 1, 12, 1 do local step = math_floor((i-1)/4) local y = -131 + i + step * 128 - step * 4 local e = surface.create_entity({name = "red-chest", position = {x,y}, force = "player", create_build_effect_smoke = false}) e.destructible = false e.minable = false table.insert(objective.comfychests2, e) end end for i = 1, 9, 1 do local y = -0.7 * height + 18 + 9 + 18 * ( math_floor((i - 1) / 3)) local x = -0.5 * width + 5 + 9 + 18 * ( i%3 ) local substation = surface.create_entity({name = "substation", position = {x,y}, force="player", create_build_effect_smoke = false}) if i == 3 then substation.disconnect_neighbour(combipower) substation.connect_neighbour({wire = defines.wire_type.green, target_entity = combipower}) end substation.minable = false substation.destructible = false for j = 1, 4, 1 do local xx = x - 2 * j local acumulator = surface.create_entity({name = "accumulator", position = {xx,y}, force="player", create_build_effect_smoke = false}) if i == 3 and j == 1 then acumulator.connect_neighbour({wire = defines.wire_type.green, target_entity = substation}) end acumulator.minable = false acumulator.destructible = false table.insert(objective.accumulators, acumulator) end for k = 1, 4, 1 do local xx = x + 2 * k local acumulator = surface.create_entity({name = "accumulator", position = {xx,y}, force="player", create_build_effect_smoke = false}) acumulator.minable = false acumulator.destructible = false table.insert(objective.accumulators, acumulator) end end local powerpole = surface.create_entity({name = "big-electric-pole", position = {0, height * -0.5 }, force="player", create_build_effect_smoke = false}) powerpole.minable = false powerpole.destructible = false local market = surface.create_entity({name = "market", position = {-29, height * -0.5 + 4}, force="neutral", create_build_effect_smoke = false}) market.minable = false market.destructible = false local repairchest = surface.create_entity({name = "blue-chest", position = {-24, height * -0.5 + 3}, force = "player"}) repairchest.minable = false repairchest.destructible = false objective.upgradechest[0] = repairchest rendering.draw_text{ text = "Repair Chest", surface = surface, target = repairchest, target_offset = {0, -2.5}, color = objective.locomotive.color, scale = 1.00, font = "default-game", alignment = "center", scale_with_zoom = false } local upgrades = Upgrades.upgrades() for i = 1, #upgrades, 1 do local e = surface.create_entity({name = "blue-chest", position = {-21 + i, height * -0.5 + 3}, force = "player"}) e.minable = false e.destructible = false objective.upgradechest[i] = e rendering.draw_sprite{ sprite = upgrades[i].sprite, surface = surface, target = e, target_offset = {0, -1.3}, font = "default-game", visible = true } end local market1_text = rendering.draw_text{ text = "Market", surface = surface, target = market, target_offset = {0, -3.5}, color = objective.locomotive.color, scale = 1.00, font = "default-game", alignment = "center", scale_with_zoom = false } local upgrade_text = rendering.draw_text{ text = "Upgrades", surface = surface, target = objective.upgradechest[8], target_offset = {0, -3.5}, color = objective.locomotive.color, scale = 1.00, font = "default-game", alignment = "center", scale_with_zoom = false } local upgrade_sub_text = rendering.draw_text{ text = "Click [Upgrades] at top of screen", surface = surface, target = objective.upgradechest[8], target_offset = {0, -2.5}, color = objective.locomotive.color, scale = 0.80, font = "default-game", alignment = "center", scale_with_zoom = false } for _, offer in pairs(Balance.market_offers()) do market.add_market_item(offer) end --generate cars-- local car_pos = { {x = width * -0.5 - 1.4, y = -128}, {x = width * -0.5 - 1.4, y = 0}, {x = width * -0.5 - 1.4, y = 128}, {x = width * 0.5 + 1.4, y = -128}, {x = width * 0.5 + 1.4, y = 0}, {x = width * 0.5 + 1.4, y = 128} } objective.car_exits = {} for i = 1, 6, 1 do local e = surface.create_entity({name = "car", position = car_pos[i], force = "player", create_build_effect_smoke = false}) e.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 16}) e.destructible = false e.minable = false e.operable = false objective.car_exits[i] = e end --generate chests inside south wagon-- local positions = {} for x = width * -0.5 + 2, width * 0.5 - 1, 1 do if x == -1 then x = x - 1 end if x == 0 then x = x + 1 end for y = 68, height * 0.5 - 4, 1 do positions[#positions + 1] = {x = x, y = y} end end table.shuffle_table(positions) local cargo_boxes = Balance.initial_cargo_boxes() local i = 1 for _ = 1, 16, 1 do if not positions[i] then break end local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false}) local inventory = e.get_inventory(defines.inventory.chest) inventory.insert({name = "raw-fish", count = math_random(2, 5)}) i = i + 1 end for _ = 1, 24, 1 do if not positions[i] then break end local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false}) i = i + 1 end for loot_i = 1, #cargo_boxes, 1 do if not positions[i] then log("ran out of cargo box positions") break end local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false}) local inventory = e.get_inventory(defines.inventory.chest) inventory.insert(cargo_boxes[loot_i]) i = i + 1 end end function Public.set_player_spawn_and_refill_fish() local objective = Chrono_table.get_table() if not objective.locomotive_cargo[1] then return end local cargo = objective.locomotive_cargo[1] if not cargo.valid then return end cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = "raw-fish", count = 1}) local position = cargo.surface.find_non_colliding_position("stone-furnace", cargo.position, 16, 2) if not position then return end game.forces.player.set_spawn_position({x = position.x, y = position.y}, cargo.surface) end function Public.award_coins(_count) if not (_count >= 1) then return end local objective = Chrono_table.get_table() if not objective.locomotive_cargo[1] then return end local cargo = objective.locomotive_cargo[1] if not cargo.valid then return end cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = "coin", count = math_floor(_count)}) end function Public.enter_cargo_wagon(player, vehicle) local objective = Chrono_table.get_table() if not vehicle then log("no vehicle") return end if not vehicle.valid then log("vehicle invalid") return end if not objective.locomotive then log("locomotive missing") return end if not objective.locomotive.valid then log("locomotive invalid") return end if not game.surfaces["cargo_wagon"] then Public.create_wagon_room() end local wagon_surface = game.surfaces["cargo_wagon"] if vehicle.type == "cargo-wagon" then for i = 1, 3, 1 do if not objective.locomotive_cargo[i] then log("no cargo") return end if not objective.locomotive_cargo[i].valid then log("cargo invalid") return end if vehicle == objective.locomotive_cargo[i] then local x_vector = vehicle.position.x - player.position.x local position if x_vector > 0 then position = {wagon_surface.map_gen_settings.width * -0.5, -128 + 128 * (i - 1)} else position = {wagon_surface.map_gen_settings.width * 0.5, -128 + 128 * (i - 1)} end player.teleport(wagon_surface.find_non_colliding_position("character", position, 128, 0.5), wagon_surface) break end end end if player.surface.name == "cargo_wagon" and vehicle.type == "car" then if objective.flame_boots then objective.flame_boots[player.index] = {fuel = 1, steps = {}} end local used_exit = 0 for i = 1, 6, 1 do if vehicle == objective.car_exits[i] then used_exit = i break end end local surface = objective.locomotive.surface local position if used_exit == 0 or objective.game_lost then position = game.forces.player.get_spawn_position(surface) else position = {x = objective.locomotive_cargo[((used_exit - 1) % 3) + 1].position.x + math_sgn(used_exit - 3.5) * 2, y = objective.locomotive_cargo[((used_exit - 1) % 3) + 1].position.y} end local position2 = surface.find_non_colliding_position("character", position, 128, 0.5) if not position2 then return end player.teleport(position2, surface) end end return Public