Jump to content

Spawning with a backpack?


Recommended Posts

I’ve seen other threads about this, but no concise answer.  If you give a player a backpack as a starting item it will appear on the character select screen as though the character will receive it, but since it can’t be put into their inventory the item is never actually given to them.  I think one person suggested something like, “on player spawn, drop item X”, but is that all there is to it, or is there a better way?

Link to comment
Share on other sites

Just now, FurryEskimo said:

I’ve seen other threads about this, but no concise answer.  If you give a player a backpack as a starting item it will appear on the character select screen as though the character will receive it, but since it can’t be put into their inventory the item is never actually given to them.  I think one person suggested something like, “on player spawn, drop item X”, but is that all there is to it, or is there a better way?

I suggested this in another thread, but my solution was to make an item with the same icon as a backpack, and once it's equipped, or moved, swap it out for a real backpack. It's sorta jank and I can't provide code on how you'd do it, but I can't think of a better solution given my limited knowledge.

Link to comment
Share on other sites

@TheSkylarr
I appreciate the suggestion.  I’ve seen this suggested a few times for various problems, but making items that spawn other items isn’t my forte.

I’ve seen code that can spawn items, and maybe the solution really is to spawn an instance, and then tell that item to equip itself to the player, idk.  Sounds easy, but I bet it would take me awhile to figure it from scratch.

Link to comment
Share on other sites

@IronHunter
Are you sure?  I'm trying it now and it doesn't seem to be working:

local master_postinit = function(inst)  --Set player's abilities here..
	--Sets starting inventory.
	inst.starting_inventory = start_inv[TheNet:GetServerGameMode()] or start_inv.default

	inst.OnNewSpawn = function()
		inst.components.inventory:Equip(SpawnPrefab("icepack"))
	end

The player's starting inventory has an icepack, but they won't actually spawn with it, and your code doesn't seem to be doing anything either.

Link to comment
Share on other sites

 

1 hour ago, FurryEskimo said:

@IronHunter
Are you sure?  I'm trying it now and it doesn't seem to be working:


local master_postinit = function(inst)  --Set player's abilities here..
	--Sets starting inventory.
	inst.starting_inventory = start_inv[TheNet:GetServerGameMode()] or start_inv.default

	inst.OnNewSpawn = function()
		inst.components.inventory:Equip(SpawnPrefab("icepack"))
	end

The player's starting inventory has an icepack, but they won't actually spawn with it, and your code doesn't seem to be doing anything either.

This works for me, literally just tested it last night.

Is there any errors?

Please attach the character.lua

As I have a custom characters with unique and vanilla custom items and this solution works fine.

  • Like 1
Link to comment
Share on other sites

@IronHunter
No errors, it just doesn't appear to do anything.

PS:  The code is slightly different now, but hasn't been tested yet:

if startinginventory == 3 or startinginventory == 4 or startinginventory == 7 then
	inst.OnNewSpawn = function()  --Test code.
		inst.components.inventory:Equip(SpawnPrefab("icepack"))
	end
end

 

furryeskimo.lua

Link to comment
Share on other sites

you are overriding inst.OnNewSpawn, merge them together with the one at the bottom of your masterposinit

15 minutes ago, FurryEskimo said:

@IronHunter
No errors, it just doesn't appear to do anything.

PS:  The code is slightly different now, but hasn't been tested yet:


if startinginventory == 3 or startinginventory == 4 or startinginventory == 7 then
	inst.OnNewSpawn = function()  --Test code.
		inst.components.inventory:Equip(SpawnPrefab("icepack"))
	end
end

 

furryeskimo.lua 35.37 kB · 0 downloads

Edit:
also it seems like your starting inventory code is a mess in general you have a unreferenced local variable,

--move this to the bottom...and merged it with the other inst.OneNewSpawn

inst.OnNewSpawn = function()  --Test code.
  onload(inst)
  if startinginventory == 3 or startinginventory == 4 or startinginventory == 7 then
    inst.components.inventory:Equip(SpawnPrefab("icepack"))
  end
end

I don't know what startinginventory references too as it seems to be a variable that doesn't even exist I can only assume its some sort of global variable in your modmain, but you should test stuff in a controlled environment without your nonfunctioning code to make sure it works before integrating it into the rest of your code.

Edited by IronHunter
  • Like 1
  • Health 1
Link to comment
Share on other sites

@IronHunter
Got it!
So this was in my Master_postinit:

inst.OnLoad = onload
inst.OnNewSpawn = onload

And now this is elsewhere in the character's prefab file:

--When loading or spawning the character.
local function onload(inst)
	inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
	inst:ListenForEvent("ms_becameghost", onbecameghost)

	if inst:HasTag("playerghost") then
		onbecameghost(inst)
	else
		onbecamehuman(inst)
	end

	if startinginventory == 3 or startinginventory == 4 or startinginventory == 7 then
	--	inst.OnNewSpawn = function()  --Test code.
			inst.components.inventory:Equip(SpawnPrefab("icepack"))
	--	end
	end
end

Seems to e working!  ^-^
  Thanks a lot!

Edited by FurryEskimo
Link to comment
Share on other sites

54 minutes ago, IronHunter said:

I edited my post with a tidier solution, as it just feels weird seeing that chunk of code in the onload, when that function is called everytime you load into a world and its caves. Cleaner code is just easier to bug fix ^-^

@IronHunter
Wait, are you telling me this will give the player a backpack every time they load the game or enter a cave?

Link to comment
Share on other sites

47 minutes ago, FurryEskimo said:

@IronHunter
Wait, are you telling me this will give the player a backpack every time they load the game or enter a cave?

I don't think it should, but it just is unnecessarily resetting the newspawn function which won't do anything.
If it works it should be fine, but my ocd likes things neat and tidy and knowing nothing weird will creep up accidentally.

  • Like 1
Link to comment
Share on other sites

@IronHunter
I just tested the code and yes, the player is given a new backpack every time they load the game, or enter/exit a cave.  Any suggestions on how to deal with this?  I only want to give the player a backpack when they first select the character and spawn for the first time.

Edit:  I just found a massive pile of backpacks out in the ocean, so I think when I'm already wearing a backpack and the game tries to give me one, it stops halfway and just drops the open off to the upper left.

Edited by FurryEskimo
Link to comment
Share on other sites

13 minutes ago, FurryEskimo said:

@IronHunter
I just tested the code and yes, the player is given a new backpack every time they load the game, or enter/exit a cave.  Any suggestions on how to deal with this?  I only want to give the player a backpack when they first select the character and spawn for the first time.

Edit:  I just found a massive pile of backpacks out in the ocean, so I think when I'm already wearing a backpack and the game tries to give me one, it stops halfway and just drops the open off to the upper left.

Does putting the code in OnNewSpawn not work? Or does the template not come with that

Link to comment
Share on other sites

@TheSkylarr
It comes with:

inst.OnLoad = onload
inst.OnNewSpawn = onload

But that code doesn't activate when you select your character, it happens Every time you exit a loading screen, aka When selecting a character, loading the world, and entering/exiting caves.

Edit:  I'm reading the multiplayer portal's code and I don't understand it too well, but it keeps referencing a 'GetTimeAlive' value.  Maybe this is important, but I feel like there's more to it.  Somehow the game knows when a new player spawns because a little light and sound play, right?

Edited by FurryEskimo
Link to comment
Share on other sites

10 minutes ago, FurryEskimo said:

@TheSkylarr
It comes with:


inst.OnLoad = onload
inst.OnNewSpawn = onload

But that code doesn't activate when you select your character, it happens Every time you exit a loading screen, aka When selecting a character, loading the world, and entering/exiting caves.

change the  inst.OnNewSpawn = onload  to

inst.OnNewSpawn = onnewspawn

then, add this function below onload

local function onnewspawn(inst)
	inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
	inst:ListenForEvent("ms_becameghost", onbecameghost)

	if inst:HasTag("playerghost") then
		onbecameghost(inst)
	else
		onbecamehuman(inst)
	end

	if startinginventory == 3 or startinginventory == 4 or startinginventory == 7 then
	--	inst.OnNewSpawn = function()  --Test code.
			inst.components.inventory:Equip(SpawnPrefab("icepack"))
	--	end
	end
end

Then, just delete the starting inventory code from onload, which should leave your onload looking like this

local function onload(inst)
	inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
	inst:ListenForEvent("ms_becameghost", onbecameghost)

	if inst:HasTag("playerghost") then
		onbecameghost(inst)
	else
		onbecamehuman(inst)
	end
end

If you have any problems let me know.

EDIT: I didn't see your reply, the portal itself is actually unconnected to how the player spawns, if you remove it people will still spawn in the world fine, it's placed at where players will spawn when the world is generated.

Edited by TheSkylarr
  • Health 1
Link to comment
Share on other sites

@TheSkylarr
Should I also delete the original 'onload' code from this 'onnewspawn' code, or will it be in there twice?

Edit:  It seems to be working!  :D

inst.OnLoad = onload
inst.OnNewSpawn = onnewspawn
--When loading or spawning the character.
local function onload(inst)
	inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
	inst:ListenForEvent("ms_becameghost", onbecameghost)

	if inst:HasTag("playerghost") then
		onbecameghost(inst)
	else
		onbecamehuman(inst)
	end
end

--Occurs the first time the character spawns.
local function onnewspawn(inst)
	if startinginventory == 3 or startinginventory == 4 or startinginventory == 7 then
		inst.components.inventory:Equip(SpawnPrefab("icepack"))
	end
end

 

Edited by FurryEskimo
Link to comment
Share on other sites

15 minutes ago, FurryEskimo said:

@TheSkylarr
Should I also delete the original 'onload' code from this 'onnewspawn' code, or will it be in there twice?

Edit:  It seems to be working!  :D


inst.OnLoad = onload
inst.OnNewSpawn = onnewspawn

--When loading or spawning the character.
local function onload(inst)
	inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
	inst:ListenForEvent("ms_becameghost", onbecameghost)

	if inst:HasTag("playerghost") then
		onbecameghost(inst)
	else
		onbecamehuman(inst)
	end
end

--Occurs the first time the character spawns.
local function onnewspawn(inst)
	if startinginventory == 3 or startinginventory == 4 or startinginventory == 7 then
		inst.components.inventory:Equip(SpawnPrefab("icepack"))
	end
end

 

You aren't going to want to delete the old code, the event listeners there make sure that respawning and dying functions happen consistantly, you should definitely add them back.

edit: I could be wrong about this, but every character mod I've looked at has those event listeners there and it doesn't do any harm if they're useless anyway.

Other than that, glad I could help.

 

Edited by TheSkylarr
Link to comment
Share on other sites

@TheSkylarr
I've been testing dying and respawning without that code, and surprisingly it still seems to work perfectly. I'm honestly not exactly sure what it's for, so it's hard to tell when/why it would activate.

I think it basically says, if when you load the game, begin listening for these events, and update the character when you die or respawn, but since it's already been told to listen when the game loads, you don't need to tell it again.

Edited by FurryEskimo
Link to comment
Share on other sites

@FurryEskimo
Ya onload loads every time you load into a world, onnewspawn only loads once when you freshly spawn into a world.
You should have separate functions for both, not merging them together as that can create a lot of undesired repetition or lack of as you have seen from your tests.

ListenForEvents listen for a event to be pushed to entity, when true it'll fire the function in the listener. In this case we run the onbecamehuman or onbecomeghost functions which I am assuming are likely blank or do negligible things, if you don't have any actual code in those functions you can delete them. But they are mostly harmless if they stick around and call and do nothing, as they are infrequent events.

  • Like 1
Link to comment
Share on other sites

I think this was just in the character prefab when I originally downloaded it, so it's likely found in many, many modded characters.

Update:  That wasn’t redundant code.  When the player spawns, they are not ‘loaded’, meaning all your ‘load’ code also needs to be in the ‘spawn’ code.  My character appeared to be normal, but their swimming ability only activated when they were loaded.  Since I was loading a test map again and again I didn’t notice this error, but when I made a new map, the swimming ability was not active yet.

Edited by FurryEskimo
Link to comment
Share on other sites

Well how about just adding onload(inst) to onnewspawn?

local function onload(inst)
	--blahblah
end

local function onnewspawn(inst)
	if startinginventory == 3 or startinginventory == 4 or startinginventory == 7 then
		inst.components.inventory:Equip(SpawnPrefab("icepack"))
	end
	onload(inst)
end

inst.OnLoad = onload
inst.OnNewSpawn = onnewspawn

Like this, on spawn, onnewspawn and onload will called together,

but on load, onload only will be called.

Edited by Combustiblemon
  • Like 1
Link to comment
Share on other sites

4 hours ago, Combustiblemon said:

Well how about just adding onload(inst) to onnewspawn?


local function onload(inst)
	--blahblah
end

local function onnewspawn(inst)
	if startinginventory == 3 or startinginventory == 4 or startinginventory == 7 then
		inst.components.inventory:Equip(SpawnPrefab("icepack"))
	end
	onload(inst)
end

inst.OnLoad = onload
inst.OnNewSpawn = onnewspawn

Like this, on spawn, onnewspawn and onload will called together,

but on load, onload only will be called.

This would work fine yeah.

Link to comment
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
 Share

×
  • Create New...