Multirez Posted January 23, 2018 Share Posted January 23, 2018 Often Entity has more than one script with the same name/path. How to call a function in a second or an another specific entity script? Link to comment Share on other sites More sharing options...
Shrooblord Posted January 23, 2018 Share Posted January 23, 2018 I'm not entirely sure what your question is, as the post title and the actual body of the post are incongruous. I'll attempt to answer both questions. Entity():invokeFunction(script, args...) is not enough parameters?Correct. Well, at face value, that is. invokeFunction(script, args...) has two arguments that can be passed to it if you first look at it. But the args... argument is in fact a shorthand for saying "zero or more" arguments, so you can pass it any amount of arguments you want, or none at all. invokeFunction("scripts/entity/ShrooblordsScript.lua"); invokeFunction("scripts/entity/ShrooblordsScript.lua", 1); and invokeFunction("scripts/entity/ShrooblordsScript.lua", "balls", true, Entity()) are all valid function calls. The trick is to figure out how many arguments the script you're invoking actually wants or needs. You'll need to take a look at the function in-code to do this properly. The best is to investigate how it's used in vanilla to see how to best invoke that function. If you're coding something yourself, you of course know what amount of arguments the function expects, so go with that. Often Entity has more than one script with the same name/path.Does it? Can you give some examples? I've seen function overrides, if that's what you mean. The entity will inherit one library's function, but then also define that same function elsewhere in code, overriding the default provided by the library. Is this what you're hinting at? How to call a function in a second or an another specific entity script?I'm also not certain what you're asking here; if you know how to identify a specific entity, then you've already got your answer. Just pass that entity's identifier as the Entity() object. For example (PSEUDOCODE; CHECK THE GAME SCRIPTS TO SEE HOW TO PROPERLY DO THIS - IN FACT THE EXAMPLE IS REALLY A LITTLE MESSY ACTUALLY; BUT FOR PROOF-OF-CONCEPT, READ AHEAD): Sector = require("Sector") Traders = {} local function getTraders() local allTraders = Sector():getEntitiesOfType("ship", "traders") table.insert("Traders", allTraders) return Traders end local function suicide() self:destroy() end --Somewhere else... Traders = getTraders() Traders():invokeFunction(suicide) Even though the above pseudocode is basically crap and useless, I hope it illustrates the point: you collect the entities you want to run your script on somehow (again, not sure what you want to do exactly because you didn't specify), and then invoke the function you want to run on those entities. ---- Does this answer your questions? If not, please provide more information so we can more properly assist you. Link to comment Share on other sites More sharing options...
Multirez Posted January 23, 2018 Author Share Posted January 23, 2018 Well, I'll try to explain the situation less abstractly, sorry for my English Often Entity has more than one script with the same name/path. Does it? Can you give some examples? If you install some upgrades on your ship and then try to Entity():getScripts() you can get something like this ... 9 : data/scripts/systems/hyperspacebooster.lua 10 : data/scripts/systems/hyperspacebooster.lua 11 : data/scripts/systems/hyperspacebooster.lua 12 : data/scripts/systems/batterybooster.lua 13 : data/scripts/systems/batterybooster.lua 14 : data/scripts/systems/energybooster.lua How to invoke getSeed function from batterybooster.lua that is number 13 in script list??? Entity():invokeFunction("data/scripts/systems/energybooster.lua", "getSeed") -- Always return seed for script #12 P.S. I really thought to delete the script number 12, read the data for the 13th, and then restore the removed, but in this way the player will lose the accumulated energy in the batteries, shields, cargo, trade history and so on... Link to comment Share on other sites More sharing options...
Shrooblord Posted January 23, 2018 Share Posted January 23, 2018 I see what you mean now. See this part of code in craftorders.lua: local function removeSpecialOrders() local entity = Entity() for index, name in pairs(entity:getScripts()) do if string.match(name, "data/scripts/entity/ai/") then entity:removeScript(index) end end end As you can see, the script is iterating through all scripts of a certain entity, and removing some of them with a certain name. You could use the same for index, name in pairs(entity:getScripts()) do ... end construction to get all scripts that are match batterybooster.lua, and then perform different operations on each index: local entity = Entity() for index, name in pairs(entity:getScripts()) do if string.match(name, "data/scripts/systems/energybooster.lua") then Entity():invokeFunction(name, "getSeed") end end I didn't test this, so I don't know if this exactly is what you need, but this should get you started, at least. EDIT: Ah, no I see now. That would still probably only return the getSeed result from the first script and not the next indeces. I'm not sure how to reference a script attached to an entity specifically by its index. It doesn't seem like any of the existing code does that, so I can't copy its example. Link to comment Share on other sites More sharing options...
Multirez Posted January 23, 2018 Author Share Posted January 23, 2018 I already broke my head over this issue, the only thing that came to my mind was to add a copy of the first script to the end of the list, and then delete it, replacing with a fictitious dummy component. And so on until I reach the position I need. Then I can delete script by index, this will make it possible to reduce the number of dummies on the object. The only exception is trading systems, but they can also be put into the cache by calling the secure() function. In any case, such solution will result in a lot of additions and deletions of scripts only to get the current state. Maybe you have any other ideas? Link to comment Share on other sites More sharing options...
Rinart73 Posted January 24, 2018 Share Posted January 24, 2018 I think I have an idea. We attach an additional script to the entity, that will act as a storage for our system upgrades info. Then we modify our system upgrades. I think that will be no problem for you since you already did this (energybooster.lua doesn't have getSeed function by default). So, we modify onInstalled function and invoke function of our storage script to 'register' it and pass upgrade info (seed, etc). There might be some issues with keeping the link which module is which, though. In the end, you will invoke function of storage script to get what you need. I'll try it in the next days to see if this will work. Link to comment Share on other sites More sharing options...
Multirez Posted January 24, 2018 Author Share Posted January 24, 2018 Thanks rinart73 for the proposed solution. Initially, I did not want to modify the vanilla scripts in the systems folder to avoid possible incompatibility with other mods that add / modify systems. But your solution looks like more attractive and it seems that I can do the modification of a basesystem.lua only. EDIT: This does not eliminate the need in the ability to run invokeFunction on the script by its index, similar to Entity():removeScript(). Link to comment Share on other sites More sharing options...
Rinart73 Posted January 24, 2018 Share Posted January 24, 2018 EDIT: This does not eliminate the need in the ability to run invokeFunction on the script by its index, similar to Entity():removeScript(). Your current problem is that invokeFunction addresses the first attached script with certain name. If done correctly, my way will work a bit differently: instead of invoking upgrades functions, upgrades themselves will invoke function of storage script (which can be only one per entity). And then your script will successfully get info from storage. Link to comment Share on other sites More sharing options...
Multirez Posted January 24, 2018 Author Share Posted January 24, 2018 EDIT: This does not eliminate the need in the ability to run invokeFunction on the script by its index, similar to Entity():removeScript(). Your current problem is that invokeFunction addresses the first attached script with certain name. If done correctly, my way will work a bit differently: instead of invoking upgrades functions, upgrades themselves will invoke function of storage script (which can be only one per entity). And then your script will successfully get info from storage. I meant that such a function is necessary for the completeness of the API, and not in this particular example. Link to comment Share on other sites More sharing options...
Rinart73 Posted January 24, 2018 Share Posted January 24, 2018 I meant that such a function is necessary for the completeness of the API, and not in this particular example. Oh, you're right, I misread. You can create new thread in the Suggestions forum. Link to comment Share on other sites More sharing options...
Shrooblord Posted January 24, 2018 Share Posted January 24, 2018 I think I have an idea. We attach an additional script to the entity, that will act as a storage for our system upgrades info. (...) So, we modify onInstalled function and invoke function of our storage script to 'register' it and pass upgrade info (seed, etc). There might be some issues with keeping the link which module is which, though. In the end, you will invoke function of storage script to get what you need. That is elegant. So you basically register and assign an index to the SMUs through an external script, rather than trying to get at the SMU scripts through another roundabout way. Then you can use that external script to reference them, since the new script knows which index points to which SMU, since that's how we programmed it to behave. Nice. 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