You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
7.0 KiB

local Arco = {}
Arco.name_gravimetrics_lab = mod_prefix.."space-gravimetrics-laboratory"
Arco.name_arcosphere_collector = mod_prefix.."arcosphere-collector"
Arco.name_arcosphere = mod_prefix.."arcosphere"
Arco.collection_global = 0.8
Arco.collection_local = 0.2 -- there are 44 space zones so this needs to be low, 0.2 means 8.8x the number of spheres are available.
function Arco.collector_get_orbs(force_name, zone_index)
local forcedata = global.forces[force_name]
-- global factor
forcedata.arcosphere_collectors_launched = forcedata.arcosphere_collectors_launched or 0
forcedata.arcospheres_collected = forcedata.arcospheres_collected or 0
local launched_global = forcedata.arcosphere_collectors_launched
local collected_next_global = math.ceil(Arco.collection_global * (math.log(launched_global+1+10)*50-math.log(10)*50))
local collect_global = math.max(0, collected_next_global - forcedata.arcospheres_collected)
-- local factor
forcedata.zone_arcospheres = forcedata.zone_arcospheres or {}
forcedata.zone_arcospheres[zone_index] = forcedata.zone_arcospheres[zone_index] or {}
forcedata.zone_arcospheres[zone_index].arcosphere_collectors_launched = forcedata.zone_arcospheres[zone_index].arcosphere_collectors_launched or 0
forcedata.zone_arcospheres[zone_index].arcospheres_collected = forcedata.zone_arcospheres[zone_index].arcospheres_collected or 0
local launched_local = forcedata.zone_arcospheres[zone_index].arcosphere_collectors_launched
local collected_next_local = math.ceil(Arco.collection_local * (math.log(launched_local+1+10)*50-math.log(10)*50))
local collect_local = math.max(0, collected_next_local - forcedata.zone_arcospheres[zone_index].arcospheres_collected)
Log.trace("launched global "..launched_global.." local "..launched_local)
Log.trace("collect global "..collect_global.." local "..collect_local)
return collect_global, collect_local -- returns 2 values
end
function Arco.collector_increment(force_name, zone_index)
local forcedata = global.forces[force_name]
forcedata.arcosphere_collectors_launched = (forcedata.arcosphere_collectors_launched or 0) + 1
forcedata.zone_arcospheres = forcedata.zone_arcospheres or {}
forcedata.zone_arcospheres[zone_index] = forcedata.zone_arcospheres[zone_index] or {}
forcedata.zone_arcospheres[zone_index].arcosphere_collectors_launched = (forcedata.zone_arcospheres[zone_index].arcosphere_collectors_launched or 0) + 1
end
function Arco.on_rocket_launched(event)
if event.rocket and event.rocket.valid then
local zone = Zone.from_surface(event.rocket.surface)
if event.rocket.get_item_count(Arco.name_arcosphere_collector) > 0 then
if zone and zone.type == "asteroid-field" then
local inv = event.rocket_silo.get_inventory(defines.inventory.rocket_silo_result)
local empty = inv.count_empty_stacks(true)
local forcedata = global.forces[event.rocket.force.name]
local inserted = 0
local spheres_global, spheres_local = Arco.collector_get_orbs(event.rocket.force.name, zone.index) -- gets 2 values
Log.trace("on_rocket_launched empty slots: " .. empty)
if empty > 0 then
if spheres_global + spheres_local > 0 then
inserted = inserted + inv.insert({name=Arco.name_arcosphere, count= spheres_global + spheres_local})
end
if inserted > 1 then
event.rocket.force.item_production_statistics.on_flow(Arco.name_arcosphere, inserted)
end
end
local inserted_global = math.min(spheres_global, inserted) -- remove from global pool first
local inserted_local = inserted - inserted_global
if inserted_global > 0 then
forcedata.arcospheres_collected = (forcedata.arcospheres_collected or 0) + inserted_global
end
if inserted_local > 0 then
forcedata.zone_arcospheres[zone.index].arcospheres_collected = (forcedata.zone_arcospheres[zone.index].arcospheres_collected or 0) + inserted_local
end
Arco.collector_increment(event.rocket.force.name, zone.index)
end
end
end
end
Event.addListener(defines.events.on_rocket_launched, Arco.on_rocket_launched)
function Arco.on_rocket_launch_ordered(event)
if event.rocket and event.rocket.valid then
local zone = Zone.from_surface(event.rocket.surface)
if event.rocket.get_item_count(Arco.name_arcosphere_collector) > 0 then
if not (zone and zone.type == "asteroid-field") then
-- launch location is invalid.
local tick_task = new_tick_task("force-message")
tick_task.force_name = event.rocket.force.name
tick_task.message = {"space-exploration.arcosphere_collector_invalid_launch"}
tick_task.delay_until = game.tick + 750 --5s
event.rocket.remove_item({name=Arco.name_arcosphere_collector, count=1})
end
end
end
end
Event.addListener(defines.events.on_rocket_launch_ordered, Arco.on_rocket_launch_ordered)
function Arco.on_entity_created(event)
local entity
if event.entity and event.entity.valid then entity = event.entity end
if event.created_entity and event.created_entity.valid then entity = event.created_entity end
if not entity then return end
if entity.name == Arco.name_gravimetrics_lab then
global.gravimetrics_labs = global.gravimetrics_labs or {}
global.gravimetrics_labs[entity.unit_number] = {
unit_unber = entity.unit_number,
force_name = entity.force.name,
entity = entity,
products_finished = 0
}
end
end
Event.addListener(defines.events.on_built_entity, Arco.on_entity_created)
Event.addListener(defines.events.on_robot_built_entity, Arco.on_entity_created)
Event.addListener(defines.events.script_raised_built, Arco.on_entity_created)
Event.addListener(defines.events.script_raised_revive, Arco.on_entity_created)
function Arco.reset_surface(surface)
for _, entity in pairs(surface.find_entities_filtered{name = Arco.name_gravimetrics_lab}) do
Arco.on_entity_created({entity = entity})
end
end
function Arco.swap_recipe(lab)
local recipe = lab.entity.get_recipe()
local set_recipe
if recipe then
if string.find(recipe.name, "-alt", 1, true) then
set_recipe = Util.replace(recipe.name, "-alt", "")
else
if game.recipe_prototypes[recipe.name.."-alt"] then
set_recipe = recipe.name.."-alt"
end
end
end
if set_recipe then
local crafting_progress = lab.entity.crafting_progress
lab.entity.set_recipe(set_recipe)
lab.entity.crafting_progress = crafting_progress
end
end
function Arco.on_nth_tick_600()
if global.gravimetrics_labs then
for unit_number, lab in pairs(global.gravimetrics_labs) do
if lab.entity and lab.entity.valid then
if lab.entity.products_finished ~= lab.products_finished then
lab.products_finished = lab.entity.products_finished
if math.random() < 0.314 then
Arco.swap_recipe(lab)
end
end
else
global.gravimetrics_labs[unit_number] = nil
end
end
end
end
Event.addListener("on_nth_tick_60", Arco.on_nth_tick_600) -- 10 seconds
return Arco