SniperDM
June 8th, 2007, 22:42
Thanks to the helpful hint of the getValue() function, I've figured out enough lua syntax to 'make' my own first script. I say 'make' because it's just a slightly modified version of the combat tracker script in the d20 ruleset of fantasygrounds.
The script does the following:
When adding an NPC to the combat tracker, if there is already a combatant with that name, it renames them both numerically. IE if there is already a 'Goblin' on the tracker and you try to add another, their names will be changed to 'Goblin 1 and Goblin 2'. From there, more Goblins will be named "Goblin 3, Goblin 4, etc..."
Automatically rolls hit points for duplicate entries beyond the first. The first monster added will always have the default given hit points.
Automatically rolls initiative for all new NPC entries added, based on the value of the initiative modifier, then sorts the added entry into the tracker based on the rolled initiative.
I make no guarantees to the orderliness or efficiency of this script, or that it's completely functional and without quirk, but it seems to work in my tests so far. Feedback is appreciated.
In order to use this script, you need to run d20unpack and then copy the ruleset from the examples directory to the ruleset directory of fantasygrounds, giving it a custom name. Then just unzip the attached file into the 'scripts' folder of this new ruleset. Of course, your campaign must be using this ruleset to make use of this script.
Here are the parts I changed.
Original:
-- Name
if source.getChild("name") then
newentry.name.setValue(source.getChild("name").getValue());
end
Modified:
-- Name
local namecount = 0;
local highnum = 0;
local check = 0;
for k, v in ipairs(getWindows()) do
if source.getChild("name") then
newentry.name.setValue(source.getChild("name").getValue());
if newentry.name.getValue() == string.sub(getWindows()[k].name.getValue(), 1, string.len(newentry.name.getValue())) then
namecount = namecount + 1;
if string.len(newentry.name.getValue()) == string.len(getWindows()[k].name.getValue()) and string.len(newentry.name.getValue()) > 0 then
for l, w in ipairs(getWindows()) do
if string.sub(getWindows()[l].name.getValue(), 1, string.len(source.getChild("name").getValue())) == source.getChild("name").getValue() then
check = tonumber(string.sub(getWindows()[l].name.getValue(), string.len(source.getChild("name").getValue())+2));
if check and highnum < check then
highnum = check;
end
end
end
getWindows()[k].name.setValue(newentry.name.getValue().." "..highnum+1);
end
end
end
end
if namecount < 2 then
newentry.name.setValue(source.getChild("name").getValue());
end
Original:
-- HP
if source.getChild("hp") then
newentry.hp.setValue(source.getChild("hp").getValue());
end
Modified:
-- HP
if source.getChild("hp") and namecount < 2 then
newentry.hp.setValue(source.getChild("hp").getValue());
else
local hdstring = source.getChild("hd").getValue();
local rollhp = 0;
for v, numdie, dietype, mod in string.gmatch(hdstring, "((%d+)d(%d+)([%+%-]*%d*))") do
if v then
for i = 1, tonumber(numdie) do
rollhp = rollhp + math.random(tonumber(dietype));
end
if tonumber(mod) then
rollhp = rollhp + tonumber(mod);
end
end
end
newentry.hp.setValue(rollhp);
end
Also added to the end of the addNpc() function, before the return statement:
--Roll initiative and sort
newentry.initresult.setValue(math.random(20)+newen try.init.getValue());
applySort(getWindows());
I hope that makes sense. Again, comments/questions are welcome.
EDIT: Removed note about list not sorting upon dropping an NPC intro tracker and file and code blocks updated too. This issue is resolved.
EDIT EDIT: One little problem niggled me that I have now resolved, using an ungodly amount of nested if and for statements, probably more sloppily than necessary. This script now numbers monsters based on the highest number present. If you should have Goblins 1 through 10 and delete all of them except for 10, adding another Goblin will create Goblin 11 instead of Goblin 1 again. On the other hand, if you delete Goblin 10 and leave 1 through 9 intact a new Goblin will be called Goblin 10 once more. This is the best I can do without modifying the way the combat tracker stores data. Files and code blocks updated to match this.
EDIT EDIT EDIT: Added hit point roller to script. Another couple code block added above to demonstrate where it goes, and attached file updated.
The script does the following:
When adding an NPC to the combat tracker, if there is already a combatant with that name, it renames them both numerically. IE if there is already a 'Goblin' on the tracker and you try to add another, their names will be changed to 'Goblin 1 and Goblin 2'. From there, more Goblins will be named "Goblin 3, Goblin 4, etc..."
Automatically rolls hit points for duplicate entries beyond the first. The first monster added will always have the default given hit points.
Automatically rolls initiative for all new NPC entries added, based on the value of the initiative modifier, then sorts the added entry into the tracker based on the rolled initiative.
I make no guarantees to the orderliness or efficiency of this script, or that it's completely functional and without quirk, but it seems to work in my tests so far. Feedback is appreciated.
In order to use this script, you need to run d20unpack and then copy the ruleset from the examples directory to the ruleset directory of fantasygrounds, giving it a custom name. Then just unzip the attached file into the 'scripts' folder of this new ruleset. Of course, your campaign must be using this ruleset to make use of this script.
Here are the parts I changed.
Original:
-- Name
if source.getChild("name") then
newentry.name.setValue(source.getChild("name").getValue());
end
Modified:
-- Name
local namecount = 0;
local highnum = 0;
local check = 0;
for k, v in ipairs(getWindows()) do
if source.getChild("name") then
newentry.name.setValue(source.getChild("name").getValue());
if newentry.name.getValue() == string.sub(getWindows()[k].name.getValue(), 1, string.len(newentry.name.getValue())) then
namecount = namecount + 1;
if string.len(newentry.name.getValue()) == string.len(getWindows()[k].name.getValue()) and string.len(newentry.name.getValue()) > 0 then
for l, w in ipairs(getWindows()) do
if string.sub(getWindows()[l].name.getValue(), 1, string.len(source.getChild("name").getValue())) == source.getChild("name").getValue() then
check = tonumber(string.sub(getWindows()[l].name.getValue(), string.len(source.getChild("name").getValue())+2));
if check and highnum < check then
highnum = check;
end
end
end
getWindows()[k].name.setValue(newentry.name.getValue().." "..highnum+1);
end
end
end
end
if namecount < 2 then
newentry.name.setValue(source.getChild("name").getValue());
end
Original:
-- HP
if source.getChild("hp") then
newentry.hp.setValue(source.getChild("hp").getValue());
end
Modified:
-- HP
if source.getChild("hp") and namecount < 2 then
newentry.hp.setValue(source.getChild("hp").getValue());
else
local hdstring = source.getChild("hd").getValue();
local rollhp = 0;
for v, numdie, dietype, mod in string.gmatch(hdstring, "((%d+)d(%d+)([%+%-]*%d*))") do
if v then
for i = 1, tonumber(numdie) do
rollhp = rollhp + math.random(tonumber(dietype));
end
if tonumber(mod) then
rollhp = rollhp + tonumber(mod);
end
end
end
newentry.hp.setValue(rollhp);
end
Also added to the end of the addNpc() function, before the return statement:
--Roll initiative and sort
newentry.initresult.setValue(math.random(20)+newen try.init.getValue());
applySort(getWindows());
I hope that makes sense. Again, comments/questions are welcome.
EDIT: Removed note about list not sorting upon dropping an NPC intro tracker and file and code blocks updated too. This issue is resolved.
EDIT EDIT: One little problem niggled me that I have now resolved, using an ungodly amount of nested if and for statements, probably more sloppily than necessary. This script now numbers monsters based on the highest number present. If you should have Goblins 1 through 10 and delete all of them except for 10, adding another Goblin will create Goblin 11 instead of Goblin 1 again. On the other hand, if you delete Goblin 10 and leave 1 through 9 intact a new Goblin will be called Goblin 10 once more. This is the best I can do without modifying the way the combat tracker stores data. Files and code blocks updated to match this.
EDIT EDIT EDIT: Added hit point roller to script. Another couple code block added above to demonstrate where it goes, and attached file updated.