Serpens Posted September 1, 2019 Share Posted September 1, 2019 (edited) 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 September 6, 2019 by Serpens Link to comment Share on other sites More sharing options...
Serpens Posted September 6, 2019 Author Share Posted September 6, 2019 (edited) 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 September 6, 2019 by Serpens Link to comment Share on other sites More sharing options...
Loki99 Posted September 6, 2019 Share Posted September 6, 2019 Great work! Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now