Dcrew Posted July 30, 2019 Share Posted July 30, 2019 (edited) I have been checking and writing different code to make this work for a couple of hours and still have not/can not solve it. Is there any way I can check if an entity has ever been dropped by any player or if any player has ever had this entity in his inventory? Edited July 30, 2019 by Dcrew Link to comment Share on other sites More sharing options...
Ultroman Posted July 30, 2019 Share Posted July 30, 2019 Not unless you set a custom variable on that player. You can add a listener to all players for when they pick up something, and if that something is the right prefab, you can just do inst.playerOnceHadAnAcorn = true and then you can check for that whenever you need to. But if you want this to "stick" when the player leaves and rejoins the server, you also have to make sure to add that this variable is saved and loaded. You can do this by extending the inst.OnSave and inst.OnLoad functions on the player characters. There are many examples of how these functions work in the original game files, so you should be able to figure it out. Link to comment Share on other sites More sharing options...
Dcrew Posted July 30, 2019 Author Share Posted July 30, 2019 Alright, in my prepare function I use: local function on_pickup_ent(ent) ent.dcrew_wasplayerowned = true print("player picked up "..ent.prefab) end for _, ent in pairs(Ents) do ent:ListenForEvent("onpickup", on_pickup_ent) end and it works, but I have no idea how to save & load it or override said functions. Link to comment Share on other sites More sharing options...
Ultroman Posted July 30, 2019 Share Posted July 30, 2019 I may have misunderstood what you wanted. I thought you wanted to know whether a player had ever had or dropped a certain entity/prefab, but from your code it seems like you want to know whether an entity has ever been in the inventory of a player. There's a big difference in where the code should go and which entity should save/load data about his, depending on what exactly you want to achieve. Can you spell out exactly what it is you want to achieve, so I know what you're going for? All the details. I don't understand which entities you are adding these events to in the code you posted. Link to comment Share on other sites More sharing options...
Dcrew Posted July 30, 2019 Author Share Posted July 30, 2019 All ents, I want to track if any & every entity has ever been in a players inventory. Link to comment Share on other sites More sharing options...
Ultroman Posted July 30, 2019 Share Posted July 30, 2019 (edited) Oh, wow, ok. Then what you have is right, assuming you have every single entity in your Ents, but you won't be getting any entities created during the game. You may want to instead set the pickup event in an AddComponentPostInit("inventoryitem", function(comp) bla bla end) That way you only affect items which actually have an inventoryitem component. An example of making things save and load can be found in several prefabs, like rock_flippable. local function onsave(inst, data) if inst.flipped then data.flipped = true end end local function onload(inst, data) -- cut some extra code which wasn't important for showing how it works if data and data.flipped then inst.flipped = true end end and then in the fn() or master_postinit() of the component or prefab you set those functions to be the new OnSave and OnLoad functions of the inst, which are automatically called during saving and loading the server. inst.OnSave = onsave inst.OnLoad = onload  Make sure that you aren't overwriting existing OnSave or OnLoad functions. You can check if they exist, and if so, instead extend them with your code, instead of just setting them to your functions. Edited August 1, 2019 by Ultroman Link to comment Share on other sites More sharing options...
Dcrew Posted July 30, 2019 Author Share Posted July 30, 2019 is there a way to create a component post init within a component instead of modmain? I've tried: AddComponentPostInit self:AddComponentPostInit self.inst:AddComponentPostInit but none of them work. Link to comment Share on other sites More sharing options...
Ultroman Posted July 30, 2019 Share Posted July 30, 2019 I don't know. Why would you want to do that? What are you trying to accomplish. Link to comment Share on other sites More sharing options...
Dcrew Posted July 30, 2019 Author Share Posted July 30, 2019 I want my script all in the one component I use. Link to comment Share on other sites More sharing options...
Ultroman Posted July 30, 2019 Share Posted July 30, 2019 You can't do that. Link to comment Share on other sites More sharing options...
Dcrew Posted July 30, 2019 Author Share Posted July 30, 2019 How can I use ComponentPostInit on inventoryitem anyway, I need the entity itself not the component: AddComponentPostInit("inventoryitem", function(inst) player_owned_ents[inst:GetGUID()] = true print("[Enhanced Biomes] Player picked up "..inst.prefab) end) Â Link to comment Share on other sites More sharing options...
Ultroman Posted July 30, 2019 Share Posted July 30, 2019 For AddComponentPostInit you actually get the component passed as a parameter and not the inst, and all components have a reference to the inst they are on, so: AddComponentPostInit("inventoryitem", function(component) player_owned_ents[component.inst:GetGUID()] = true print("[Enhanced Biomes] Player picked up "..component.inst.prefab) end) Link to comment Share on other sites More sharing options...
Dcrew Posted July 30, 2019 Author Share Posted July 30, 2019 (edited) That doesn't work: AddComponentPostInit("inventoryitem", function(component) local ent = component.inst if ent and ent.prefab then print("[Enhanced Biomes] Player picked up "..ent.prefab) end end) Nothing happens when picking up an entity. Edited July 30, 2019 by Dcrew Link to comment Share on other sites More sharing options...
Ultroman Posted July 30, 2019 Share Posted July 30, 2019 (edited) That's because at the point that a component is initialized, the prefab isn't done initializing yet, and for some stupid reason the "prefab" variable holding the name is one of the last things that happens for an instance of a prefab, so the "prefab" variable is not available to you on component.inst inside AddComponentPostInit. Also, you can't be sure that any OTHER components on the prefab have been applied yet, so almost anything you want to do concerning OTHER components or insts in AddComponentPostInit must be delayed with component.inst:DoTaskInTime(0, function(inst) bla bla end) But, since you want to do this to every single item that has the inventoryitem component, and the inventoryitem component is the one with the onpickupfn, you can safely set that inside your AddComponentPostInit using component:SetOnPickupFn(fn), and all listeners and custom variables can still be added to component.inst. Edited July 30, 2019 by Ultroman Link to comment Share on other sites More sharing options...
Dcrew Posted July 30, 2019 Author Share Posted July 30, 2019 I didn't get that working fully so I did some things, and it works now: local function ent_onpickup(ent) if TUNING.ENHANCEDBIOMES.PLAYER_OWNED_ENTS[ent.GUID] then print("T") TUNING.ENHANCEDBIOMES.PLAYER_OWNED_ENTS[ent.GUID] = nil end end local function ent_ondropped(ent) print("player dropped "..ent.prefab) TUNING.ENHANCEDBIOMES.PLAYER_OWNED_ENTS[ent.GUID] = true end AddComponentPostInit("inventoryitem", function(component) local ent = component.inst ent:ListenForEvent("ondropped", ent_ondropped) ent:ListenForEvent("onpickup", ent_onpickup) end) Except, ent.GUID may be unique within the session but when I reload that game session it doesn't stick, I am saving & loading: function EnhancedBiomes:OnSave() local data = {} data["last_seg_used"] = last_seg_used data["ent"] = {} for k, v in pairs(TUNING.ENHANCEDBIOMES.PLAYER_OWNED_ENTS) do data["ent"][k] = v end return data end function EnhancedBiomes:OnLoad(data) if data then last_seg_used = data["last_seg_used"] or 0 if data["ent"] then for k, v in pairs(data["ent"]) do TUNING.ENHANCEDBIOMES.PLAYER_OWNED_ENTS[k] = v end end end end So each entity's GUID isn't sufficient since I want it to load used entitys from past sessions too, I'm not sure what to do here. Link to comment Share on other sites More sharing options...
Ultroman Posted July 30, 2019 Share Posted July 30, 2019 First time the object runs throught your code, you save its GUID in your own variable on its instance, and make sure to save/load that variable. Then that variable will always be the same between sessions. Then you can save the GUIDs instead of saving the entire entity (which btw is not a good idea). Link to comment Share on other sites More sharing options...
Dcrew Posted July 30, 2019 Author Share Posted July 30, 2019 (edited) I have no idea how to save and load to/from the entity itself. Not fluent with Lua nor DST API Edited July 30, 2019 by Dcrew Link to comment Share on other sites More sharing options...
Ultroman Posted July 30, 2019 Share Posted July 30, 2019 I wrote a post about that here. You know how to extend a function, right? Link to comment Share on other sites More sharing options...
Dcrew Posted July 31, 2019 Author Share Posted July 31, 2019 I don't, I did say I'm not fluent with Lua nor DST API. Link to comment Share on other sites More sharing options...
Ultroman Posted July 31, 2019 Share Posted July 31, 2019 If you want to have an easier time modding, I highly recommend that you go through the Lua Crash Course, possibly some more "Getting started with Lua" things, and check out the newcomer post if you haven't already. Modding is gonna be really annoying if you have to wait for other people to answer questions about syntax and basic functionality. Just a friendly suggestion. Function extension/chaining is essentially piggybacking off of an existing function, while keeping the original functionality of the function intact, so as to not break the game. One huge benefit of this, is that several mods can take turns extending/chaining a function, and so they will all have a much better chance to keep working, i.e., be compatible with each other. This is an example of extending/chaining a function which is declared with a : like this Container:RemoveItem(item, wholestack) Notice that we add the first parameter 'self' because we're beclaring the function with . instead of : and functions declared with a : automatically get the self parameter passed into them as a hidden first parameter. local oldRemoveItem = inst.components.container.RemoveItem inst.components.container.RemoveItem = function(self, item, wholestack) local returnedItem = oldRemoveItem(self, item, wholestack) -- do whatever you want with the item, which MIGHT have been removed from the container. end If the function is declared as a normal function, i.e. local myFunction = function(parameter1) -- code end -- or local function myFunction(parameter1) -- code end you omit the self parameter local oldSomeFunction = inst.components.container.SomeFunction inst.components.container.SomeFunction = function(parameter1) -- Do something before the original function is called, perhaps changing parameter1. local returnValue = oldSomeFunction(parameter1) -- Do something after the function is called, perhaps altering the return value. return returnValue end You only need to save and return the return value if the original function returns something. Otherwise you can just do local oldSomeFunction = inst.components.container.SomeFunction inst.components.container.SomeFunction = function(parameter1) -- Do something before the original function is called, perhaps changing parameter1. oldSomeFunction(parameter1) -- Do something after the function is called, perhaps altering the return value. end  Link to comment Share on other sites More sharing options...
Dcrew Posted July 31, 2019 Author Share Posted July 31, 2019 How can I check if a item is picked up? Using the 'onpickup' inventoryitem event triggers even when you just click an item in your inventory, I want to only trigger it if it's picked up off of the ground, I thought inventoryitem.owner would be the answer, but it sets to nil. Link to comment Share on other sites More sharing options...
Ultroman Posted July 31, 2019 Share Posted July 31, 2019 If an item is in an inventory, must it not have been picked up at some point already? If so, you can rely on your variable already being set for this item, and thus not do anything.I don't know if it helps, but any prefab that is being instantiated always starts out not having an owner and being placed on the ground at 0, 0, 0. Then they are usually repositioned, or put into an inventory or container immediately, or something similar. There isn't really something that tells you whether the item was laying on the floor. There is only the owner variable, which is a player if it is in their itemslots or equipslots, or a container (backpack or chest) as long as the item is in there. Not sure which owner it has when it is in the mouse-slot. You can extend the original PickUp functions and such and simply print the name of the function and which owner it has before the original function is called and which owner it has after. That should tell you a lot. Link to comment Share on other sites More sharing options...
Dcrew Posted July 31, 2019 Author Share Posted July 31, 2019 Nevermind I solved that one, I still have no idea how to save data with ents though, I browsed around many DST script files including the entity script, and just couldn't figure much out, is there any mods you know that save & load custom data to/from ents? So I can gain the knowledge and insight from it/them because doing this all day for 2 days straight is stressing me out a very lot D: Link to comment Share on other sites More sharing options...
Ultroman Posted July 31, 2019 Share Posted July 31, 2019 (edited) From what I posted here which parts are you unsure about? All ents may or may not have an OnSave and OnLoad function on their inst, so if there is one you extend it and call your save-function alongside the original one, and if there isn't one, you just set it to be your save-function. Your save function should just have and use the same parameters as in the code snippet I posted. Edited July 31, 2019 by Ultroman Link to comment Share on other sites More sharing options...
Dcrew Posted August 1, 2019 Author Share Posted August 1, 2019 (edited) Well it has GetSaveRecord() to which I have no idea even after reading its contents, how to use it, other than that it seems it saves entity data through the components it has, to which I'd like to not have to attach a new component to every entity just to save some custom data to it. Edited August 1, 2019 by Dcrew 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