mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
369 lines
10 KiB
Lua
369 lines
10 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
|
|
PLUGIN.name = "Test"
|
|
PLUGIN.author = "Gr4Ss"
|
|
PLUGIN.description = ""
|
|
|
|
PLUGIN.ingIndex = {}
|
|
PLUGIN.ingredients = {}
|
|
PLUGIN.itemRecipes = {}
|
|
PLUGIN.uncraftables = {}
|
|
PLUGIN.baseResourceCost = {}
|
|
PLUGIN.recipeTier = {}
|
|
PLUGIN.smugglingWorth = {}
|
|
PLUGIN.makeFromBaseCost = {}
|
|
PLUGIN.recipeVariantPreference = {
|
|
["comp_unrefinedchemical"] = "break_artwhiskey_chemical",
|
|
["comp_adhesive"] = "rec_comp_adhesive",
|
|
["comp_strong_adhesive"] = "rec_comp_strong_adhesive",
|
|
}
|
|
|
|
PLUGIN.costOverride = {
|
|
["drink_proc_whiskey"] = 12,
|
|
["drink_breen_water"] = 5
|
|
}
|
|
|
|
PLUGIN.bIncludeCooking = false
|
|
|
|
function PLUGIN:InitializedPlugins()
|
|
self:CalculateCraftingMatrix()
|
|
end
|
|
|
|
function PLUGIN:CalculateCraftingMatrix()
|
|
self:ParseRecipes()
|
|
self:ManualCraftingRecipe("comp_bloodsyringe", 1, {["comp_syringe"] = 1})
|
|
if (self.bIncludeCooking) then
|
|
self:ManualCraftingRecipe("baking_bread_slice", 8, {["baking_bread"] = 1}, {"tool_knife"})
|
|
end
|
|
|
|
for k, v in pairs(ix.plugin.list.smuggler.itemList) do
|
|
self.smugglingWorth[k] = v.buy / (v.stackSize or 1)
|
|
self.makeFromBaseCost[k] = v.sell / (v.stackSize or 1)
|
|
end
|
|
|
|
for k, v in pairs(self.costOverride) do
|
|
self.makeFromBaseCost[k] = v
|
|
end
|
|
|
|
self:AddToolsAsIngredients()
|
|
|
|
self:CalculateUncraftables()
|
|
|
|
self:CreateCraftingMatrixCSV()
|
|
|
|
--[[
|
|
for k, v in pairs(ix.recipe.stored) do
|
|
if (!self:IsValidRecipe(v)) then continue end
|
|
for result, amount in pairs(v.result) do
|
|
if (!ingIndex[result]) then
|
|
ingIndex[result] = #ingredients + 1
|
|
ingredients[#ingredients + 1] = {
|
|
sources = {v.name},
|
|
craftable = true
|
|
}
|
|
else
|
|
ingredients[ ingIndex[result] ].craftable = true
|
|
table.insert(ingredients[ ingIndex[result] ].sources, v.name)
|
|
end
|
|
end
|
|
end
|
|
--]]
|
|
|
|
self:CalculateResultCosts()
|
|
table.SortByMember(self.uncraftables, "count")
|
|
|
|
local changed = true
|
|
local loop = 0
|
|
while (changed and loop < 20) do
|
|
changed = false
|
|
loop = loop + 1
|
|
for k, v in pairs(self.baseResourceCost) do
|
|
local cost = 0
|
|
for ing, amount in pairs(v) do
|
|
if (!self.makeFromBaseCost[ing]) then
|
|
--print("missing sell price", ing)
|
|
continue
|
|
end
|
|
cost = cost + amount * self.makeFromBaseCost[ing]
|
|
end
|
|
|
|
local craftingRecipes = self.itemRecipes[k]
|
|
if (craftingRecipes) then
|
|
for _, data in pairs(craftingRecipes) do
|
|
if (#craftingRecipes > 1 and data.id != self.recipeVariantPreference[k]) then continue end
|
|
local cost2 = 0
|
|
for ing, amount in pairs(data.ingredients) do
|
|
if (!self.makeFromBaseCost[ing]) then
|
|
--print("missing sell price", ing)
|
|
continue
|
|
end
|
|
cost2 = cost2 + amount * self.makeFromBaseCost[ing]
|
|
end
|
|
|
|
cost = math.min(cost2, cost)
|
|
end
|
|
end
|
|
local newCost = math.min(self.makeFromBaseCost[k] or math.huge, cost)
|
|
if (!self.makeFromBaseCost[k] or self.makeFromBaseCost[k] != newCost) then
|
|
changed = true
|
|
end
|
|
self.makeFromBaseCost[k] = math.min(self.makeFromBaseCost[k] or math.huge, cost)
|
|
end
|
|
end
|
|
self:CreateResultCostCSV()
|
|
|
|
--PrintTable(self.uncraftables)
|
|
end
|
|
|
|
local whitelist = {["crafting"] = true, ["medicine"] = true}
|
|
if (PLUGIN.bIncludeCooking) then whitelist["cooking"] = true end
|
|
function PLUGIN:IsValidRecipe(recipe)
|
|
if (!whitelist[recipe.skill]) then return false end
|
|
if (recipe.category == "Matériaux") then return false end
|
|
if (!recipe.ingredients or !recipe.result) then return false end
|
|
|
|
return true
|
|
end
|
|
|
|
function PLUGIN:AddNewIngredient(ingredient)
|
|
if (!self.ingIndex[ingredient]) then
|
|
self.ingIndex[ingredient] = #self.ingredients + 1
|
|
self.ingredients[#self.ingredients + 1] = {
|
|
id = ingredient,
|
|
sources = {},
|
|
craftable = self.itemRecipes[ingredient] != nil
|
|
}
|
|
end
|
|
end
|
|
|
|
function PLUGIN:SetIngredientCraftable(ingredient, name)
|
|
if (self.ingIndex[ingredient]) then
|
|
self.ingredients[self.ingIndex[ingredient]].craftable = true
|
|
table.insert(self.ingredients[self.ingIndex[ingredient]].sources, name)
|
|
end
|
|
end
|
|
|
|
function PLUGIN:AddToolsAsIngredients()
|
|
for result, variants in pairs(self.itemRecipes) do
|
|
for variant, data in ipairs(variants) do
|
|
for _, tool in ipairs(data.tools) do
|
|
self:AddNewIngredient(tool)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function PLUGIN:ManualCraftingRecipe(result, amount, ingredients, tools, station, skill, level)
|
|
for ingredient in pairs(ingredients) do
|
|
self:AddNewIngredient(ingredient)
|
|
end
|
|
|
|
self.itemRecipes[result] = self.itemRecipes[result] or {}
|
|
table.insert(self.itemRecipes[result], {
|
|
amount = amount,
|
|
ingredients = ingredients,
|
|
tools = tools or {},
|
|
station = station,
|
|
recipe = "Manual Crafting",
|
|
skill = skill or "None",
|
|
level = level or 0
|
|
})
|
|
self.ingredients[self.ingIndex[result]].craftable = true
|
|
table.insert(self.ingredients[self.ingIndex[result]].sources, "Manual Crafting")
|
|
end
|
|
|
|
function PLUGIN:ParseRecipes()
|
|
for _, recipe in pairs(ix.recipe.stored) do
|
|
if (!self:IsValidRecipe(recipe)) then continue end
|
|
for ingredient, amount in pairs(recipe.ingredients) do
|
|
self:AddNewIngredient(ingredient)
|
|
end
|
|
|
|
for result, amount in pairs(recipe.result) do
|
|
self:SetIngredientCraftable(result, recipe.name)
|
|
|
|
self.itemRecipes[result] = self.itemRecipes[result] or {}
|
|
table.insert(self.itemRecipes[result], {
|
|
id = recipe.uniqueID,
|
|
amount = amount,
|
|
ingredients = recipe.ingredients,
|
|
tools = recipe.tools,
|
|
station = recipe.station,
|
|
recipe = recipe.name,
|
|
skill = recipe.skill,
|
|
level = recipe.level
|
|
})
|
|
|
|
if (!recipe.tools) then
|
|
self.itemRecipes[result][#self.itemRecipes[result]].tools = {recipe.tool}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function PLUGIN:CalculateUncraftables()
|
|
for k, v in ipairs(self.ingredients) do
|
|
if (!v.craftable) then
|
|
self.uncraftables[#self.uncraftables + 1] = {id = v.id, count = 0}
|
|
end
|
|
end
|
|
end
|
|
|
|
function PLUGIN:IsUncraftable(item)
|
|
for k, v in ipairs(self.uncraftables) do
|
|
if (v.id == item) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
function PLUGIN:SelectSingleVariant(result, variants)
|
|
if (#variants > 1) then
|
|
if (self.recipeVariantPreference[result]) then
|
|
for _, data in pairs(variants) do
|
|
if (data.id ==self.recipeVariantPreference[result]) then
|
|
return data.ingredients, data.amount
|
|
end
|
|
end
|
|
else
|
|
table.SortByMember(variants, "level", true)
|
|
self.recipeVariantPreference[result] = variants[1].id
|
|
return variants[1].ingredients, variants[1].amount
|
|
end
|
|
else
|
|
return variants[1].ingredients, variants[1].amount
|
|
end
|
|
end
|
|
|
|
function PLUGIN:CalculateBaseResourceCost(ingredients, resAmount)
|
|
local inputs = {}
|
|
for ing, amount in pairs(ingredients) do
|
|
if (self:IsUncraftable(ing)) then
|
|
inputs[ing] = (inputs[ing] or 0) + amount / resAmount
|
|
elseif (self.baseResourceCost[ing]) then
|
|
for resIng, resAm in pairs(self.baseResourceCost[ing]) do
|
|
inputs[resIng] = (inputs[resIng] or 0) + resAm * amount / resAmount
|
|
end
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
return inputs
|
|
end
|
|
|
|
function PLUGIN:CalculateResultCosts()
|
|
local bNewFound = false
|
|
local iters = 1
|
|
repeat
|
|
-- reset loop condition
|
|
local tempResult = {}
|
|
bNewFound = false
|
|
for result, variants in pairs(self.itemRecipes) do
|
|
-- prevent doing the same recipe again and again
|
|
if (self.baseResourceCost[result]) then continue end
|
|
|
|
local ingredients, amount = self:SelectSingleVariant(result, variants)
|
|
if (!ingredients) then print("PANIC", result) end
|
|
|
|
local inputs = self:CalculateBaseResourceCost(ingredients, amount)
|
|
if (inputs) then
|
|
bNewFound = true
|
|
self.recipeTier[result] = iters
|
|
tempResult[result] = inputs
|
|
for ing in pairs(inputs) do
|
|
for k, tbl in ipairs(self.uncraftables) do
|
|
if (tbl.id == ing) then
|
|
self.uncraftables[k].count = (self.uncraftables[k].count or 0) + 1
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
for k, v in pairs(tempResult) do
|
|
self.baseResourceCost[k] = v
|
|
end
|
|
|
|
iters = iters + 1
|
|
until bNewFound == false
|
|
end
|
|
|
|
function PLUGIN:CreateCraftingMatrixCSV()
|
|
if (file.Exists("craftingMatrix.csv", "DATA")) then
|
|
file.Delete("craftingMatrix.csv")
|
|
end
|
|
|
|
local outputString = ""
|
|
local ingOffset = 5
|
|
for i = 1, ingOffset do
|
|
outputString = outputString..";"
|
|
end
|
|
for k, v in ipairs(self.ingredients) do
|
|
outputString = outputString..v.id..";"
|
|
end
|
|
file.Append("craftingMatrix.csv", outputString.."\n")
|
|
|
|
for result, variants in pairs(self.itemRecipes) do
|
|
table.SortByMember(variants, "level", true)
|
|
for variant, data in ipairs(variants) do
|
|
local outputRow = {result, data.recipe, data.skill, data.level, data.amount}
|
|
for ingredient, amount in pairs(data.ingredients) do
|
|
outputRow[self.ingIndex[ingredient] + ingOffset] = amount
|
|
end
|
|
|
|
for _, tool in ipairs(data.tools) do
|
|
outputRow[self.ingIndex[tool] + ingOffset] = "T"
|
|
end
|
|
|
|
outputString = ""
|
|
for i = 1, #self.ingredients + ingOffset do
|
|
outputString = outputString..string.gsub(outputRow[i] or "", "%.", ",")..";"
|
|
end
|
|
file.Append("craftingMatrix.csv", outputString.."\n")
|
|
end
|
|
end
|
|
end
|
|
|
|
function PLUGIN:CreateResultCostCSV()
|
|
if (file.Exists("craftingBaseResourceMatrix.csv", "DATA")) then
|
|
file.Delete("craftingBaseResourceMatrix.csv")
|
|
end
|
|
|
|
local outputString = ""
|
|
local ingOffset = 5
|
|
for i = 1, ingOffset do
|
|
outputString = outputString..";"
|
|
end
|
|
for k, v in ipairs(self.uncraftables) do
|
|
outputString = outputString..v.id..";"
|
|
end
|
|
file.Append("craftingBaseResourceMatrix.csv", outputString.."\n")
|
|
|
|
for result, costs in pairs(self.baseResourceCost) do
|
|
local outputRow = {result, self.recipeTier[result], self.smugglingWorth[result] or "N/A", self.makeFromBaseCost[result], math.max((self.smugglingWorth[result] or 0) - self.makeFromBaseCost[result])}
|
|
for ingredient, amount in pairs(costs) do
|
|
for k, uncraft in ipairs(self.uncraftables) do
|
|
if (uncraft.id == ingredient) then
|
|
outputRow[k + ingOffset] = amount
|
|
end
|
|
end
|
|
end
|
|
|
|
outputString = ""
|
|
for i = 1, #self.uncraftables + ingOffset do
|
|
outputString = outputString..string.gsub(outputRow[i] or "", "%.", ",")..";"
|
|
end
|
|
file.Append("craftingBaseResourceMatrix.csv", string.gsub(outputString, "%.", ",").."\n")
|
|
end
|
|
end |