1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-02-03 13:12:11 +02:00
ComfyFactorio/functions/loot_raffle.lua
2020-10-29 23:52:45 +01:00

520 lines
12 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"] = 2,
["iron-chest"] = 8,
["steel-chest"] = 32,
["storage-tank"] = 64,
["transport-belt"] = 2,
["fast-transport-belt"] = 16,
["express-transport-belt"] = 64,
["underground-belt"] = 8,
["fast-underground-belt"] = 64,
["express-underground-belt"] = 256,
["splitter"] = 16,
["fast-splitter"] = 64,
["express-splitter"] = 256,
["loader"] = 128,
["fast-loader"] = 256,
["express-loader"] = 1024,
["burner-inserter"] = 2,
["inserter"] = 4,
["long-handed-inserter"] = 8,
["fast-inserter"] = 16,
["filter-inserter"] = 32,
["stack-inserter"] = 128,
["stack-filter-inserter"] = 160,
["small-electric-pole"] = 2,
["medium-electric-pole"] = 32,
["big-electric-pole"] = 64,
["substation"] = 256,
["pipe"] = 1,
["pipe-to-ground"] = 8,
["pump"] = 32,
["rail"] = 4,
["train-stop"] = 64,
["rail-signal"] = 8,
["rail-chain-signal"] = 8,
["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"] = 4,
["red-wire"] = 4,
["green-wire"] = 4,
["arithmetic-combinator"] = 16,
["decider-combinator"] = 16,
["constant-combinator"] = 8,
["power-switch"] = 16,
["programmable-speaker"] = 16,
["stone-brick"] = 2,
["concrete"] = 1,
["hazard-concrete"] = 1,
["refined-concrete"] = 2,
["refined-hazard-concrete"] = 2,
["cliff-explosives"] = 32,
["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"] = 10,
["iron-plate"] = 1,
["copper-plate"] = 1,
["solid-fuel"] = 16,
["steel-plate"] = 8,
["plastic-bar"] = 8,
["sulfur"] = 4,
["battery"] = 16,
["explosives"] = 3,
["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"] = 10,
["submachine-gun"] = 32,
["shotgun"] = 16,
["combat-shotgun"] = 256,
["railgun"] = 512,
["rocket-launcher"] = 128,
["flamethrower"] = 512,
["land-mine"] = 2,
["landfill"] = 20,
["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"] = 6,
["explosive-rocket"] = 8,
["atomic-bomb"] = 8192,
["flamethrower-ammo"] = 32,
["grenade"] = 16,
["cluster-grenade"] = 64,
["poison-capsule"] = 32,
["slowdown-capsule"] = 16,
["defender-capsule"] = 48,
["distractor-capsule"] = 256,
["destroyer-capsule"] = 1024,
["light-armor"] = 50,
["heavy-armor"] = 250,
["modular-armor"] = 512,
["power-armor"] = 2048,
["power-armor-mk2"] = 32768,
["solar-panel-equipment"] = 256,
["fusion-reactor-equipment"] = 15000,
["energy-shield-equipment"] = 128,
["energy-shield-mk2-equipment"] = 2048,
["battery-equipment"] = 96,
["battery-mk2-equipment"] = 2048,
["personal-laser-defense-equipment"] = 1500,
["discharge-defense-equipment"] = 2048,
["discharge-defense-remote"] = 32,
["belt-immunity-equipment"] = 128,
["exoskeleton-equipment"] = 1500,
["personal-roboport-equipment"] = 512,
["personal-roboport-mk2-equipment"] = 4096,
["night-vision-equipment"] = 256,
["stone-wall"] = 5,
["gate"] = 16,
["gun-turret"] = 64,
["laser-turret"] = 1024,
["flamethrower-turret"] = 2048,
["artillery-turret"] = 1024,
["radar"] = 32,
["rocket-silo"] = 65536,
}
local tech_tier_list = {
"iron-gear-wheel",
"iron-plate",
"iron-stick",
"stone-brick",
"copper-cable",
"copper-plate",
"pipe",
"pipe-to-ground",
"automation-science-pack",
"boiler",
"burner-inserter",
"burner-mining-drill",
"electronic-circuit",
"firearm-magazine",
"inserter",
"iron-chest",
"lab",
"light-armor",
"offshore-pump",
"electric-mining-drill",
"pistol",
"radar",
"repair-pack",
"small-electric-pole",
"steam-engine",
"stone-furnace",
"transport-belt",
"wooden-chest",
"assembling-machine-1",
"long-handed-inserter",
"fast-inserter",
"filter-inserter",
"underground-belt",
"splitter",
"loader",
"small-lamp",
"gun-turret",
"stone-wall",
"logistic-science-pack",
"steel-plate",
"steel-chest",
"submachine-gun",
"shotgun",
"shotgun-shell",
"heavy-armor",
"assembling-machine-2",
"explosives",
"advanced-circuit",
"red-wire",
"green-wire",
"arithmetic-combinator",
"decider-combinator",
"constant-combinator",
"power-switch",
"programmable-speaker",
"landfill",
"fast-transport-belt",
"fast-underground-belt",
"fast-splitter",
"fast-loader",
"solar-panel",
"gate",
"engine-unit",
"battery",
"railgun",
"railgun-dart",
"chemical-science-pack",
"military-science-pack",
"steel-furnace",
"concrete",
"hazard-concrete",
"refined-concrete",
"refined-hazard-concrete",
"accumulator",
"medium-electric-pole",
"big-electric-pole",
"rail",
"locomotive",
"cargo-wagon",
"fluid-wagon",
"train-stop",
"rail-signal",
"rail-chain-signal",
"stack-inserter",
"stack-filter-inserter",
"pumpjack",
"oil-refinery",
"chemical-plant",
"solid-fuel",
"storage-tank",
"pump",
"empty-barrel",
"water-barrel",
"crude-oil-barrel",
"land-mine",
"rocket-launcher",
"rocket",
"sulfur",
"plastic-bar",
"piercing-rounds-magazine",
"grenade",
"defender-capsule",
"car",
"modular-armor",
"night-vision-equipment",
"belt-immunity-equipment",
"heavy-oil-barrel",
"light-oil-barrel",
"lubricant-barrel",
"petroleum-gas-barrel",
"sulfuric-acid-barrel",
"battery-equipment",
"solar-panel-equipment",
"speed-module",
"productivity-module",
"effectivity-module",
"cliff-explosives",
"processing-unit",
"electric-engine-unit",
"production-science-pack",
"utility-science-pack",
"electric-furnace",
"substation",
"flying-robot-frame",
"roboport",
"logistic-chest-passive-provider",
"logistic-chest-storage",
"construction-robot",
"roboport",
"logistic-chest-passive-provider",
"logistic-chest-storage",
"logistic-robot",
"personal-roboport-equipment",
"flamethrower",
"flamethrower-ammo",
"flamethrower-turret",
"piercing-shotgun-shell",
"cluster-grenade",
"destroyer-capsule",
"poison-capsule",
"slowdown-capsule",
"combat-shotgun",
"tank",
"cannon-shell",
"explosive-cannon-shell",
"explosive-rocket",
"distractor-capsule",
"nuclear-reactor",
"heat-exchanger",
"heat-pipe",
"steam-turbine",
"centrifuge",
"uranium-fuel-cell",
"used-up-uranium-fuel-cell",
"uranium-235",
"uranium-238",
"power-armor",
"energy-shield-equipment",
"exoskeleton-equipment",
"battery-mk2-equipment",
"speed-module-2",
"productivity-module-2",
"effectivity-module-2",
"low-density-structure",
"rocket-fuel",
"assembling-machine-3",
"express-transport-belt",
"express-underground-belt",
"express-splitter",
"express-loader",
"laser-turret",
"logistic-chest-active-provider",
"logistic-chest-requester",
"logistic-chest-buffer",
"personal-roboport-mk2-equipment",
"nuclear-fuel",
"energy-shield-mk2-equipment",
"personal-laser-defense-equipment",
"discharge-defense-equipment",
"discharge-defense-remote",
"speed-module-3",
"productivity-module-3",
"effectivity-module-3",
"space-science-pack",
"beacon",
"rocket-control-unit",
"fusion-reactor-equipment",
"artillery-wagon",
"artillery-turret",
"artillery-shell",
"artillery-targeting-remote",
"uranium-rounds-magazine",
"uranium-cannon-shell",
"explosive-uranium-cannon-shell",
"atomic-bomb",
"power-armor-mk2",
"satellite",
"rocket-silo",
}
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
--tier = float 0-1; 1 = everything unlocked
function Public.get_tech_blacklist(tier)
local blacklist = {}
local size_of_tech_tier_list = #tech_tier_list
local min_index = math_floor(size_of_tech_tier_list * tier)
for i = size_of_tech_tier_list, min_index, -1 do
blacklist[tech_tier_list[i]] = true
end
return blacklist
end
function Public.get_item_value(item)
local value = item_worths[item]
return value
end
return Public