284 lines
9.0 KiB
Lua
284 lines
9.0 KiB
Lua
require 'gui'
|
|
|
|
local shared = require 'shared'
|
|
local update_rate = shared.update_rate
|
|
local update_slots = shared.update_slots
|
|
local compactify = shared.compactify
|
|
local validity_check = shared.validity_check
|
|
local combine_tempatures = shared.combine_tempatures
|
|
|
|
local function setup()
|
|
global.units = global.units or {}
|
|
|
|
if remote.interfaces['PickerDollies'] then
|
|
remote.call('PickerDollies', 'add_blacklist_name', 'fluid-memory-unit', true)
|
|
remote.call('PickerDollies', 'add_blacklist_name', 'fluid-memory-unit-combinator', true)
|
|
end
|
|
end
|
|
|
|
script.on_init(setup)
|
|
script.on_configuration_changed(function()
|
|
setup()
|
|
|
|
for unit_number, unit_data in pairs(global.units) do
|
|
if unit_data.item and not validity_check(unit_number, unit_data) then
|
|
if not game.fluid_prototypes[unit_data.item] then shared.memory_unit_corruption(unit_number, unit_data) end
|
|
end
|
|
end
|
|
end)
|
|
|
|
local min = math.min
|
|
local function render_fluid_animation(item, entity)
|
|
local color = game.fluid_prototypes[item].base_color
|
|
rendering.draw_animation{
|
|
animation = 'fluid-memory-unit-animation',
|
|
tint = {
|
|
min(0.9, color.r + 0.2),
|
|
min(0.9, color.g + 0.2),
|
|
min(0.9, color.b + 0.2)
|
|
},
|
|
render_layer = 'higher-object-above',
|
|
target = entity,
|
|
surface = entity.surface
|
|
}
|
|
end
|
|
|
|
local function update_unit_exterior(unit_data, inventory_count)
|
|
local entity = unit_data.entity
|
|
unit_data.previous_inventory_count = inventory_count
|
|
local total_count = unit_data.count + inventory_count
|
|
|
|
if inventory_count > 0 then
|
|
local temperature = combine_tempatures(unit_data.count, unit_data.temperature, inventory_count, entity.fluidbox[1].temperature)
|
|
entity.fluidbox[1].temperature = temperature
|
|
unit_data.temperature = temperature
|
|
end
|
|
|
|
shared.update_combinator(unit_data.combinator, {type = 'fluid', name = unit_data.item}, total_count)
|
|
shared.update_display_text(unit_data, entity, compactify(total_count))
|
|
shared.update_power_usage(unit_data, total_count)
|
|
end
|
|
|
|
local function detect_item(unit_data)
|
|
local fluidbox = unit_data.entity.fluidbox
|
|
local fluid = fluidbox[1]
|
|
if fluid then
|
|
fluidbox.set_filter(1, {name = fluid.name, force = true})
|
|
render_fluid_animation(fluid.name, unit_data.entity)
|
|
unit_data.item = fluid.name
|
|
unit_data.temperature = fluid.temperature
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function update_unit(unit_data, unit_number, force)
|
|
local entity = unit_data.entity
|
|
local powersource = unit_data.powersource
|
|
local combinator = unit_data.combinator
|
|
local container = unit_data.container
|
|
|
|
if validity_check(unit_number, unit_data, force) then return end
|
|
|
|
local changed = false
|
|
|
|
if unit_data.item == nil then changed = detect_item(unit_data) end
|
|
local item = unit_data.item
|
|
if item == nil then return end
|
|
local comfortable = unit_data.comfortable
|
|
|
|
local inventory_count = entity.get_fluid_count(item)
|
|
if inventory_count > comfortable then
|
|
local amount_removed = entity.remove_fluid{name = item, amount = inventory_count - comfortable}
|
|
unit_data.temperature = combine_tempatures(unit_data.count, unit_data.temperature, amount_removed, entity.fluidbox[1].temperature)
|
|
unit_data.count = unit_data.count + amount_removed
|
|
inventory_count = inventory_count - amount_removed
|
|
changed = true
|
|
elseif inventory_count < comfortable then
|
|
if unit_data.previous_inventory_count ~= inventory_count then
|
|
changed = true
|
|
end
|
|
local to_add = comfortable - inventory_count
|
|
if unit_data.count < to_add then
|
|
to_add = unit_data.count
|
|
end
|
|
if to_add ~= 0 then
|
|
local amount_added = entity.insert_fluid{name = item, amount = to_add, temperature = unit_data.temperature}
|
|
unit_data.count = unit_data.count - amount_added
|
|
inventory_count = inventory_count + amount_added
|
|
end
|
|
end
|
|
|
|
if force or changed then update_unit_exterior(unit_data, inventory_count) end
|
|
end
|
|
|
|
script.on_nth_tick(update_rate, function(event)
|
|
local smooth_ups = event.tick % update_slots
|
|
|
|
for unit_number, unit_data in pairs(global.units) do
|
|
if unit_data.lag_id == smooth_ups then
|
|
update_unit(unit_data, unit_number)
|
|
end
|
|
end
|
|
end)
|
|
|
|
local function on_created(event)
|
|
local entity = event.created_entity or event.entity
|
|
if entity.name ~= 'fluid-memory-unit' then return end
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
local force = entity.force
|
|
|
|
local combinator = surface.create_entity{
|
|
name = 'fluid-memory-unit-combinator',
|
|
position = {position.x, position.y - 1.25},
|
|
force = force
|
|
}
|
|
combinator.operable = false
|
|
combinator.destructible = false
|
|
|
|
local powersource = surface.create_entity{
|
|
name = 'fluid-memory-unit-powersource',
|
|
position = position,
|
|
force = force
|
|
}
|
|
powersource.destructible = false
|
|
|
|
local unit_data = {
|
|
entity = entity,
|
|
comfortable = 0.5 * entity.fluidbox.get_capacity(1),
|
|
powersource = powersource,
|
|
combinator = combinator,
|
|
count = 0,
|
|
lag_id = math.random(0, update_slots - 1)
|
|
}
|
|
global.units[entity.unit_number] = unit_data
|
|
|
|
local stack = event.stack
|
|
local tags = stack and stack.valid_for_read and stack.type == 'item-with-tags' and stack.tags
|
|
if tags and tags.name then
|
|
unit_data.count = tags.count
|
|
unit_data.temperature = tags.temperature
|
|
unit_data.item = tags.name
|
|
entity.fluidbox.set_filter(1, {name = tags.name, force = true})
|
|
render_fluid_animation(tags.name, entity)
|
|
update_unit(unit_data, entity.unit_number, true)
|
|
else
|
|
shared.update_power_usage(unit_data, 0)
|
|
end
|
|
end
|
|
|
|
script.on_event(defines.events.on_built_entity, on_created)
|
|
script.on_event(defines.events.on_robot_built_entity, on_created)
|
|
script.on_event(defines.events.script_raised_built, on_created)
|
|
script.on_event(defines.events.script_raised_revive, on_created)
|
|
|
|
script.on_event(defines.events.on_entity_cloned, function(event)
|
|
local entity = event.source
|
|
if entity.name ~= 'fluid-memory-unit' then return end
|
|
local destination = event.destination
|
|
|
|
local unit_data = global.units[entity.unit_number]
|
|
local position = destination.position
|
|
local surface = destination.surface
|
|
|
|
local powersource, combinator = unit_data.powersource, unit_data.combinator
|
|
|
|
if powersource.valid then
|
|
powersource = powersource.clone{position = position, surface = surface}
|
|
else
|
|
powersource = surface.create_entity{
|
|
name = 'memory-unit-powersource',
|
|
position = position,
|
|
force = force
|
|
}
|
|
powersource.destructible = false
|
|
end
|
|
|
|
if combinator.valid then
|
|
combinator = combinator.clone{position = {position.x, position.y - 1.25}, surface = surface}
|
|
else
|
|
combinator = surface.create_entity{
|
|
name = 'fluid-memory-unit-combinator',
|
|
position = {position.x, position.y - 1.25},
|
|
force = force
|
|
}
|
|
combinator.destructible = false
|
|
combinator.operable = false
|
|
end
|
|
|
|
local item = unit_data.item
|
|
global.units[destination.unit_number] = {
|
|
powersource = powersource,
|
|
combinator = combinator,
|
|
item = item,
|
|
count = unit_data.count,
|
|
entity = destination,
|
|
temperature = unit_data.temperature,
|
|
comfortable = unit_data.comfortable,
|
|
lag_id = math.random(0, update_slots - 1)
|
|
}
|
|
|
|
if item then
|
|
render_fluid_animation(item, destination)
|
|
destination.fluidbox.set_filter(1, {name = item, force = true})
|
|
update_unit(global.units[destination.unit_number], destination.unit_number, true)
|
|
end
|
|
end)
|
|
|
|
local function on_destroyed(event)
|
|
local entity = event.entity
|
|
if entity.name ~= 'fluid-memory-unit' then return end
|
|
|
|
local unit_data = global.units[entity.unit_number]
|
|
global.units[entity.unit_number] = nil
|
|
unit_data.powersource.destroy()
|
|
unit_data.combinator.destroy()
|
|
|
|
local item = unit_data.item
|
|
local count = unit_data.count
|
|
local buffer = event.buffer
|
|
|
|
if buffer and item and count ~= 0 then
|
|
buffer.clear()
|
|
buffer.insert('fluid-memory-unit-with-tags')
|
|
local stack = buffer.find_item_stack('fluid-memory-unit-with-tags')
|
|
local temperature = unit_data.temperature
|
|
stack.tags = {name = item, count = count, temperature = temperature}
|
|
stack.custom_description = {
|
|
'item-description.fluid-memory-unit-with-tags',
|
|
compactify(count),
|
|
item,
|
|
string.format('%.2f', temperature)
|
|
}
|
|
end
|
|
end
|
|
|
|
script.on_event(defines.events.on_player_mined_entity, on_destroyed)
|
|
script.on_event(defines.events.on_robot_mined_entity, on_destroyed)
|
|
script.on_event(defines.events.on_entity_died, on_destroyed)
|
|
script.on_event(defines.events.script_raised_destroy, on_destroyed)
|
|
|
|
local function pre_mined(event)
|
|
local entity = event.entity
|
|
if entity.name ~= 'fluid-memory-unit' then return end
|
|
|
|
local unit_data = global.units[entity.unit_number]
|
|
local item = unit_data.item
|
|
|
|
if item then
|
|
local in_inventory = entity.get_fluid_count(item)
|
|
|
|
if in_inventory > 0 then
|
|
local temperature = entity.fluidbox[1].temperature
|
|
local new_count = unit_data.count + entity.remove_fluid{name = item, amount = in_inventory}
|
|
unit_data.temperature = combine_tempatures(unit_data.count, unit_data.temperature, in_inventory, temperature)
|
|
unit_data.count = new_count
|
|
end
|
|
end
|
|
end
|
|
|
|
script.on_event(defines.events.on_pre_player_mined_item, pre_mined)
|
|
script.on_event(defines.events.on_robot_pre_mined, pre_mined)
|
|
script.on_event(defines.events.on_marked_for_deconstruction, pre_mined)
|