Jump to content

Portal location


Recommended Posts

Hi,

I'm currently working on some custom functions to ease some of the admin tasks, and one of them is helping out players that ask for a character change. Now, to make things even easier for us was thinking about teleporting the player that requested the change to the portal (prefab "multiplayer_portal") where he would drop all the stuff in his inventory and his/her backpack (if has one) then despawn, but I don't know how to actually grab portal's coordinates in order to teleport the player there.

This is the code i got so far:

function m_change(player)
    if player ~= nil then
        local player = UserToPlayer(player)
        local x,y,z = [missing code in here for portal location]
        player.Transform:SetPosition(x, y, z)
        player.components.inventory:DropEverything()
        TheWorld:PushEvent("ms_playerdespawnanddelete", player)
    end
end
	
Edited by cezarica
Link to comment
Share on other sites

Had some other stuff under the code but for some reason it's gone.. anyway..

Any suggestions on the above code would be more than welcome.

Not sure on the if player ~= nil then part. I want it to continue if the player is not empty, is this correct?

Also, how could I implement a way for it to match the full player name if I only feed it a few characters? for instance find "cezarica" if I said only "cez".

Link to comment
Share on other sites

function GetPortalPosition()
	local f = TheSim:FindEntities(0,0,0,TheWorld.Map:GetSize()*4)
	for k,v in ipairs(f) do
		if (v.prefab=="multiplayer_portal") then
			return Vector3(v.Transform:GetWorldPosition())
		end
	end
end

Use this function to get the coordinates of the spawn portal.

Change this:
	local x,y,z = [missing code in here for portal location]
	player.Transform:SetPosition(x, y, z)

To this:
	local fpt = GetPortalPosition()
	player.Transform:SetPosition(fpt.x, 0, fpt.z)
Quote

Also, how could I implement a way for it to match the full player name if I only feed it a few characters? for instance find "cezarica" if I said only "cez".

for k,v in ipairs(AllPlayers) do
	if string.match(string.lower(v:GetDisplayName()), string.lower("cez"))~=nil then
		--stuff
	end
end

 

Link to comment
Share on other sites

 

From a performance standpoint it's probably better to set the gate on startup than find it with a global search. There will generally only be one portal per world so it should work.

Modmain:

AddPrefabPostInit("multiplayer_portal", function(inst)
	--replace _MYMODNAME with the name of your mod. You generally don't want to stick your own variables right in global itself.
	GLOBAL._MYMODNAME.PORTAL_LOCATION = Vector3(inst.Transform:GetWorldPosition())

end)

and use that variable instead of GetPortalPosition.

Edited by code4240
Realized Any was unnecessary
Link to comment
Share on other sites

39 minutes ago, cezarica said:

The stuff I have in mind is not a mod per-se, but stuff i write in customcommands.lua so will this work? I have zero experience with this so..

Thanks guys. :)

If it's just a console command, then use the function I've provided. If it's for a mod, then @code4240's way is a lot better.

Link to comment
Share on other sites

Quick question. Instead of:

local fpt = GetPortalPosition()
	player.Transform:SetPosition(fpt.x, 0, fpt.z)

won't work with:

local x,y,z = GetPortalPosition()
player.Transform:SetPosition(x, y, z)

?

Edit: Also, isn't better to break the loop and return outside the loop like:

function GetPortalPosition()
	local f = TheSim:FindEntities(0,0,0,TheWorld.Map:GetSize()*4)
	for k,v in ipairs(f) do
		if (v.prefab == "multiplayer_portal") then
			local coords = Vector3(v.Transform:GetWorldPosition())
			break
		end
	end
	return coords
end

I know isn't nice to return a variable that might not exist, but it's clearly not the case. Could add a:

if coords ~= nil then
	return coords
end

to make it look nice :)

Edited by cezarica
Link to comment
Share on other sites

I was talking with a friend (who also doesn't know any LUA) and expressed a valid concern about storing all world entities inside an variable that might cause lag and decided to tackle the problem with a different approach:

function GetPortalPosition()
    local coords
    for _,v in pairs(Ents) do
        if v.prefab ~= nil and v.prefab == "multiplayer_portal" then
            coords = Point(v.Transform:GetWorldPosition())
            break
        end
    end
    return coords
end

and to use it:

local coords = GetPortalPosition()
player.Transform:SetPosition(coords.x, coords.y, coords.z)

I do the break on a match because it's pointless to continue finding matches since there's just one portal.

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...