LordMogar Posted May 4, 2015 Share Posted May 4, 2015 So, I've been working on an item mod. It's working perfectly so far except I just can't figure out how to add one of the features I want to. It's meant to be a character specific item that lets the character regain a small amount of sanity over time whilst being kept in their inventory. However, it's not an equipable item. Could anyone help me figure out the code for this? Everything I've tried so far has resulted in a crash. Link to comment Share on other sites More sharing options...
Blueberrys Posted May 4, 2015 Share Posted May 4, 2015 @LordMogar You could create a PeriodicTask to run when the item is given to the character (picked up), and remove it when it's taken away (dropped, put in chest, etc).The inventoryitem component pushes events: onputininventory, ondropped, and onpickup. You can see how they function in "..\scripts\components\inventoryitem.lua". Syntax.-- Where inst is the item's instance-- Replace event_name according to your code designinst:ListenForEvent("event_name", function(inst, data) -- Activate PeriodicTask local task = inst:DoPeriodicTask(1, function() -- Heal or something end) -- Deactivate PeriodicTask -- Ideally, this would be associated with another event listener, not inside this function task:Cancel()end) Link to comment Share on other sites More sharing options...
LordMogar Posted May 4, 2015 Author Share Posted May 4, 2015 I've been messing with the stuff you gave me for a while now and it keeps crashing. I'm not sure I'm doing this entirely right. :/ inst:ListenForEvent("onputininventory", function(inst, data) local task = inst:DoPeriodicTask(1, function(inst) inst.components.sanity:DoDelta(20) end) inst:ListenForEvent("ondropped", function(inst, data) task:Cancel()end) Here's the error it keeps giving. 42: ')' expected (to close '(' at line 30) near 'return' Link to comment Share on other sites More sharing options...
Blueberrys Posted May 4, 2015 Share Posted May 4, 2015 @LordMogar I don't think you've completely grasped the concept of functions and variables yet.Does this make more sense?-- This function will be called when the ondropped event is pushed.local function SomeFunction(inst, data) print("Item dropped!")end-- Associates the SomeFunction function with the ondroppped event.inst:ListenForEvent("ondropped", SomeFunction)- Edit: Couldn't find the post explaining this topic in detail. Edit 2:local taskinst:ListenForEvent("onputininventory", function(inst, data) task = inst:DoPeriodicTask(1, function() -- Do something end)end)inst:ListenForEvent("ondropped", function(inst, data) if task then task:Cancel() task = nil endend) Link to comment Share on other sites More sharing options...
LordMogar Posted May 5, 2015 Author Share Posted May 5, 2015 No, I'm not very good with this stuff unfortunately, I'm surprised I've gotten as far in with the process of making mods as I have. I tried applying the script from your second edit. I added in the sanity component and got past the main menu and ingame, a step up from previous attempts. This time however upon picking up the item the game crashes and prints the error, "attempt to index field 'sanity' (a nil value)". Here's the whole .lua file for my item's prefab. Did I forget to add something?local assets ={ Asset("ANIM", "anim/bear.zip"), Asset("SOUND", "sound/common.fsb"),}local function fn() local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() inst.entity:AddNetwork() MakeInventoryPhysics(inst) inst.AnimState:SetBank("bear") inst.AnimState:SetBuild("bear") inst.AnimState:PlayAnimation("idle") if not TheWorld.ismastersim then return inst end inst:AddComponent("inspectable") inst:AddComponent("inventoryitem") inst.components.inventoryitem.atlasname = "images/inventoryimages/bear.xml"local task inst:ListenForEvent("onputininventory", function(inst, data) task = inst:DoPeriodicTask(1, function() inst.components.sanity:DoDelta(20) end)end) inst:ListenForEvent("ondropped", function(inst, data) if task then task:Cancel() task = nil endend) MakeHauntableLaunch(inst) return instendreturn Prefab( "common/inventory/bear", fn, assets) Link to comment Share on other sites More sharing options...
Blueberrys Posted May 5, 2015 Share Posted May 5, 2015 @LordMogar I figured this would arise. The inst you are referring to isn't the player instance, it's the item's instance.You can access the owner of the item like so.inst.owner.components.sanity:DoDelta(20)I'd suggest checking if everything is valid too.if inst.owner and inst.owner.components.sanity then -- ...end Link to comment Share on other sites More sharing options...
LordMogar Posted May 5, 2015 Author Share Posted May 5, 2015 Well, the game isn't crashing at all anymore. However the item has gone back to doing nothing at all when in the inventory, so the desired effect isn't working. :/ I'm probably not using this correctly? Like I've mentioned I'm not good with this.if inst.owner and inst.owner.components.sanity thenlocal task inst:ListenForEvent("onpickup", function(inst, data) inst.task = inst:DoPeriodicTask(1, function() inst.owner.components.sanity:DoDelta(20) end)end)inst:ListenForEvent("ondropped", function(inst, data) if task then task:Cancel() task = nil endend)end Link to comment Share on other sites More sharing options...
Blueberrys Posted May 5, 2015 Share Posted May 5, 2015 @LordMogar-- inst.owner may be nil over here-- you don't want to check it until the person has the itemlocal task inst:ListenForEvent("onpickup", function(inst, data) -- Why was this inst.task? it should be just task -- Unless you're going to use inst.task elsewhere too. task = inst:DoPeriodicTask(1, function() if inst.owner and inst.owner.components.sanity then -- If statement is for this part inst.owner.components.sanity:DoDelta(20) end end)end) inst:ListenForEvent("ondropped", function(inst, data) if task then task:Cancel() task = nil endend) Edit: Read comments above again, changed them a bit.Edit2: Changed code a bit. Re-read. Link to comment Share on other sites More sharing options...
LordMogar Posted May 5, 2015 Author Share Posted May 5, 2015 Just tried it with your revisions, it still isn't doing anything. I have no idea what's up with it. Edit: Just saw your edit woops, I'll try it out again.Edit2: Nope, it still isn't doing anything. Link to comment Share on other sites More sharing options...
Blueberrys Posted May 5, 2015 Share Posted May 5, 2015 @LordMogar Just looked through the inventoryitem code. I think the inst.owner variable might not be set upon picking up items. Luckily, the event passes that information. Change this part.inst:ListenForEvent("onpickup", function(inst, data) -- data.owner contains the instance of whoever picked the item if data.owner and data.owner.components.sanity then task = inst:DoPeriodicTask(1, function() data.owner.components.sanity:DoDelta(20) end) endend) Link to comment Share on other sites More sharing options...
LordMogar Posted May 5, 2015 Author Share Posted May 5, 2015 Works like a charm! Now just gotta tweak it to a more reasonable value. Thank you very much for the help. Edit: Except for one thing. It doesn't seem to be cancelling the task when the item is dropped. Link to comment Share on other sites More sharing options...
LordMogar Posted May 5, 2015 Author Share Posted May 5, 2015 Bumping for help to fix that one last issue. The task doesn't cancel upon the item dropping. Link to comment Share on other sites More sharing options...
Blueberrys Posted May 5, 2015 Share Posted May 5, 2015 @LordMogar Ensure the "task" variable is only being used once, and you're using it consistantly. Not inst.task and task, just one or the other.local task -- Puts variable in outer scope so it can be accessed in both functions-- Inside the pickup function if not task then -- Ensure it won't be overwritten unless it's nil task = something end-- Inside the drop function if task then task:Cancel() endEdit: fixed "if not task" Link to comment Share on other sites More sharing options...
LordMogar Posted May 5, 2015 Author Share Posted May 5, 2015 Only task is being used, no inst.task or anything like that.local task inst:ListenForEvent("onpickup", function(inst, data) if data.owner and data.owner.components.sanity then task = inst:DoPeriodicTask(1, function() data.owner.components.sanity.dapperness = 0.1 end) endend) inst:ListenForEvent("ondropped", function(inst, data) if task then task:Cancel() task = nil endend) Link to comment Share on other sites More sharing options...
Blueberrys Posted May 5, 2015 Share Posted May 5, 2015 @LordMogar Re-read my post, notice the if statements. Try to figure it out, this one is simple if you give it some thought. If you still can't get it, ask. Programming is all about figuring out solutions for problems, you're gonna have to practice it yourself if you wanna make something worthwhile. Link to comment Share on other sites More sharing options...
LordMogar Posted May 5, 2015 Author Share Posted May 5, 2015 I'm afraid I still don't get it. Maybe I've been staring at it for too long? I've noted that in your post you said to include "if task then" inside the pickup function, which my code lacks. However I don't see where or how to apply that if needed, considering it doesn't fit in the context of mine. Does that have anything to do with why it isn't working? Link to comment Share on other sites More sharing options...
Blueberrys Posted May 5, 2015 Share Posted May 5, 2015 @LordMogar Yup, that's the part.local task inst:ListenForEvent("onpickup", function(inst, data) if data.owner and data.owner.components.sanity then if not task then -- Fits right here -- You don't want the task variable below to be overwritten unless it's nil task = inst:DoPeriodicTask(1, function() data.owner.components.sanity.dapperness = 0.1 end) end endend) inst:ListenForEvent("ondropped", function(inst, data) if task then task:Cancel() task = nil endend)Edit: Whoops, completely reversed that. Should be "if not task then". Fixed. Sorry bout that, haha. Link to comment Share on other sites More sharing options...
LordMogar Posted May 5, 2015 Author Share Posted May 5, 2015 Nah it's okay, we all make mistakes. It's actually still not working correctly. Same problem, doesn't get rid of the sanity buff upon being dropped. Link to comment Share on other sites More sharing options...
Blueberrys Posted May 5, 2015 Share Posted May 5, 2015 @LordMogar Ah.. I just realize you changed the sanity DoDelta command to a dapperness value. If you're using dapperness, then you won't have to use a PeriodicTask at all.local ownerinst:ListenForEvent("onpickup", function(inst, data) owner = data.owner if owner and owner.components.sanity then owner.components.sanity.dapperness = 0.1 endend)inst:ListenForEvent("ondropped", function(inst, data) if owner and owner.components.sanity then owner.components.sanity.dapperness = 0 endend) Link to comment Share on other sites More sharing options...
LordMogar Posted May 5, 2015 Author Share Posted May 5, 2015 Thanks a lot! Works perfectly now and I even learned a couple of things, haha. Yeah I realized sanity DoDelta wasn't at all what I was looking for, so I changed it. I probably should have mentioned, oops. Edit: Here's the item I was working on, if you were curious. http://i.imgur.com/ss8egLG.png Link to comment Share on other sites More sharing options...
RedRock911 Posted May 17, 2015 Share Posted May 17, 2015 Thanks a lot! Works perfectly now and I even learned a couple of things, haha. Yeah I realized sanity DoDelta wasn't at all what I was looking for, so I changed it. I probably should have mentioned, oops. Edit: Here's the item I was working on, if you were curious. http://i.imgur.com/ss8egLG.png Thats pretty cool! 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.