pyrovoice Posted May 28, 2015 Share Posted May 28, 2015 Hi guys, i'm trying to create a new item that is trader , so it can accept only certain items, and then is harvestable, so it can "grow" items of that type. I have a trader problem atm, here's the code :inst:AddComponent("trader")inst.components.trader:SetAcceptTest(isMultiplicable)inst.components.trader.onaccept = startGrowthinst.components.trader.onrefuse = refused-- Check if the item is in the list based on its namelocal function isMultiplicable(item) name = item.prefab for k,v in pairs(multiplicables) do if v.debugName == name then return v end end return nilend-- Define the list of items this object may acceptlocal function startGrowth(inst, item) itemToProduce = item if not itemToProduce == nil then -- Set the harvester values inst.components.harvestable:SetUp(v.elementName, v.numberCreated, v.timeToCreate, onharvest, nil) -- Start to grow inst.components.harvestable:StartGrowing() endendlocal multiplicables ={ cutgrass = {debugName="cutgrass", numberCreated=5, timeToCreate=10}, woodLog = {debugName="log", numberCreated=3, timeToCreate=10}} So The component trader uses the isMultiplicable function that check is the item is in the multiplicables list (by comparing the names). If yes, it uses the startGrowth function that set the item to grow and the other parameters using the multiplicables parameters. After some time, the player can then harvest the object and get a number of resource of the same type that he used. The onrefused just throw an error I actually have a problem with the isMultiplicable function, I tried to give it cutgrass and it refused it. Would you know why this happened ? Link to comment Share on other sites More sharing options...
Mobbstar Posted May 28, 2015 Share Posted May 28, 2015 from scripts/components/trader.lua:function Trader:CanAccept( item ) return self.enabled and (not self.test or self.test(self.inst, item))end As you can see, the first parameter is the instance (the trader), the second variable is the item. Can you show your "refused" function? If you haven't declared that, then it should be obvious why there's an error (Lua is actually more tolerant when it comes to null-values, but undeclared variables still cause problems like in Java) (EDIT: Also, onaccept's second parameter is the giver, the third is the item.) EDIT2: The "startGrow" function will cause an error too. I commented it as much as I could local function startGrowth(inst, item) --fill in the giver (inst,guy,item) itemToProduce = item if not itemToProduce == nil then --any variable that's not nil or false is considered true, so you can remove both the "not" and the "== nil" -- Set the harvester values inst.components.harvestable:SetUp(v.elementName, v.numberCreated, v.timeToCreate, onharvest, nil) --where does "v" come from? This function doesn't know it (Lua is function-orientated, not object-orientated). You can define a variable in the instance when iterating though (inst.product = v) or use the keys (multiplicables[item.prefab]) -- Start to grow inst.components.harvestable:StartGrowing() endend Link to comment Share on other sites More sharing options...
pyrovoice Posted May 28, 2015 Author Share Posted May 28, 2015 local function refused() inst.AnimState:PlayAnimation(inst.anims.hit)endAnd the animation is not added, so it fail. I'm using ressources from an other mod that does not have animations yet so I can't really add an animation, and I need a way of seeing if it accept or not So I need to create a isMultiplicable function that has the same parameters right ? Link to comment Share on other sites More sharing options...
pyrovoice Posted May 28, 2015 Author Share Posted May 28, 2015 okay I made the changes, I still have an error but going home now, so BRB in 2 hours New code : -- Define the list of items this object may acceptlocal function startGrowth(inst, giver, item) infos = nil for k,v in pairs(inst.multiplicables) do if v.debugName == name then infos = v end end if itemToProduce then -- Set the harvester values inst.components.harvestable:SetUp(infos.elementName, infos.numberCreated, infos.timeToCreate, onharvest, nil) -- Start to grow inst.components.harvestable:StartGrowing() endend-- Check if the item is in the list based on its namelocal function isMultiplicable(inst, item) name = item.prefab for k,v in pairs(inst.multiplicables) do if v.debugName == name then return true end end return falseendlocal function refused() inst.AnimState:PlayAnimation(inst.anims.hit)endlocal function fn(Sim) local inst = CreateEntity() local trans = inst.entity:AddTransform() local anim = inst.entity:AddAnimState() inst.entity:AddSoundEmitter() inst.entity:AddDynamicShadow() inst.DynamicShadow:SetSize( 4, 3 ) local minimap = inst.entity:AddMiniMapEntity() minimap:SetIcon( "w_pond.tex" ) MakeObstaclePhysics(inst, .4) anim:SetBank("w_pond") anim:SetBuild("w_pond") anim:PlayAnimation("bees_loop") inst:AddTag("structure") inst:AddTag("playerowned") inst:AddComponent("inspectable") inst.components.inspectable.getstatus = function(inst) if inst.components.harvestable and inst.components.harvestable:CanBeHarvested() then return "READY" end end inst:AddComponent("harvestable") -- inst.components.harvestable:SetUp(nil, nil, nil, onharvest, updatelevel) inst:AddComponent("trader") inst.components.trader:SetAcceptTest(isMultiplicable) inst.components.trader.onaccept = startGrowth inst.components.trader.onrefuse = refused inst:AddComponent("lootdropper") inst:AddComponent("workable") inst.components.workable:SetWorkAction(ACTIONS.HAMMER) inst.components.workable:SetWorkLeft(4) inst.components.workable:SetOnFinishCallback(onhammered) return instendI got an error in the CanAccept function, so in isMultipliable I guess. I'll look into it. Thanks a lot for your help ! Link to comment Share on other sites More sharing options...
Mobbstar Posted May 28, 2015 Share Posted May 28, 2015 okay I made the changes, I still have an error but going home now, so BRB in 2 hours New code : -snip-I got an error in the CanAccept function, so in isMultipliable I guess. I'll look into it. Thanks a lot for your help ! Now both "name" in the for loop and "itemtoproduce" in the if-statement are undeclared variable names. The former can be directly replaced by "item.prefab", the latter should be "infos".Also, did you define "onharvest"? If so, make sure you declare that before the "startGrowth" function. There's no such thing as "inst.anims.hit" in the code. You can either place the anim string directly or create a table with the strings (in the main function "fn").Also, that function "refused" needs to get the "inst" parameter. "onhammered" near the bottom should be declared too, for the case you're missing it. I initially had the impression that you'd be experienced in Java, but you seem to have problems with declarations (which are a bit more annoying in Java than in Lua). Maybe it's just hasty work though Link to comment Share on other sites More sharing options...
pyrovoice Posted May 28, 2015 Author Share Posted May 28, 2015 yeah I was quite in a hurry, and as a java dev I can't stand the variables without types x) i'll past the full code :require "prefabutil"local assets ={ Asset("ANIM", "anim/w_pond.zip"), Asset("ANIM", "anim/bee_box.zip"),}local multiplicables ={ cutgrass = {debugName="cutgrass", numberCreated=5, timeToCreate=10}, woodLog = {debugName="log", numberCreated=3, timeToCreate=10}} local function onhammered(inst, worker) if inst:HasTag("fire") and inst.components.burnable then inst.components.burnable:Extinguish()end inst.SoundEmitter:KillSound("loop") inst.components.lootdropper:DropLoot() inst.SoundEmitter:PlaySound("dontstarve/common/destroy_wood") inst:Remove()endlocal function onhit(inst, worker) if not inst:HasTag("burnt") then inst.AnimState:PlayAnimation(inst.anims.hit) inst.AnimState:PushAnimation(inst.anims.idle, false) endendlocal function setlevel(inst, level) if not inst.anims then inst.anims = {idle = level.idle, hit = level.hit} else inst.anims.idle = level.idle inst.anims.hit = level.hitend inst.AnimState:PlayAnimation(inst.anims.idle)endlocal function onbuilt(inst) inst.AnimState:PlayAnimation("place") inst.AnimState:PushAnimation("idle", false)end-- Define the list of items this object may acceptlocal function startGrowth(inst, giver, item) infos = nil for k,v in pairs(inst.multiplicables) do if v.debugName == item.prefab then infos = v end end if infos then -- Set the harvester values inst.components.harvestable:SetUp(infos.elementName, infos.numberCreated, infos.timeToCreate, onharvest, nil) -- Start to grow inst.components.harvestable:StartGrowing() endend-- Check if the item is in the list based on its namelocal function isMultiplicable(inst, item) name = item.prefab for k,v in pairs(inst.multiplicables) do if v.debugName == name then return true end end return falseendlocal function refused() inst.AnimState:PlayAnimation(inst.anims.hit)endlocal function fn(Sim) local inst = CreateEntity() local trans = inst.entity:AddTransform() local anim = inst.entity:AddAnimState() inst.entity:AddSoundEmitter() inst.entity:AddDynamicShadow() inst.DynamicShadow:SetSize( 4, 3 ) local minimap = inst.entity:AddMiniMapEntity() minimap:SetIcon( "w_pond.tex" ) MakeObstaclePhysics(inst, .4) anim:SetBank("w_pond") anim:SetBuild("w_pond") anim:PlayAnimation("bees_loop") inst:AddTag("structure") inst:AddTag("playerowned") inst:AddComponent("inspectable") inst.components.inspectable.getstatus = function(inst) if inst.components.harvestable and inst.components.harvestable:CanBeHarvested() then return "READY" end end inst:AddComponent("harvestable") -- inst.components.harvestable:SetUp(nil, nil, nil, onharvest, updatelevel) inst:AddComponent("trader") inst.components.trader:SetAcceptTest(isMultiplicable) inst.components.trader.onaccept = startGrowth inst.components.trader.onrefuse = refused inst:AddComponent("lootdropper") inst:AddComponent("workable") inst.components.workable:SetWorkAction(ACTIONS.HAMMER) inst.components.workable:SetWorkLeft(4) inst.components.workable:SetOnFinishCallback(onhammered) return instendreturn Prefab("common/w_pond", fn, assets, prefabs), MakePlacer( "common/w_pond_placer", "w_pond", "w_pond", "bees_loop" ) Still the same error, just got home EDIt : so no onHarvest method, since I don't have anything to do more than what the component does itself. Do I still need to create an empty function ? Link to comment Share on other sites More sharing options...
Mobbstar Posted May 28, 2015 Share Posted May 28, 2015 @pyrovoice, you are refering to "onharvest" when there is no variable called that. The component does not strictly request it, so you can leave it out (or replace with nil if you need to set the parameter after). It's that easy. I see where the "inst.anims.hit" comes from now. You haven't really installed that system yet, so I suggest a placeholder of some kind. Consider "pushing" an idle animation afterwards (same as "PlayAnimation" but called "PushAnimation", so it plays after the current and previously queued ones). On a side note, this looks like an interesting thing. Link to comment Share on other sites More sharing options...
pyrovoice Posted May 28, 2015 Author Share Posted May 28, 2015 fixed, I got an error, apparently local function startGrowth(inst, giver, item) infos = nil for k,v in pairs(inst.multiplicables) do if v.debugName == item.prefab then infos = vinst.multiplicables does not return a table. I think there is an access problem since apparently it returned nil. Should I pass inst.components.trader:SetAcceptTest(isMultiplicable(this)) or something ? And I think i'll focus on animations when the item work, so I can be happy inside Link to comment Share on other sites More sharing options...
Blueberrys Posted May 28, 2015 Share Posted May 28, 2015 @pyrovoice In your code, multiplicables is a local variable, not a child of the "inst" table.In your code where you can access multiplicables, use:inst.multiplicables = multiplicablesThen you can access it through the inst table. Link to comment Share on other sites More sharing options...
Mobbstar Posted May 28, 2015 Share Posted May 28, 2015 fixed, I got an error, apparently local function startGrowth(inst, giver, item) infos = nil for k,v in pairs(inst.multiplicables) do if v.debugName == item.prefab then infos = vinst.multiplicables does not return a table. I think there is an access problem since apparently it returned nil. Should I pass inst.components.trader:SetAcceptTest(isMultiplicable(this)) or something ? And I think i'll focus on animations when the item work, so I can be happy inside I totally missed that. It's a refernce problem. Lua is not object-orientated, unlike Java. In Java, anything in a class belongs to that classs. In Lua, "ownership" needs to be explicit. You declared the table as "local", meaning it's a variable in this file/function/loop/whatever. Local variables only exist in the block they're created (until the next "end" or "return" is reached, if you will). So, all you need to do is remove the "inst.". Or you declare the table in the main function "fn" as "inst.multiplicables". ...what BlueBerrys said. Sorry if my wording is confusing, I am mostly self-learned. And careful with things like "inst.components.trader:SetAcceptTest(isMultiplicable(this))". Using brackets fires a function, and unless they "return" something specific (e.g. return "bar", "foo") they return nil. If you, for some reason, need to pass a variable to that function, you can cheat a bit by making another function like so: blabla:SetSomething(function(standardvariables) MyFunction(specialVariable, standardvariables, blah) end) Link to comment Share on other sites More sharing options...
pyrovoice Posted May 28, 2015 Author Share Posted May 28, 2015 Oh okay ! that has been fixed, and I also fixed the local infos in startGrowth Now, the item accept cutgrass, make it grow and let us harvest it after 10 sec, but don't give anything on harvest. This is supposed to be handled in harvestable component right ? Maybe I have to change-- Set the harvester valuesinst.components.harvestable:SetUp(infos.elementName, infos.numberCreated, infos.timeToCreate, nil, nil)edit : i think it was -- Set the harvester valuesinst.components.harvestable:SetUp(infos.debugName, infos.numberCreated, infos.timeToCreate, nil, nil) that was wrong, I fixed it and testing EDIT2: YES ! it worked ! not the way I wanted it, but this is still nice x) So, the problem with harvester is that you spawn 1 amount every X seconds, up to MAX (defined in the file). What I would like it to spawn X after the MAX time, not one by one. I need to see a bit more in the harvestable component Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.
Please be aware that the content of this thread may be outdated and no longer applicable.