Sign in to follow this  
Micklo202

URGENT: Making a character specific item?

Recommended Posts

Micklo202    5

Hello and thank you so much for taking the time to read this!

ok so basically my friend and i have been working on a character mod for DST, we've been making loads of progress. Until we wanted to give our character a weapon only she can (Use/Equip/Pickup). 

i've scoured the web the web and found this piece of code from @DarkXero:

Spoiler

    inst.components.inventoryitem.cangoincontainer = false  
    inst.components.inventoryitem.onputininventoryfn = function(inst, player) 
    if player.prefab ~= "star" then 
        inst:DoTaskInTime(0.1, function()
        
        player.components.inventory:DropItem(inst)
        player.components.talker:Say("It seems to slip right out of my hands!")
    end)
    end
    end

the code worked perfectly, made other players drop the item and even said they can't use it. BUT whenever i try to place the weapon into a backpack or chest it immediately crashes the game... i have no idea why... I've been doing my best to try different codes. even using:

inst:AddComponent("characterspecific")  inst.components.characterspecific:SetOwner("star")

but unfortunately still haven't worked. keeps giving me an error: "attempt to index field 'inventory' (a nil value)" 

Here's my star_axe.lua and client_log.txt 

can you please take a look at the code and see what it is im doing wrong? Thanks in advance!

Edited by Micklo202

Share this post


Link to post
Share on other sites
Lumina    2152

I'm sorry but i don't see anything more urgent here than any request any people can ask here. So i don't think it's fair to put "urgent" in title.

So, what is your problem exactly if you have a code ?

Share this post


Link to post
Share on other sites
Lumina    2152

Ok. So you put a line making your item unable to go in container, this line :

	inst.components.inventoryitem.cangoincontainer = false

However, this line shouldn't crash your game, it should just prevent you to put this item in container (like chest, and i suppose, backpack). The question is : why it's make the game crash ? The line seems similar to some lines i could find in code, like backpack and some others stuff, so i'm not sure it's the problem, or why it's the problem.

Share this post


Link to post
Share on other sites
Micklo202    5

yea i've guessed that too. so i removed that line and it still gave me the same error.. could it be somthing to do with modmain.lua ? or is that irrelevant when it comes to items?

Share this post


Link to post
Share on other sites
Lumina    2152

@Micklo202 I think that if modmain.lua was involved, the error log would show it. Since it mention staraxe, it's probably not related to modmain.

[00:01:34]: [string "../mods/Star MOD/scripts/prefabs/star_axe.l..."]:76: attempt to index field 'inventory' (a nil value)

So, the line that seems to be related is :

		player.components.inventory:DropItem(inst)

line 75 in the file you give, but probably this. So maybe the problem is that there is a test missing, like being sure there is an inventory component or something ?
I suppose (reading the old topic you pick the code on) that it was why the line "inst.components.inventoryitem.cangoincontainer = false" was added, but the bug was supposed to be fixed, with or without this line. Maybe it got reverted for any reason ?

Anyway i'm not sure what exactly is wrong here...

 

Topic for reference.

Share this post


Link to post
Share on other sites
Lumina    2152

@Micklo202At least, if the item is craftable, you could easily make the item craftable only by the owner. But maybe this is already the case. And maybe someone will find a fix, there are really good modders here.

Still, i suggest you attach your zipped mod here, someone could have idea and want to do some testing.

Share this post


Link to post
Share on other sites
HabdomeRaider    151

When an item is put into a container such as a backpack, the "player" in onputininventoryfn will be the backpack, not the player. As such it will have a container component, not an inventory component.

Share this post


Link to post
Share on other sites
HabdomeRaider    151

You'll want to make the code conditional on whether the thing it's being put into is a player or a container.

inst.components.inventoryitem.onputininventoryfn = function(inst, inv)
	if inv.components.inventory then
		// This is a player. Use your current code
	end
	if inv.components.container then
		// This is a container or a backpack. You'll have to do something else.
	end
end

Do you want the item to be able to be placed into chests and backpacks?

Share this post


Link to post
Share on other sites
HabdomeRaider    151

Then you just need to add a check for player.components.inventory. For example:

inst.components.inventoryitem.onputininventoryfn = function(inst, player) 
	if player.components.inventory and player.prefab ~= "star" then 
		inst:DoTaskInTime(0.1, function()
			
				player.components.inventory:DropItem(inst)
				player.components.talker:Say("It seems to slip right out of my hands!")
			
	end)

 

Share this post


Link to post
Share on other sites
HabdomeRaider    151

However, this still allows a character with a full inventory to put the item into their backpack (because then it is never in their actual inventory). You will need to add a check for player.components.container and figure out a similar solution for that.

 

Share this post


Link to post
Share on other sites
Micklo202    5

thank you so much for the tips, im now able to put the item in the backpack and chests, but unfortunately im unable to test the other player at the moment my friend's asleep =\ 

when you say "check" does that mean "if" and "then"? im pretty new to all of this...

 

Share this post


Link to post
Share on other sites
HabdomeRaider    151

Yeah, you use an "if-then" block to check to see whether the item is being put into an inventory or a container.

You can test other characters on your own by switching to a different character and using the console (press the ` or ~ key) and typing:

c_give("star_axe")

to give yourself a star axe.

Share this post


Link to post
Share on other sites
Micklo202    5

ok ive test the item with an other player and they dropped it which is perfect! thats exactly what i wanted! thank you so much!!

 

ok and for:  player.components.container  will i have to keep that in the same function area  as: player.components.inventory or will i have to start a new function?

something like this?

inst.components.inventoryitem.onputininventoryfn = function(inst, player) 
	if player.components.inventory and player.prefab ~= "star" then 
		inst:DoTaskInTime(0.1, function()
			
				player.components.inventory:DropItem(inst)
				player.components.talker:Say("It seems to slip right out of my hands!")
			
	end)
    
inst.components.inventoryitem.onputininventoryfn = function(inst, player) 
	if player.components.container and player.prefab ~= "star" then 
		inst:DoTaskInTime(0.1, function()
			
				player.components.container:DropItem(inst)
				player.components.talker:Say("It seems to slip right out of my hands!")
			
	end)  
Edited by Micklo202

Share this post


Link to post
Share on other sites
Lumina    2152
inst.components.inventoryitem.onputininventoryfn = function(inst, player) 
	if player.components.inventory and player.prefab ~= "star" then 
		inst:DoTaskInTime(0.1, function()
			
				player.components.inventory:DropItem(inst)
				player.components.talker:Say("It seems to slip right out of my hands!")
			
	elseif player.components.container and player.prefab ~= "star" then 
		inst:DoTaskInTime(0.1, function()
			
				player.components.container:DropItem(inst)
				player.components.talker:Say("It seems to slip right out of my hands!")
			
	end)  

More something like that. Ok, so sorry i wasn't able to try this yesterday, it was late, i guessed this kind of check could work but since i wasn't sure i didn't want to raise your hope. Thanks habdomeraider !

I'm not sure of the code, so try it, but you should be able to use something like

if then

elseif then

end

When you have to differents cases you want to check.

 

Share this post


Link to post
Share on other sites
HabdomeRaider    151

Ok, looks like a better way to do this is to use GetGrandOwner. GetGranOwner will tell you whose inventory you are in, and if you're in a backpack, it will tell you whose backpack.

inst.components.inventoryitem.onputininventoryfn = function(inst, player) 
	local owner = inst.components.inventoryitem:GetGrandOwner()
	if owner.components.inventory and owner.prefab ~= "star" then 
		inst:DoTaskInTime(0.1, function()
				owner.components.inventory:DropItem(inst)
				owner.components.talker:Say("It seems to slip right out of my hands!")
			
	end)
end

There's probably still some corner cases that this doesn't cover, like if Star puts the Axe in a backpack and drops the backpack and someone else picks up the backpack, I don't know if this stops that. It also won't help if another player is also playing Star and takes your Axe. It just keeps the Axe out of non-Star players.

Share this post


Link to post
Share on other sites

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
Sign in to follow this