PDA

View Full Version : Two extensions using the same lua file ?



PolluxTroy
June 5th, 2017, 11:04
Hi,

I've created two extensions separatly, that are using the same lua script. Each extension is embbeding this file but with some modification for one of it, and some for the other.
The first have a loadorder of 201, and the second have a loadorder of 202.

But if i use both of them in a new campaign, the second extension overwrite the first one.

Is there a way to have two extensions using a same lua script (data_common.lua) ? How i can do ?

Thanks for your awnsers
Regards

Trenloe
June 5th, 2017, 12:32
As data_common.lua is what's known as a global script package there are ways of updating portions of it.

What are you changing in each of your extensions?

PolluxTroy
June 5th, 2017, 18:46
I've modified creatures size and added skills.

Trenloe
June 5th, 2017, 18:50
Can you provide a bit more information? e.g the changes you've actually made. Then I can give you example code on how to do the modifications.

PolluxTroy
June 5th, 2017, 18:54
In data_common.lua, i've modified this part (just replacing size values) for the first :

creaturesize = {
["fine"] = 1,
["diminutive"] = 2,
["tiny"] = 3,
["small"] = 4,
["medium"] = 5,
["large"] = 6,
["huge"] = 7,
["gargantuan"] = 8,
["colossal"] = 9,
["F"] = 1,
["D"] = 2,
["T"] = 3,
["S"] = 4,
["M"] = 5,
["L"] = 6,
["H"] = 7,
["G"] = 8,
["C"] = 9,
};

And for the second extension, this part :


skilldata = {
["Appraise"] = {
stat = "intelligence"
},
["Balance"] = {
stat = "dexterity",
armorcheckmultiplier = 1
},
["Bluff"] = {
stat = "charisma"
},
["Climb"] = {
stat = "strength",
armorcheckmultiplier = 1
},
["Concentration"] = {
stat = "constitution"
},
["Craft"] = {
sublabeling = true,
stat = "intelligence"
},
["Decipher Script"] = {
stat = "intelligence",
trainedonly = 1
},
["Diplomacy"] = {
stat = "charisma"
},
["Disable Device"] = {
stat = "intelligence",
trainedonly = 1
},
["Disguise"] = {
stat = "charisma"
},
["Escape Artist"] = {
stat = "dexterity",
armorcheckmultiplier = 1
},
["Forgery"] = {
stat = "intelligence"
},
["Gather Information"] = {
stat = "charisma"
},
["Handle Animal"] = {
stat = "charisma",
trainedonly = 1
},
["Heal"] = {
stat = "wisdom"
},
["Hide"] = {
stat = "dexterity",
armorcheckmultiplier = 1
},
["Intimidate"] = {
stat = "charisma"
},
["Jump"] = {
stat = "strength",
armorcheckmultiplier = 1
},
["Knowledge"] = {
sublabeling = true,
stat = "intelligence",
trainedonly = 1
},
["Listen"] = {
stat = "wisdom"
},
["Move Silently"] = {
stat = "dexterity",
armorcheckmultiplier = 1
},
["Open Lock"] = {
stat = "dexterity",
trainedonly = 1
},
["Perform"] = {
sublabeling = true,
stat = "charisma"
},
["Profession"] = {
sublabeling = true,
stat = "wisdom",
trainedonly = 1
},
["Ride"] = {
stat = "dexterity"
},
["Search"] = {
stat = "intelligence"
},
["Sense Motive"] = {
stat = "wisdom"
},
["Sleight of Hand"] = {
stat = "dexterity",
armorcheckmultiplier = 1,
trainedonly = 1
},
["Speak Language"] = {
},
["Spellcraft"] = {
stat = "intelligence",
trainedonly = 1
},
["Spot"] = {
stat = "wisdom"
},
["Survival"] = {
stat = "wisdom"
},
["Swim"] = {
stat = "strength",
armorcheckmultiplier = 2
},
["Tumble"] = {
stat = "dexterity",
armorcheckmultiplier = 1,
trainedonly = 1
},
["Use Magic Device"] = {
stat = "charisma",
trainedonly = 1
},
["Use Rope"] = {
stat = "dexterity"
}
}

Trenloe
June 5th, 2017, 19:04
OK, so in your extension that modifies creature size, have a LUA file (called using a <script> entry from extension.xml) that is:


new_creaturesize = {
["fine"] = 1,
["diminutive"] = 2,
["tiny"] = 3,
["small"] = 4,
["medium"] = 5,
["large"] = 6,
["huge"] = 7,
["gargantuan"] = 8,
["colossal"] = 9,
["F"] = 1,
["D"] = 2,
["T"] = 3,
["S"] = 4,
["M"] = 5,
["L"] = 6,
["H"] = 7,
["G"] = 8,
["C"] = 9,
};

function onInit()
DataCommon.creaturesize = new_creaturesize;
end

This will overwrite just the creaturesize LUA table in the DataCommon package.

And, you can probably guess what it will be for the skills:


new_skilldata = {
["Appraise"] = {
stat = "intelligence"
},
["Balance"] = {
stat = "dexterity",
armorcheckmultiplier = 1
},
["Bluff"] = {
stat = "charisma"
},
["Climb"] = {
stat = "strength",
armorcheckmultiplier = 1
},
["Concentration"] = {
stat = "constitution"
},
["Craft"] = {
sublabeling = true,
stat = "intelligence"
},
["Decipher Script"] = {
stat = "intelligence",
trainedonly = 1
},
["Diplomacy"] = {
stat = "charisma"
},
["Disable Device"] = {
stat = "intelligence",
trainedonly = 1
},
["Disguise"] = {
stat = "charisma"
},
["Escape Artist"] = {
stat = "dexterity",
armorcheckmultiplier = 1
},
["Forgery"] = {
stat = "intelligence"
},
["Gather Information"] = {
stat = "charisma"
},
["Handle Animal"] = {
stat = "charisma",
trainedonly = 1
},
["Heal"] = {
stat = "wisdom"
},
["Hide"] = {
stat = "dexterity",
armorcheckmultiplier = 1
},
["Intimidate"] = {
stat = "charisma"
},
["Jump"] = {
stat = "strength",
armorcheckmultiplier = 1
},
["Knowledge"] = {
sublabeling = true,
stat = "intelligence",
trainedonly = 1
},
["Listen"] = {
stat = "wisdom"
},
["Move Silently"] = {
stat = "dexterity",
armorcheckmultiplier = 1
},
["Open Lock"] = {
stat = "dexterity",
trainedonly = 1
},
["Perform"] = {
sublabeling = true,
stat = "charisma"
},
["Profession"] = {
sublabeling = true,
stat = "wisdom",
trainedonly = 1
},
["Ride"] = {
stat = "dexterity"
},
["Search"] = {
stat = "intelligence"
},
["Sense Motive"] = {
stat = "wisdom"
},
["Sleight of Hand"] = {
stat = "dexterity",
armorcheckmultiplier = 1,
trainedonly = 1
},
["Speak Language"] = {
},
["Spellcraft"] = {
stat = "intelligence",
trainedonly = 1
},
["Spot"] = {
stat = "wisdom"
},
["Survival"] = {
stat = "wisdom"
},
["Swim"] = {
stat = "strength",
armorcheckmultiplier = 2
},
["Tumble"] = {
stat = "dexterity",
armorcheckmultiplier = 1,
trainedonly = 1
},
["Use Magic Device"] = {
stat = "charisma",
trainedonly = 1
},
["Use Rope"] = {
stat = "dexterity"
}
}

function onInit()
DataCommon.skilldata = new_skilldata;
end

PolluxTroy
June 5th, 2017, 19:53
Oh ok, i understand. So i can overwrite any functions using this ?

Thank you Trenoloe for you awsnwer ;)

Trenloe
June 5th, 2017, 20:23
Oh ok, i understand. So i can overwrite any functions using this ?
Only data and functions in global script packages, and then there may be some cases when you can't fully do this - e.g. the script needs to make use of local scope script variables, which you can't access from outside of the original LUA script file. You can't do this for scripts attached to controls or window classes either. See Using Scripts and Script Block Scope here: https://www.fantasygrounds.com/modguide/scripting.xcp

PolluxTroy
June 6th, 2017, 11:49
Another question, again ^^

If i want to overwrite a function ? Is there a way to do it without embedding the whole lua file ?

(like in manager_char.lua)

Trenloe
June 6th, 2017, 16:20
If i want to overwrite a function ? Is there a way to do it without embedding the whole lua file ?

(like in manager_char.lua)
Yes, with the limitations I mentioned in post #8.

Things to check:
1) Is campaign\scripts\manager_char.lua a global script package? If it's not, then you can't override functions. Answer: it's defined in base.xml with a script name of "CharManager", so this is a global script package.
2) Does the function you plan to override use local script variables outside of the function that you won't be able to access from outside the script package? As you will be overriding a script package function, the new function will be running outside of the original script package and so won't have access to script data defined as "local" in the original script file. A quick look at manager_char.lua suggests you'll be OK. But double check in any code you override.

an example of a global script package that uses local script variables is the 3.5E scripts\manager_effect.lua - there are four variables at the top of the file, and two are defined as "local" (nLocked and aUsedActionEffects) so these aren't accessible from outside of base script package and you couldn't override functions that use these variables, without modifying the base LUA file - which kinda defeats the purpose of using function overrides.

3) Does the function call other functions in the script package? If so, you'll need to put the script package name (CharManager in this case) in front of the function calls.

Without knowing which function you're considering overriding, I can't say for sure. But on a quick look on the above points, it appears that you will be able to override functions from outside manager_char.lua.

Now, how to do it? Very similar to how the data tables were overridden earlier in this thread.


function onInit()
CharManager.onCharItemAdd = my_onCharItemAdd;
end

function my_onCharItemAdd(nodeItem)
-- My new code here!!! Example:
Debug.console("New function running...")
-- End of my new code.

DB.setValue(nodeItem, "carried", "number", 1);
DB.setValue(nodeItem, "showonminisheet", "number", 1);

if DB.getValue(nodeItem, "type", "") == "Goods and Services" then
local sSubType = DB.getValue(nodeItem, "subtype", "");
if (sType == "Goods and Services") and StringManager.contains({"Mounts and Related Gear", "Transport", "Spellcasting and Services"}, sSubType) then
DB.setValue(nodeItem, "carried", "number", 0);
end
end

CharManager.addToArmorDB(nodeItem);
CharManager.addToWeaponDB(nodeItem);
end

Note: I haven't tested this. The above example takes onCharItemAdd from the original script file - make changes that you want to make. Note that the last two function calls addToArmorDB and addToWeaponDB need "CharManager." in front of them so that the functions in the original script package can be accessed.

PolluxTroy
June 6th, 2017, 17:26
Thank you so much Trenloe for your help, i've got all i need to work ;)

PS : It's working great !

Trenloe
June 6th, 2017, 17:32
Thank you so much Trenloe for your help, i've got all i need to work ;)

PS : It's working great !
Excellent! :)

One thing - keep copies of the original files you modified/took code from. This will allow you to quickly compare possible future FG base code changes (updates, bugfixes etc.) and see if you need to update your code to incorporate future changes. The fact that you're just including your changes in an extension, rather than making a small change to the original files, will reduce the possibility of you needing to do this. But it's still possible that a change may be needed down the road. I usually include the original file in the extension itself (easy for me to access later) - with a naming like manager_char_3.5E_v330.lua indicating the ruleset and original version.

PolluxTroy
June 6th, 2017, 17:48
Yep, sounds like a good advice ^^ TY

For information, I'm adapting some things to the way we play Pathfinder.