Jump to content

[Solved] Adventure mod, force same character after worldjump, how?


Recommended Posts

I recently released my adventure mod https://steamcommunity.com/sharedfiles/filedetails/?id=1847959350

This mod uses a worldjump component written by DarkXero, which saves some OnSave Data from the players into a file when worldjumping and loads them after the worldjump (worldjump== delete current world and generate a new one). After the worldjump and when a player from previous worlds joins, we can give him back alle the items he had before and so on. Also players who left the server prior to worldjump can join and get their stuff they had when leaving. So this is no problem.

But for the adventure I would like to force the users to use the same character in this new world they had in previous world. Of course I can save the prefab of their character within worldjump or somehwere else, but how to load this BEFORE the playerpostinit and at best even before the player is in the lobby to select a new character?
 

Possible solutions:

1) My favourit solution would be to use the same  mechanic the game already uses to spawn in the character when a player joins a server for not the first time. In this case you dont have a lobbyscreen and the game just spawns your old character.
But even after hours of searching in the game code, I was not able to find out where and how this is done by the game...

2) Hook into the redux/lobbyscreen and set "character_for_game" to the desired prefab and close the lobbyscreen. This works, but the problem is to get the desired prefab. The prefab is saved somewhere at the server and while the user is in the lobby "ThePlayer" does not exist. So I have no clue how we should transfer the prefab saved at server to the client.
2.1) Normally I would use netvar, but I usually attach them to the player, which is not possible if no player exists yet. We could auto-spawn wilson, then use netvars to let the client know the prefab, then send the player back to the lobbyscren and now auto-spawn the desired prefab, if we were able to save it somewhere on client that is not thee player. But this seems to be a very dirty workaround and I dont want to do this.
2.2) We could also save the prefab somewhere else, directly at the client, for example within playerprofile or make another file at clients pc, so we can read it out while hooking into the lobbyscreen. BUT: this can lead to an unlimited number of files/entries within playerprofile cause we will never know if this prefab for a specific session is ever needed again or not (we save the prefab everytime when player leaves a session, not only during worldjump).  This also leads me to my assumption, that the game itself wont save such stuff at client side, only at server side, cause the game would have the same problem.

So how to solve this?

Edited by Serpens
Link to comment
Share on other sites

solved it with help of usercommands (to make client call a server function, cause rpc is not possible) and with netvars based on forest_network (TheWorld.net):

-- #################################################
--## force same character code...

_G.TUNING.TELEPORTATOMOD.adv_forcechar_prefabs = nil

local UserCommands = _G.require("usercommands")
AddUserCommand("adv_forcechar",{
    permission = _G.COMMAND_PERMISSION.USER,
    vote = false,
    params = {},
    serverfn = function(params, caller)
        print("adv_playerinlobby")
        local userid = caller.userid
        if _G.TheWorld and _G.TheWorld.components and _G.TheWorld.components.worldjump and _G.TheWorld.components.worldjump.player_data and _G.TheWorld.components.worldjump.player_data[userid] then
            if not table.contains(_G.TheWorld.components.worldjump.player_ids,userid) then -- only the first time in lobbyscreen (eg dont do it when we change char in new portal)
                local prefab = _G.TheWorld.components.worldjump.player_data[userid].prefab
                _G.TUNING.TELEPORTATOMOD.adv_forcechar_prefabs:set(tostring(userid).."###"..tostring(prefab))
            end
        end
    end,
})

local function IsScreenInStackAndReturnScreen(screenname)
    for _,screen_in_stack in pairs(TheFrontEnd.screenstack) do
        if screen_in_stack.name == screenname then
            return screen_in_stack
        end
    end
    return false
end

AddPrefabPostInit("forest_network",function(worldnet)
    _G.TUNING.TELEPORTATOMOD.adv_forcechar_prefabs = _G.net_string(worldnet.GUID, "adv_forcechar.player", "adv_forcechar_dirty")
    _G.TUNING.TELEPORTATOMOD.adv_forcechar_prefabs:set("")
    
    if CLIENT_SIDE then
        worldnet:ListenForEvent("adv_forcechar_dirty", function(worldnet) 
            local adv_forcechar = _G.TUNING.TELEPORTATOMOD.adv_forcechar_prefabs:value()
            local adv_forcechar_split = string.split(adv_forcechar, "###") -- we send userid+###+prefab within netvar
            local userid,prefab = adv_forcechar_split[1],adv_forcechar_split[2]
            if TheNet:GetUserID()==userid then
                local lobbyscreen = IsScreenInStackAndReturnScreen("LobbyScreen")
                if lobbyscreen then
                    lobbyscreen:Hide()
                    lobbyscreen.character_for_game = prefab
                    lobbyscreen.cb(lobbyscreen.character_for_game) -- currentskin is nil, but we will use the normal worldjump load to add the skin back
                else
                    print("no lobbyscreen")
                end
            else
                print("userid unequal")
            end
        end)
    end
end)

local function LobbyHook(self) -- force same player
    -- _G.scheduler:ExecuteInTime(0,function()
        print("LobbyHook")
        UserCommands.RunUserCommand("adv_forcechar", {}, _G.TheNet:GetClientTableForUser(_G.TheNet:GetUserID()))
    -- end, "get_data_about_self")
end
if _G.TUNING.TELEPORTATOMOD.experimentalcode and _G.TUNING.TELEPORTATOMOD.repickcharacter==false then
    AddClassPostConstruct("screens/redux/lobbyscreen", LobbyHook)
end
--#################################################################

 

Edited by Serpens
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...