mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-06 00:23:49 +02:00
302 lines
8.0 KiB
Lua
302 lines
8.0 KiB
Lua
--[[
|
|
roll(budget, max_slots, blacklist) returns a table with item-stacks
|
|
budget - the total value of the item stacks combined
|
|
max_slots - the maximum amount of item stacks to return
|
|
blacklist - optional list of item names that can not be rolled. example: {["substation"] = true, ["roboport"] = true,}
|
|
]]
|
|
|
|
local Public = {}
|
|
|
|
local table_shuffle_table = table.shuffle_table
|
|
local table_insert = table.insert
|
|
local table_remove = table.remove
|
|
local math_random = math.random
|
|
local math_floor = math.floor
|
|
|
|
local item_worths = {
|
|
["wooden-chest"] = 4,
|
|
["iron-chest"] = 8,
|
|
["steel-chest"] = 64,
|
|
["storage-tank"] = 64,
|
|
["transport-belt"] = 4,
|
|
["fast-transport-belt"] = 16,
|
|
["express-transport-belt"] = 64,
|
|
["underground-belt"] = 16,
|
|
["fast-underground-belt"] = 64,
|
|
["express-underground-belt"] = 256,
|
|
["splitter"] = 16,
|
|
["fast-splitter"] = 64,
|
|
["express-splitter"] = 256,
|
|
["loader"] = 64,
|
|
["fast-loader"] = 256,
|
|
["express-loader"] = 1024,
|
|
["burner-inserter"] = 2,
|
|
["inserter"] = 8,
|
|
["long-handed-inserter"] = 16,
|
|
["fast-inserter"] = 32,
|
|
["filter-inserter"] = 40,
|
|
["stack-inserter"] = 128,
|
|
["stack-filter-inserter"] = 160,
|
|
["small-electric-pole"] = 4,
|
|
["medium-electric-pole"] = 32,
|
|
["big-electric-pole"] = 64,
|
|
["substation"] = 256,
|
|
["pipe"] = 1,
|
|
["pipe-to-ground"] = 15,
|
|
["pump"] = 32,
|
|
["rail"] = 8,
|
|
["train-stop"] = 64,
|
|
["rail-signal"] = 16,
|
|
["rail-chain-signal"] = 16,
|
|
["locomotive"] = 512,
|
|
["cargo-wagon"] = 256,
|
|
["fluid-wagon"] = 256,
|
|
["artillery-wagon"] = 16384,
|
|
["car"] = 128,
|
|
["tank"] = 4096,
|
|
["logistic-robot"] = 256,
|
|
["construction-robot"] = 256,
|
|
["logistic-chest-active-provider"] = 256,
|
|
["logistic-chest-passive-provider"] = 256,
|
|
["logistic-chest-storage"] = 256,
|
|
["logistic-chest-buffer"] = 512,
|
|
["logistic-chest-requester"] = 512,
|
|
["roboport"] = 2048,
|
|
["small-lamp"] = 16,
|
|
["red-wire"] = 4,
|
|
["green-wire"] = 4,
|
|
["arithmetic-combinator"] = 16,
|
|
["decider-combinator"] = 16,
|
|
["constant-combinator"] = 16,
|
|
["power-switch"] = 16,
|
|
["programmable-speaker"] = 32,
|
|
["stone-brick"] = 2,
|
|
["concrete"] = 4,
|
|
["hazard-concrete"] = 4,
|
|
["refined-concrete"] = 16,
|
|
["refined-hazard-concrete"] = 16,
|
|
["cliff-explosives"] = 256,
|
|
["repair-pack"] = 8,
|
|
["boiler"] = 8,
|
|
["steam-engine"] = 32,
|
|
["solar-panel"] = 64,
|
|
["accumulator"] = 64,
|
|
["nuclear-reactor"] = 8192,
|
|
["heat-pipe"] = 128,
|
|
["heat-exchanger"] = 256,
|
|
["steam-turbine"] = 256,
|
|
["burner-mining-drill"] = 8,
|
|
["electric-mining-drill"] = 32,
|
|
["offshore-pump"] = 16,
|
|
["pumpjack"] = 64,
|
|
["stone-furnace"] = 4,
|
|
["steel-furnace"] = 64,
|
|
["electric-furnace"] = 256,
|
|
["assembling-machine-1"] = 32,
|
|
["assembling-machine-2"] = 128,
|
|
["assembling-machine-3"] = 512,
|
|
["oil-refinery"] = 256,
|
|
["chemical-plant"] = 128,
|
|
["centrifuge"] = 2048,
|
|
["lab"] = 64,
|
|
["beacon"] = 512,
|
|
["speed-module"] = 128,
|
|
["speed-module-2"] = 512,
|
|
["speed-module-3"] = 2048,
|
|
["effectivity-module"] = 128,
|
|
["effectivity-module-2"] = 512,
|
|
["effectivity-module-3"] = 2048,
|
|
["productivity-module"] = 128,
|
|
["productivity-module-2"] = 512,
|
|
["productivity-module-3"] = 2048,
|
|
["wood"] = 1,
|
|
["raw-fish"] = 16,
|
|
["iron-plate"] = 1,
|
|
["copper-plate"] = 1,
|
|
["solid-fuel"] = 16,
|
|
["steel-plate"] = 8,
|
|
["plastic-bar"] = 8,
|
|
["sulfur"] = 4,
|
|
["battery"] = 16,
|
|
["explosives"] = 4,
|
|
["crude-oil-barrel"] = 8,
|
|
["heavy-oil-barrel"] = 16,
|
|
["light-oil-barrel"] = 16,
|
|
["lubricant-barrel"] = 16,
|
|
["petroleum-gas-barrel"] = 16,
|
|
["sulfuric-acid-barrel"] = 16,
|
|
["water-barrel"] = 4,
|
|
["copper-cable"] = 1,
|
|
["iron-stick"] = 1,
|
|
["iron-gear-wheel"] = 2,
|
|
["empty-barrel"] = 4,
|
|
["electronic-circuit"] = 4,
|
|
["advanced-circuit"] = 16,
|
|
["processing-unit"] = 128,
|
|
["engine-unit"] = 8,
|
|
["electric-engine-unit"] = 64,
|
|
["flying-robot-frame"] = 128,
|
|
["satellite"] = 32768,
|
|
["rocket-control-unit"] = 256,
|
|
["low-density-structure"] = 64,
|
|
["rocket-fuel"] = 256,
|
|
["nuclear-fuel"] = 1024,
|
|
["uranium-235"] = 1024,
|
|
["uranium-238"] = 32,
|
|
["uranium-fuel-cell"] = 128,
|
|
["used-up-uranium-fuel-cell"] = 8,
|
|
["automation-science-pack"] = 4,
|
|
["logistic-science-pack"] = 16,
|
|
["military-science-pack"] = 64,
|
|
["chemical-science-pack"] = 128,
|
|
["production-science-pack"] = 256,
|
|
["utility-science-pack"] = 256,
|
|
["space-science-pack"] = 512,
|
|
["pistol"] = 4,
|
|
["submachine-gun"] = 32,
|
|
["shotgun"] = 16,
|
|
["combat-shotgun"] = 256,
|
|
["railgun"] = 512,
|
|
["rocket-launcher"] = 128,
|
|
["flamethrower"] = 512,
|
|
["land-mine"] = 8,
|
|
["firearm-magazine"] = 4,
|
|
["piercing-rounds-magazine"] = 8,
|
|
["uranium-rounds-magazine"] = 64,
|
|
["shotgun-shell"] = 4,
|
|
["piercing-shotgun-shell"] = 16,
|
|
["railgun-dart"] = 16,
|
|
["cannon-shell"] = 8,
|
|
["explosive-cannon-shell"] = 16,
|
|
["uranium-cannon-shell"] = 64,
|
|
["explosive-uranium-cannon-shell"] = 64,
|
|
["artillery-shell"] = 128,
|
|
["rocket"] = 8,
|
|
["explosive-rocket"] = 8,
|
|
["atomic-bomb"] = 16384,
|
|
["flamethrower-ammo"] = 32,
|
|
["grenade"] = 16,
|
|
["cluster-grenade"] = 64,
|
|
["poison-capsule"] = 64,
|
|
["slowdown-capsule"] = 16,
|
|
["defender-capsule"] = 16,
|
|
["distractor-capsule"] = 128,
|
|
["destroyer-capsule"] = 256,
|
|
["light-armor"] = 32,
|
|
["heavy-armor"] = 256,
|
|
["modular-armor"] = 1024,
|
|
["power-armor"] = 4096,
|
|
["power-armor-mk2"] = 32768,
|
|
["solar-panel-equipment"] = 256,
|
|
["fusion-reactor-equipment"] = 8192,
|
|
["energy-shield-equipment"] = 512,
|
|
["energy-shield-mk2-equipment"] = 4096,
|
|
["battery-equipment"] = 128,
|
|
["battery-mk2-equipment"] = 2048,
|
|
["personal-laser-defense-equipment"] = 2048,
|
|
["discharge-defense-equipment"] = 2048,
|
|
["discharge-defense-remote"] = 32,
|
|
["belt-immunity-equipment"] = 256,
|
|
["exoskeleton-equipment"] = 1024,
|
|
["personal-roboport-equipment"] = 512,
|
|
["personal-roboport-mk2-equipment"] = 4096,
|
|
["night-vision-equipment"] = 256,
|
|
["stone-wall"] = 8,
|
|
["gate"] = 16,
|
|
["gun-turret"] = 64,
|
|
["laser-turret"] = 1024,
|
|
["flamethrower-turret"] = 2048,
|
|
["artillery-turret"] = 8192,
|
|
["radar"] = 32,
|
|
["rocket-silo"] = 65536,
|
|
}
|
|
|
|
local item_names = {}
|
|
for k, v in pairs(item_worths) do table_insert(item_names, k) end
|
|
local size_of_item_names = #item_names
|
|
|
|
local function get_raffle_keys()
|
|
local raffle_keys = {}
|
|
for i = 1, size_of_item_names, 1 do
|
|
raffle_keys[i] = i
|
|
end
|
|
table_shuffle_table(raffle_keys)
|
|
return raffle_keys
|
|
end
|
|
|
|
function Public.roll_item_stack(remaining_budget, blacklist)
|
|
if remaining_budget <= 0 then return end
|
|
local raffle_keys = get_raffle_keys()
|
|
local item_name = false
|
|
local item_worth = 0
|
|
for _, index in pairs(raffle_keys) do
|
|
item_name = item_names[index]
|
|
item_worth = item_worths[item_name]
|
|
if not blacklist[item_name] and item_worth <= remaining_budget then break end
|
|
end
|
|
|
|
local stack_size = game.item_prototypes[item_name].stack_size
|
|
|
|
local item_count = 1
|
|
|
|
for c = 1, math_random(1, stack_size), 1 do
|
|
local price = c * item_worth
|
|
if price <= remaining_budget then
|
|
item_count = c
|
|
else
|
|
break
|
|
end
|
|
end
|
|
|
|
return {name = item_name, count = item_count}
|
|
end
|
|
|
|
local function roll_item_stacks(remaining_budget, max_slots, blacklist)
|
|
local item_stack_set = {}
|
|
local item_stack_set_worth = 0
|
|
|
|
for i = 1, max_slots, 1 do
|
|
if remaining_budget <= 0 then break end
|
|
local item_stack = Public.roll_item_stack(remaining_budget, blacklist)
|
|
item_stack_set[i] = item_stack
|
|
remaining_budget = remaining_budget - item_stack.count * item_worths[item_stack.name]
|
|
item_stack_set_worth = item_stack_set_worth + item_stack.count * item_worths[item_stack.name]
|
|
end
|
|
|
|
return item_stack_set, item_stack_set_worth
|
|
end
|
|
|
|
function Public.roll(budget, max_slots, blacklist)
|
|
if not budget then return end
|
|
if not max_slots then return end
|
|
|
|
local b
|
|
if not blacklist then
|
|
b = {}
|
|
else
|
|
b = blacklist
|
|
end
|
|
|
|
budget = math_floor(budget)
|
|
if budget == 0 then return end
|
|
|
|
local final_stack_set
|
|
local final_stack_set_worth = 0
|
|
|
|
for attempt = 1, 5, 1 do
|
|
local item_stack_set, item_stack_set_worth = roll_item_stacks(budget, max_slots, b)
|
|
if item_stack_set_worth > final_stack_set_worth or item_stack_set_worth == budget then
|
|
final_stack_set = item_stack_set
|
|
final_stack_set_worth = item_stack_set_worth
|
|
end
|
|
end
|
|
--[[
|
|
for k, item_stack in pairs(final_stack_set) do
|
|
game.print(item_stack.count .. "x " .. item_stack.name)
|
|
end
|
|
game.print(final_stack_set_worth)
|
|
]]
|
|
return final_stack_set
|
|
end
|
|
|
|
return Public |