mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 07:24:52 +09:00
Reimplement core method for crafting_queue sync
* New method avoids all dataloss and prefectly replicates the queue * Made proper description in readme * Added packages to make lerna build happy * Added reference to main readme
This commit is contained in:
1 parent
87218e4803
commit
a4a667ef06
7 files changed
+91
-43
No files matched your search
@@ -34,7 +34,7 @@ inventory_sync.events[defines.events.on_player_joined_game] = function(event)
|
||||
end
|
||||
|
||||
-- Upload inventory when a player leaves the game. Triggers on restart after crash if player was online during crash.
|
||||
inventory_sync.events[defines.events.on_player_left_game] = function(event)
|
||||
inventory_sync.events[defines.events.on_pre_player_left_game] = function(event)
|
||||
local playerIndex = event.player_index
|
||||
inventory_sync.uploadInventory(playerIndex)
|
||||
global.download_cache[playerIndex] = "" -- Clear cache to avoid leaking memory to people quitting during download
|
||||
|
||||
@@ -3,33 +3,28 @@ function load_crafting_queue(crafting_queue, player)
|
||||
local inventory = player.get_main_inventory()
|
||||
|
||||
-- Give player some more inventory space to avoid duplicating items
|
||||
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 100
|
||||
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 1000
|
||||
|
||||
-- Add items to inventory
|
||||
for _, item in pairs(crafting_queue.ingredients) do
|
||||
inventory.insert(item)
|
||||
end
|
||||
|
||||
-- Load crafting queue
|
||||
for _, queueItem in pairs(crafting_queue) do
|
||||
for _, queueItem in pairs(crafting_queue.crafting_queue) do
|
||||
local recipe = game.recipe_prototypes[queueItem.recipe]
|
||||
game.print("Crafting "..queueItem.recipe)
|
||||
-- Add items to inventory
|
||||
for _, item in pairs(recipe.ingredients) do
|
||||
local count = math.floor(item.amount * queueItem.count / math.max(recipe.main_product.amount, 1))
|
||||
if count > 0 then
|
||||
inventory.insert({
|
||||
name = item.name,
|
||||
count = count,
|
||||
})
|
||||
end
|
||||
end
|
||||
-- game.print("Crafting "..queueItem.recipe)
|
||||
|
||||
-- Start crafting (consume items)
|
||||
player.begin_crafting {
|
||||
count = queueItem.count,
|
||||
recipe = queueItem.recipe,
|
||||
silent = true, -- Fail silently if items are missing
|
||||
-- silent = true, -- Fail silently if items are missing
|
||||
}
|
||||
end
|
||||
|
||||
-- Remove extra inventory slots
|
||||
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus - 100
|
||||
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus - 1000
|
||||
end
|
||||
|
||||
return load_crafting_queue
|
||||
@@ -9,46 +9,87 @@ function save_crafts(event)
|
||||
return
|
||||
end
|
||||
|
||||
-- Serialize crafting queue
|
||||
if player.crafting_queue == nil then
|
||||
player.print("You can't save nothing, you silly goose")
|
||||
return
|
||||
end
|
||||
for _, queueItem in pairs(player.crafting_queue) do
|
||||
crafting_queue[queueItem.index] = {
|
||||
count = queueItem.count,
|
||||
recipe = queueItem.recipe,
|
||||
}
|
||||
end
|
||||
|
||||
-- Give player some more inventory space to avoid duplicating items
|
||||
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 100
|
||||
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus + 1000
|
||||
|
||||
-- Save current items
|
||||
local inventory = player.get_main_inventory()
|
||||
local old_items = inventory.get_contents()
|
||||
|
||||
-- Cancel old crafts to get the items back
|
||||
while player.crafting_queue_size > 0 do
|
||||
local old_queue = player.crafting_queue
|
||||
local queueItem = player.crafting_queue[1]
|
||||
local recipe = game.recipe_prototypes[queueItem.recipe]
|
||||
|
||||
|
||||
-- Cancel craft
|
||||
player.cancel_crafting {
|
||||
index = 1,
|
||||
count = 1,
|
||||
}
|
||||
|
||||
-- Remove ingredients from inventory
|
||||
for _, item in pairs(recipe.ingredients) do
|
||||
local inventory = player.get_main_inventory()
|
||||
inventory.remove({
|
||||
name = item.name,
|
||||
count = item.amount,
|
||||
local rightmost_right_index = 0 -- 0 indexed since it is subtractive in a 1 indexed language
|
||||
local new_queue = player.crafting_queue
|
||||
while
|
||||
new_queue ~= nil and
|
||||
new_queue[#new_queue - rightmost_right_index] ~= nil and
|
||||
new_queue[#new_queue - rightmost_right_index].count >= old_queue[#old_queue - rightmost_right_index].count
|
||||
do
|
||||
rightmost_right_index = rightmost_right_index + 1
|
||||
end
|
||||
local oldItem = old_queue[#old_queue - rightmost_right_index]
|
||||
local newItem = nil
|
||||
if new_queue ~= nil then
|
||||
newItem = new_queue[#new_queue - rightmost_right_index]
|
||||
end
|
||||
|
||||
-- Figure out how many items to add to queue
|
||||
local added = oldItem.count
|
||||
if newItem ~= nil then
|
||||
added = oldItem.count - newItem.count
|
||||
if oldItem.recipe ~= newItem.recipe then
|
||||
log("ERROR: Old item "..oldItem.recipe.." is not equal "..newItem.recipe)
|
||||
end
|
||||
end
|
||||
|
||||
-- If the last item we added was of the same type, merge them in the queue
|
||||
if #crafting_queue > 0 and crafting_queue[#crafting_queue].recipe == oldItem.recipe then
|
||||
crafting_queue[#crafting_queue].count = crafting_queue[#crafting_queue].count + added
|
||||
else
|
||||
-- If the last item was of a different type, add a new item to the queue
|
||||
table.insert(crafting_queue, {
|
||||
recipe = oldItem.recipe,
|
||||
count = added,
|
||||
})
|
||||
end
|
||||
game.print("Canceled craft "..recipe.name)
|
||||
-- game.print("Saved craft "..oldItem.recipe)
|
||||
end
|
||||
|
||||
-- Find amount of items added and remove from inventory
|
||||
local new_items = inventory.get_contents()
|
||||
local difference = {}
|
||||
for k,v in pairs(new_items) do
|
||||
local old_count = old_items[k]
|
||||
local diff = v
|
||||
if old_count ~= nil then
|
||||
diff = diff - old_count
|
||||
end
|
||||
if diff > 0 then
|
||||
local ingredient = {
|
||||
name = k,
|
||||
count = diff,
|
||||
}
|
||||
inventory.remove(ingredient)
|
||||
table.insert(difference, ingredient)
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove extra inventory slots
|
||||
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus - 100
|
||||
player.character_inventory_slots_bonus = player.character_inventory_slots_bonus - 1000
|
||||
|
||||
global["saved_crafting_queue_"..player.name] = crafting_queue
|
||||
global["saved_crafting_queue_"..player.name] = {
|
||||
crafting_queue = crafting_queue,
|
||||
ingredients = difference,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local clusterio_api = require("modules/clusterio/api")
|
||||
local serialize = require("modules/clusterio/serialize")
|
||||
local inventories = require("modules/inventory_sync/define_player_inventories")
|
||||
local save_crafts = require("modules/inventory_sync/save_crafts")
|
||||
|
||||
function upload_inventory(playerIndex)
|
||||
local player = game.players[playerIndex]
|
||||
@@ -68,7 +69,8 @@ function upload_inventory(playerIndex)
|
||||
end
|
||||
end
|
||||
|
||||
-- Serialize crafting queue saved by /csc or /save-crafts
|
||||
-- Serialize crafting queue saved by /csc or /save-crafts OR automatically
|
||||
save_crafts({player_index = player.name})
|
||||
serialized_player.crafting_queue = global["saved_crafting_queue_"..player.name]
|
||||
if serialized_player.crafting_queue == nil then
|
||||
serialized_player.crafting_queue = {}
|
||||
|
||||
Reference in new issue
Block a user