Jump to content


  • Posts

  • Joined

  • Last visited

1 Follower

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I've uploaded the current version of the mod to the github. https://github.com/Li-Zero/PZ-Simplify Some stuffs are not included yet because they're in unfinished state. And, there's no comment for the new stuffs. So, you might want to take a look at the examples. And also the extension folder. There's nothing much but overall, it should enhance your coding style. Unless you like those heavily nested codes. Do take note that I've extended the 'require' function to include 'cache/lua/server_name' and root mod folders. The only problem is that, those files will print inaccurate errors if there's any and will be improvised if possible. The provided modloader is just an example and you don't need to pay attention to it for now. For those who needs tools for adding custom events and triggers, you can use available 'EventManager' and 'Events' modules. I've done some tests and it should work as expected. The methods for adding and removing hooks are finalized and wouldn't be changed. This also includes the 'CommandChannels' module. Lastly, I'm looking for collaborators to improve this framework. The direction for this framework would be providing the tools modders need and also workaround for architecture's limitations. Please pm me if you're interested. Please submit bug reports at github alright.
  2. That's more to current game's architecture problem. It's not fully migrated from SP to MP. So, you might want to work on custom server data storage and grab data from player when they are connected.
  3. Oh shoot... I made a mistake. When you are using 'getDescriptor' method to get the forename, you need to call 'getForename' instead of 'getForname'. That's how it's defined for player descriptor object. Sorry, I forgot about the inconsistent method names. if not isServer() then return end; local function WergioServerData() local players = getOnlinePlayers(); for i=0, players:size()-1 do local p = players:get(i); print(type(p)); print(p:getUsername()); print(type(p:isAsleep())); if p:isAsleep() then print(p:getUsername() .. " is asleep"); else print(p:getUsername() .. " is awake"); end local pd = p:getDescriptor(); print(type(pd)); print(pd:getForename()); print(pd:getSurname()); end end Events.EveryTenMinutes.Add(WergioServerData); As for the object type, I think you can try ':toString()' method for it. Not sure if this works or defined by the developers. Haven't test it yet.
  4. The functions you called are meant to return the forename and surname of the first player on their pc. If you want to access the other player's name, you need to call 'getDescriptor' on the player's object. As for 'isAsleep' function, try it again for another error check because I went through the source and it really exists under super class (IsoGameCharacter) methods. if still not working, you can try 'isOnlyPlayerAsleep'. local players = getOnlinePlayers(); for i=0, players:size()-1 do local p = players:get(i); local str = string.format("%s %s (%s): ", p:getDescriptor():getForname(), p:getDescriptor():getSurname(), p:getUsername()); -- Try 'isAsleep' again for another error check -- if 'isAsleep' really don't really work, try 'isOnlyPlayerAsleep' if p:isAsleep() then str = str .. "is asleep"; else str = str .. "is awake"; end print(str); end
  5. Heya developers, I tried working on database utility and 'getSteamID' is suffering from loss of precision. Could you please add a function to return player steamid64 as steamid? If you would like to do the bit shift method, you can refer to this image link. https://developer.valvesoftware.com/w/images/0/01/Steam_id_explanation.png https://developer.valvesoftware.com/wiki/SteamID Otherwise, if you would like to do the easy way, you only need to do this. (Please forgive me because the forum code editor wouldn't load for me) lConstant = 76561197960265728 lRemainder = lSteamID64 % 2 string.format("STEAM_0:%s:%s, lRemainder.toString(), ((lSteamID64 - lConstant + lRemainder) / 2).toString()) I don't recommend the easy way because you can't extract that one value which is the mentioned universe value inside the wiki. Thank you.
  6. Hello developers, current 'getTableResult' and 'executeQuery' global functions require a game client to run those functions and this is forcing modders to make their own custom player data storage. It would be great if you can make it available for server-side modding. This would save us a lot of time. Thank you. And, I have a question about 'ServerWorldDatabase#executeQuery' function. The 'PreparedStatement' variable is not closed after using it. Will this not cause an issue for dedicated servers running 24/7?
  7. Zeros

    Database Utility

    Hi, is there's any database utility mod available or tutorial for it? I'm planning to add 'ping location' feature for my radar mod but it can be annoying if one has the intention to spam it. So, in order to deal with these kind players, I would like to add some sort privilege check which can be modified by server admins / mods. Would like to know if someone already made it before I make an attempt. Thank you. edited: It seems that the server sql database is only available for client side modding but not the server side which seems to be contradicting. I'll post a suggestion about making it available for server-side modding.. Anyway, please let me know if you know any utility mod for storing custom player data.
  8. I encountered a critical issue when using the second version. Since the switch function is defined once without getting values from the table function arguments, it will use the very first upvalue, meaning that the function will not receive any new data. Therefore, I've added variable arguments parameter to the switch function. local validate = function(t) if (not t) then error("Switch: Argument is nil", 2) elseif (type(t) ~= "table") then error("Switch: Argument is not a table", 2) end end local switch = function(val, t, ...) validate(t) local args = {...} if t[val] then if (#args > 0) then return t[val](unpack(args)) else return t[val]() end else return t["default"]() end end local tSwitch = {} -- Example One - Without Arguments do tSwitch.Value = tSwitch.Value or { [1] = function() print("One") end, [2] = function() print("Two") end, [3] = function() print("Three") end, [4] = function() print("Four") end, [5] = function() print("Five") end, default = function() print("Unknown value!") end, } for i=1, 6 do switch(i, tSwitch.Value) end end --Example Two - With Arguments do tSwitch.Var = tSwitch.Var or { ["add"] = function(i1, i2) print(i1 + i2) end, } switch("add", tSwitch.Var, 5, 10) end
  9. Hi, I need someone to evaluate which piece of code should used on rendering call. To be honest, I'm thinking of scrapping the FIRST VERSION because it's recreating table and closure. Worst case is recreating the closure on each call. I might be wrong about this hence I need someone to point out what I'm missing. I would appreciate it if there's better idea to improve the first version because variation one coding style is much more familiar. local validate = function(t) if (not t) then error("Switch: Argument is nil", 2) elseif (type(t) ~= "table") then error("Switch: Argument is not a table", 2) end end -- First Version local switch = function(val) return function(t) validate(t) if t[val] then return t[val]() else return t["default"]() end end end -- Variation 1 local function render(...) local i = 10 switch(i) { [1] = function() print("One") end, [10] = function() print("Ten") end, default = function() print("Unknown value!") end, } end -- Variation 2 local tSwitch = {} local function render(...) local i = 10 tSwitch.Value = tSwitch.Value or { [1] = function() print("One") end, [10] = function() print("Ten") end, default = function() print("Unknown value!") end, } switch(i)(tSwitch.Value) end -- Second Version local switch = function(val, t) validate(t) if t[val] then return t[val]() else return t["default"]() end end local tSwitch = {} local function render(...) local i = 10 tSwitch.Value = tSwitch.Value or { [1] = function() print("One") end, [10] = function() print("Ten") end, default = function() print("Unknown value!") end, } switch(i, tSwitch.Value) end
  10. I went through the source again. The most legitimate way to transfer files is to use the server and client commands. You can try look at gameserver, gameclient and packettypes for more details. To be honest, I might have skipped some important things while scanning for related functions. If you need better transfer method, an external application might be required for clients to download the mods. Otherwise, try sending suggestion to developers to consider second option for downloading mods which is the game server. Anyway, since there's no other option left.. I can only try override player spawn now to create the timeout window.
  11. No problem. And, your input is highly appreciated since there might be other solutions to current issues I encountered. I haven't test it yet since I had to streamline some processes involved with the mod loading. My mods became awfully messy after implementing the trial MP mod loader. This is delaying the test. I'm using server / client command events to transfer the files. I have no idea if there's other available file transfer method(s) but, the method I'm using only handle file request from clients after the server game logic starts ticking. This creates an issue of players needing a window to download / load mods without ruining the progress. Therefore, yes. I need some sort of timeout function. That's why I considered waiting lobby as an option since I was running out of idea on how to do it. Thanks for the heads up, I will look for the queue functionality later and see if it's possible. Otherwise, I can try radical approach I recently came up with such as overriding the player spawn process through character creation mod and create the window from there. As for the suggestion to hook the workshop download process, it might be possible if there's a way for clients to download the mods without waiting for the server game logic to start ticking. After giving some consideration, there's a need to look at how the server sandbox settings gets transmitted to the clients when connecting. There might be another file transfer method available. Thanks stuck. I almost forgot to check for other file transfer method.
  12. I've not tested it yet but you can try this to play your sound. local soundManager = getSLSoundManager() local soundList = soundManager:getStorySounds() for i=0, soundList:size() - 1 do --print(soundList[i]:getName()) if (soundList[i]:getName() == "filename_maybe") then soundList[i]:playSound() end end --[[ -- There's two more sound managers available but I haven't look check any of it yet. getWorldSoundManager() getSoundManager() --]]
  13. For custom player data, I recommend you to create your own player data storage instead of relying on player:getModData(). You can use player steam id as primary identifier and player character forename and surname as the secondary identifier. Reason for secondary identifier is because of the pc with co-op players. The only way to recognize who is actually who is to check the character's name. Related functions: player:getSteamID() player:getDescriptor():getForename() player:getDescriptor():getSurname() getModFileReader(strModId, strPath, false) - last argument is for creating a new file but i don't recommend it. getModFileWriter(strModId, strPath, bCreate, bAppend) FYI, getModFileReader returns a java bufferedreader object while the other one returns custom writer class with exposed write, writeln and close functions.
  14. I've been busy lately so now I would like to give report my current progress on the mod loader. 1. Turning it from SP into MP based mod loader requires me to ensure that player request for server response and wait for it. Once established, only then can they start loading the mods. I haven't tested it on dedicated server yet but for listen server host, you can only get server response few seconds after you're spawned using the 'OnPlayerUpdate' event. This is caused by listen server to start ticking right after the host player start the player update tick. For MP clients, I think it might be fine to use 'OnConnected' event but this will need further testing which I am planning to do tonight. 2. Mods using the mod loader feature can only be loaded after player update start ticking or when connected if possible. Custom event is needed for mods that initialize data using those two events. 3. There might be a need for waiting lobby to ensure that the connected players has fully loaded the mods. 4. I tried sending read-only loading order array through server and client command but it's not working since metatable are not transmitted together with the array. So, there's a need to apply custom metatable after the client receive the data. 5. After going through intensive testing, it's possible to make clients join without having version mismatch issue. This require modders cooperation though. They'll need to make multiple workshop pages. - Server Mod: You don't need to enable the mod, just copy mod script files for server and clients to server folder. Server will let clients to download those client files when they joined the server. - Client Mod: Contain some other files such as textures, item definitions and etc. These files usually don't get updated that frequent. It's fine to enable it in workshop mod list. 6. Need UI for download progress. There you go. Sorry for the rough report though. I'll take a look at it later.
  15. Nah, more like replacing the distribution logic with yours. Just in case you need better manipulation on the distribution. I had a look at the source again and the reason why your map items didn't spawn probably because the loot table you modified didn't get selected for loot generation. Single type of container can contain more than one loottable, and if you didn't force it, it has chance of not getting selected. Pretty sure those mods have the other loottable entry removed or set it's weight lower. Otherwise, there's high chance their items of not being spawned. Here's the problematic part. -- 'media/lua/server/Items/Distributions.lua -- Look at the procList -- Each entry is a loot table to be selected -- Related functions inside ItemPickerJava: #rollProceduralItem and #getDistribInHashMap gasstorage = { counter = { procedural = true, procList = { {name="JanitorChemicals", min=0, max=99, weightChance=100}, {name="JanitorCleaning", min=0, max=1, forceForTiles="fixtures_sinks_01_0;fixtures_sinks_01_1;fixtures_sinks_01_2;fixtures_sinks_01_3;fixtures_sinks_01_4;fixtures_sinks_01_5;fixtures_sinks_01_6;fixtures_sinks_01_7;fixtures_sinks_01_8;fixtures_sinks_01_9;fixtures_sinks_01_10;fixtures_sinks_01_11;fixtures_sinks_01_16;fixtures_sinks_01_17;fixtures_sinks_01_18;fixtures_sinks_01_19"}, {name="JanitorMisc", min=1, max=1, weightChance=100}, {name="JanitorTools", min=0, max=1, weightChance=100}, } }, crate = { procedural = true, procList = { {name="GasStorageMechanics", min=1, max=99, weightChance=100}, {name="GasStorageCombo", min=0, max=99, weightChance=80}, } }, metal_shelves = { procedural = true, procList = { {name="GasStorageMechanics", min=1, max=99, weightChance=100}, {name="GasStorageCombo", min=0, max=99, weightChance=80}, } } } Hope this new information helps with your next distribution test.
  • Create New...