PDA

View Full Version : Fumble Dice



Zeus
May 4th, 2009, 21:52
Hello all, hoping someone can help me out as I am new to FGII and completely green when it comes to Lua programming.

My group have been playing D&D since the mid 70s, pretty much D&D upto 3.5e. We have recently decided to move to 4e and I have been steadily preparing our campaign and FG2 for our groups needs over the past few weeks. I am so far very happy with FG2, its so far proven to be a great asset to our D&D gaming. The group are also excited and raring to go.

One thing that we have discussed and would like to bring into FG2 and our game is Fumble dice for when attack rolls equal 1 (Automatic Miss under 4e core rules). The idea being players roll a customised 1d6 to determine the nature of the fumble e.g. simple miss, drop weapon, break weapon, hit ally etc. etc.

The Fumble die rolls have added some fun elements into our past gaming and we would collectivley like to continue this tradition as we move to the latest edition.

I have thus far figured out (from various forum posts) that I can create a custom die in gameelements.xml with somthing like:
<customdie name="dF">
<model>d6</model>
<menuicon>customdice</menuicon>
<script>
function onValue(result)
return result; -- or return math.ceil(result);
end
</script>
</customdie>

Back in FG2 if I type /die 1dF, FG2 rolls a 1d6 but the result value in the chat
window displays ?0 I have tried various return values statements to get this
to work but to no avail I can't even get the example from the documentation
to work, e.g. return math.ceil(result/2)

Am I missing something?

I have see in other posts that I may also have to create a modified
onDiceLanded() handler in chat_chat.lua however I just havn't got
a clue where to start.

Can some kind soul provide a similar example that I can draw from?
Or can anyone provide an extension to foundation/3.5e rulesets that
I can again possibly adapt for use with 4E_JPG.

Thanks in advance.

Foen
May 4th, 2009, 22:03
I think there are two problems here. Firstly, the Lua language is slightly different when embedded in XML compared to being in a standalone file. In XML there is no concept of an end-of-line so your line comment (using -- ) effectively comments out the rest of the script block. You should try --[[ comment ]] instead.

Secondly, to get something more meaningful in the chat box, you need to amend onDiceLanded in chat_chat, as you point out. This is quite bothersome to override in an extension (as it is tightly bound with other code) but should be OK in a custom ruleset.

If you are modding the JPG 4e ruleset, you might want to pause before creating your own version: once you fork from a standard version, it is very much more difficult to reflect more recent code changes in the unmodified ruleset.

Hope this steers you along the right path, and please shout if you want more input!

Cheers

Foen

Zeus
May 4th, 2009, 23:06
I think there are two problems here. Firstly, the Lua language is slightly different when embedded in XML compared to being in a standalone file. In XML there is no concept of an end-of-line so your line comment (using -- ) effectively comments out the rest of the script block. You should try --[[ comment ]] instead.

Secondly, to get something more meaningful in the chat box, you need to amend onDiceLanded in chat_chat, as you point out. This is quite bothersome to override in an extension (as it is tightly bound with other code) but should be OK in a custom ruleset.

If you are modding the JPG 4e ruleset, you might want to pause before creating your own version: once you fork from a standard version, it is very much more difficult to reflect more recent code changes in the unmodified ruleset.

Hope this steers you along the right path, and please shout if you want more input!

Cheers

Foen
Thanks Foen.

The -- comment for the alternative return statement was just included in the post to ease understanding.

The statements I have used in gameelements.xml are:

<customdie name="dF">
<model>d6</model>
<menuicon>customdice</menuicon>
<script>
function onValue(result)
return math.ceil(result/2);
end
</script>
</customdie>

and

<customdie name="dF">
<model>d6</model>
<menuicon>customdice</menuicon>
<script>
function onValue(result)
return result;
end
</script>
</customdie>

Both produced the ?0 result in the chat window.

So an extension sounds like its a no no then and modded ruleset is the way to go. I think I understand the caution around modding the existing 1.4.4 release, particularly as I believe 1.5 is imminent, however I would like to still try to get it to work in 1.4.4 and then if successful would look to adapt this for future versions of the 4E_JPG ruleset as they are released. Therefore I am prepared for the ongoing development.

What I need is a good foundation and starting position as I havn't got a clue about Lua and what would be required for modification of the required onDiceLanded() handler, any help you can offer here would be greatly appreciated.

Thanks again.

peterb
May 5th, 2009, 19:03
On line 216 in chat_chat.lua you have:


result_str = " [AUTOMATIC MISS]";

If you change that line to a function call, such as:


result_str = myAutomaticMiss();

and then let myAutomaticMiss() create your return string as you want it you should get what you want.

Zeus
May 5th, 2009, 19:09
On line 216 in chat_chat.lua you have:


result_str = " [AUTOMATIC MISS]";
If you change that line to a function call, such as:


result_str = myAutomaticMiss();
and then let myAutomaticMiss() create your return string as you want it you should get what you want.

Thanks Peter. So you suggest creating a function that returns a string type and within the function I guess a simple if block to change the output string based upon the result of the die roll e.g.

if result==1 then
return_string="Miss"
elsif result==2 then
...

Sounds straight forward enough, I'll give it a go this weekend when I have some free time. I'll let you all know how I get on.

Thanks again for the kind assistance.

Zeph.

Does Lua support a Case or Switch statements?

peterb
May 5th, 2009, 21:07
Does Lua support a Case or Switch statements?

AFAIK no...

Foen
May 5th, 2009, 21:09
Sorry, no case or switch statements. For simple multi-branch constructs you can use if...elseif..else, otherwise you might want to establish a table with the values:


local map = {[1]="Shite",[2]="Miss",[3]="Close",
[4]="Closer",[5]="Hit",[6]="Smackeroo"};

function resultString(value)
return map[value];
end

Or something similar could be extended for ranges etc.

Just a thought,

Foen

Foen
May 5th, 2009, 21:15
BTW, a good reference for Lua can be found at the official web site, www.lua.org. The version of Lua in FG is 5.1 (with some sand-box restrictions) but a good place to start is the Lua 5.0 pdf manual here (https://www.lua.org/ftp/refman-5.0.pdf).

Cheers

Foen

Zeus
May 5th, 2009, 22:29
BTW, a good reference for Lua can be found at the official web site, www.lua.org (https://www.lua.org). The version of Lua in FG is 5.1 (with some sand-box restrictions) but a good place to start is the Lua 5.0 pdf manual here (https://www.lua.org/ftp/refman-5.0.pdf).

Cheers

Foen

Thanks for the guidance Foen as well as the code suggestion above (looks far more elegant with a table (Lua speak for array?). I shall give it a go and let you all know how it works out.

First things first though any idea why my customdie (detailed in earlier posts) yields a ?0 result when I use /die 1dF or the custom menu to roll? What I am expecting at the moment is a normal 1d6 result but nothing.

Zeus
May 5th, 2009, 22:41
OK got it working by chaging the name of my custom die to d1.

Anything else seems to cause it to not like the name as all rolls yield a 0 result. Is there any naming convention that I need to comply with.

d1 works for now but would prefer fumble or f1 (latter returns result of 0+1). Any ideas?

Zeus
May 5th, 2009, 22:49
PeterB/Foen,

Wait. Thinking about this I am not sure how this will work.

If a player rolls a 1 on an attack the ruleset is setup at present to show "AUTOMATIC MISS".

The suggestion from Peterb to change the return string to a function call to return fumble type e.g. Miss, Hit Ally, Break Weapon etc. is not really enough as the fumble die first needs to be rolled.

So is there a way of auto rolling the fumble die (1d1 in my case) so I can determine the fumble type from its result? Can I call this auto-roll from within the chat_chat.lua script? If not can I prompt the Player to roll a fumble die and then output the specific fumble type from the result?


Thanks for your patience.

Moon Wizard
May 5th, 2009, 23:35
You could use the approach similar to the Confirmation attack roll on potential critical attacks used in the d20_JPG ruleset.

Also, instead of defining a new die. You really only need to define a new roll type. If you notice in the D&D rulesets, there are attack, damage, save, and init roll types.

Here's a potential outline for how to implement:
* When a 1 is rolled on an "attack" roll, then make a new "fumble" roll using a d6.
* When a "fumble" roll lands, you process it separately from the other roll types.
* The fumble table is implemented in the "fumble" roll processor, using the d6 value as lookup.
* Output the result to the chat window.

Cheers,
JPG

Foen
May 6th, 2009, 05:42
I have used 'm' for minus dice (such as m6 to give -d6), but I've no idea what naming is allowed.

Zeus
May 6th, 2009, 11:47
Yes, Fumble rolls implemented and working in 4E_JPG v1.4.4. Many thanks to Peterb, Foen and moon_wizard for their kind assistance, patience and guidance.

It seems to work fine for drag/double-click attack rolls and even seems to work fine for CT attack roll drops. I'm so very happy.

Here's an overview of the code changes:

1. Added FumbleRoll(type, bonus, desc, custom) to chatmanager.lua

-- Fumble Roll
function FumbleRoll(type, bonus, desc, custom)
local dice = {};
table.insert(dice, "d6");
DieControlThrow(type, bonus, desc, custom, dice);
end

2. Updated line 216 in chat_chat.lua from:

result_str = " [AUTOMATIC MISS"];

to

result_str = " [FUMBLED]";
base_desc = "[FUMBLE ROLL] ";
ChatManager.FumbleRoll("fumble", draginfo.getNumberData(), base_desc, custom);

3. Updated onDiceLanded(draginfo) in chat_chat.lua to include new fumble clause for dragtype

function onDiceLanded(draginfo)
local dragtype = draginfo.getType();
if dragtype == "attack" or dragtype == "damage" or dragtype == "init" or
dragtype == "skill" or dragtype == "dice" then
processDiceLanded(draginfo);
return true;
elseif dragtype == "recharge" then
processRechargeRoll(draginfo);
return true;
elseif dragtype == "fumble" then
processFumbleDiceLanded(draginfo)
return true;
end
end

4. Added new processFumbleDiceLanded(draginfo) and FumbleResultString(value) functions to chat_chat.lua.

function processFumbleDiceLanded(draginfo)
-- Build the basic message to deliver
local entry = ChatManager.createBaseMessage(custom);
entry.dice = draginfo.getDieList();
-- Build the result message
local result = entry.dice[1].result;
local result_string = FumbleResultString(result);
entry.text = entry.text .. draginfo.getDescription() .. result_string;
-- Deliver the message
deliverMessage(entry);
end

function FumbleResultString(value)
-- Build local table for Fumble Results
local map = {[1]="Miss!",[2]="Hit Self!!!",[3]="Hit Ally!!!",[4]="Drop Weapon!!!",[5]="Break Weapon!!!",[6]="No Effect"};
return map[value];
end

If anyone sees anything which may cause a problem please let me know. In addition just as soon as moon_wizard releases v1.5 of the 4E_JPG ruleset, I'll take a look to see what, if any, changes would be required. I'll post finding back here in this thread.

Once again many thanks for the assistance.

Zeus
May 6th, 2009, 13:37
Just updated processFumbleDiceLanded(draginfo) to include pc/node name details for consistant message output:

function processFumbleDiceLanded(draginfo)
-- Get any custom data about this roll
local custom = draginfo.getCustomData();
if not custom then
local class, nodename = draginfo.getShortcutData();
if nodename then
local node = DB.findNode(nodename);
if class == "charsheet" then
custom = {pc = node};
else
custom = {npc = node};
end
else
custom = {};
end
end
-- Build the basic message to deliver
local entry = ChatManager.createBaseMessage(custom);
entry.dice = draginfo.getDieList();
-- Build the result message
local result = entry.dice[1].result;
local result_string = FumbleResultString(result);
entry.text = entry.text .. draginfo.getDescription() .. result_string;
-- Deliver the message
deliverMessage(entry);
end

Llellwylliell
May 10th, 2009, 18:53
I may be jumping in late, and my comments are entirely non technical, but they are true and you would do well to consider them.

4e is built around combat. Sure you can do other things, and combat is only really good when properly contextualized through a meaningful (and ideally player driven) storyline, but that isn't what the engine is for. It is for putting a few of your tokens on the map and using teamwork to beat the crap out of some bad guy tokens. It is big on teamwork.

Aside from any technical difficulties in achieving fumbles in FG2, they will kill your game. Likely they will be the source of some laughs, to be sure, but odds are they are eventually going to get everyone killed when someone smashes another player with an enormous daily power.

I could go into detail, but in brief, people need their weapons / wands / bows etc and cannot afford to drop them or have them break. As a rule, you don't disarm weapons in 4e, and sundering them is unthinkable.

My friendly advice is: leave fumbles in the same bin you left thac0.

Zeus
May 13th, 2009, 11:00
I may be jumping in late, and my comments are entirely non technical, but they are true and you would do well to consider them.

4e is built around combat. Sure you can do other things, and combat is only really good when properly contextualized through a meaningful (and ideally player driven) storyline, but that isn't what the engine is for. It is for putting a few of your tokens on the map and using teamwork to beat the crap out of some bad guy tokens. It is big on teamwork.

Aside from any technical difficulties in achieving fumbles in FG2, they will kill your game. Likely they will be the source of some laughs, to be sure, but odds are they are eventually going to get everyone killed when someone smashes another player with an enormous daily power.

I could go into detail, but in brief, people need their weapons / wands / bows etc and cannot afford to drop them or have them break. As a rule, you don't disarm weapons in 4e, and sundering them is unthinkable.

My friendly advice is: leave fumbles in the same bin you left thac0.
Thanks for the warning. After having used it though in the last few games it appears to be working pretty well. Its nicely complementing the critical hit on a 20 and thus appears to be balancing quite well.

It also adds a nice amount of drama to attack rolls as the players know a roll of 1 is likley to result in some sort of trouble. The 4e DMG also comments on Fumbles as an additional House Rule that can be introduced. However rather than the break weapon, drop weapon blah blah thy suggest offering Combat Advantage to the player characters opponents.

Anyway the code definatley works in FG2 2.3.6 and 2.4 RC4 and I have successfully tested it with moon_wizards 4E_JPG v1.4.4 and the recently released v1.5 ruleset.

Llellwylliell
May 13th, 2009, 18:02
Offering combat advantage is reasonable. I monsters can fumble as well then I can see how that would add an extra consideration into a groups tactics round by round.