Jump to content

Recommended Posts

I'm trying to create a mod which adds a machine in game to process a material into another.

I've got a couple of problems though.

 

  1. The textures I've added are invisible inside the game.
  2. I cant find the scripts for recipes. Where are they stored?
  3. more problems will show up I'm sure.

 

I've attached the modfiles. feel free to look around.

 

All help is appreciated as long as I am learning.

stone_grinder.zip

@Whire, Oh, scripts/preparedfoods.lua

 

 

 

Whats the problem with this then? when i run it gives me:

 

note: the lines 90-150 still needs to be edited with names and such. But i dont think it has anything to do with my error.

[00:00:05]: [string "../mods/stone_grinder/scripts/processer.lua"]:8: table index is nil

preparedprocess.lua

local process ={	gravel =	{		test = function(processer, names, tags) return names.rocks end,			},}return process

processer.lua

require "tuning"local processerrecipes = {}function AddProcesserRecipe(processer, recipe)	if not processerrecipes[processer] then		processerrecipes[processer] = {}	end	processerrecipes[processer][recipe.name] = recipeendlocal materials = {}function AddMaterialValues(names, tags, canprocess)	for _,name in pairs(names) do		materials[name] = { tags= {}}				if canprocess then			materials[name.."_processed"] = {tags={}}		end		for tagname,tagval in pairs(tags) do			materials[name].tags[tagname] = tagval			--print(name,tagname,tagval,ingtable[name].tags[tagname])			if canprocess then				materials[name.."_processed"].tags.processed = 1				materials[name.."_processed"].tags[tagname] = tagval			end		end	endendlocal stones = {"rocks"}AddMaterialValues(stones, {stone=1}, true)--our naming conventions aren't completely consistent, sadlylocal aliases={	cookedsmallmeat = "smallmeat_cooked",	cookedmonstermeat = "monstermeat_cooked",	cookedmeat = "meat_cooked"}local function IsProcessingMaterial(prefabname)	local name = aliases[prefabname] or prefabname	if materials[name] then		return true	endendlocal null_material = {tags={}}local function GetMaterialData(prefabname)	local name = aliases.prefabname or prefabname	return materials[name] or null_materialendlocal process = require("preparedprocess")for k,recipe in pairs (process) do	AddProcesserRecipe("stone_grinder", recipe)endlocal function GetMaterialValues(prefablist)	local prefabs = {}	local tags = {}	for k,v in pairs(prefablist) do		local name = aliases[v] or v		prefabs[name] = prefabs[name] and prefabs[name] + 1 or 1		local data = GetMaterialData(name)		if data then			for kk, vv in pairs(data.tags) do				tags[kk] = tags[kk] and tags[kk] + vv or vv			end		end	end	return {tags = tags, names = prefabs}endfunction GetCandidateRecipes(processer, ingdata)	local recipes = processerrecipes[processer] or {}	local candidates = {}	--find all potentially valid recipes	for k,v in pairs(recipes) do		if v.test(processer, ingdata.names, ingdata.tags) then			table.insert(candidates, v)		end	end	return candidatesendlocal function CalculateRecipe(cooker, names)	local ingdata = GetIngredientValues(names)	local candidates = GetCandidateRecipes(cooker, ingdata)	table.sort( candidates, function(a,b) return (a.weight or 1) > (b.weight or 1) end )	local total = 0	for k,v in pairs(candidates) do		total = total + (v.weight or 1)	endendlocal function TestRecipes(processer, prefablist)	local ingdata = GetIngredientValues(prefablist)	print ("materials:")	for k,v in pairs(prefablist) do		if not IsProcessingMaterials(v) then			print ("NOT MATERIAL:", v)		end	end	for k,v in pairs(ingdata.names) do		print (v,k)	end	print ("\nMaterial tags:")	for k,v in pairs(ingdata.tags) do		print (tostring(v), k)	end	local recipe = CalculateRecipe(processer, prefablist)	print ("Make:", recipe)end--TestRecipes("cookpot", {"tallbirdegg","meat","carrot","meat"})return { CalculateRecipe = CalculateRecipe, IsCookingIngredient = IsCookingIngredient, recipes = processerrecipes, materials=materials}

preparedprocess.lua

processer.lua

Hi there !
Maybe it's not what you're trying to do, but did you know you can specify directly what can and can't go in your container ?

I did a similar item for my 'blacksmith' mod.
It's a furnace that take 3 item (rock, flint,...) and combine it to create one new item (iron, steel,...).

 

I put this in my mod main :

-- This test what items can go in the furnacefunction params.furnace.itemtestfn(container, item, slot)    if item.prefab == "flint" or	item.prefab == "rocks" or	item.prefab == "ash" or	item.prefab == "charcoal" or	item.prefab == "iron" or	item.prefab == "goldnugget" or	item.prefab == "moonrocknugget" or	item.prefab == "sharp_crystal"	then        return true    end	return falseend

I can give you all the code if you think it can help =)

So! I've solved the problem! :)

However now i need to find and make my own function for transforming the material i put in into something. Something a lot like this:

ACTIONS.COOK.fn = function(act)	if act.target.components.cooker ~= nil then	    local ingredient = act.doer.components.inventory:RemoveItem(act.invobject)        ingredient.Transform:SetPosition(act.target.Transform:GetWorldPosition())        if ingredient.components.health and ingredient.components.combat then            act.doer:PushEvent("killed", {victim = ingredient})        end	    local product = act.target.components.cooker:CookItem(ingredient, act.doer)	    if product then	        act.doer.components.inventory:GiveItem(product, nil, act.target:GetPosition())	        return true	    end    elseif act.target.components.stewer ~= nil then        if act.target.components.stewer.cooking then            --Already cooking            return true        end        local container = act.target.components.container        if container ~= nil and container:IsOpen() and not container:IsOpenedBy(act.doer) then            return false, "INUSE"        elseif not act.target.components.stewer:CanCook() then            return false        end		act.target.components.stewer:StartCooking()		return true    endend

Hi there !

Maybe it's not what you're trying to do, but did you know you can specify directly what can and can't go in your container ?

I did a similar item for my 'blacksmith' mod.

It's a furnace that take 3 item (rock, flint,...) and combine it to create one new item (iron, steel,...).

 

I put this in my mod main :

-- This test what items can go in the furnacefunction params.furnace.itemtestfn(container, item, slot)    if item.prefab == "flint" or	item.prefab == "rocks" or	item.prefab == "ash" or	item.prefab == "charcoal" or	item.prefab == "iron" or	item.prefab == "goldnugget" or	item.prefab == "moonrocknugget" or	item.prefab == "sharp_crystal"	then        return true    end	return falseend

I can give you all the code if you think it can help =)

 

 

Id be happy to go through it and see how you do the "cooking" process. :-)

 

 

 

---------------------------------------------------------------------------------------------------------------------------------------

 

So, I did some changes to my files. and ended up with this error :

 

[00:34:17]: [string "scripts/bufferedaction.lua"]:14: attempt to index local 'action' (a nil value)LUA ERROR stack traceback:scripts/bufferedaction.lua:14 in (field) _ctor (Lua) <2-17>   self (valid:true) =      options = table: 08C69AE0      doer = 115082 - wilson (valid:true)      onsuccess = table: 08C69860      doerownsobject = false      onfail = table: 08C69978      target = 114987 - stone_grinder (valid:true)   doer = 115082 - wilson (valid:true)   target = 114987 - stone_grinder (valid:true)   action = nil   invobject = nil   pos = nil   recipe = nil   distance = nil   forced = nil

Heres the code executing BufferedAction:Do()   :

scripts/containers.lua

----------------------------------------------------------------------------[[ stone_grinder ]]--------------------------------------------------------------------------params.stone_grinder ={    widget =    {        slotpos =        {            Vector3(157, 5),			Vector3(-157, 5),        },        animbank = "ui_stone_grinder",        animbuild = "ui_stone_grinder",        pos = Vector3(-200, 0, 0),        side_align_tip = 100,        buttoninfo =        {            text = "Grind",            position = Vector3(0, -63, 0),        },    },    acceptsstacks = true,    type = "processer",}function params.stone_grinder.itemtestfn(container, item, slot)    return processer.IsProcessingMaterial(item.prefab)endfunction params.stone_grinder.widget.buttoninfo.fn(inst)    if inst.components.container ~= nil then        BufferedAction(inst.components.container.opener, inst, ACTIONS.PROCESS):Do()    elseif inst.replica.container ~= nil and not inst.replica.container:IsBusy() then        SendRPCToServer(RPC.DoWidgetButtonAction, ACTIONS.PROCESS.code, inst, ACTIONS.PROCESS.mod_name)    endendfunction params.stone_grinder.widget.buttoninfo.validfn(inst)    return inst.replica.container ~= nil and inst.replica.container:IsFull()end

bufferedaction.lua

 

BufferedAction = Class(function(self, doer, target, action, invobject, pos, recipe, distance, forced)    self.doer = doer    self.target = target    self.initialtargetowner = target ~= nil and target.components.inventoryitem ~= nil and target.components.inventoryitem.owner or nil    self.action = action    self.invobject = invobject    self.doerownsobject = doer ~= nil and invobject ~= nil and invobject.replica.inventoryitem ~= nil and invobject.replica.inventoryitem:IsHeldBy(doer)    self.pos = pos    self.onsuccess = {}    self.onfail = {}    self.recipe = recipe    self.options = {}    self.distance = distance or action.distance     self.forced = forced    self.autoequipped = nil --true if invobject should've been auto-equippedend)function BufferedAction:Do()    if self:IsValid() then                local success, reason = self.action.fn(self)        if success then            if self.invobject and self.invobject:IsValid() then                self.invobject:OnUsedAsItem(self.action)            end            self:Succeed()                    else            self:Fail()        end                return success, reason    endendfunction BufferedAction:TestForStart()    if self:IsValid() then        if self.action.testfn then            local pass, reason = self.action.testfn(self)            return pass, reason        else            return true        end    endendfunction BufferedAction:IsValid()    return (self.invobject == nil or self.invobject:IsValid()) and           (self.doer == nil or (self.doer:IsValid() and (not self.autoequipped or self.doer.replica.inventory:GetActiveItem() == nil))) and           (self.target == nil or (self.target:IsValid() and self.initialtargetowner == (self.target.components.inventoryitem ~= nil and self.target.components.inventoryitem.owner or nil))) and           (not self.doerownsobject or (self.doer ~= nil and self.invobject ~= nil and self.invobject.replica.inventoryitem ~= nil and self.invobject.replica.inventoryitem:IsHeldBy(self.doer))) and           (self.validfn == nil or self.validfn())endfunction BufferedAction:GetActionString()    if self.doer and self.doer.ActionStringOverride then        local str = self.doer.ActionStringOverride(self.doer, self)        if str then            return str        end    end    return GetActionString(self.action.id, self.action.strfn ~= nil and self.action.strfn(self) or nil)endfunction BufferedAction:__tostring()    local str= self:GetActionString() .. " " .. tostring(self.target)        if self.invobject then        str = str.." With Inv:" .. tostring(self.invobject)    end        if self.recipe then        str = str .. " Recipe:" ..self.recipe    end    return strendfunction BufferedAction:AddFailAction(fn)    table.insert(self.onfail, fn)endfunction BufferedAction:AddSuccessAction(fn)    table.insert(self.onsuccess, fn)endfunction BufferedAction:Succeed()    for k,v in pairs(self.onsuccess) do        v()    end        self.onsuccess = {}    self.onfail = {}    endfunction BufferedAction:Fail()    for k,v in pairs(self.onfail) do        v()    end        self.onsuccess = {}    self.onfail = {}end

edit: I figure that in containers.lua : line 250 ACTIONS.PROCESS is not defined anywhere. The cookpots equivalent is ACTIONS.COOK but i cant seem to find where its defined.

 

Edited by Whire

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...