PDA

View Full Version : Restricting Acing to only wildcards



chillybilly
November 10th, 2020, 19:54
Is there are way to make non wildcards (Extras) not have their dice ace (explode)?

https://www.fantasygrounds.com/forums/showthread.php?38569-Ikael-s-miscellaneous-extensions

In this thread, the extension limits acing to 1 reroll but it's for everyone. Is there any way to check first to see if the roll came from an extra and, if so, limit rerolls to 0?

Doswelk
November 11th, 2020, 08:26
There is no way in FG to do that, SWADE as written all trait and damage rolls can Ace, you may be able to write an extension to do so, but I suspect it would be complicated as you are trying to go against the whole design of the system...

chillybilly
November 11th, 2020, 13:45
Thank you for the response (even if it's not good news). I just wondering if it's possible to get the value of the "wildcard" variable in the ruleset that determines if a PC/NPC is a wildcard or extra right before the roll with a local test = wildcard.getvalue() kind of line of code and then if test = 0 (the value set to extras), use the acing restriction extension above except with it's value change to 0 to not allow acing.
I've actually tinnkered with the extension to not allowing acing. I'm just stuck on figuring out how to read the wildcard variable right before the roll. pretty sure "wildcard" is the name of the variable but the local test = line code doesn't work.

chillybilly
November 11th, 2020, 13:55
Let me explain better...

In the SW ruleset, in the record_npc.xml file this part of the file creates the varialbe that determines if an NPC is a wildcard that gets a wildcard die or an extra that doesn't.

-<windowclass name="npc_header">
<margins control="0,0,0,7"/>
<script file="campaign/scripts/npc_header.lua"/>
-<sheetdata>
-<link_record_header_id>
<class>npc</class>
</link_record_header_id>
<anchor_record_header_right name="rightanchor"/>
<record_activateid/>
<record_token name="token"/>
<record_isidentified name="isidentified"/>
<icon_record_locked/>
<button_record_locked/>
-<string_record_name_npc name="name">
<empty textres="library_recordtype_empty_npc"/>
</string_record_name_npc>
-<string_record_name_npc name="nonid_name">
<empty textres="library_recordtype_empty_nonid_npc"/>
<invisible/>
</string_record_name_npc>

<record_wildcardtool name="wildcardtool"/>

<hs name="wilddie"/>


-<hn name="wildcard">

<default>0</default>

</hn>

</sheetdata>
</windowclass>

So, I believe that "Wildcard" is the name of the variable to determine if the NPC is a wildcard or extra and the default is 0 or extra.

In the Acing Restriction extension... it's beautifully simple... here is the important code:

<base>
<script name="SWAceLimitOne">
function onInit()
TraitManager.customizeRoll = customizeRoll
end
function customizeRoll(rRoll)
rRoll.custom.maxacing = 0

end
</script>
</base>

Can the code me changed to read the varialbe (wildcard) to check if the roll is being made by an extra and then if so, trigger the restriction? Something like this...

<base>
<script name="SWAceLimitOne">
function onInit()
TraitManager.customizeRoll = customizeRoll
end
function customizeRoll(rRoll)
local test = wildcard.getValue()
if test == 0 then
rRoll.custom.maxacing = 0
end

end
</script>
</base>


When I try this, I get the error:

attempt to index global 'wildcard' (a nil value)

This makes me think that I am attempting to recall the value of wildcard incorrectly in the added code of the extenstion... that's where I am stuck.

chillybilly
November 11th, 2020, 15:54
Just an update. I've got it to where players can ace but the host cannot with this tweaked extension code

function onInit()
TraitManager.customizeRoll = customizeRoll
end
function customizeRoll(rRoll)
if User.isHost() then rRoll.custom.maxacing = 0
end
end

My preference would be to allow Wildcard NPCs (bosses) to ace but this is a step forward.

Trenloe
November 11th, 2020, 16:40
wildcard is a nil value because the script scope is not related to the window where wildcard is a control. TraitManager is a global script package, which doesn't have direct access to the GUI.

customizeRoll receives rRoll - which includes the actor making the roll - stored in rRoll.actor

Assuming that wildcard is a database field for NPCs and PCs (I haven't checked, I'm just going by the XML pasted above), then you should be able to extract the value from the database.

Try something like this (I haven't tested):

function customizeRoll(rRoll)
local nodeCT = ActorManager.getCTNode(rRoll.actor);
if nodeCT then
local nWildcard = DB.getValue(nodeCT, "wildcard", 0);
if nWildcard == 0 then
rRoll.custom.maxacing = 0;
end
end
end

chillybilly
November 11th, 2020, 17:02
Thank you, Trenloe!

The code doesn't work but that's almost assuredly because "wildcard" is not the database field. I thought it was but I'll look over the coding to see where I went wrong and then insert that correct name.

chillybilly
November 11th, 2020, 18:05
I tried to use an NPC variable I was almost certain I knew the name of (reach) and still couldn't get it to work.

Here is the coding for record.npc.xml
<windowclass name="npc_combat">
<margins control="0,0,0,2" />
<script file="campaign/scripts/npc_combat.lua"/>
<sheetdata>
<anchor_column name="columnanchor" />

<label_column name="defeatedmarker_label">
<static textres="defeatedmarker_label" />
</label_column>
<defeatedmarker_combobox_npc name="defeatedmarker" />
<label_column name="spacereach_label">
<static textres="size_spacereach" />
</label_column>
<size_space name="space" />
<size_reach name="reach" />

"reach" is the variable name, right? So I set the Trenloe written code to look for that...

function customizeRoll(rRoll)
local nodeCT = ActorManager.getCTNode(rRoll.actor);
if nodeCT then
local nWildcard = DB.getValue(nodeCT, "reach", 0);
if nWildcard == 2 then
rRoll.custom.maxacing = 0;
end
end
end

Then loaded up the program and manually changed the NPC to have reach 2. Still, the dice would ace.

Trenloe
November 11th, 2020, 20:01
Don't look at the GUI specification. Look in the actual FG database - because this is where you're going to have to go for things like this.

Without FG running open the campaign db.xml file. The code I provided above will hopefully provide the base database node for the actor within the combat tracker. The Savage Worlds ruleset has a slightly different structure to other rulesets, so there may need to be additional database navigation to get to the data needed.

Put some debug in customizeRoll code to output to the console what the nodeCT object is actually pointing to. Use Debug.console("nodeCT = ", nodeCT); and check where that points to within the campaign db.xml file.

chillybilly
November 11th, 2020, 20:47
I know you are spoon-feeding me this and I'm too dumb to swallow....

here is a picture with the db open and then FG running. I changed an NPC reach to 7 and found that in the database and I also found (I think) th wildcard variable which correctly is zero since the NPC is an extra.

41011

Shouldn't this work (if reach is 7)

function customizeRoll(rRoll)
local nodeCT = ActorManager.getCTNode(rRoll.actor);
if nodeCT then
local nWildcard = DB.getValue(nodeCT, "reach", 0);
if nWildcard == 7 then
rRoll.custom.maxacing = 0;
end
end
end

Trenloe
November 11th, 2020, 20:56
Like I mentioned - put some debug code into the script to see *exactly* where node CT is pointing to. Savage Worlds has the additional <combatants> structure within the Combat Tracker which other rulesets don't have, so that might be causing an issue for ActorManager.getCTNode returning the actual actor node.

chillybilly
November 11th, 2020, 21:02
oh god.. how do I put the debug code into the script? I assume I cut and paste this:

Debug.console("nodeCT = ", nodeCT);

into this:

function customizeRoll(rRoll)
local nodeCT = ActorManager.getCTNode(rRoll.actor);
if nodeCT then
local nWildcard = DB.getValue(nodeCT, "reach", 0);
if nWildcard == 7 then
rRoll.custom.maxacing = 0;
end
end
end


So... it should look like this?

function customizeRoll(rRoll)
local nodeCT = ActorManager.getCTNode(rRoll.actor);
Debug.console("nodeCT = ", nodeCT);
if nodeCT then
local nWildcard = DB.getValue(nodeCT, "reach", 0);
if nWildcard == 7 then
rRoll.custom.maxacing = 0;
end
end
end

And then, I open FG, type /console and then try a roll to see if it aces?

Also, here is another picture to show how far into db the reach (and wildcard) variable are.

41014

Trenloe
November 11th, 2020, 21:04
So... it should look like this?

function customizeRoll(rRoll)
local nodeCT = ActorManager.getCTNode(rRoll.actor);
Debug.console("nodeCT = ", nodeCT);
if nodeCT then
local nWildcard = DB.getValue(nodeCT, "reach", 0);
if nWildcard == 7 then
rRoll.custom.maxacing = 0;
end
end
end

And then, I open FG, type /console and then try a roll to see if it aces?
Yep.

chillybilly
November 11th, 2020, 21:07
I tried the above, rolled three times (one of them aced) and got this

41015

And by the way, I am totally cool if you want to throw up your hands and tell me to take a coding class at my local college! You've helped me many, many times in the past and I kind of gotta believe it's getting old for you.

Trenloe
November 11th, 2020, 21:10
I tried the above, rolled three times (one of them aced) and got this

41015
That was what I feared - it doesn't work for the Savage Worlds ruleset.


And by the way, I am totally cool if you want to throw up your hands and tell me to take a coding class at my local college! You've helped me many, many times in the past and I kind of gotta believe it's getting old for you.
I'll look at it a bit more before I throw my hands in the air! :D

chillybilly
November 11th, 2020, 21:15
I really do appreciate your help in this.

Is there a way I can have that extension work only when the left alt key is pressed or something? It did work when I did the user.ishost thing and I'm not picky. It'd just be nice to be able to have something where I can make extras not ace and wildcards ace even if I have to press a button or change a setting for something.

Anyway, thanks for the help and Curse You, Savage Worlds Ruleset!

Trenloe
November 11th, 2020, 21:20
Try this:


function customizeRoll(rRoll)
local sActorType, nodeCT = CharacterManager.asCharActor(rRoll.actor);
Debug.console("rRoll.actor, sActorType, nodeCT = ", rRoll.actor, sActorType, nodeCT);
if nodeCT then
local nWildcard = DB.getValue(nodeCT, "wildcard", 0);
if nWildcard == 0 then
rRoll.custom.maxacing = 0;
end
end
end

Trenloe
November 11th, 2020, 21:23
Is there a way I can have that extension work only when the left alt key is pressed or something? It did work when I did the user.ishost thing and I'm not picky. It'd just be nice to be able to have something where I can make extras not ace and wildcards ace even if I have to press a button or change a setting for something.
You can use if Input.isAltPressed() then... but I wouldn't recommend that as the Savage Worlds ruleset already uses ALT a lot to change functionality.

chillybilly
November 11th, 2020, 21:27
I really hope your sitting on your own private island drinking margaritas somewhere.

Your coding worked perfectly. Extras don't ace and wildcards do.

THANKS SO MUCH! I've given you rep (that you hardly need) but I wish there was something more I could do. You should consider a patreon or something! You'd be able to afford a second island.

Trenloe
November 11th, 2020, 21:30
Haha - glad that worked.

I'm quite happy with this island thanks. Although the margartia goblins have slowed recently, I'll have to crack the whip a bit... :D